笔试题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);
}
解析:
(这题里有关于优先级的问题,可以上网查查)
答案大家可以自行复制代码打印看看
标签:解析,进阶,int,笔试,C语言,char,printf,main From: https://blog.csdn.net/m0_75122019/article/details/142330087