在C语言中有专门的字符串变量,通常用一个字符数组来存放一个字符串。字符串总是以’\0’作为串的结束符。
当把一个字符串存入一个数组时,也把结束符 ‘\0’存入数组,并以此作为该字符串是否结束的标志。有了’\0’标志后,就不必再用字符数组的长度来判断字符串的长度了。
strlen、sizeof、length、size对比
1、(C中)数组或字符串的长度:sizeof(单目运算符、关键字)、strlen(函数)
1.1、sizeof单目运算符:获取编译时分配(确定了)的总空间的字节数(如果有则包括"\0")👉不能返回动态内存大小
参数可以是数组、指针、类型、对象、函数等
char sArr[] = "ILOVEC";
printf("sArr的长度=%d\n", sizeof(sArr)); 👉结果为7(因为它包括结束字符 null)
可以以函数作为参数,例如:
short f();
printf("%d\n", sizeof(f()));
输出的结果是sizeof(short),即2。
字符数组 没有\0 有数组长度,不需要标识结束
字符串 有\0 需要\0以此来标识结束
c语言没有string类型,故用字符数组存放,并用\0标识结束👉实现类似c++中的字符串结构
char str[]="xunlei"; 需要末尾胡添加\0👉sizeof(str)=7
char str2[]={
'x','u','n','l','e','i'}; 没必要添加\0👉sizeof(str2)=6
1.2、strlen函数:计算字符串长度(从起始位置知道"\0",但不包括"\0")
当数组名作为参数传入时,实际上数组就退化成指针了
size_t strlen(const char *str) 参数必须是字符型指针(char*)且必须以“\0”结尾
{
assert(str != NULL);
int len;
while((*str++) != '\0')
{
len++;
}
return len;
}
size_t和int的区别
①int在32位和64位架构中都是4字节(有符号数)
②size_t在不同架构中长度不同(无符号数)
1、32位架构中被定义为:typedef unsigned int size_t; (4字节)
2、64位架构中被定义为:typedef unsigned long size_t; (8字节)
为什么要使用size_t:
不同架构中自适应长度,避免了固定4字节(可能不够大)或者固定8字节(可能浪费)时的问题
影响:由于函数 strlen 返回的是一个类型为 size_t 的值,从而有可能让程序导致意想不到的结果,如下面的示例代码所示:
情况1:
if(strlen(x)>= strlen(y))→→→→→真假看具体情况
比如if(strlen(x)>= 5)
情况2:
if(strlen(x)- strlen(y)>= 0)→→size_t-size_t=size_t是无符号整型→必定满足>=0→必定为真
比如if(strlen(x)- 5>=0)
1.3、sizeof、strlen的比较以及实例:
1)sizeof操作符的结果类型是size_t,它在头文件中typedef为unsigned int类型。
2)sizeof是运算符,strlen是函数。
3)sizeof可以用类型做参数,strlen只能用char*做参数,且必须是以’’\0’'结尾的。
4)数组做sizeof的参数不退化,传递给strlen就退化为指针了。
5)大部分编译程序 在编译的时候就把sizeof计算过了 是类型或是变量的长度。这就是sizeof(x)可以用来定义数组维数的原因
char str[20]=“0123456789”;
int a=strlen(str); //a=10;
int b=sizeof(str); //而b=20;
6)strlen的结果要在运行的时候才能计算出来,用来计算字符串的长度,不是类型占内存的大小。
7)sizeof后如果是类型必须加括弧,如果是变量名可以不加括弧。这是因为sizeof是个操作符不是个函数。
8)当使用了一个结构类型或变量时, sizeof 返回实际的大小, 当使用一静态地空间数组, sizeof 返回全部数组的尺寸。 sizeof 操作符不能返回被动态分配的数组或外部的数组的尺寸
char* aa = "0123456789";
printf("sizeof(aa)=%d sizeof(*aa)=%d strlen(aa)=%d\r\n", sizeof(aa), sizeof(*aa), strlen(aa));
//4(指针ss的空间) 1(指针长度) 10(\0前的数据长度)
char bb[] = "0123456789"