#include <stdio.h>
int main()
{
int a[5] = { 1, 2, 3, 4, 5 };
int *ptr = (int *)(&a + 1);
printf( "%d,%d", *(a + 1), *(ptr - 1));
return 0;
}
//
程序的结果是什么?
答案中显示第一个是2,第二个是5
咱们先来解释一下第一个答案的原因,首先,a代表的是数组首元素的地址,a+1代表的是2的地址,2解引用就是2,所以答案是2
第二个当中,答案是5,首先,我们知道&a代表的是整个数组的地址,&a+1则是跳过了这个数组,然后转化为int*类型,存放到了ptr当中。
ptr-1代表着此时原本在数组末尾的地址向前移动了一步,此时代表的是5的地址,然后解引用,代表的就是5.
//在X86环境下
//假设结构体的??是20个字节
//程序输出的结构是啥?
#include<stdio.h>
struct Test
{
int Num;
char* pcName;
short sDate;
char cha[2];
short sBa[4];
}*p = (struct Test*)0x100000;
int main()
{
printf("%p\n", p + 0x1);
printf("%p\n", (unsigned long)p + 0x1);
printf("%p\n", (unsigned int*)p + 0x1);
return 0;
}
看到这个答案,大家知道原因吗?此时编译器为x86环境,这是因为最初的机器基本都是x86环境
首先,我们知道p是0x100000,而p+1跳过的是一个结构体大小,这个机构体是20个字节,所以可能有好多同学觉得答案是0x100020,但是这个是16进制啊,所以答案应该是00100014
第二个的答案是00100001,这个是因为首先p进行了类型的强制转换,从结构体类型转换成了整数类型,整数类型+1,那真的是+1,所以答案是00100001,
第三个答案是是00100004,有了上面的那个例子,这个例子是不是就很好理解,因为此时的p被强制类型转换成了指针类型,指针类型的大小是4/8,此时是x86环境下,所以指针的大小是4,所以答案是00100004
#include <stdio.h>
int main()
{
int a[3][2] = { (0, 1), (2, 3), (4, 5) };
int *p;
p = a[0];
printf( "%d", p[0]);
return 0;
}
?
这个答案,大家有想到吗?,首先,a数组的这个部分大家看懂了吗
这个是你们认为的a数组,然后设立了一个整数指针p,将a的首行的地址存放到了p当中,然后将p的首元素打印出来,答案是1,这个时候你可能好奇了,答案应该是0呀,怎么会是1呢,别着急,听我慢慢和你说。
首先,a数组就不是上面表现的那样的,(0,1)这个是一个逗号表达式,输出结果是1
所以上面的第一个式子其实等价于下面的这个式子
int a[3][2] = { 1,3,5 };
?
这个搞懂的话,后面的顺其自然自然也懂了。
//假设环境是x86环境,程序输出的结果是啥?
#include <stdio.h>
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是一个数组指针,指向的数组当中有4个整数类型的元素,a是一个五行五列的数组
然后将a的地址给了p,所以此时p是数组首元素的地址,而指针-指针的绝对值=二者之间相差的元素个数而p【0】,p【1】,还是p【4】只能包含4个元素,而a【0】,a【2】等能包含5个元,所以&p【4】【2】-&a【4】【2】的结果应该是-4,因为是小地址-大地址,所以用%d打印的时候,打印出来的结果就是-4,当用%p打印的时候,打印的应该是-4的补码(把补码当成了-4的地址,打印出来),结果就是FFFFFFFC
#include <stdio.h>
int main()
{
int aa[2][5] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
int *ptr1 = (int *)(&aa + 1);
int *ptr2 = (int *)(*(aa + 1));
printf( "%d,%d", *(ptr1 - 1), *(ptr2 - 1));
return 0;
}
?
有了上面的几道题的经验之后,这道题大家有想法吗?
这里面有两个关键点,首先第一个是&aa+1,这个是跳过了整个数组,此时ptr1指向了aa数组的末尾,第二个是aa+1,这个时候aa是数组名,代表的是数组首元素的地址,也就是aa数组第一行的地址,+1就是指向了第一行元素的末尾,第二行的开始,所以答案第一个是10,第二个是5
#include <stdio.h>
int main()
{
char *a[] = {"work","at","alibaba"};
char**pa = a;
pa++;
printf("%s\n", *pa);
return 0;
}
?
?在这道题当中,首先创建了一个数组a,a当中的每个元素都是char*类型的指针,下一步当中,把创建了一个指针pa,来存放a的地址,而a的类型是char*,而后pa++,此时pa,指向的是at的地址,然后将pa解引用,打印出来,结果就是at。