您的位置:首页 > 编程语言 > C语言/C++

c语言指针相关面试题

2018-01-06 17:09 351 查看
例1

int main()
{
int a[5] = { 1, 2, 3, 4, 5 };
int *ptr = (int *)(&a + 1);
printf("%d %d\n", *(a + 1), *(ptr - 1));
system("pause");
return 0;
}


程序结果:2 5

分析:数组名在sizeof内部单独出现和&(数组名)这两种情况下,数组名表示整个数组。

其他情况下,数组名均表示首元素的地址。

所以这里的(a+1)的a表示首元素的地址,+1表示下一个元素的地址,解引用表示下一个下一个元素2.

(&a+1)对a取地址,取得是首元素的地址,+1是指向下一个数组的起始地址。所以ptr-1指向该数组的在最后一个元素,解引用表示该元素5.

这里区分一下:

(a+1):即数组名+1,指向该数组内下一个元素。

(&a+1):即&(数组名)+1,指向下一个数组的起始。

例2:

struct Test
{
int num;
char *p;
short s;
char c[2];
short sd[4];
}*p;
int main()
{
printf("%#x\n", p);
printf("%#x\n", p + 0x1);
printf("%#x\n", (unsigned long)p + 0x1);
printf("%#x", (unsigned int *)p + 0x1);

system("pause");
return 0;
}


先来看结果:



分析:p是一个结构体指针,他的地址我们其实并不关心。这道题考察了对不同类型的+1,到底是加多少。

对p+1:p是一个指针,对指针+1,加其指向类型的大小。该结构体大小由于内存对齐我们可以得到是20,所以16进制运算得如图结果。

将p强转为无符号长整形,对p+1,就是+1。

将p强转为无符号整形指针类型,对p+1就是加其指向类型的大小,即就是4。

例3:

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


这道题有一个很容易出错的陷阱,在定义二维数组时用了逗号表达式,所以这个二维数组并不是题目上的数据,而是{1,3,5,0,0,0};

所以p[0]就是该数组第一个元素1.

例4

int main()
{
int a[2][5] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
int *ptr1 = (int *)(&a + 1);
int *ptr2 = (int *)(*(a + 1));
printf("%d,%d", *(ptr1 - 1), *(ptr2 - 1));

system("pause");
return 0;
}


分析:这道题考察了对二维数组的理解,我们知道数组在内存中是线性连续存放的,所以二维数组也是如此。

&a+1:与一维数组同理,所以此时+1指向了下一个数组的起始位置,*(ptr1-1)即就是该数组的最后一个元素10。

(a+1):指向下一个元素,这里需要我们将二维数组看作一维数组(该数组有两个元素,每个元素是一个一维数组),所以a此时表示第一个元素,+1指向下一个元素即就是第二个一维数组的起始,*(ptr2-1)即就是上一个一维数组的最后一个元素5;

例5

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


这道题主要考察了二级指针,首先a中的字符串串都在字符常量区保存,a指向该区域的起始地址。pa++,指向了下一个字符串的地址,所以结果是:at。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: