自学内容网 自学内容网

C语言指针进阶笔试题(含解析)

笔试题1:

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 + 1),a是首元素的地址,加1 之后就是第二个元素的地址,解引用就是2。ptr是&a+1,取出的是整个数组的地址,加1跳过整个数组:

强转为int*之后 -1 :

笔试题2:

//告知这个结构体大小是20个字节,必须在x86环境下
struct Test
{
int Num;
char* pcName;
short sData;
char cha[2];
short sBa[4];
}*p;
//假设p的值是0x100000. 0x是16进值
int main()
{
printf("%p\n", p + 0x1);
printf("%p\n", (unsigned long)p + 0x1);
printf("%p\n", (unsigned int*)p + 0x1);
}

 解析:0x1 16进值也是1,所以第一个就是结构体指针加1,跳过一个结构体的大小,第二个被强转成整形,加1 就是加1 ,没什么意义。第三个强转的int*,所以加1就是跳过一个int类型。

笔试题3:

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;
}

解析:ptr1很好理解,取出了整个数组的地址,加1之后被强转为int*,和第一天差不多,ptr[-1] == *(ptr - 1)。ptr2首先把地址强转成整形加1就是加1了,然后又被强转成int*,解引用是怎么样的?

 这是内存设置中的样子,int*取出四个字节。

笔试题4:

int main()
{
int a[3][2] = { (0,1),(2,3),(4,5) };
int* p;
p = a[0];
printf("%d", p[0]);
return 0;
}

解析:二维数组初始化里有几个小括号,这几个小括号是逗号表达式,所以二维数组里的元素只有,1,3,5。a[0]是第一行数组的数组名,所以p[0]是第一行数组的第一个元素。

笔试题5:

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 是以内存方式打印,打印地址的,不管是什么都打印成内存指针的样子。

笔试题6:

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;
}

解析:

笔试题7:

int main()
{
char* a[] = { "work","at","alibaba" };
char** pa = a;
pa++;
printf("%s\n", *pa);
return 0;
}

解析: 

解引用pa之后找到的就是"a"的地址,所以打印出来是“at” 。

笔试题8:

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);
}

解析: ​​​​​​​

(这题里有关于优先级的问题,可以上网查查)

答案大家可以自行复制代码打印看看 


原文地址:https://blog.csdn.net/m0_75122019/article/details/142330087

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!