指针和数组笔试题解析


前言

大家好我是艾老虎尤,在编程领域,指针和数组是两个非常重要的概念。它们广泛应用于各种编程语言和软件系统开发中,深刻影响着程序的性能和效率。因此,掌握指针和数组的使用方法和技巧至关重要。本文将为您提供一些关于指针和数组的笔试题解析,帮助您在面试中脱颖而出,话不多说我们直接开始。
建议不熟悉sizeof和strlen的小伙伴看看这篇文章:sizeof和strlen的区别


一维数组

小提示
1:sizeof(数组名),数组名表示整个数组,计算的是整个数组的大小,单位是字节
2:&数组名,数组名表示整个数组,取出的是整个数组的地址
3:除此之外所有的数组名都是数组首元素的地址

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.参考第一条提示,数组有四个元素,每个元素的大小是4个字节,总大小就是16个字节
printf("%d\n",sizeof(a));

2.参考第三条提示,a+0是第一个元素的地址,是地址就是4或者8个字节
printf("%d\n",sizeof(a+0));

3.参考第三条提示,数组首元素的地址被解引用,计算的是数组首元素的大小,也就是4个字节
printf("%d\n",sizeof(*a));

4.参考第三条提示,a+1是第二个元素的地址,是地址就是4或者8个字节
printf("%d\n",sizeof(a+1));

5.a[1]就是数组的第二个元素,求的就是第二个元素的大小,也就是4个字节
printf("%d\n",sizeof(a[1]));

6.参考第二条提示,取出的是整个数组的地址,是地址就是4或者8个字节
printf("%d\n",sizeof(&a));

7.先取出整个数组的地址,再解引用就拿到了数组,可以理解成和&相互抵消了,所以&a=a,a就是整个数组,求的就是整个数组的大小,也就是16个字节
printf("%d\n",sizeof(*&a));

8.&a是整个数组的地址,&a+1就跳过了整个数组,指向数组后面的空间,是一个地址,大小就是4或者8个字节
printf("%d\n",sizeof(&a+1));

9.对首元素取地址,是一个地址,大小就是4或者8个字节
printf("%d\n",sizeof(&a[0]));

10.首元素地址+1就是第二个元素的地址,是一个地址,大小就是4或者8个字节
printf("%d\n",sizeof(&a[0]+1));

结果展示:
在这里插入图片描述


字符数组1.0(sizeof求值)

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.参考第一条提示,arr单独放在sizeof内部,计算的是整个数组的大小,也就是6个字节
printf("%d\n", sizeof(arr));

2.arr没有单独放到sizeof内部,代表它是数组首元素的地址,地址+0,还是首元素的地址,是地址,大小就是4或者8个字节
printf("%d\n", sizeof(arr+0));

3.arr没有单独放到sizeof内部,代表它是数组首元素的地址,对数组首元素地址解引用,也就是求a的大小,也就是1个字节
printf("%d\n", sizeof(*arr));

4.arr[1]就是第二个元素,也就是b的大小,就是1字节
printf("%d\n", sizeof(arr[1]));

5.&arr取出的是整个数组的地址,是地址就是4或者8个字节
printf("%d\n", sizeof(&arr));

6.&arr取出的是整个数组的地址,+1就是跳过了整个数组,指向了后面空间的地址,是地址就是4或者8个字节
printf("%d\n", sizeof(&arr+1));

7.取出第一个元素后+1,指向的是b的地址,是地址就是4或者8个字节
printf("%d\n", sizeof(&arr[0]+1));

结果展示
在这里插入图片描述


字符数组1.1(strlen求值)

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

解析:

  1. arr是数组首元素的地址,里面不能确定\0的位置,所以求长度的结果是随机值
    printf("%d\n", strlen(arr));

2.同问题1,求长度的结果是随机值
printf("%d\n", strlen(arr+0));

3.数组首元素解引用,拿到的就是第一个元素,对字符a求值,是非法访问
printf("%d\n", strlen(*arr));

4.同问题3
printf("%d\n", strlen(arr[1]));

5.同问题1和问题2,求长度的结果是随机值
printf("%d\n", strlen(&arr));

6.&arr是数组的地址,对它+1是跳过了整个数组,所以求长度的结果是随机值
printf("%d\n", strlen(&arr+1));

7.取出第一个元素的地址+1,就是第二个元素的地址,也就是b的地址,所以求长度的结果也是随机值
printf("%d\n", strlen(&arr[0]+1));


字符数组2.0(sizeof求值)

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

解析:

char arr[]=[a b c d e f \0]数组是7个元素
sizeof只关注内存空间的大小,单位是字节
strlen是求字符串长度,统计的是\0之前出现字符的个数,一定要找到\0才算结束

1.数组名单独放在sizeof内部,计算的是数组总大小,是7个字节
printf("%d\n", sizeof(arr));
2.arr是数组首元素的地址,对它+0还是首元素的地址,是地址大小就是4或者8个字节
printf("%d\n", sizeof(arr+0));

3.*arr是数组首元素,大小是1字节
printf("%d\n", sizeof(*arr));

4.arr[1]是第二个元素,大小是1字节
printf("%d\n", sizeof(arr[1]));

5.&arr取出的是整个数组的地址,是地址大小就是4或者8个字节
printf("%d\n", sizeof(&arr));

6.&arr+1是跳过了整个数组,指向后面的地址,是地址大小就是4或者8个字节
printf("%d\n", sizeof(&arr+1));

7.arr[0]+1是第二个元素的地址,是地址大小就是4或者8个字节

结果展示
在这里插入图片描述


字符数组2.1(strlen求值)

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是数组首元素的地址,strlen从首元素的地址开始统计,\0前面一共6个元素,大小就是6
printf("%d\n", strlen(arr));

2.arr是数组首元素的地址,+0还是首元素的地址,strlen从首元素的地址开始统计,\0前面一共6个元素,长度就是6
printf("%d\n", strlen(arr+0));

3.*arr是第一个元素也就是字符a,非法访问
printf("%d\n", strlen(*arr));

4.arr[1]是第二个元素,也就是字符b,非法访问
printf("%d\n", strlen(arr[1]));

5.取出整个数组的地址,长度是6
printf("%d\n", strlen(&arr));

6.取出整个数组的地址+1,就是跳过了整个数组的地址,不能确定\0的位置,所以长度是随机值
printf("%d\n", strlen(&arr+1));

7.取出数组首元素的地址向后偏移一位,也就是从b的地址开始向后找\0,长度是5
printf("%d\n", strlen(&arr[0]+1));


字符数组3.0(sizeof求值)

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

1.p是一个指针变量,大小就是4或者8个字节
printf("%d\n", sizeof(p));

2.*p存放的是a,p+1就是b的地址,是地址就是4或者8个字节
printf("%d\n", sizeof(*p));

3.*p是字符a,大小是1字节
printf("%d\n", sizeof(*p));

4.p[0]*(p+0)*p,同上,大小是1字节
printf("%d\n", sizeof(p[0]));

5.取出指针变量p的地址,是地址大小就是4或者8个字节
printf("%d\n", sizeof(&p));

6.&p+1是跳过p变量后的地址,是地址大小就是4或者8个字节
printf("%d\n", sizeof(&p+1));

7.p[0]*(p+0)*p,*p==a,对a&就是拿到a的地址,+1拿到b的地址,是地址大小就是4或者8个字节
printf("%d\n", sizeof(&p[0]+1));

结果展示:
在这里插入图片描述


字符数组3.1(strlen求值)

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里面存放的是a的地址,长度就是6
printf("%d\n", strlen(p));

2.p里面存放的是a的地址,+1就是b的地址,向后找\0长度就是5
printf("%d\n", strlen(p+1));

3.*p就是字符a,非法访问
printf("%d\n", strlen(*p));

4.同上,p[0]是字符a,非法访问
printf("%d\n", strlen(p[0]));

5.&p拿到的是p这个指针变量的起始地址,从这里开始求字符串长度完全是随机值
printf("%d\n", strlen(&p));

6.&p+1跳过了整个数组,指向了后面的大小,长度也是随机值
printf("%d\n", strlen(&p+1));

7.如题四,p[0]是a的地址,+1就是b的地址,从这里向后找\0,长度是5
printf("%d\n", strlen(&p[0]+1));


二维数组

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

1.计算整个数组的大小==344=48个字节
printf("%d\n",sizeof(a));

2.a[0][0]是第一行第一列的元素,大小是4个字节
printf("%d\n",sizeof(a[0][0]));

3.a[0]指向是第一行的数组名,第一行一共四个元素,大小是16个字节
printf("%d\n",sizeof(a[0]));

4.a[0]作为第一行的数组名,没有单独放到sizeof内部,没有&,表示的就是数组首元素的地址,+1表示第一行第二个元素的地址,是地址大小就是4或者8个字节
printf("%d\n",sizeof(a[0]+1));

5.同上,对第一行第二个元素的地址解引用,求的就是第一行第二个元素的大小,结果是4字节
printf("%d\n",sizeof(*(a[0]+1)));

6.a是二维数组的数组名,表示首元素的地址,也就是第一行的地址,+1就是第二行的地址,是地址大小就是4或者8个字节
printf("%d\n",sizeof(a+1));

7.同上,对第二行的地址解引用,求的就是第二行的大小,大小就是16个字节
printf("%d\n",sizeof(*(a+1)));

8.对第一行的数组名&就是第一行的地址,+1就是第二行的地址,是地址大小就是4或者8个字节
printf("%d\n",sizeof(&a[0]+1));

9.同上,对第二行的地址解引用,求的就是第二行的大小,就是16个字节
printf("%d\n",sizeof(*(&a[0]+1)));

10.a是首元素的地址,也就是第一行的地址,对第一行解引用,求的就是第一行的大小,大小是16个字节
printf("%d\n",sizeof(*a));

11.如果数组存在第四行,a[3]就是第四行的数组名,数组名单独放在sizeof内部,计算的是第四行的大小,大小是16个字节
注意:sizeof并没有访问这块空间,所以不存在越界访问
printf("%d\n",sizeof(a[3]));

结果展示:
在这里插入图片描述

总结

数组名的意义:
1. sizeof(数组名),这里的数组名表示整个数组,计算的是整个数组的大小。
2. &数组名,这里的数组名表示整个数组,取出的是整个数组的地址。
3. 除此之外所有的数组名都表示首元素的地址。

通过本文,我们探讨了一些关于指针和数组的笔试题解析,希望通过这些解析,为您的面试提供帮助,您能更好地理解指针和数组的概念和使用方法,并将其应用到实际工作中。同时,我们也期待您的反馈和建议,以便不断完善我们的内容,更好地服务于广大程序员朋友。

  • 14
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 13
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 13
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值