指针是C语言的灵魂,他的玩法多种多样,这篇文章带来指针的笔试题详解,可以帮助我们更好的理解与巩固指针的知识
目录
- 预备知识:
- 题目:
题目比较多,但切记戒骄戒躁,保持空杯心态,相信看完一定会有提升
开始之前要先来一点预备知识:
预备知识:
数组名:
数组名大部分情况下是首元素地址,但有两种情况例外
1.当sizeof(数组名)
,此时数组名代表整个数组
,求出的是整个数组的大小,单位是字节。
2.当&数组名
,此时数组名代表整个数组
,取出的是整个数组的地址,虽然与首元素地址相同,但含义不一样。
sizeof:
sizeof
是一个操作符,可以求变量(类型)所占空间的大小。
strlen:
strlen
是一个为库函数,可以获取字符串的长度,不算字符串中的'\0'
一一一一一一一一一一分割线一一一一一一一一一一一
题目:
假设都在32位机器下进行
第一组:
//一维数组
int a[] = {1,2,3,4};
printf("%d\n",sizeof(a));//1
printf("%d\n",sizeof(a+0));//2
printf("%d\n",sizeof(*a));//3
printf("%d\n",sizeof(a+1));//4
printf("%d\n",sizeof(a[1]));//5
printf("%d\n",sizeof(&a));//6
printf("%d\n",sizeof(*&a));//7
printf("%d\n",sizeof(&a+1));//8
printf("%d\n",sizeof(&a[0]));//9
printf("%d\n",sizeof(&a[0]+1));//10
答案:
1.16
a代表整个数组,每个数组元素是int类型,一共4个元素,故为16字节大小
2.4
a为首元素地址,当地址进行±运算时,与指针类型有关,a的类型为int*,所以+0时,地址会向前跳过0个整形,仍旧是首元素地址
3.4
a为首元素地址,当解引用时,得到的是arr[0],也就是第一个整形元素,大小为4
4.4
a为首元素地址,当地址进行±运算时,与指针类型有关,a的类型为int*,所以+1时,地址会向前跳过1个整形,而数组是连续存放的,故地址会指向第二个数组元素。
5.4
a[1]是一个整形,为数组第二个整形元素,大小是4字节
6.4
&数组名代表的是取出整个元素的地址,但不管是什么地址,在32位下地址都是4个字节大小
7.16
- 此题有两种解法:
- 1.*与&结合会相互抵消,数组名在sizeof中就是求出整个数组的大小
2.&数组名取出的是整个数组的地址,当地址进行解引用时,与指针类型有关,解引用一个数组指针类型的内容,就会访问一个大小为此数组的内容,即4个整形变量的数组,大小为16字节
8.4
a代表整个数组,当地址进行±运算时,与指针类型有关,而此数组指针的类型是 int(*)[4], 数组指针+1会跳过一个数组,也就是跳过4个整形的数组,而运算后的结果仍旧是地址,故答案为4
9.4
&a[0]代表的是第一个元素的地址,地址大小为4字节
10.4
&a[0]代表的是第一个元素的地址,当地址进行±运算时,与指针类型有关,整形指针+1会跳过一个整形,即&a[0]+1指向数组第二个元素,为第二个元素的地址,大小为4个字节
一一一一一一一一一一分割线一一一一一一一一一一一
第二组:
//字符数组
char arr[] = {'a','b','c','d','e','f'};
printf("%d\n", sizeof(arr));//1
printf("%d\n", sizeof(arr+0));//2
printf("%d\n", sizeof(*arr));//3
printf("%d\n", sizeof(arr[1]));//4
printf("%d\n", sizeof(&arr));//5
printf("%d\n", sizeof(&arr+1));//6
printf("%d\n", sizeof(&arr[0]+1));//7
答案:
1.6
arr在sizeof中为整个数组,求出的是整个数组的大小,单位是字节,结果为6字节
2.4
arr此时为首元素地址,类型为char*,字符指针+0会跳过0个字符大小,此时仍指向首元素地址,地址大小为4字节
3.1
arr此时为首元素地址,类型为char*,解引用arr会访问一个char大小的内容,为数组第一个元素,大小为1字节
4.1
arr[1]代表数组第二个元素,类型为char,大小为1字节
5.4
arr代表整个数组,取出的是整个数组的地址,地址的大小为4字节
6.4
arr代表整个数组,取出的是整个数组的地址,当地址进行±运算时,与指针类型有关,数组指针的类型为 char (*)[6] ,数组指针+1会跳过一个数组,在这就是跳过6个字符,运算后的结果依然是地址,大小为4
7.4
&arr[0]代表第一个元素的地址,当地址进行±运算时,与指针类型有关,字符指针+1会跳过一个字符,&arr[0]+1代表第二个元素地址,大小为4字节
一一一一一一一一一一分割线一一一一一一一一一一一
第三组:
char arr[] = {'a','b','c','d','e','f'};
printf("%d\n", strlen(arr));//1
printf("%d\n", strlen(arr+0));//2
printf("%d\n", strlen(*arr));//3
printf("%d\n", strlen(arr[1]));//4
printf("%d\n", strlen(&arr));///5
printf("%d\n", strlen(&arr+1));//6
printf("%d\n", strlen(&arr[0]+1));//7
答案:
1.随机值
arr为首元素地址,但arr数组中没有’\0’,故结果为随机值
2.随机值
arr为首元素地址,当地址进行±运算时,与指针类型有关,字符指针+0会向前跳过0个字符,地址不变,而arr数组中没有’\0’,故结果为随机值
3.err
arr为首元素地址,*arr为第一个元素’a’,传入strlen中会把a的ASCII码值当做地址,而此地址为野指针,会报错。
4.err
arr[1]为数组第二个元素’b’,传入strlen中会把b的ASCII码值当做地址,而此地址为野指针,会报错。
5.随机值
arr为整个数组地址,首先要知道strlen的参数为
传入strlen后数组指针会被强转为char *类型,而他们两的值是一样的,故结果为随机值
6.随机值
arr为整个数组地址,当地址进行±运算时,与指针类型有关,数组指针+1会向前跳过一个数组,故此时地址为跳过一个数组的地址,由于不清楚什么时候遇到’\0’,故为随机值
7.随机值
&arr[0]为首元素地址,当地址进行±运算时,与指针类型有关,字符指针+1会向前跳过一个字符,故此时地址为跳过一个字符的地址,由于不清楚什么时候遇到’\0’,故为随机值
一一一一一一一一一一分割线一一一一一一一一一一一
第四组:
char arr[] = "abcdef";
printf("%d\n", sizeof(arr));
printf("%d\n", sizeof(arr+0));
printf("%d\n", sizeof(*arr));
printf("%d\n", sizeof(arr[1]));
printf("%d\n", sizeof(&arr));
printf("%d\n", sizeof(&arr+1));
printf("%d\n", sizeof(&arr[0]+1));
答案:
1.7
arr代表整个数组,在sizeof中会求出整个数组的大小,为7字节,因为写成字符串形式自带’\0’
2.4
arr为首元素地址,当地址进行±运算时,与指针类型有关,字符指针+1会向前跳过1个字符,故此时地址为跳过一个字符的地址,则结果为4
3.1
arr为首元素地址,类型为char* ,解引用时会访问一个字节,为’a’,字符a的大小为1的字节
4.1
arr[1]为数组中第二个元素的地址,为char类型,大小为1字节
5.4
arr为整个数组地址,&arr为整个元素的地址,是地址就是4个字节
6.4
arr为整个数组地址,&arr为整个元素的地址,类型为char(*)[7],数组指针+1会跳过1个数组,&arr+1为跳过一个数组后的地址,是地址大小就是4字节
7.4
&arr[0]为首元素地址,当地址进行±运算时,与指针类型有关,字符指针+1会向前跳过1个字符,故此时地址为跳过一个字符的地址,则结果为4
此贴会持续更新,欢迎交流与纠错