第十五章(指针5)

1. sizeof和strlen的对⽐

2. 数组和指针笔试题解析

一、sizeof(操作符)和strlen函数的对比

在我们初学习的时候,有许多同学会把sizeof和strlen函数给混淆,那么本章我们就来详细的探讨一下。

sizeof:是用来计算变量所占空间的大小的,单位是字节,如果操作数是类型的话,我们计算的是类型的大小。

我们举例子来说明

int main()
{
	int num1 = 10;
	double num2 = 5.0;
	printf("%zd\n", sizeof(int));
	printf("%zd\n", sizeof(num1));
	printf("%zd\n", sizeof(10));
	printf("%zd\n", sizeof(double));
	printf("%zd\n", sizeof(num2));
	printf("%zd\n", sizeof(5.0));

	return 0;
}

在这里插入图片描述
1.2
strlen函数:求字符串的长度的,针对的是字符串(这个就是一个很大的区别)

strlen函数统计的是字符串\0之前的字符串,遇见\0停止。(如果字符中没有\0可能会造成越界访问)。


int main()
{
	char arr1[10] = { 'a','b','c','d','e','f'};
	char arr2[10] = "abcdef";
	printf("%zd\n", sizeof(arr1)); //求得是字节的大小
	printf("%zd\n", sizeof(arr2));

	printf("%d\n", strlen(arr1));  //求的是字符串的长度
	printf("%d\n", strlen(arr2));  //遇见\0为止

	return 0;
}

在这里插入图片描述
printf(“%d\n”, strlen(arr1)); 打印出来的是6其实并不是,是随机值,因为我们是字符,字符没有\0,需要我们来添加,如果没有添加,就会自动在内存中找,直到遇见\0为止,所以是一个随机值。

1.3 sizeof和strlen函数的对比

在这里插入图片描述
我们来分析以下题目

注意:以下题目来自比特就业课(可能略有改动)

2.1一维数组

int main()
{
	int a[] = { 1,2,3,4 };
	printf("%zd\n", sizeof(a));//a是数组名,sizeof(a)计算的是整个数组的大小 16
	printf("%zd\n", sizeof(a + 0)); //a + 0,数组名表示的数组首元素的地址 地址的大小是 4/8
	printf("%zd\n", sizeof(*a));  //*a 是首元素 1 ,整形   4
	printf("%zd\n", sizeof(a + 1)); // 表示的是 2的地址 4/8
	printf("%zd\n", sizeof(a[1]));  //表示的是 2 整形 4
	printf("%zd\n", sizeof(&a));  //表示的是地址 4 /8
	printf("%zd\n", sizeof(*&a));  //*&a==a表示的是整个数组 ,16
	printf("%zd\n", sizeof(&a + 1));  //依旧是地址,只不过是跳过了该数组的地址,指向下一个  4 \8

	printf("%zd\n", sizeof(&a[0]));  //表示的是1的地址,  4 / 8
	printf("%zd\n", sizeof(&a[0] + 1)); // 地址加1还是地址,  是地址就是4 / 8
		return 0;
}

在这里插入图片描述
2.2 字符数组

int main()
{
	char arr[] = { 'a','b','c','d','e','f' };  //字符数组,一个字符占一个字节
	printf("%zd\n", sizeof(arr));  //sizeof(arr)是个特例,计算的是整个数组的大小。 6
	printf("%zd\n", sizeof(arr + 0));   //arr + 0是地址  4 /8
	printf("%zd\n", sizeof(*arr));  //拿出的是a,一个字符   1
	printf("%zd\n", sizeof(arr[1]));  //拿出的是一个字符b   1
	printf("%zd\n", sizeof(&arr)); //取出的是整个数组的地址 ,是地址就是 4 /8 
	printf("%zd\n", sizeof(&arr + 1));//地址+1还是地址,4/8
	printf("%zd\n", sizeof(&arr[0] + 1)); //找出的是b的地址  //4/8
	return 0;
}

在这里插入图片描述

代码2:

int main()
{
	//strlen函数计算的是字符串的长度,计算的\0之前的长度
	char arr[] = { 'a','b','c','d','e','f' };//字符数组
	printf("%zu\n", strlen(arr));  //没有\0,所以是个随机值。
	printf("%zu\n", strlen(arr + 0));//依旧是个随机值
	printf("%zu\n", strlen(*arr)); // 解引用得出的是'a',一个字符,不符合逻辑,无法打印
	printf("%zu\n", strlen(arr[1]));//得出的是'b'
	printf("%zu\n", strlen(&arr));  //地址 ,无法打印
	printf("%zu\n", strlen(&arr + 1));//地址
	printf("%zu\n", strlen(&arr[0] + 1));//地址
	return 0;
}

在这里插入图片描述

代码3

int main()
{

	//sizeof 计算的是数据字节的大小
	char arr[] = "abcdef";  //字符数组,字符串(后边隐藏一个\0)
	printf("%zd\n", sizeof(arr)); //特例计算的是整个数组的大小,7
	printf("%zd\n", sizeof(arr + 0));// 地址 4 /8
	printf("%zd\n", sizeof(*arr));//第一个字符a 1
	printf("%zd\n", sizeof(arr[1]));//第二个字符b 1
	printf("%zd\n", sizeof(&arr)); //地址  4/8
	printf("%zd\n", sizeof(&arr + 1)); //地址 4 /8
	printf("%zd\n", sizeof(&arr[0] + 1)); //地址 4 /8 
	return 0;
}

代码4:

int main()
{
	//  strlen 求的是字符串长度
	char arr[] = "abcdef";  //字符数组
	printf("%zd\n", strlen(arr));  //6
	printf("%zd\n", strlen(arr + 0)); //6
	printf("%d\n", strlen(*arr)); //取出的是一个a,报错 无法打印
	printf("%d\n", strlen(arr[1]));//b,无法打印
	printf("%d\n", strlen(&arr)); //地址 ,不符合 无法打印
	printf("%d\n", strlen(&arr + 1));  //地址
	printf("%d\n", strlen(&arr[0] + 1)); //地址
	return 0;
}

在这里插入图片描述

代码5:

int main()
{
	//sizeof 计算的是数据的大小,单位是字节   
	char* p = "abcdef";    //字符指针
	printf("%zd\n", sizeof(p)); //p是地址,4/8
	printf("%zd\n", sizeof(p + 1)); //依旧是指针  4/ 8
	printf("%zd\n", sizeof(*p)); // 这个是字符 a 1
	printf("%zd\n", sizeof(p[0])); //字符  1
	printf("%zd\n", sizeof(&p));// 地址 4 /8
	printf("%zd\n", sizeof(&p + 1));//地址 4 /8
	printf("%zd\n", sizeof(&p[0] + 1)); //地址 指向的是b的地址 4/8
	return 0;
}

在这里插入图片描述
代码 6 :

int main()
{
	char* p = "abcdef"; //字符指针
	printf("%zd\n", strlen(p));//p首元素的地址,strlen函数可以通过接收函数指针来访问  6
	printf("%zd\n", strlen(p + 1));  //地址   从第二个元素的地址接收之后开始访问  5
	printf("%zd\n", strlen(*p)); //a,报错
	printf("%zd\n", strlen(p[0]));//a报错
	printf("%zd\n", strlen(&p));//地址
	printf("%zd\n", strlen(&p + 1));  //地址
	printf("%zd\n", strlen(&p[0] + 1)); //地址
	return 0;
}

在这里插入图片描述
2.3 二维数组

int main()   //二维数组是由一维数组组成的数组名表示数组首元素的地址
{
	int a[3][4] = { 0 };
	printf("%zd\n", sizeof(a)); //a是数组名,sizeof(a)表示计算的是整个数组的大小 12 *4
	printf("%zd\n", sizeof(a[0][0]));  //拿出的是一个元素 0    4
	printf("%zd\n", sizeof(a[0]));  //拿出的是一维数组的名字 sizeof(arr)计算的是整个数组的大小 16
	printf("%zd\n", sizeof(a[0] + 1));  //第二行的地址 4 /8
	printf("%zd\n", sizeof(*(a[0] + 1))); //第二行第一个元素 4 
	printf("%zd\n", sizeof(a + 1)); //第二行的地址 4/8
	printf("%zd\n", sizeof(*(a + 1))); //取出的是arr[1]该一维数组整个数组的大小 16
	printf("%zd\n", sizeof(&a[0] + 1)); //地址 4/8
	printf("%zd\n", sizeof(*(&a[0] + 1)));  //取出的是arr[1]该一维数组整个数组的大小 16
	printf("%zd\n", sizeof(*a));  //取出的是arr[0]该一维数组整个数组的大小 16
	printf("%zd\n", sizeof(a[3])); //取出的是arr[3]该一维数组整个数组的大小 16
	return 0;
}

在这里插入图片描述

这里我们总结一下:
1.sizeof(数组名),这里的数组名表示整个数组计算的是整个数组的大小
2.&数组名,这里的数组名表示整个数组,取出的是整个数组的地址。
3.除此之外的数组名都表示数组的首元素的地址。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值