指针笔试题讲解(让指针变得简单易懂)

数组名的理解 : 数组名就是首元素地址

但是有两个例外:

1. sizeof(数组名)这里的数组名表示整个数组的大小,sizeof(数组名)计算的是整个数组的大小,单位是字节

2. &数组名 这里的数组名表示整个数组 ,&数组名取出的是数组的地址

目录

一.笔试题 ( 1 )

sizeof的解释

二.笔试题 ( 2 )

strlen函数的解释

[三 .笔试题 ( 3 )](#三 .笔试题 ( 3 ))

[四. 笔试题 ( 4 )](#四. 笔试题 ( 4 ))

五.笔试题 ( 5 )

一.笔试题 ( 1 )

博主个人建议 : 自己先做一遍,看看哪个做错了,然后再看博主的解释

做对的题,自己想想因为什么得这个数,看看与博主的解释一样不

sizeof的解释

sizeof ()是C语言中常用的运算符,可以计算操作数的大小。. sizeof的结果是无符号整数类型,通常用size_t表示。. sizeof可以应用于各种数据类型,包括基本的数据类型,例如整数和浮点类型,指针类型和符合数据类型,结构体等等。

cs 复制代码
int main()
{
	//一维数组
	int a[] = { 1,2,3,4 };

	printf("%d\n", sizeof(a)); 
    
	printf("%d\n", sizeof(a + 0));
    
	printf("%d\n", sizeof(*a));
	
	printf("%d\n", sizeof(a + 1));
	
	printf("%d\n", sizeof(a[1]));

	printf("%d\n", sizeof(&a));
	
	printf("%d\n", sizeof(*&a));
	
	printf("%d\n", sizeof(&a + 1));

	printf("%d\n", sizeof(&a[0]));
	
	printf("%d\n", sizeof(&a[0] + 1));	
	
	return 0;
}

博主自己做了一遍 printf("%d\n", sizeof(&a)); 我认为这个打印的是16 因为 ,&数组名 ,这里的数组名表示整个数组 ,但是事实上我只想对了一半

&a - 是取出数组的地址,但是数组的地址也是地址,是地址就是4/8个Byte (在32位下是4个字节,64位下是8个字节) 数组的地址 和 数组首元素的地址 的本质区别是类型的区别,并非大小的区别

上面的代码解释如下:

cs 复制代码
int main()
{
	//一维数组
	int a[] = { 1,2,3,4 };//4个元素,每个元素使int类型(4个字节)

	printf("%d\n", sizeof(a));
	//数组名a单独放在sizeof内部,数组名表示整个数组,计算的是整个数组的大小单位是字节,是16字节
	
	printf("%d\n", sizeof(a + 0));
	//a并非单独放在sizeof内部,也没有&,所以数组名a是数组首元素的地址,a+0还是首元素的地址
    //是地址大小就是4/8 Byte

	printf("%d\n", sizeof(&a));
	// &a - 是取出数组的地址,但是数组的地址也是地址,是地址就是4/8个Byte
	//数组的地址 和 数组首元素的地址 的本质区别是类型的区别,并非大小的区别
	
	
	printf("%d\n", sizeof(*&a));
	//对数组指针解引用访问一个数组的大小,单位是字节
	//sizeof(*&a) --- sizeof(a) 

	printf("%d\n", sizeof(&a + 1));
	//&a数组的地址,&a+1还是地址,是地址就是4/8个字节

	printf("%d\n", sizeof(&a[0]));
	//&a[0]是首元素的地址, 计算的是地址的大小 4/8 个字节

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

	return 0;
}

拓展:&a[0] + 1是第二个元素的地址,大小 4/8 个字节

同样表示第二个元素地址的写法还有 &a[1] &a[0]+1 a+1


二.笔试题 ( 2 )

指针变量的大小和类型无关,不管什么类型的指针变量,大小都是4/8个字节
指针变量是用来存放地址的,地址存放需要多大空间,指针变量的大小就是几个字节
32位环境下,地址是32个二进制位,需要4个字节,所以指针变量的大小就是4个字节
64位环境下,地址是64个二进制位,需要8个字节,所以指针变量的大小就是8个字节

strlen函数的解释

strlen函数,只有遇到 ' \0 ' 时才停止

cs 复制代码
#include <string.h>

int main()
{
	//字符数组
	char arr[] = { 'a','b','c','d','e','f' };
	printf("%d\n", strlen(arr));
	printf("%d\n", strlen(arr + 0));
	printf("%d\n", strlen(*arr));
	printf("%d\n", strlen(arr[1]));
	printf("%d\n", strlen(&arr));
	printf("%d\n", strlen(&arr + 1));
	printf("%d\n", strlen(&arr[0] + 1));
	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));
	return 0;
}

自己要先做一遍!!!!!!!!!!!!!!!!再看解释

博主,自己做的时候,printf("%d\n", sizeof(*arr));

我认为它应该是4个字节,又是想对了一半

arr是首元素的地址,正常来说地址是4/8个字节,但是它是*arr

*arr就是第一个元素所以它是 1 个字节

cs 复制代码
int main()
{
	//字符数组
	char arr[] = { 'a','b','c','d','e','f' };//6

	printf("%d\n", strlen(arr));//随机值,arr是首元素的地址	
	printf("%d\n", strlen(arr + 0));//随机值,arr是首元素的地址, arr+0还是首元素的地址
	printf("%d\n", strlen(*arr));//err,arr是首元素的地址, *arr就是首元素 - 'a' - 97
	//站在strlen的角度,认为传参进去的'a'-97就是地址,97作为地址,直接进行访问,就是非法访问
	printf("%d\n", strlen(arr[1]));//err, 'b' - 98
	printf("%d\n", strlen(&arr));//随机值
	//&arr -- char (*)[6]
	//const char*
	printf("%d\n", strlen(&arr + 1));//随机值
	printf("%d\n", strlen(&arr[0] + 1));//随机值
	printf("%d\n", sizeof(arr));//6 数组名arr单独放在sizeof内部,计算的是整个数组的大小,单位是字节
	printf("%d\n", sizeof(arr + 0));//arr是首元素的地址==&arr[0],是地址就是4/8个字节
	printf("%d\n", sizeof(*arr));//arr是首元素的地址,*arr就是首元素,大小就是1Byte
	printf("%d\n", sizeof(arr[1]));//1
	printf("%d\n", sizeof(&arr));//&arr是数组的地址,sizeof(&arr)就是4/8个字节
	printf("%d\n", sizeof(&arr + 1));//&arr+1 是跳过数组后的地址,是地址就是4/8个字节
	printf("%d\n", sizeof(&arr[0] + 1));//第二个元素的地址,是地址就是4/8Byte
	return 0;
}

三 .笔试题 ( 3 )

cs 复制代码
int main()
{
	char arr[] = "abcdef";
	printf("%d\n", strlen(arr));
	printf("%d\n", strlen(arr + 0));
	printf("%d\n", strlen(*arr));
	printf("%d\n", strlen(arr[1]));
	printf("%d\n", strlen(&arr));
	printf("%d\n", strlen(&arr + 1));
	printf("%d\n", strlen(&arr[0] + 1));*/
	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));

	return 0;
}

自己要先做一遍!!!!!!!!!!!!!!!!再看解释 ( 重要的事情说三遍)

printf("%d\n", sizeof(arr));我认为这个是 6 但是结果是7,因为我少算了一个 ' \0 '

|---------------------|
| a b c d e f \0 共7个 |

(每个笔试题必须要错一个,脑袋疼)

cs 复制代码
int main()
{
	char arr[] = "abcdef";
	printf("%d\n", strlen(arr));//字符串长度,遇到'\0'停止所以是6
	printf("%d\n", strlen(arr + 0));//字符串长度,遇到'\0'停止,6
	printf("%d\n", strlen(*arr));//err 传参错误,应该传的是字符串的地址
	printf("%d\n", strlen(arr[1]));//传参错误,道理同上
	printf("%d\n", strlen(&arr));//数组首元素地址,6
	printf("%d\n", strlen(&arr + 1));//随机值
	printf("%d\n", strlen(&arr[0] + 1));//从b开始往后所以答案是5
	printf("%d\n", sizeof(arr));//整个数组包括'\0'所以是7
	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));//第二个元素地址
	return 0;
}

四. 笔试题 ( 4 )

cs 复制代码
int main()
{
	char* p = "abcdef";
	printf("%d\n", strlen(p));
	printf("%d\n", strlen(p + 1));
	printf("%d\n", strlen(*p));
	printf("%d\n", strlen(p[0]));
	printf("%d\n", strlen(&p));
	printf("%d\n", strlen(&p + 1));
	printf("%d\n", strlen(&p[0] + 1));
    printf("%d\n", sizeof(p));
	printf("%d\n", sizeof(p + 1));
	printf("%d\n", sizeof(*p));
	printf("%d\n", sizeof(p[0]));
 	printf("%d\n", sizeof(&p));
	printf("%d\n", sizeof(&p + 1));
	printf("%d\n", sizeof(&p[0] + 1));
    return 0;

}

我这次错了很多 (可能是眼睛太大了,没看见是 char* p )

大家在看东西的时候一定要观察仔细!!!!

printf("%d\n", strlen(p + 1));首元素地址+1,从b开始所以应该是5

printf("%d\n", strlen(&p) 随机值,

printf("%d\n", strlen(&p + 1));随机值

大家有什么不懂的可以去看笔试题 ( 3 )的解释

cs 复制代码
	printf("%d\n", strlen(p));   //6
	printf("%d\n", strlen(p + 1));  //5
	printf("%d\n", strlen(*p));   //err
	printf("%d\n", strlen(p[0])); //err
	printf("%d\n", strlen(&p));   //随机值
	printf("%d\n", strlen(&p + 1));//随机值
	printf("%d\n", strlen(&p[0] + 1));    //5
    printf("%d\n", sizeof(p));//4/8 计算的是指针变量的大小
	printf("%d\n", sizeof(p + 1));//p+1还是地址,大小是4/8个字节
	printf("%d\n", sizeof(*p));//1个字节, *p == 'a'
	printf("%d\n", sizeof(p[0]));//1个字节, p[0]--> *(p+0) --> *p == 'a';
 	printf("%d\n", sizeof(&p));//4/8个字节,&p 是地址
	printf("%d\n", sizeof(&p + 1));//&p是地址,&p+1还是地址,是地址就是4/8个字节
	printf("%d\n", sizeof(&p[0] + 1));

五.笔试题 ( 5 )

cs 复制代码
int a[3][4] = { 0 };
	printf("%d\n", sizeof(a));
	printf("%d\n", sizeof(a[0][0]));
	printf("%d\n", sizeof(a[0]));
	printf("%d\n", sizeof(a[0] + 1));
	printf("%d\n", sizeof(*(a[0] + 1)));
	printf("%d\n", sizeof(a + 1));
	printf("%d\n", sizeof(*(a + 1)));
	printf("%d\n", sizeof(&a[0] + 1));
	printf("%d\n", sizeof(*(&a[0] + 1)));
	printf("%d\n", sizeof(*a));
	printf("%d\n", sizeof(a[3]));
cs 复制代码
int main()
{
	int a[3][4] = { 0 };

	printf("%zd\n", sizeof(a));//48-数组名a单独放在了sizeof内存,表示整个数组,sizeof(a)计算的是数组的大小,单位是字节
	printf("%zd\n", sizeof(a[0][0]));//4-a[0][0]是数组的第一行第一个元素,这里计算的就是一个元素的大小,单位是字节
	printf("%zd\n", sizeof(a[0]));//16 - a[0]是第一行这个一维数组的数组名,数组名单独放在了sizeof内部
	//a[0]就表示整个第一行这个一维数组,sizeof(a[0])计算的整个第一行这个一维数组的大小

	printf("%zd\n", sizeof(a[0] + 1));//4/8 - a[0]并非单独放在sizeof内部,也没有&,所以a[0]表示第一行这个一维数组首元素的地址
	//也就是第一行第一个元素的地址
	//a[0] <---> &a[0][0]
	//a[0]+1 ---> &a[0][1]
	printf("%zd\n", sizeof(*(a[0] + 1)));//4 - a[0] + 1是第一行第二个元素的地址,*(a[0] + 1))就是第一行第二个元素
	//
	printf("%zd\n", sizeof(a + 1));//4/8
	//a 作为二维数组的数组名,并没有单独放在sizeof内部,也没有&,a就是数组首元素的地址,也就是第一行的地址, a 的类型是 int(*)[4]
	//a+1 就是第二行的地址,类型是:int(*)[4]
	//
	printf("%zd\n", sizeof(*(a + 1)));//16 a+1是第二行的地址,*(a+1)就是第二行,计算的就是第二行的大小
	//另外一个角度理解:*(a+1) -- a[1]
	//sizeof(a[1]) - a[1]这个第二行的数组名,单独放在了sizeof内部,计算的是第二行的大小

	printf("%zd\n", sizeof(&a[0] + 1));//4/8
	//a[0]是第一行的数组名,&a[0]取出的是数组的地址,取出的是第一行这个一维数组的地址,类型就是int(*)[4]
	//&a[0]+1 就是第二行的地址,类型就是int(*)[4]
	printf("%zd\n", sizeof(*(&a[0] + 1)));//*(&a[0] + 1)得到的就是第二行,计算的就是第二行的大小

	printf("%zd\n", sizeof(*a));//16
	//a表示数组首元素的地址,也就是第一行的地址
	//*a 就是第一行,也就相当于是第一行的数组名
	//*a--> *(a+0) -- a[0]
	//
	printf("%zd\n", sizeof(a[3]));//16-不会越界,
	//a[3] --    arr[0]
	//int [4]    int [4]
	

	//int a = 10;
	//sizeof(a);//sizeof(int)

	//表达式 有2个属性:值属性,类型属性
	//2+3    = 5
	//       = int
	  
	return 0;
}

新人博主,如果有地方解释的不对或者不清晰,麻烦大佬们海涵,如果可以麻烦从评论区指出,我一定会加以修改,万分感谢

最后麻烦大佬们动一下发财的小手一键三连,千万分感谢

相关推荐
AC使者1 小时前
5820 丰富的周日生活
数据结构·算法
cwj&xyp2 小时前
Python(二)str、list、tuple、dict、set
前端·python·算法
xiaoshiguang36 小时前
LeetCode:222.完全二叉树节点的数量
算法·leetcode
爱吃西瓜的小菜鸡6 小时前
【C语言】判断回文
c语言·学习·算法
别NULL6 小时前
机试题——疯长的草
数据结构·c++·算法
TT哇6 小时前
*【每日一题 提高题】[蓝桥杯 2022 国 A] 选素数
java·算法·蓝桥杯
yuanbenshidiaos8 小时前
C++----------函数的调用机制
java·c++·算法
唐叔在学习8 小时前
【唐叔学算法】第21天:超越比较-计数排序、桶排序与基数排序的Java实践及性能剖析
数据结构·算法·排序算法
ALISHENGYA8 小时前
全国青少年信息学奥林匹克竞赛(信奥赛)备考实战之分支结构(switch语句)
数据结构·算法
chengooooooo8 小时前
代码随想录训练营第二十七天| 贪心理论基础 455.分发饼干 376. 摆动序列 53. 最大子序和
算法·leetcode·职场和发展