前言
本次对为面试题题量不大有一些难大家可以试试.
废话: 写的有点累就不写废话了.
笔试题
答案我都放在了代码块里在最底部.
第一题
int main() { int a[5] = { 1, 2, 3, 4, 5 }; int *ptr = (int *)(&a + 1); printf( "%d,%d", *(a + 1), *(ptr - 1)); return 0; } //程序的结果是什么? //答 2 5
第一个答案a为首元素地址+1后解引用是第二个元素的地址
第二个答案中&a+1是跳过了整个数组所以ptr指向的是5后的地址又因为ptr是int*类型
-1回跳了4个字节就指向了5
第二题
//由于还没学习结构体,这里告知结构体的大小是20个字节 struct Test { int Num; char *pcName; short sDate; char cha[2]; short sBa[4]; }*p; //假设p 的值为0x100000。 如下表表达式的值分别为多少? //已知,结构体Test类型的变量大小是20个字节 int main() { printf("%p\n", p + 0x1); printf("%p\n", (unsigned long)p + 0x1); printf("%p\n", (unsigned int*)p + 0x1); return 0; } //答案: 0x100014 0x100001 0x100004
第一个答案: 结构题的大小为20个字节我们创建的结构题可以类似于关键字在指针是也奏效我们的结构体指针可以直接跳过20个字节通过16进制打印就是答案
第二个答案: 因为对p强制类型转换成了整数(泛意)所以加上16进制的1就和正常整数加1一样通过地址的形式打印出来就是答案
第三个答案: 与第二个类似我们的指针是根据类型进行跳跃的我们unsigned int*类型的指针一次跳动四个字节如答案所示.
小结: 本次题目主要考察陌生类型的代码我们的处理能力.
第三题
//%x是对十六进制的打印 %#x可以在打印时增加前缀0x 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; } //答案: 4 2000000
第一个答案: 与第一题的相似我们只需知道解引用操作符[X]可以理解为*(ptr+X)所以ptr[-1]相当于*(ptr1-1) 所以为4
第二个答案: 比较复杂涉及到我们使用编译器的大小端储存问题俺使用的是VS2019为小端储存我们以小端储存(不知道大小端的下面有连接)为例:
https://blog.csdn.net/qq_61434711/article/details/121798086?spm=1001.2014.3001.5501
我们将a强制类型转换成int那么我们的(int)a+1也就是以我们a的储存地址加上了一个字节后赋给了ptr2
这里我们用图片讲解:
小端存储将1按照16进制存储成01000000 当我们读取的时候就反过来00000001来使用而ptr2这个指针因为只跳动了一个字节所以他指向的内容变成了00000002当我们读取的时候翻过来就出现了答案20000000.
第四题
#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; } //答案: 1
解析: 考验逗号表达式小括号内的为逗号表达式(0,1) 的结果就是1 所以相当于
int a[3][2] = {1,3,5};
因为a是二维数组a[0]表示a第一行的元素首元素的地址所以p[0]其实就是a数组首行首列的元素1.
第五题
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; } //FFFFFFFC -4
俩地址相减的值为他俩之间的元素个数(可为负)
第一问: p为数组指针它指向4个元素的数组可作为二维数组使用相当于一行有四列的二维数组我们为了描述清晰我还是画图吧:
我把这两个元素对应的位置都画在了图上这两个内存指向头部(如下图)
两者之间的元素又因为&p[4][2]为小地址小地址减去大地址为负数及-4
答案一 : 是以地址的形式打印-4 我们储存-4以补码储存: 11111111111111111111111111111100
再以地址形势打印: FFFFFFFC
正常整形形势 : -4