C语言进阶⑫(指针下)(指针和数组笔试题解析)(杨氏矩阵)(上):https://developer.aliyun.com/article/1513059
笔试题4:
#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; }
解析:
#include<stdio.h> int main() { int a[3][2] = { (0, 1), (2, 3), (4, 5) }; //()不是{} 是逗号表达式! 天坑 1 3 // 5 0 // 0 0 int* p; p = a[0]; printf("%d", p[0]);//p==a[0] p[0]==a[0][0]==1 return 0; }
笔试题5:
#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; }
解析:
#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; } //a的类型是int(*)[5]+1跳过5*4个字节 p的类型是int(*)[4] +1跳过4*4个字节 //答案是FFFFFFFC,-4 看图
能力有限,再看看佬的讲解:
笔试题6:
#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; }
解析:
#include<stdio.h> int main() { int aa[2][5] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; int* ptr1 = (int*)(&aa + 1); //&aa整个数组的地址+1跳过整个数组 int* ptr2 = (int*)(*(aa + 1));//首元素(首元素是第一行)地址+1,第二行地址 //第二行首元素地址解引用得到6 int*没有意义,本来就是 *(aa + 1)相当于aa[1] printf("%d,%d", *(ptr1 - 1), *(ptr2 - 1));//指针减一(前一个元素):10,5 return 0; }
笔试题7:
#include<stdio.h> int main() { char* a[] = { "work","at","alibaba" }; char** pa = a; pa++; printf("%s\n", *pa); return 0; }
解析:
#include<stdio.h> int main() { char* a[] = { "work","at","alibaba" };//指针数组 char** pa = a; pa++;//跳过数组里的一个元素,跳到at的地址 printf("%s\n", *pa);//at(%s从a开始向后打印字符串) return 0; }
笔试题8:
#include<stdio.h> 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; }
解析:哪一步不懂可以看看放在后面的佬的图
#include<stdio.h> int main() { char* c[] = { "ENTER","NEW","POINT","FIRST" }; char** cp[] = { c + 3,c + 2,c + 1,c }; char*** cpp = cp; printf("%s\n", **++cpp);//++cpp==c+2 解引用得c+2内容,即POINT地址 再解引用得POINT printf("%s\n", *-- * ++cpp + 3);//++cpp在上一行基础在+1得到c+1地址 //解引用得c+1内容 再--得到c的内容 再解引用得到ENTER的地址即E的地址 //再+3得到第二个E的地址 打印出ER printf("%s\n", *cpp[-2] + 3);//*cpp[-2]==*(*(cpp-2)) //cpp在上面内容-2得到c+3的内容 解引用得到c+3地址 再解引用得到FIRST地址 //再+3得到S的地址 打印出ST printf("%s\n", cpp[-1][-1] + 1);//cpp[-1][-1]==*(*(cpp-1)-1) //++cpp等价于cpp=cpp+1 cpp变了 但cpp-2 cpp没有变 还是指向c+1 //cpp在上面内容-1得到c+2的内容 解引用得到c+2地址 再-1得到c+1的地址 //再解引用得到NEW的地址 再+1得到E的地址 打印出EW return 0; }
可以一边看文字一边画图理解:(也可以配合调试)
佬的讲解:
C语言进阶⑫(指针下)(指针和数组笔试题解析)(杨氏矩阵)(下):https://developer.aliyun.com/article/1513066