笔试题一
✅程序的结果是什么?
#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;
}
详解:&a取出的是整个数组的地址 ,&a+1表示增加了一整个数组的大小,单位是字节数组名a为首元素的地址&a[0],则*(a+1)即 a[1] 的值
故答案为2 5
笔试题二
#include<stdio,h>
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;
}
详解:&a取出的是整个数组的地址 ,&a+1表示增加了一整个数组的大小,单位是字节
ptr1[-1] = ptr1 -1 , 由图可知 ,(int *)(&a + 1) 在内存中指向的是 04 00 00 00
使用%x打印即 00 00 00 04, 故 ptr1[-1] = 4
由上图可知,(int*)((int)a+1) 在内存中指向的是 00 00 00 02
在小端存储模式下用十六进制表示,即 02 00 00 00
使用%x打印即 2 00 00 00, 故*ptr2 = 2 00 00 00
笔试题三
#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;
}
详解:
int a[3][2] = { (0, 1), (2, 3), (4, 5) };
// = {1,3,5}
// 1 3 a[0] 即第一行的数组名 ,p= a[0]则p[0] = a[0][0] = 1
// 5 0
// 0 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;
}
详解:&p[4] [2] - &a[4] [2] 指针相减得到元素个数,为4个,又低地址-高地址,%d打印结果为 -4
使用%p打印时,打印-4地址
原码10000000 00000000 00000000 0000 0100
反码11111111 11111111 11111111 11111011
补码11111111 11111111 11111111 11111100
即FF FF FF FC
笔试题五
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取出的是整个数组的地址 ,&aa+1表示增加了一整个数组的大小,单位是字节
aa 表示的是首元素的地址
笔试题六
#include <stdio.h>
int main()
{
char *a[] = {"work","at","alibaba"};
char**pa = a;
pa++;
printf("%s\n", *pa);
return 0;
}
详解: char* a[] 为一个存放字符串地址的数组,其中a 表示字符串”work“首元素的地址, 赋值给了papa++时,向前移动一个char的大小,即指向字符串”at'' 的首元素的地址,故 pa = "at";
笔试题七
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>
#include<stdlib.h>
int main()
{
char* c[] = {"ANTER","NEW","POINT","FIRST"};
char** cp[] = {c + 3,c + 2,c + 1,c};
char*** cpp = cp;
printf("%s\n",**++cpp);//POINT
//cpp+1指向c+2,两次解引用后找到POINT
printf("%s\n", *--*++cpp + 3);//ER
//++cpp:cpp指向c+1
//*(++cpp):得到c指针数组的第二个元素的指针的内容
//--(*(++cpp)):第二个元素指针-1,得到第一个元素指针的内容
//*(--(*(++cpp))):解引用得到ENTER
//*(--(*(++cpp)))+3:指向E,输出ER
printf("%s\n",*cpp[-2]+3);//ST
//注意cpp到目前为止还是指向c+1,cpp[-2]指向的地址内容变化,cpp的指向并未变化
//*cpp[-2]==*(*(cpp+(-2))) 所以*cpp[-2]指向,c+3,得到的是FIRST
//*cpp[-2]+3指向S
printf("%s\n",cpp[-1][-1]+1);//EW
//注意cpp到目前为止还是指向c+1
//cpp[-1][-1]+1 == *(*(cpp-1)-1)+1
//*(cpp-1)指向c+2;
//*(*(cpp-1)-1)指向c[2]的内容;
//*(*(cpp-1)-1)+1指向NEW中的N
return 0;
}