sizeof和strlen最全区别,以及指针和数组运算解析

今天解元给大家带来sizeof和strlen的使用以及区别,以及指针和数组运算解析
请添加图片描述



简介

1.sizeof

sizeof是C语言的内置运算符,以字节为单位给出指定类型的大小。C99和C11提供%zd转换说明匹配sizeof的返回类型。一些不支持C99和C11的编译器可用%u或%lu代替%zd。

该程序的输出如下:
以下均用于64位系统

Type int has a size of 4 bytes.//int 类型占用4个字节
Type char has a size of 1 bytes.//char 类型占用1个字节
Type float has a size of 4 bytes.//float 类型占用4个字节
Type long has a size of 4 bytes.//long 类型占用4个字节
Type long long has a size of 8 bytes.//long long 类型占用8个字节
Type double has a size of 8 bytes.//double 类型占用8个字节
Type long double has a size of 8 bytes.//long double 类型占用8个字节

注意:
1.这个关键字返回size_t类型的值。
2.表达式要么是标识符,要么是类型转换表达式(用圆括号括起来的类型说明符)。
3.当应用于结构类型或变量时,sizeof返回实际大小,其中可能包括为对齐而插入的填充字节。 当应用于静态维度数组时,sizeof返回整个数组的大小。 sizeof操作符不能返回动态分配的数组或外部数组的大小。
在这里插入图片描述

2.strlen

C语言库函数提供多个处理字符串的函数,ANSI C把这些函数的原形放在string.h头文件中。而strlen就是其中之一。

strlen()函数用于统计字符串的长度。知道找到字符串中的‘\0’为止。

size_t strlen ( const char * str );//返回类型为size_t

返回char字符串的长度
例如:

/* strlen example */
#include <stdio.h>
#include <string.h>

int main ()
{
  char szInput[256];
  printf ("Enter a sentence: ");//输入一个句子
  gets (szInput);
  printf ("The sentence entered is %u characters long.\n",(unsigned)strlen(szInput));//输入的句子长度为
  return 0;
}

输出结果:

Enter sentence: just testing//输入句子为 just testing
The sentence entered is 12 characters long.//输入的句子长度为12个字符。

对比

有上可见两者区别:

sizeof的功能是计算一个数据类型的大小,这个类型可以是数组、函数、指针、对象等,单位为字节,它的返回值是size_t类型,也就是unsigned int类型,是一个无符号整数。注意:sizeof不是一个函数,它是一个运算符,所以它不需要包含任何头文件。

*strlen的功能是计算一个指定字符串的长度,函数原型是size_t strlen(const char s),它的返回值是size_t类型,也就是unsigned int类型,返回的是字符串的长度,需要包含头文件#inlude <string.h>,参数s是字符串首地址。

即:
1、sizeof会将空字符\0计算在内,而strlen不会将空字符\0计算在内;

2、sizeof会计算到字符串最后一个空字符\0并结束,而strlen如果遇到第一个空字符\0的话就会停止并计算遇到的第一个空字符\0前面的长度。

重头戏

好东西肯定是压轴的啦:

sizeof和strlen最全对比

先看一下然后进入正题:
sizeof(数组名)-数组表示的是整个数组的-计算的是整个数组的大小,
&数组名表示整个数组,取出的是整个数组的地址;
除上面这两个之外,其他所有的数组名都是数组首元素的地址

1.一维数组

#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 a+0是数组第一个元素的地址,sizeof(a+0)计算的是地址的大小
	printf("%d\n", sizeof(*a));//4 *a是数组第一个元素,sizeof(*a)计算的是数组第一个元素的大小
	printf("%d\n", sizeof(a + 1));//4/8 a+1是数组第二个元素的地址,sizeof(a+1)计算的是第二个元素的大小
	printf("%d\n", sizeof(a[1]));// 4 a[1]访问的是数组第二个元素,计算的是数组第二个元素的大小

	printf("%d\n", sizeof(&a));//4/8 &a虽然是整个数组的地址,但是还是地址,sizeof(&a)计算的是一个地址的大小
	printf("%d\n", sizeof(*&a));//16 &a是取的是整个数组的地址,解引用后就是整个数组,所以计算的是数组的大小;
	printf("%d\n", sizeof(&a + 1));//4/8 取整个数组的地址+1跳过整个数组,指向4后面空间的地址,因为是地址,所以是4或者8个字节
	printf("%d\n", sizeof(&a[0]));//4/8,取出的是数组第一个元素的地址,所以为4或者8
	printf("%d\n", sizeof(&a[0] + 1));//4/8 第一个元素地址加1得到数组第二个元素的地址,所以为4或者8
	return 0;
}

2.字符数组

#include<stdio.h>
#include<string.h>
int main()
{
	字符数组,温馨提示strlen找\0找到才停止
	char arr[] = { 'a','b','c','d','e','f' };
	printf("%d\n", sizeof(arr));//  6  整个数组,六个元素,每个元素一个字节
	printf("%d\n", sizeof(arr + 0));//4/8 求的是地址大小,arr+0等于没加,重点这是一个地址
	printf("%d\n", sizeof(*arr));//1 首元素地址,解引用指向a,所以为1
	printf("%d\n", sizeof(arr[1]));// 1  数组第二个元素,一个字节
	printf("%d\n", sizeof(&arr));//4/8  数组的地址!
	printf("%d\n", sizeof(&arr + 1));//4/8  加一后跳过整个数组,指向f后面的一个空间的地址
	printf("%d\n", sizeof(&arr[0] + 1));//4/8 &arr[0](本质是int*)取出a的地址,加一跳过一个元素指向b的地址
	
	printf("%d\n", strlen(arr));//随机值,找不到\0
	printf("%d\n", strlen(arr + 0));//与上一样
	printf("%d\n", strlen(*arr));//报错,97
	printf("%d\n", strlen(arr[1]));//98 报错
	printf("%d\n", strlen(&arr));//&arr的时候,取出的是数组的地址,向后找,还是随机值
	printf("%d\n", strlen(&arr + 1));//跳过一个数组后,还是随机值-6
	printf("%d\n", strlen(&arr[0] + 1));//随机值+1
	return 0;
}

小多,别慌,认真看完

#include<stdio.h>
#include<string.h>
int main()
{
	char arr[] = "abcdef";
	printf("%d\n", sizeof(arr));//7 长度 
	printf("%d\n", sizeof(arr + 0));// 4/8arr+0地址
	printf("%d\n", sizeof(*arr));// 1 arr首元素地址,*解引用第一个元素
	printf("%d\n", sizeof(arr[1]));//1 数组第二个元素
	printf("%d\n", sizeof(&arr));//4/8 整个数组的地址char(*)[7]
	printf("%d\n", sizeof(&arr + 1));//4/8加一跳过整个数组,指向地址
	printf("%d\n", sizeof(&arr[0] + 1));//4/8 第一个元素的地址取出来+1,就是第二个元素的地址

	printf("%d\n", strlen(arr));//6
	printf("%d\n", strlen(arr + 0));//6
	printf("%d\n", strlen(*arr));//err
	printf("%d\n", strlen(arr[1]));//err
	printf("%d\n", strlen(&arr));//6
	printf("%d\n", strlen(&arr + 1));//随机值
	printf("%d\n", strlen(&arr[0] + 1));//5
	return 0;
}
#include<stdio.h>
#include<string.h>
int main()
{
	char* p = "abcdef";
	printf("%d\n", sizeof(p));//4/8  p指向a的地址,
	printf("%d\n", sizeof(p + 1));//4/8 数组首元素加一得到b的地址,
	printf("%d\n", sizeof(*p));//1	p指向a,a的字节为1
	printf("%d\n", sizeof(p[0]));//1 p+0相当于*(p+0),还是1
	printf("%d\n", sizeof(&p));//4/8  地址,大小固为4/8
	printf("%d\n", sizeof(&p + 1));//4/8  跳过一个p,但是指向的还是地址
	printf("%d\n", sizeof(&p[0] + 1));//4/8   指向b的地址 

	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

	return 0;
}

还有,还有别走

3.二维数组

#include<stdio.h>
#include<string.h>
int main()
{
	int a[3][4] = { 0 };
	printf("%d\n", sizeof(a));
	//48 数组名单独放到sizeof内部,计算整个数组的大小3*4*4
	printf("%d\n", sizeof(a[0][0]));
	//4  第一行第一个元素
	printf("%d\n", sizeof(a[0]));
	//16 a[0]就可以理解为二维数组第一行的数组名,计算的是第一行的大小
	printf("%d\n", sizeof(a[0] + 1));
	//4  a[0]作为数组名并没有单独放在sizeof内部,也没有取地址,所以a[0]就是第一行第一个元素的地址
    //a[0]+1的时候就是第一行第二个元素的地址,地址,所以是4个字节

	printf("%d\n", sizeof(*(a[0] + 1)));
	// 4 同上,但是解引用之后指向的是一个元素

	printf("%d\n", sizeof(a + 1));//4 
	//a表示二维数组的数组名,并没有取地址,也没有单独放在sizeof内部,所以a就是二维数组首元素的地址即:第一行的地址
	//a+1就是二维数组第二行的地址,既然是地址就是四个字节

	printf("%d\n", sizeof(*(a + 1)));
	//16 同上解引用后就是整个第二行的大小、、*(a + 1)<=>a[1]
	//a+1是第二行的地址,所以*(a + 1)是第二行,计算的就是第二行的大小

	printf("%d\n", sizeof(&a[0] + 1));
	//4 &a[0],取出第一行的地址加一得到第二行的地址,地址大小为4
	//解释:a[0]是第一行的数组名,&a[0]取出的是第一行的地址,&a[0] + 1就是第二行的地址

	printf("%d\n", sizeof(*(&a[0] + 1)));
	//16,&a[0] + 1就是第二行的地址,解引用*(&a[0] + 1)后计算的是第二行的大小

	printf("%d\n", sizeof(*a));
	//16 解释:a作为二维数组的数组名,没有单独放在sizeof内,a就是首元素的地址,即第一行的地址,
	//所以*a就是第一行,计算的是第一行的大小
	printf("%d\n", sizeof(a[3]));
	//16 解释a[3]是第四行的数组名(如果有的话),如果不存在,也能通过类型进行大小的



看够了嘛?
.
.
.
.
没看够关注呗

总结

燕子三连吧燕子
在这里插入图片描述
在这里插入图片描述
别找了没有总结,上面的全部都是干货!!!

  • 21
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 16
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 16
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

#唐解元

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值