深入了解strlen和sizeof

我们之前学习过strlen和sizeof的区别:

1.strlen是一个库函数使用时需要引用#include<string.h>这个头文件,而sizeof是一个运算符号;

2.strlen计算的是'\0'之前的字符个数,sizefo计算的是所占空间内存的大小,单位是字节;

3.strlen计算时不包含'\0',而sizeof包含'\0';

4.strlen遇到'\0'才结束;

5.strlen只能用char做参数,sizeof可以用类型做参数;

6.sizeof的类型是unsigned int ,是一个无符号的整型;

 现在可以更深入的学习并运用好sizeof和strlen在数组和指针的运用里:

看下面的题目来提升一下对sizeof和strlen的认知吧!

1.sizeof在整型数组中的使用:
#include<stdio.h>

int main()
{
	int a[] = { 1,2,3,4 };

	printf("%d\n", sizeof(a)); // 16
	//sizeof(数组名)是指整个数组
	//计算的是整个数组的大小,单位是字节
	printf("%d\n", sizeof(a+0)); // 4/8
	//sizeof(数组名+0)指的是首元素的地址
	//a不是单独放在sizeof里面,也没有取地址,所以指的是首元素,a+0还是首元素
	printf("%d\n", sizeof(*a));// 4/8
	//*a都是指a首元素的地址,*是对a的首元素解引用,找到的就是首元素的地址
	printf("%d\n", sizeof(a+1));// 4/8
	//这里的a指的是首元素的地址
	//a+1就是指第二个元素的地址
	printf("%d\n", sizeof(a[1]));// 4/8
	//a[0]是指数组的第一个元素
	//a[1]就是指数组的第二个元素
	printf("%d\n", sizeof(&a));// 4/8
	//&a代表的整个数组的起始地址
	//数组的地址也是地址
	printf("%d\n", sizeof(*&a));// 16
	//&a --->int(*)[4]
	//&a拿到的是数组名的地址,类型是int(*)[4]一种数组指针
	//数组指针解引用找到的是数组
	//*&a  --> a
	printf("%d\n", sizeof(&a+1));// 4/8
	//&a取的是整个数组的地址,&a+1就是在整个数组之后的一个元素
	printf("%d\n", sizeof(&a[0]));// 4/8
	//&a[0]取的是整个数组的第一个元素
	printf("%d\n", sizeof(&a[0]+1));// 4/8
	//&a[0]+1指的是数组第一个元素之后的一个元素,第二个元素
	return 0;
}
2.sizeof在字符数组中的使用:
#include<stdio.h>
#include<string.h>

int main()
{
	char arr[] = { 'a','b','c','d','e','f' };
	printf("%d\n", sizeof(arr)); // 6
//	//sizeof(数组名)代表的是整个元素
	printf("%d\n", sizeof(arr + 0)); // 4/8
//	//arr+0代表的是&arr[0]所以是地址的大小,单位是字节
	printf("%d\n", sizeof(*arr));// 1
//	//*&arr[0]是指arr[0]所以大小是一个字节
	printf("%d\n", sizeof(arr[1]));// 1
//	//arr[1]大小就是一个字节
	printf("%d\n", sizeof(&arr));// 4/8            -------|           
//	//                                                    |
	printf("%d\n", sizeof(&arr + 1));// 4/8    如果指的是地址所对应的字节就是4/8,只是单个的元素对应的就是1byte
//
	printf("%d\n", sizeof(&arr[0] + 1));// 4/8            | 
//                                                 -------|
// //sizeof(arr[0]+1),arr[0]是char类型的,1是int类型的,都小于4个字节所以是整型提升为int类型                                        
//	return 0;
//}
 3:strlen在字符数组中的使用:
int main()
{
	char arr[] = { 'a','b','c','d','e','f' };
//
//	//strlen(const char* str)  只能接收指针
//
	printf("%d\n", strlen(arr)); //随机值 
//	//sizeof(数组名),代表整个数组
//	//因为数组里没有'\0',stlen库函数只有遇到'\0'才会停止,
//	//计算开头到'\0'为止中间的长度
	printf("%d\n", strlen(arr + 0)); //随机值 
//	//&arr[0]开始到'\0'中间的长度
	printf("%d\n", strlen(*arr));//err,野指针 
//	//*arr[0]是指a这个元素,strlen(a)==strlen(97)报错
	printf("%d\n", strlen(arr[1]));// err,野指针
//	//这也是一个元素‘b’,strlen(b)==strlen(98)报错
	printf("%d\n", strlen(&arr));// 随即值
//	//指这个数组从开头到‘\0’的长度
	printf("%d\n", strlen(&arr + 1));//随机值-6 
//	//指这个数组后第一个元素开始计算
	printf("%d\n", strlen(&arr[0] + 1));//随机值-1
//	//指这个数组的第二个元素开始计算
	return 0;
//}
4.sizeof在字符串数组中的使用:
int main()
{
	char arr[] = "abcdef";
	printf("%d\n", sizeof(arr)); // 7
//	//sizeof(数组名)是指整个数组,字符串后面自带'\0'
	printf("%d\n", sizeof(arr + 0)); // 4/8
//	//&arr[0]是一个地址,所以是4/8byte
	printf("%d\n", sizeof(*arr));// 1
//	//arr[0]指的是一个元素,a是一个字节char类型
	printf("%d\n", sizeof(arr[1]));// 1
//	//arr[1]指的也是一个元素,b是一个字节char类型
	printf("%d\n", sizeof(&arr));// 4/8
//	//取整个数组arr是一个地址
	printf("%d\n", sizeof(&arr + 1));// 4/8
//	//是在数组arr之后的元素地址
	printf("%d\n", sizeof(&arr[0] + 1));// 4/8
//	//指的是第二个元素的地址
	return 0;
//}
5.strlen在字符串中的使用:
int main()
{
	char arr[] = "abcdef";
//
//	//strlen(const char* str)  只能接收指针
//
	printf("%d\n", strlen(arr)); //6
//	//sizeof(数组名),代表整个数组
//	//因为数组里没有'\0',stlen库函数只有遇到'\0'才会停止,
//	//计算开头到'\0'为止中间的长度
	printf("%d\n", strlen(arr + 0)); //6 
//	//&arr[0]开始到'\0'中间的长度
	printf("%d\n", strlen(*arr));//err,野指针 
//	//*arr[0]是指a这个元素,strlen(a)==strlen(97)报错
	printf("%d\n", strlen(arr[1]));// err,野指针
//	//这也是一个元素‘b’,strlen(b)==strlen(98)报错
	printf("%d\n", strlen(&arr));// 6
//	//指这个数组从开头到‘\0’的长度
	printf("%d\n", strlen(&arr + 1));//随机值 
//	//指这个数组后第一个元素开始计算
//	//已经跳过了这个数组,在'f'后的'\0'之后开始计算
	printf("%d\n", strlen(&arr[0] + 1));//5
//	//指这个数组的第二个元素开始计算
	return 0;
//}
6.sizeof在指针指向字符串的使用:
int main()
{
	char *arr = "abcdef";
	printf("%d\n", sizeof(arr)); // 4/8
//	//sizeof(数组名)是指整个数组
//	//但是*arr是一个地址,指的是首元素地址
	printf("%d\n", sizeof(arr + 1)); // 4/8
//	//&arr[0]是一个地址,地址传地址相当于二级指针,所以是4/8byte
	printf("%d\n", sizeof(*arr));// 1
//	//arr[0]指的是一个元素,a是一个字节char类型
	printf("%d\n", sizeof(arr[0]));// 1
//	//arr[1]指的也是一个元素,b是一个字节char类型
	printf("%d\n", sizeof(&arr));// 4/8
//	//取整个数组arr是一个地址,二级指针地址
	printf("%d\n", sizeof(&arr + 1));// 4/8
//	//是在数组arr之后的元素地址,二级指针地址
	printf("%d\n", sizeof(&arr[0] + 1));// 4/8
//	//指的是第二个元素的地址,地址二级指针地址
	return 0;
//}
7.strlen在指针指向字符串的使用:
int main()
{
	char* a = { "abcdef" };

	//strlen(const char* str)  只能接收指针

	printf("%d\n", strlen(a)); //6
	//sizeof(数组名),代表整个数组
	//因为数组里没有'\0',stlen库函数只有遇到'\0'才会停止,
	//计算开头到'\0'为止中间的长度
	printf("%d\n", strlen(a + 1)); //5 
	//&arr[1]开始到'\0'中间的长度
	//第一个元素不被函数计算在内
	// 
	//printf("%d\n", strlen(*a));//err,野指针 
	*arr[0]是指a这个元素,strlen(a)==strlen(97)报错
	//printf("%d\n", strlen(a[0]));// err,野指针
	这也是一个元素‘b’,strlen(b)==strlen(98)报错

	printf("%d\n", strlen(&a));// 随机值
	//指这个数组从开头到第二个‘\0’的长度
	//因为它相当于二级指针,第一个‘\0'是*的
	//第二个‘\0’才是&arr的
	printf("%d\n", strlen(&a + 1));//随机值 
	//指这个数组后第一个元素开始计算
	//已经跳过了这个数组,在'f'后的'\0'之后开始计算
	printf("%d\n", strlen(&a[0] + 1));//5
	//指这个数组的第二个元素开始计算
	return 0;
}
8.sizeof在二维数组中的使用:
#include<stdio.h>

int main()
{
	int a[3][4] = { 0 };
	printf("%d\n", sizeof(a));// 48
	//sizeof(数组名),代表整个数组元素大小,单位byte
	printf("%d\n", sizeof(a[0][0]));// 4
	//代表第一个元素大小
	printf("%d\n", sizeof(a[0]));// 16
	//代表第一行的全部元素大小
	printf("%d\n", sizeof(a[0]+1));/// 4/8
	//访问第一行的地址+1,就是第二行的地址&arr[1]
	printf("%d\n", sizeof(*(a[0]+1)));// 16
	//对第二行的地址解引用就是计算第二行的全部元素大小
	printf("%d\n", sizeof(a + 1));// 4/8
	//不是单独放在sizeof里面
	//就是代表a数组的首元素
	//二维数组的首元素是指a[0]
	//&a[0]+1 == &a[1] 地址大小是4/8byte
	printf("%d\n", sizeof(*(a + 1)));// 16
	//对第二行的地址解引用就是计算第二行的全部元素大小
	printf("%d\n", sizeof(&a[0] + 1));// 4/8
	//&a[1]是地址,地址的大小就是4/8byte
	printf("%d\n", sizeof(*(&a[0] + 1)));// 16
	//对&a[1]解引用就是整个一行的元素大小
	printf("%d\n", sizeof(*a));//16
	//不是单独放在sizeof里面,就是值得是第一个元素的地址
	//对第一个元素的地址解引用就是第一个元素的大小
	printf("%d\n", sizeof(a[3]));// 16
	//a[3]虽然越界,但是sizeof不会越界访问
	//只会根据数组大小来判断,
	//因为他本身是一个三行四列的大小
	//现在就算跳到了第四行,但是他还是4列,大小为16byte
	//与a[0]结果一样
	return 0;
}

  • 13
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值