文章目录
前言
大家好我是艾老虎尤,在编程领域,指针和数组是两个非常重要的概念。它们广泛应用于各种编程语言和软件系统开发中,深刻影响着程序的性能和效率。因此,掌握指针和数组的使用方法和技巧至关重要。本文将为您提供一些关于指针和数组的笔试题解析,帮助您在面试中脱颖而出,话不多说我们直接开始。
建议不熟悉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));
解析:
- 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. 除此之外所有的数组名都表示首元素的地址。
通过本文,我们探讨了一些关于指针和数组的笔试题解析,希望通过这些解析,为您的面试提供帮助,您能更好地理解指针和数组的概念和使用方法,并将其应用到实际工作中。同时,我们也期待您的反馈和建议,以便不断完善我们的内容,更好地服务于广大程序员朋友。