【C语言】十分钟,带你分清楚sizeof和strlen

前言

阅读本文章,笔者会向你介绍sizeof和strlen的定义以及两者的区别,笔者还会通过讲解具体的笔试题带你深入理解。

一 sizeof介绍

在C语言中,sizeof是判断数据类型长度符的关键字
(注意sizeof不是函数,它在程序没有运行时就计算出结果了)。

sizeof作用就是返回一个对象或者类型所占的内存字节数

#include <stdio.h>
int main()
{
	int arr[10];
	printf("%d", sizeof(arr));
	return 0;
}
  • sizeof单位是字节,因此结果为40

二 strlen介绍

strlen是一个计算给定字符串的(unsigned int型)长度的函数
(不包括’\0’在内)。

它从内存的某个位置(可以是字符串开头,中间某个位置,甚至是某个不确定的内存区域)开始扫描,直到碰到第一个字符串结束符’\0’为止。

#include <stdio.h>
#include <string.h>
int main()
{
	char str[] = "asdf";
	printf("%d", strlen(str));
	return 0;
}
  • 结果为4,计算的是所含元素的个数。

三 strlen和sizeof

1.适用范围

sizeof
1.计算数组所包含的字节数。
2.用于数据类型,如 sizeof (int)。
3.用于指针,根据编译器是X64 or X86, 得到 8 or 4。

strlen
用于计算字符串长度。

2.sizeof和数组名

数组名通常代表首元素地址,但存在两个特殊情况。

1.sizeof中包含的数组名代表整个数组,因此得到的结果为整个数组包含的字节数

在这里插入图片描述

2.&arr代表整个数组的地址,而不代表首元素地址。当我们给它+1时会跳过整个数组。

在这里插入图片描述

  • 两个十六进制数相减可以得到40,也就是arr包含的字节数。

四 题目实战

1.一维数组

//一维数组
int a[] = {1,2,3,4};
printf("%d\n",sizeof(a));
printf("%d\n",sizeof(a+0));//指针
printf("%d\n",sizeof(*a));//int类型
printf("%d\n",sizeof(a+1));//指针
printf("%d\n",sizeof(a[1]));//int类型
printf("%d\n",sizeof(&a));//指针
printf("%d\n",sizeof(*&a));//* 和 &可以看成相互抵消,等于sizeof(a)
printf("%d\n",sizeof(&a+1));//指针
printf("%d\n",sizeof(&a[0]));//指针
printf("%d\n",sizeof(&a[0]+1));//指针

运行结果
在这里插入图片描述

  • 当sizeof后面仅有首元素地址时,a代表整个数组,输出数组包含的所有字节数,因此第一个为16。但是如果改变为 printf("%d\n",sizeof(a+0)); 此时a就代表首元素地址。

  • 这串代码在X86环境下运行,因此sizeof指针为8, sizeof(int)类型的是4

  • a[2] 可以看成 *(a + 2)

2.字符数组

//字符数组
char arr[] = {'a','b','c','d','e','f'};
printf("%d\n", sizeof(arr));//arr占据的全部空间
printf("%d\n", sizeof(arr+0));//指针
printf("%d\n", sizeof(*arr));// 首元素'a'
printf("%d\n", sizeof(arr[1]));//首元素'a'
printf("%d\n", sizeof(&arr));//指针
printf("%d\n", sizeof(&arr+1));//指针
printf("%d\n", sizeof(&arr[0]+1));//指针
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));//随机值

运行结果
在这里插入图片描述

  • 用这种方式定义arr时,数组的最后没有 ‘\0’ ,因此strlen(指针) 返回值无法确定,返回随机值。

  • strlen接收指针,无法读取*arr和arr[1]。

  • 为什么&arr+1明明越界了还能输出呢?
    因为sizeof是一个关键字,而不是函数,里面的内容并不会运算。

char arr[] = "abcdef";
printf("%d\n", sizeof(arr));//abcdef占的空间+'\0'
printf("%d\n", sizeof(arr+0));//首元素地址
printf("%d\n", sizeof(*arr));//字符a
printf("%d\n", sizeof(arr[1]));//字符a
printf("%d\n", sizeof(&arr));//指针
printf("%d\n", sizeof(&arr+1));//指针
printf("%d\n", sizeof(&arr[0]+1));//指针
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));//元素个数-1

运行结果
在这里插入图片描述

  • char arr[] = " abcdef " ; 定义的字符串会在末尾自动加上’ \0 ',sizeof也会加上它所占的空间。

  • &arr+1跳过了’ \0 ',所以不知道在哪里停止,输出随机值。

char *p = "abcdef";
printf("%d\n", sizeof(p));//指针(此时不是数组名)
printf("%d\n", sizeof(p+1));//指针
printf("%d\n", sizeof(*p));//首元素a
printf("%d\n", sizeof(p[0]));//首元素a
printf("%d\n", sizeof(&p));//指针
printf("%d\n", sizeof(&p+1));//指针
printf("%d\n", sizeof(&p[0]+1));//指针
printf("%d\n", strlen(p));//元素个数
printf("%d\n", strlen(p+1));//元素个数-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));//元素个数-1
  • p为指针并且指向字符串首元素的地址。

运行结果
在这里插入图片描述

  • 不要把指针当做数组名

3.二维数组

//二维数组
int a[3][4] = {0};
printf("%d\n",sizeof(a));//数组名单独在sizeof中代表整个数组
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));//等于a+1
printf("%d\n",sizeof(*(&a[0]+1)));//等于*(a+1)
printf("%d\n",sizeof(*a));//第一行的数组名
printf("%d\n",sizeof(a[3]));//表示一个包含四个元素数组的数组名

运行结果
在这里插入图片描述

  • 这道题有点复杂,我们画个图来理解。
    在这里插入图片描述

  • 左边是一个3*4的二维数组(内存中是连续的,这样画是为了方便理解),第一行的数据可以用 a[0][j] 表示,j的范围是0~3。由此我们可以类比旁边的一维数组,我们把二维数组看成三个一维数组,然后就可以假设——a[0]就是第一行这个“一维数组”的数组名。同理,a[1]就是第二行数组的数组名。

  • a是二维数组的数组名,也就是数组首元素的地址,我们已经知道二维数组的首元素是a[0],那么a就是a[0]的地址即 a = &a[0]。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

诺伯里-

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

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

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

打赏作者

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

抵扣说明:

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

余额充值