生命是一条艰险的峡谷,只有勇敢的人才能通过。 ——米歇潘
说明:用的vs都是x86的环境,也就是32位平台。
建议:对于难题来说,一定要配合画图来解决问题。
第一题:
#include<stdio.h>
int main()
{
int a[4] = { 1,2,3,4 };
int* ptr1 = (int*)(&a + 1);
//&a表示取出整个数组的地址,&a+1也就跳过了一个数组
//此时ptr1也就是4后面一个数的地址
int* ptr2 = (int*)((int)a + 1);
printf("%x,%x", ptr1[-1], *ptr2);
//ptr1[-1]表示为*(ptr1-1),ptr1-1就表示数组的最后一个数的地址
//*(ptr1-1)也就是4
return 0;
}
在int* ptr2 = (int*)((int)a + 1)中,a为地址,但是 (int)a 将a强制转换为整数。
比如:假设a的地址就是0x0012ff40,(int)a将a强制转换为整数0012ff40,+1之后就变成了0012ff41。与之前的a的地址比较,就变了1,故相当于加上了一个字节。
又因为最后是以%x打印出来的,4的十六进制就是4,最后打印出来就是4。
而0x02000000以%x打印出来就是2000000,最后结果就是2000000。
第二题:
int main()
{
int a[3][2] = { (0,1),(2,3),(4,5)};
int* p;
p = a[0];
//a[0]表示第一行的数组名,而数组名表示首元素的地址
//a[0]就相当于&arr[0][0]
printf("%d\n", p[0]);
//p[0]表示为*(p+0),最后也就是a[0][0]的值,也就是0
return 0;
}
答案为什么是1呢?刚刚我们分析的没有问题呀,确实刚刚我们分析的是没有问题的。
但是仔细看看你会发现,二维数组里面是括号,而不是花括号。int a[3][2] = { (0,1),(2,3),(4,5)}。
这样的话二维数组里面就是三个逗号表达式呀,而逗号表达式的结果就是最后一个值得结果。二维数组最后结果就是int a[3][2] ={1,3,5}。所以a[0][0]也就是1了呀。
此题给我们一个教训:在做题时一定要认真的看题,注意细节,方可立于不败之地。
第三题:
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]);
//指针减指针是中间的数字个数。
//p解引用访问4个整型
return 0;
}
可以看出中间元素是4个,但是是低地址减搞地址,所以以%d打印出来的结果是-4。
-4的原码:10000000000000000000000000000100
反码: 111111111111111111111111111111111011
补码: 111111111111111111111111111111111100
以%p打印出来的是十六进制的数,所以-4的补码转换为16进制为:FFFFFFFC
所以最后的结果是:FFFFFFFC,-4。
第四题:
int main()
{
int aa[2][5] = { 1,2,3,4,5,6,7,8,9,10 };
int* ptr1 = (int*)(&aa + 1);
//&aa取出整个数组的地址,&aa+1跳过整个数组
int* ptr2 = (int*)(*(aa + 1));
//aa表示第一行的地址,aa+1之后就是第二行的地址
//也就是&a[2],解引用就变成了a[1]
//而a[1]是第二行的数组名,而数组名表示数组首元素的地址
printf("%d,%d", *(ptr1 - 1), *(ptr2 - 1));
//(ptr1 - 1)表示数组最后一个数组的地址,解引之后就是10
//(ptr2 - 1)也就是表示5的地址了
return 0;
}
第五题:
int main()
{
char* a[] = { "hello","world","quick" };//这是一个指针数组
char** pa = a;//pa表示首元素的地址
pa++;//指向下一个地址
printf("%s\n", *pa);
//这时pa就表示&a[1],*pa就是a[1]
return 0;
}
第六题:
好,最难的来了,我们还是一样,慢慢分析。
int main()
{
char* c[] = { "PAPER","BIT","POWER","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;
}
感谢支持!