1. 先思考以下的指针变量, 取值后会是多少
- char temp[20]={11,22,33,44,55,66,77,88,99};
- char *p1 = temp;
- printf("*p1=%d", *p1);// 想想看会是多少呢?
对于上例题中的结果想必很多同学知道答案, 为 11(你计算对了么)
我们分析一下: 因为 p1 是一个指针变量, 即可以存储指针 (即地址), 而程序中把 temp 赋值给了 p1, 又因为 temp 为 char 类型数组的名字, 即是下标为 0 的元素的地址, 所以 p1 这个指针变量存储的是 temp[0] 这个元素的地址,*p1 得到的结果为 11, 就不足为奇了
2. 接着上面的代码, 再添加如下代码,
printf("*(p1+1)=%d", *(p1+1));
此时程序会输出多少呢?
答案为 22
同样接下来咱们分析一下: 因为 p1 保存了 temp[0]这个元素的地址, 即 p1 指向了 temp[0], 而 p1+1 的结果可以理解为 temp[1]的地址, 所以 *(p1+1)就是取的 temp[1]的值, 即 22
3. (预告: 接下来的是重头戏)
接着上面的代码, 再添加如下代码:
printf("*(char *)((short*)p1+1)=%d", *(char *) ((short *)p1+1));
此时程序会输出多少呢?
答案为 33
啊???33??? 怎么计算的呢?
下面咱们仔细分析一下这个值为什么会是 33
<1> p1 在定义的时候已经进行了赋值, 即初始化为 temp[0]元素的地址
<2 > 根据优先级以及结合性, 对应表达式 *(char*) ((short *)p1+1)的计算先后顺为: 先对 p1 进行临时性的强制类型转换, 即此时 p1 这个指针变量的类型已经变成了 short * 类型; 但要注意此时 p1 保存的还是 temp[0]元素的地址; 接下来要对 p1 进行 + 1 了, 此时到底指向了哪里呢?
告诉大家一个技巧: 对一个指针变量 + 1 的时候, 指针到底向后偏移多少个字节, 要根据指针变量当前的类型而定, 如果是 char * 的那么 + 1 会向后偏移 1 个字节, 如果是 short * 那么 + 1 会向后偏移 2 个字节, 如果是 int * 那么就会向后偏移 4 个字节(具体的要根据不同的编译器而定);
根据刚刚告诉大家的小技巧, 试试看(short *)p1+1 会指向哪个元素呢?
对了, 此时 p1 指向了 temp[2]这个元素, 注意, 因为此时 p1 的类型已经转换为 short*, 所以如果此时取值会根据 p1 指向的地址连续取 2 个字节的数据当做结果此时肯定不是 33,,, 有的同学已经注意到了在最外边还有一个 (char*) 即类型转换, 此时又把 p1 的类型转换为 char * 了, 然后再取值就会得到 33
来源: http://www.jianshu.com/p/7746df88faae