指针面试题目及解析(上)

指针使c语言中比较难的一类题目,在很多面试题目上也经常能够看到,下面我们一起来看一些与指针有关的面试题。首先,在做题之前,我们需要了解数组名的一些相关知识,1.sizeof括号里单独放一个数组名,这个数组名表示整个数组;2.&数组名中的数组名表示整个数组;3.除此之外,其它的数组名表示数组首元素地址

注:以下结果均为x86环境下的结果

一、一维数组
​
int a[] = {1,2,3,4};
1.printf("%d\n",sizeof(a));
2.printf("%d\n",sizeof(a+0));
3.printf("%d\n",sizeof(*a));
4.printf("%d\n",sizeof(a+1));
5.printf("%d\n",sizeof(a[1]));
6.printf("%d\n",sizeof(&a));
7.printf("%d\n",sizeof(*&a));
8.printf("%d\n",sizeof(&a+1));
9.printf("%d\n",sizeof(&a[0]));
10.printf("%d\n",sizeof(&a[0]+1));

​

1.sizeof内单独放一个数组名a,故a表示整个数组,该数组有4个元素,每元素为4个字节,故结果为16;

2.sizeof内并不是单独一个数组名,故a表示数组首元素地址,只要是地址,其大小就为4;

3.a为数组首元素地址,解引用得到数组首元素1,1的大小为4;

4.a为数组首元素地址,a+1跳过一个整形,为第二个元素的地址,地址的大小为4;

5.a[1]为数组第二个元素,大小为4;

6.&a为真个数组的地址,地址的大小为4;

7.*&a(相当于a),a表示整个数组,大小为16;

8.&a+1跳过整个数组,是一个地址,大小为4;

9.&a[0]为第一个元素的地址,大小为4;

10.&a[0]+1跳过一个整形,为第二个元素的地址,大小为4;

运行结果如下:

二、字符数组
(1)代码1
char arr[] = {'a','b','c','d','e','f'};
1  printf("%d\n", sizeof(arr));
2  printf("%d\n", sizeof(arr+0));
3  printf("%d\n", sizeof(*arr));
4  printf("%d\n", sizeof(arr[1]));
5  printf("%d\n", sizeof(&arr));
6  printf("%d\n", sizeof(&arr+1));
7  printf("%d\n", sizeof(&arr[0]+1));

1.sizeof里单独一个arr,表示整个数组,数组有6个元素,每个元素大小为1,故结果为6;

2.arr表示数组首元素地址,地址的大小为4;

3.arr表示数组首元素地址,解引用得到数组首元素,大小为1;

4.arr[2]为数组第二个元素,大小为1;

5.&arr表示整个数组的地址,大小为4;

6.&arr+1跳过整个数组,是一个地址,大小为4;

7.&arr[0]+1表示第二个元素的地址,大小为4;

运行结果如下:

(2)代码2
char arr[] = {'a','b','c','d','e','f'};
1  printf("%d\n", strlen(arr));
2  printf("%d\n", strlen(arr+0));
3  printf("%d\n", strlen(*arr));
4  printf("%d\n", strlen(arr[1]));
5  printf("%d\n", strlen(&arr));
6  printf("%d\n", strlen(&arr+1));
7  printf("%d\n", strlen(&arr[0]+1));

做题之前,需要注意此处不在使用sizeof计算数组或元素大小了,而是使用strlen来计算字符串的长度,strlen的特点是它是一个库函数,传给strlen的参数必须是一个地址,否则系统将会报错,且它在遇到\0时即停止计算,计算的长度不包括\0

1.arr表示数组首元素,因为数组arr中没有\0,因此结果为随机值,最小为6;

2.同1;

3.arr表示数组首元素地址,*arr即为数组首元素,但strlen要求参数必须为一个地址,因此这段代码是错误的;

4.同3,arr[1]为数组第二个元素,不是一个地址,代码错误;

5.&arr为数组第二个元素的地址,其数值与arr一样(它们的区别知识在运算是跳过的字节不一样),但是strlen是一个字节一个字节计算长度的,但由于没有\0,结果为随机值,最小为6(结果与1相同);

6.&arr+1跳过一个数组,同理,其结果为随机值,最小为0;

7.&arr[0]+1为数组第二个元素的地址,其结果为随机值,但比第1题结果小1;

(3)代码3
char arr[] = "abcdef";
1  printf("%d\n", sizeof(arr));
2  printf("%d\n", sizeof(arr+0));
3  printf("%d\n", sizeof(*arr));
4  printf("%d\n", sizeof(arr[1]));
5  printf("%d\n", sizeof(&arr));
6  printf("%d\n", sizeof(&arr+1));
7  printf("%d\n", sizeof(&arr[0]+1));

与前两题不同,这里是把字符串赋值给数组,字符串末尾会自动包含一个\0

1.arr表示整个数组,数组元素个数为7(\0也是数组的一个元素),每个元素占一个字节,故结果为7;

2..arr为数组首元素地址,地址的大小为4;

3.arr为数组首元素地址,*arr为数组首元素,大小为1;

4.arr[1]为数组第二个元素,大小为1;

5.&arr为真个数组的地址,地址大小为4;

6.&arr+1跳过整个数组,是一个地址,大小为4;

7.&arr[0]+1表示数组第二个元素的地址,大小为4;

运行结果如下:

(4)代码4
char arr[] = "abcdef";
1  printf("%d\n", strlen(arr));
2  printf("%d\n", strlen(arr+0));
3  printf("%d\n", strlen(*arr));
4  printf("%d\n", strlen(arr[1]));
5  printf("%d\n", strlen(&arr));
6  printf("%d\n", strlen(&arr+1));
7  printf("%d\n", strlen(&arr[0]+1));

1.arr是数组首元素地址(注意这里不是sizeof),故长度为6;

2.同上;

3.strlen的参数必须为地址,而*arr为数组第一个元素,代码错误;

4.同3,arr[1]为数组第二个元素,代码错误;

5.&arr为整个数组的地址,但是strlen是一个字节一个字节计算长度的,因此结果同1,长度为6;

6.&arr+1跳过整个数组(即也跳过了数组最后一个元素\0),因此长度为随机值,最小为0(一开始就遇到\0时);

7.&arr[0]+1为数组第二个元素的地址,即从第二个元素开始计算长度,结果为5;

(5)代码5
char *p = "abcdef";
1  printf("%d\n", sizeof(p));
2  printf("%d\n", sizeof(p+1));
3  printf("%d\n", sizeof(*p));
4  printf("%d\n", sizeof(p[0]));
5  printf("%d\n", sizeof(&p));
6  printf("%d\n", sizeof(&p+1));
7  printf("%d\n", sizeof(&p[0]+1));

做题之前,我们需要知道,p是一个字符指针,将一个字符串常量赋值给p,实际是将字符串的第一个元素的地址赋值给p(把常量字符串想象成数组,p可以理解为数组名【只是在有些时候当数组名,但其本质还是一个指针】

1.p是一个指针,指针的大小为4;

2.p+1,指向数组第二个元素,是一个地址,大小为4;

3.*p是数组第一个元素,大小为1;

4.同3;

5.&p为整个数组的地址,地址的大小为4;

6.&p+1跳过整个数组,是一个地址,大小为4;

7.&p[0]+1为数组第二个元素的地址,大小为4;

运行结果如下:

(6)代码6
char *p = "abcdef";
1  printf("%d\n", strlen(p));
2  printf("%d\n", strlen(p+1));
3  printf("%d\n", strlen(*p));
4  printf("%d\n", strlen(p[0]));
5  printf("%d\n", strlen(&p));
6  printf("%d\n", strlen(&p+1));
7  printf("%d\n", strlen(&p[0]+1));

1.p指向第一个元素,故长度为6;

2.p+1指向第二个元素,故长度为5;

3.*p不是地址,故代码错误;

4.p[0]不是地址,代码错误;

5.&p取的是指针变量的地址,其类型为char**,虽然是一个地址,但是不知道指向谁,故结果为随机值;

6.&p+1同上,为随机值

7.&p[0]+1为第二个元素的地址,故长度为5;

三、二维数组
int a[3][4] = {0};
1  printf("%d\n",sizeof(a));
2  printf("%d\n",sizeof(a[0][0]));
3  printf("%d\n",sizeof(a[0]));
4  printf("%d\n",sizeof(a[0]+1));
5  printf("%d\n",sizeof(*(a[0]+1)));
6  printf("%d\n",sizeof(a+1));
7  printf("%d\n",sizeof(*(a+1)));
8  printf("%d\n",sizeof(&a[0]+1));
9  printf("%d\n",sizeof(*(&a[0]+1)));
10 printf("%d\n",sizeof(*a));
11 printf("%d\n",sizeof(a[3]));

在做题之前,我们需要知道,二维数组的首元素是第一行,即一维数组,a[x][y]中的a[x]可以当成是每一行的数组名

1.sizeof里面单独一个数组名,表示整个数组,大小为48;

2.即第一个元素的大小,为4;

3.a[0]为第一行的数组名,故这里a[0]表示第一行,大小为16;

4.a[0]表示第一行的首元素地址,故a[0]+1表示第一行第二列的元素的地址,地址的大小为4;

5.为第一行第二列的元素,大小为4;

6.a表示二维数组首元素地址,即第一行的地址,则a+1表示第二行的地址,地址的大小为4;

7.*(a+1)表示第二行,大小为16;

8.a[0]为第一行的数组名,则&a[0]+1表示第二行的地址,大小为4;

9.*(a[0]+1)表示第二行,大小为16;

10.a表示二维数组的首元素地址,即第一行的地址,则*a表示第一行,大小为16;

11.a[3]表示二维数组的第三行的数组名,这里表示第三行,大小为16;

  • 26
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值