#include<stdio.h>
int main()
{
int a[4] = { 1, 2, 3, 4 };
int* ptr1 = (int*)(&a + 1);
int* ptr2 = (int*)((int)a + 1);
printf("%x,%x", ptr1[-1], *ptr2);
return 0;
}
需要强调的是ptr2,a强制类型转换为int型再+1,再转化为int*类型,是指真正的在地址上+1,众所周知int类型大小是4,这个可以使其指向a的第一个元素的第二个字节出(要注意大端存储和小端存储)。
int main()
{
int a[5][5];
int(*p)[4];
p = a;
printf( "%p,%d\n", &p[4][2] - &a[4][2], &p[4][2] - &a[4][2]);
return 0;
}
计算后的数字以补码的形式存储在内存中,若按照%p的形式打印则转变成16进制,直接被解析不转换成原码
(四个二进制位转化位一个十六进制位)
int main() { char *c[] = {"ENTER","NEW","POINT","FIRST"}; char**cp[] = {c+3,c+2,c+1,c}; char***cpp = cp; printf("%s\n", **++cpp); printf("%s\n", *--*++cpp+3); printf("%s\n", *cpp[-2]+3); printf("%s\n", cpp[-1][-1]+1); return 0; }
c是一个指针数组,则数组名表示首元素的地址,即第一个数组的地址也即字符串ENTER的地址,c+数字指的是地址移动多少个数组,如果想移动字符串内部的指针,则可以通过解引用的方法,如果想得到第一个数组第二个元素的话,*(*(c+0)+1)得到的便是第一组第二个元素的值
由此可知:对指向一个数组的指针进行解引用操作得到的是该数组首元素的地址
知道了这些,我们可以着手做这个问题了
由题意我们可以得到如下图片,接着开始解答
**++cpp根据操作符优先级,先进行++运算,之后得到的是cp+1,即可答案得到POINT
第二个继续++得到
根据操作符优先级+的优先级比*的优先级要低,则继续得到的是c+1,若--得到的是c的地址,之后再解引用,c是数组指针,根据数组指针解引用得到数组首元素的地址得解引用得到了E(第一个)的地址,再+3得到的是E(第二个)的地址。答案得到ER
cpp[-2]=*(cpp-2)得到的是c+3,之后再*得到的是F(首元素)的地址,之后再+3得到的是S的地址答案得到ST
cpp[-1][-1]=*(*(cpp-1)-1),*(cpp-1)拿到c+2,之后再-1解引用得到NEW,可得答案得EW