先看意气风发段代码

写在前头

sizeof、strlen、字符串、数组,提到那一个概念,相信学过C语言的人都能耳濡目染,也能谈得井井有条,然则,在事实上行使中,当那么些内容交织在一起时,我们却不自然能搞地清晰,本文的目的正是帮忙我们将相关知识计算清楚。

 

正文

先看生机勃勃段代码

 1 #include <stdio.h>
 2 #include <stdlib.h>
 3 
 4 void testchar(char str[])
 5 {
 6     printf("%d %dn", sizeof(str), strlen(str));
 7 }
 8 
 9 void testint(int arr[])
10 {
11     printf("%dn", sizeof(arr));
12 }
13 
14 int main()
15 {
16     char str[] = "abc";
17     printf("%d %dn", sizeof(str), strlen(str)); //4 3
18 
19     char str1[10] = "abc";
20     printf("%d %dn", sizeof(str1), strlen(str1)); //10 3
21 
22     char dog[] = "wangwangmiao";
23     printf("%d %dn", sizeof(dog), strlen(dog)); //14 8
24     testchar(dog); //4 8
25 
26     char *cat = "wangwangmiaomiao";
27     printf("%d %dn", sizeof(cat), strlen(cat)); //4 8
28     
29     int arr[10] = { 0 };
30     printf("%d %dn", sizeof(arr), sizeof(arr[11])); //40 4
31     testint(arr); //4
32 
33     return 0;
34 }

 

 结果

 图片 1

在讲明上边的例子在此以前,大家先来讲一说sizeof和strlen。

语法上的真面目分裂:

sizeof是运算符,strlen是函数。

适用范围不平等:

对sizeof(name)来讲,name能够是变量名也能够是项目名,对strlen来说,参数必需是char*类别的,即strlen仅用于字符串。

关键——从底部看本质

strlen(ptr)的实践机理是:从参数ptr所指向的内部存款和储蓄器起头向下计数,直到内部存款和储蓄器中的内容是全0(即’’)为止(不会对’’实行计数)。用strlen衡量字符串的尺寸,其实正是依赖那些规律。

sizeof(name)的实践机理是:就算name是一个项目名,得到的是该类型的抑扬顿挫(所谓类型的尺寸,指的是:假诺存在贰个该项目标变量,这么些变量在内部存款和储蓄器中所占用的字节数),如若name是贰个变量名,那么,sizeof(name)并不会真正访谈该变量,而是先得知该变量的品类,然后再回来该品种的深浅(即就是struct那样的复杂类型,编译器在编写翻译时也会依附它的各种域记录其大小,所以,由项目得到类型大小,不是大器晚成件难事)。换句话说,本质上,sizeof的演算对象是种类。假设name是二个变量名,那么,sizeof怎样“对待”name的项目,将是二个关键难点。(前面大家会对这点有深远的体味)

下面提到的那一点,是领略好sizeof和strlen的不二诀要,是放之所在皆准的轨道。下边,大家就以如此的金科玉律来剖析上边的事例。

a.

char str[] = "abc";
printf("%d %dn", sizeof(str), strlen(str)); //4 3

此间,是用数组的款式注明字符串,编写翻译器会自行在字符串前边加上’’,所以,数组的因素个数是4并不是3。对于sizeof(str)来讲,sizeof将str视为char
[4]l类型的变量,所以,sizeof(str)的结果便是一切数组所占领的半空中大小。对于strlen(str)来讲,它从str指向的内部存款和储蓄器最早计数,直到遇见全0的内部存款和储蓄器(’’),所以最终获得结果3。

b.

char str1[10] = "abc";
printf("%d %dn", sizeof(str1), strlen(str1)); //10 3

 

编写翻译器为char
str1[10]分配拾叁个数组成分大小的空中,那与开首化它的字符串未有关联,所以sizeof(str1)获得10。

c.

char dog[] = "wangwangmiao";
printf("%d %dn", sizeof(dog), strlen(dog)); //14 8
testchar(dog); //4 8

前两句和a中的情形亦然,sizeof(dog)输出整个数组所占的内部存款和储蓄器大小(包蕴编写翻译器加上去的’’),strlen(dog)遇到’’就甘休,所以输出8。

再看后面包车型客车函数调用,数组名dog作为函数实参传入,大家再来回看一下testchar函数

void testchar(char str[])
{
    printf("%d %dn", sizeof(str), strlen(str));
}

咱俩发掘,这里sizeof(str)并未有像sizeof(dog)那样获得14,而是获得了4。这是因为,str是函数形参,尽管它是以数组名的格局现身的,传给它的实参也实在是数组名,但sizeof仅仅把它当成贰个char*品类的指针对待,所以,sizeof(str)的结果就是char
*花色所占的空间4。至于strlen(str),大家前边说过,它试行的机理正是从str指向的内部存款和储蓄器早前向下计数,直到遇见’’,所以仍然收获8。

d.

char *cat = "wangwangmiaomiao";
printf("%d %dn", sizeof(cat), strlen(cat)); //4 8 

是因为cat明显宣示为char*,所以sizeof将它正是指针,获得4。

e.

int arr[10] = { 0 };
printf("%d %dn", sizeof(arr), sizeof(arr[11])); //40 4
testint(arr); //4

眼下说过,当数组名作为函数形参现身时,sizeof仅仅将其正是一个指针,不然,sizeof以为它表示整个数组,所以,sizeof(arr)获得任何数组所占的字节数40,而testint(arr)的结果是int*项指标指针的尺寸4。

sizeof(int[11])中,很显然数组越界了,但并不会现身运维时不当。原因是:依附大家付出的判别法则,sizeof并不曾真正访谈arr[11],根据arr的声明,sizeof知道arr[11]是int型的,所以回来int类型的大大小小。

至于testint(arr),道理和c中的testchar(dog)相同。

 

最终,基于上面包车型地铁研商,给出编码法则:

1.千古不要用sizeof来求字符串长度!它不是干这么些活的,所以您也永恒不会拿走正确答案。

2.不要自作聪明地用sizeof(arr)/sizeof(arr[0])那样的代码求数组的长短!sizeof亦非干那个活的。要是arr是函数形参,获得的结果将是谬误的(除非您在三十几位系统下恰好注脚int
arr[1]或者char
arr[4]等,但那纯属巧合)。既然是数组,长度自然是已知的,求数主管度那意气风发自家,正是适得其反的鲁钝行为。

 

写在末端

本文的目标,正是使读者对C语言的基础知识——sizeof和strlen有叁个实质的认知,同不常候对与之有关的易错、易混问题有一个不易、清晰的论断。由于在下德薄能鲜,错误脱漏之处在劫难逃,希望广大读者积极评论指正,您的争辩指正是在下发展的不竭重力。

相关文章

发表评论

电子邮件地址不会被公开。 必填项已用*标注

*
*
Website