题一:
//程序的结果是什么? int main(){ int a[5] = { 1, 2, 3, 4, 5 }; int *ptr = (int *)(&a + 1); printf( "%d,%d", *(a + 1), *(ptr - 1)); return 0; }
int main(){ int a[5] = { 1, 2, 3, 4, 5 }; int *ptr = (int *)(&a + 1); //&a取到整个数组的地址,+1跳过这个数组指向下一个地址 //(int *)强转类型 printf( "%d,%d", *(a + 1), *(ptr - 1)); //a+1表示第二个元素的地址,解引用得到第二个元素,也就是2 //ptr - 1得到第五个元素的地址,解引用得到第五个元素,也就是5 return 0; }
struct Test { int Num; char* pcName; short sDate; char cha[2]; short sBa[4]; }*p; //假设p 的值为0x100000。 如下表表达式的值分别为多少? int main() { printf("%p\n", p + 0x1); printf("%p\n", (unsigned long)p + 0x1); printf("%p\n", (unsigned int*)p + 0x1); return 0; }
struct Test { int Num; char* pcName; short sDate; char cha[2]; short sBa[4]; }*p; //1个int4字节,1个char*4字节,1个short2字节 //1个存放两元素的char数组2字节,1个存放四元素的short数组8字节 //所以这个结构体的大小为4+4+2+2+8=20字节 int main() { printf("%p\n", p + 0x1); //0x1表示十六进制下的1 //p是一个结构体指针,p的值为0x100000 //加一就相当于加了20,20换成十六进制就为14 //所以结果为0x100014 printf("%p\n", (unsigned long)p + 0x1); //(unsigned long)把p的类型强转了,加一就是加一 //结果为0x100001 printf("%p\n", (unsigned int*)p + 0x1); //(unsigned int*)把p强转成一个int类型的指针 //加一相当于加四 //结果为0x100004 return 0; }
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; }
int main() { int a[4] = { 1, 2, 3, 4 }; int* ptr1 = (int*)(&a + 1); //&a取到整个数组的地址,+1跳过整个数组 //int*强转类型,ptr1每次加减只跳过四个字节 int* ptr2 = (int*)((int)a + 1); //a代表首元素地址,被强转为int类型,就是一串二进制数 //+1,就是这串二进制数+1,相当于变动了一个字节 //int*强转类型,长度编程4个字节 printf("%x,%x", ptr1[-1], *ptr2); //ptr[-1]相当于*(ptr1-1),得到结果是4,以十六进制打印还是4 //*ptr2得到的十六进制是2000000 return 0; }
题四:
int main() { int a[3][2] = { (0, 1), (2, 3), (4, 5) }; int* p; p = a[0]; printf("%d", p[0]); return 0; }
int main() { int a[3][2] = { (0, 1), (2, 3), (4, 5) }; //注意!!!这里是()不是{},有谁上当了我不说话(doge) //所以a[3][2]实际存放的是{ 1, 3, 5} int* p; p = a[0]; //p存放的是数组a[3][2]的第一行地址 printf("%d", p[0]); //p[0]相当于*p,即*a[0],得到第一行第一个元素,也就是1 return 0; }
题五:
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; }
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][2]与&a[4][2]之间的元素个数为4 //但是地址是从低到高排的,所以结果为-4 //负数在内存中以补码存放 //-4补码:11111111 11111111 11111111 11111100 //%p以指针的形式打印,不会管什么补码原码会 //直接把这串二进制以十六进制的形式打印出来,结果为FF FF FF FC //%d打印出来的值才是-4 return 0; }
题六:
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; }
int main() { int aa[2][5] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; int* ptr1 = (int*)(&aa + 1); //&aa取到整个数组的地址,+1跳过这个数组 //int*强转类型,ptr1长度为4个字节 int* ptr2 = (int*)(*(aa + 1)); //aa表示第一行地址,+1得到第二行地址 //解引用得到第二行第一个元素的地址 //(int*)是个烟雾弹,有没有它结果都一样 printf("%d,%d", *(ptr1 - 1), *(ptr2 - 1)); //ptr1-1得到第二行第五个元素的地址,解引用得到10 //ptr2-1得到第一行第五个元素的地址,解引用得到5 return 0; }
题七:
int main() { char* a[] = { "work","at","alibaba" }; char** pa = a; pa++; printf("%s\n", *pa); return 0; }
int main() { char* a[] = { "work","at","alibaba" }; //"alibaba"划重点,说明这是阿里的题(doge) //char*类型,所以存放的是三个单词的首字母的地址 char** pa = a; //a表示首元素的地址,一个char*的地址,用二级指针存放 pa++; //pa++,指向第二个元素 printf("%s\n", *pa); //pa解引用得到字符串“at”首字母“a”的地址 //%s,从“a”开始打印,遇到“\0”停止 //字符串会自动在末尾加上一个“\0” //所以打印结果为“at” //阿里?就这?我,会做!明天,offer!懂? return 0; }
题八:
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; }
int main() { char* c[] = { "ENTER","NEW","POINT","FIRST" }; //char*类型,所以存放的是三个单词的首字母的地址 char** cp[] = { c + 3,c + 2,c + 1,c }; char*** cpp = cp; //cpp存放cp首元素地址 printf("%s\n", **++cpp); //++cpp存放cp第二个元素的地址,cpp已存放的值已经发生改变 //解引用得到c+2即c第三个元素的地址 //再次解引用得到‘P’的地址 //则%s打印出"POINT" printf("%s\n", *-- * ++cpp + 3); //cpp存放的是cp[1]的地址,++cpp则指向cp[2] //解引用得到“c+1”,--(c+1)得到c,指向‘E’的地址 //‘E’+3得到第二个‘E’的地址 //%s从第二个‘E’开始打印,结果为“ER” printf("%s\n", *cpp[-2] + 3); //cpp存放的是cp[2]的地址,cpp[-2]即*(cpp-2),得到“c+3” //再次解引用,得到‘F’的地址 //‘F’+3得到‘S’的地址 //%s从‘S’开始打印,结果为“ST” printf("%s\n", cpp[-1][-1] + 1); //cpp[-1][-1]相当于*(*(cpp-1)-1) //*(cpp-1)得到“c+2”,c+2-1 == c+1 //*(c+1)得到‘N’的地址 //‘N’+1得到‘E’的地址 //%s从‘E’开始打印,结果为‘EW’ return 0; }