类型转换

关于类型转换

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
int p = 0x12345678;
char *t;
t = (char *)&p;
printf("p:0x%x\n",&p);
printf("q[0]:0x%x\n",q[0]);
printf("&q[0]:0x%x\n",&q[0]);
printf("q[1]:0x%x\n",q[1]);
printf("&q[1]:0x%x\n",&q[1]);
printf("q[2]:0x%x\n",q[2]);
printf("&q[2]:0x%x\n",&q[2]);
printf("q[3]:0x%x\n",q[3]);
printf("&q[3]:0x%x\n",&q[3]);
运行结果:
p:0xffffcbc4
q[0]:0x78
&q[0]:0xffffcbc4
q[1]:0x56
&q[1]:0xffffcbc5
q[2]:0x34
&q[2]:0xffffcbc6
q[3]:0x12
&q[3]:0xffffcbc7
  • &p本来是int *类型,强制转换为char *

    1
    2
    int a = 10;
    int *p = &a;
  • int *p表示(int *)p,即指向整型变量的指针变量

  • p对于a的首地址
  • p所对内存长度为sizeof(int)个字节

对指针进行强制类型转换时并不改变指针的值,即对应的首地址,但其对应的内存长度会改变。许多编译器对指针类型要求严格,在传递指针时要进行强制类型转换。

1
2
3
int m = 20;
float t;
t = (float)m;

此时的强制类型转换,会将m处存放的值转化为float型的变量赋给t里的内容。
再举一例:

1
2
3
char ch1 = 0x0A; // 假设ch1地址位于20H,即m[20H] = 0x0AH
char* p1 = &ch1;
char** pp1 = &p1;

观察下表:

variable addr value
ch1 20 0A
None 21 CC
p1 22 20
pp1 23 22

若内存空间可看成一个数组:char m[256],则

1
char ch1 = **pp1;

因此,可理解成:

1
char ch1 = m[m[pp1]]; // 解二级指针引用

同样地,

1
2
3
char ch2 = *p1;
可理解成:
char ch2 = m[p1];// 解指针引用

在汇编层面,就是按上述叙述理解,比如:

1
2
MOV EAX, [EDA + 8]
CALL EAX

总结

当你想动态分配内存给二维数组,如矩阵、表等的时候,就可以使用(* *)这种二级指针进行操作了。简单地说,二级指针能够修改上一级的指针,就像一级指针能修改其指向的值。
同时,二级指针相对于一级指针来说,其减少了函数传参,如需传一个*offset来指示函数调用后的偏移量,而若传二级指针,则在函数调用后,指针就自动直接指向偏移后的地址了。
另一方面,二级指针,只是指向的变量换成指针了而已。