目录
笔试题1:
笔试题2:
笔试题3:
笔试题4:
笔试题5:
写在最后:
笔试题1:
#includeint main() { int a[5] = { 1, 2, 3, 4, 5 }; int* ptr = (int*)(&a + 1); printf("%d,%d", *(a + 1), *(ptr - 1)); return 0; }
程序运行结果如下:
笔试题2:解析:
对于*(a+1),a表示该数组元素的首地址,即1的地址,首地址元素加1代表表示数组中第二个元素的地址,即表示2的地址,对其* 解引用,作用就是相当于a[1],访问该数组的第二个元素,在屏幕上输出2。对于*(ptr-1),&a就是该数组的地址,数组地址加1就是跳过一个a数组的大小的地址,这时候类型为int * [5],然后强制类型转换为int *,*(ptr-1)指向a数组元素内容5。
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; }
程序运行结果如下:
笔试题3:解析:
&a得到就是数组a的地址,&a+1就是跳过一个数组a的大小,本来类型是int * [4],强制类型转换成int*,ptr[-1]回退的是一个整型的空间,因为其类型是int*,一次能够访问4个字节,所以对其进行输出后的结果是4。对a进行强制类型转换后a的类型就变成了int,+1就是简单的加1,取出的数组就是00 00 00 02,因为其是小端存储,并且是按照16进制形式进行打印,所以打印结果是20 00 00 00。
#includeint main() { int a[3][2] = { (0, 1), (2, 3), (4, 5) }; int* p; p = a[0]; printf("%d", p[0]); return 0; }
程序运行结果是:
笔试题4:解析:
对数组a进行初始化时用到了逗号(,)表达式,像{ (0,1),(2,3),(4,5) }的初始化赋值等于{1,3,5},二维数组按行存放,a[3][2]表示3行2列,第一列内容是1,3,第二行是5,0,第三行为0,0。a[0]是第一行的数组名,而此处的数组名代表的是第一行第一个元素的地址 ,即a的地址,p[0]代表的是第一行第一个元素的地址,且此时的类型也是int*,对其进行解引用之后就是数组第一行第一个元素的内容,即1。
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; }
程序运行结果是:
笔试题5:解析:
&aa+1就是跳过一个二维数组aa的大小,指向10的后面,此时的类型是int (*)[2][5],强制类型转换后变成int*。此时使ptr1-1就是回退一个整型元素,此时指向元素10,*解引用之后得到元素10。
aa是数组首元素的地址,即二维数组第一行的地址,aa+1跳过一行,此时是数组第二行的地址,*解引用之后就是第二行的数组名,强制类型转换后类型变成了int *,此时使ptr2-1就是回退一个元素,指向元素5,*解引用之后得到元素5。
int main() { char* a[] = { "work","at","boss" }; char** pa = a; pa++; printf("%sn", *pa); return 0; }
程序运行结果是:
写在最后:解析:
char* a[] = { "work","at","boss" };
对数组a进行{ }的初始化,即等价于a[0]="work",a[1]="a"t,a[2]="boss";a表示的是数组首元素的地址,a[0]的地址,pa的类型是char**,即二级指针,+1后跳过一个char *大小类型,pa++后pa指向的是a[1],存储的是a[1]即at的地址,*解引用之后得到的就是字符串常量中"at"中a的地址。
以上是个人粗略的理解,仅供讨论参考,如有出错请在评论区指正出来,我会及时改正。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)