C语言 strlen与sizeof的区别
strlen是一个函数,它的参数必须是字符型指针(char *),且必须是以结束字符'\0'结尾的;
strlen的函数调用返回的是size_t类型,即结果类型是size_t类型(无符号整型);
strlen在运行时刻才能计算结果,故它计算的是字符串的长度,不是类型占内存的大小;
strlen只关心存储的数据内容的长度,不管空间的大小与类型,即strlen计算的是空间中字符的个数(不包括'\0');
strlen(char*)函数的功能是返回字符串的实际长度,该函数实际完成的功能是从代表该字符串的第一个地址开始遍历,直到遇到结束字符'\0',返回长度不包括'\0',
如果字符串没有赋值,strlen(char*)返回的结果将是不定的,因为它将从该字符串的首地址一直遍历直到遇到'\0';
当数组名作为参数传入时,实际上数组就退化成指针了。
sizeof是一个单目运算符(算符/操作符/关键字),它是结果类型是size_t,在头文件用typedef定义为unsigned int类型;
sizeof的参数可以是数组、指针、类型、对象、函数等,它返回的是变量声明后所占的内存数,非实际长度,即它计算的是分配空间的实际字节数;
sizeof的功能是获取保证能容纳实现所建立的最大对象的字节大小;
sizeof是在编译时刻计算缓冲区长度,因此sizeof不能返回动态分配的内存空间大小;
sizeof是在编译的时候就将结果计算出来了是类型所占空间的字节数,所以数组名做参数时计算的是整个数组的大小;
当函数分别如下时,sizeof返回的值表示含义如下:
数组--编译时分配的数组空间大小
指针--存储该指针所用的空间大小(存储该指针的地址的长度,如长整型,应该为4)
类型--该类型所占的空间大小
对象--对象的实际占用空间大小
函数--函数的返回类型所占的空间大小,函数返回类型不能为void
当用sizeof来返回类型以及静态分配的对象、结构或数组所占的空间,返回值跟对象、结构、数组所存储的内容没有关系;
当sizeof适用于一个结构类型或变量时,sizeof 返回实际的大小;
当sizeof适用于一个静态的空间数组, sizeof 返回全部数组的尺寸;
sizeof 操作符不能返回动态地被分派了的数组或外部的数组的尺寸;
#转载内容:
1.sizeof操作符的结果类型是size_t,它在头文件中typedef为unsigned int类型。 该类型保证能容纳实现所建立的最大对象的字节大小。 2.sizeof是算符,strlen是函数。 3.sizeof可以用类型做参数,strlen只能用char*做参数,且必须是以'\0'结尾的。 sizeof还可以用函数做参数,比如: short f(); printf("%d\n", sizeof(f())); 输出的结果是sizeof(short),即2。 4.数组做sizeof的参数不退化,传递给strlen就退化为指针了。 5.大部分编译程序 在编译的时候就把sizeof计算过了 是类型或是变量的长度这就是sizeof(x)可以用来定义数组维数的原因 char str[20]="0123456789"; //str是编译期大小已经固定的数组 int a=strlen(str); //a=10; //strlen()在运行起确定 int b=sizeof(str); //而b=20; //sizeof()在编译期确定 6.strlen的结果要在运行的时候才能计算出来,时用来计算字符串的长度,而不是类型占内存的大小。 7.sizeof后如果是类型必须加括弧,如果是变量名可以不加括弧。这是因为sizeof是个操作符不是个函数。 8.当适用了于一个结构类型时或变量, sizeof 返回实际的大小, 当适用一静态地空间数组, sizeof 归还全部数组的尺寸。 sizeof 操作符不能返回动态地被分派了的数组或外部的数组的尺寸 9.数组作为参数传给函数时传的是指针而不是数组,传递的是数组的首地址, 如: fun(char [8]) fun(char []) 都等价于 fun(char *) 在C++里参数传递数组永远都是传递指向数组首元素的指针,编译器不知道数组的大小 如果想在函数内知道数组的大小, 需要这样做: 进入函数后用memcpy拷贝出来,长度由另一个形参传进去 fun(unsiged char *p1, int len) { unsigned char* buf = new unsigned char[len+1] memcpy(buf, p1, len); } 我们能常在用到 sizeof 和 strlen 的时候,通常是计算字符串数组的长度 看了上面的详细解释,发现两者的使用还是有区别的,从这个例子可以看得很清楚: char str[20]="0123456789"; int a=strlen(str); //a=10; >>>> strlen 计算字符串的长度,以结束符 0x00 为字符串结束。 int b=sizeof(str); //而b=20; >>>> sizeof 计算的则是分配的数组 str[20] 所占的内存空间的大小,不受里面存储的内容改变。 上面是对静态数组处理的结果,如果是对指针,结果就不一样了
char* ss = "0123456789";
sizeof(ss) 结果 4 ===》ss是指向字符串常量的字符指针,sizeof 获得的是一个指针的之所占的空间,应该是 长整型的,所以是4
sizeof(*ss) 结果 1 ===》*ss是第一个字符 其实就是获得了字符串的第一位'0' 所占的内存空间,是char类 型的,占了 1 位
strlen(ss)= 10 >>>> 如果要获得这个字符串的长度,则一定要使用 strlen。
————————————————
版权声明:本文为CSDN博主「飘过的小牛」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/niushuai666/article/details/7677210
下面我们来看一看sizeof和strlen的具体使用: 首先看几个例子 : 第一个例子: char* s = "0123456789"; sizeof(s); //结果 4 ===》s是指向字符串常量的字符指针 sizeof(*s); //结果 1 ===》*s是第一个字符 strlen(s); //结果 10 ===》有10个字符,strlen是个函数内部实现是用一个循环计算到\0为止之前 strlen(*s); //结果 10 ===》错误 char s[] = "0123456789"; sizeof(s); //结果 11 ===》s是数组,计算到\0位置,因此是10+1 strlen(s); //结果 10 ===》有10个字符,strlen是个函数内部实现是用一个循环计算到\0为止之前 sizeof(*s); //结果 1 ===》*s是第一个字符 char s[100] = "0123456789"; sizeof(s); //结果是100 ===》s表示在内存中的大小 100×1 strlen(s); //结果是10 ===》strlen是个函数内部实现是用一个循环计算到\0为止之前 int s[100] = "0123456789"; sizeof(s); //结果 400 ===》s表示再内存中的大小 100×4 strlen(s); //错误 ===》strlen的参数只能是char* 且必须是以‘\0‘结尾的 char q[]="abc"; char p[]="a\n"; sizeof(q),sizeof(p),strlen(q),strlen(p);\\结果是 4 3 3 2 char p[] = {'a','b','c','d','e','f','g','h'}; char q[] = {'a','b','c','d,'\0','e','f','g'}; sizeof(p); //结果是8 ===》p表示在内存中的大小 8×1 strlen(p); //为一个随机值,结果与编译器有关,不同编译器结果一般不同 sizeof(q); //结果是8 ===》p表示在内存中的大小 8×1 strlen(q); //结果为4 ===》存在'\0',遇到'\0'计算停止。 第二个例子 struct Stu { int i; int j; char k; }; Stu stu; printf("%d\n",sizeof(Stu)); //结果 12 ===》内存补齐 printf("%d\n",sizeof(stu));; //结果 12 ===》内存补齐 这个例子是结构体的内存对齐所导致的,计算结构变量的大小就必须讨论数据对齐问题。为了CPU存取的速度最快(这同CPU取数操作有关,详细的介绍可以参考一些计算机原理方面的书),C语言在处理数据时经常把结构变量中的成员的大小按照4或8的倍数计算,这就叫数据对齐(data alignment)。这样做可能会浪费一些内存,但理论上速度快了。当然这样的设置会在读写一些别的应用程序生成的数据文件或交换数据时带来不便,如有不理解的可以看看另外关于一篇内存对齐的博客。 ———————————————— 版权声明:本文为CSDN博主「Oragen」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。 原文链接:https://blog.csdn.net/magic_world_wow/article/details/80500473
char * str = “12345”; strlen(str) = 5, 字符串实际长度为5(不包括”/0”) sizeof(str) = 4, str是指向字符串首地址的指针 sizeof(*str) = 1, *str是字符串的第一个字符 char arr[] = “12345”; strlen(arr) = 5, 字符串实际长度为5(不包括”/0”) sizeof(arr) = 6, arr是数组,计算到默认的”/0”的位置 sizeof(*arr) = 1, *arr是字符串数组的第一个字符 char arr1[100] = “12345” sizeof(arr1) = 100, arr1表示在内存中分配的大小,100x1 = 100 strlen(arr1) = 5, 字符串实际长度为5(不包括”/0”) ———————————————— 版权声明:本文为CSDN博主「小虎Sam很忙」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。 原文链接:https://blog.csdn.net/lazy_tiger/article/details/2150371
/*判断一*/ if(strlen(x)>= strlen(y)) { } /*判断二*/ if(strlen(x)- strlen(y)>= 0) { } 从表面上看,上面的两个判断表达式完全相等,但实际情况并非如此。其中,判断表达式一没什么问题,程序也能够完全按照预想的那样工作;但判断表达式二的结果就不一样了,它将永远是真,这是为什么呢? 原因很简单,因为函数 strlen 的返回结果是 size_t 类型(即无符号整型),而 size_t 类型绝不可能是负的。因此,语句“if(strlen(x)-strlen(y)>=0)”将永远为真。 同样,就算表达式中同时包含了有符号整数和无符号整数,还是有可能产生意想不到的结果,如下面的代码所示: /*判断一*/ if(strlen(x)>= 5) { } /*判断二*/ if(strlen(x)- 5>=0) { } 很显然,判断表达式二的结果还是永远是真,其原因与上面相同。
参考:
http://c.biancheng.net/view/342.html
https://blog.csdn.net/niushuai666/article/details/7677210
https://blog.csdn.net/magic_world_wow/article/details/80500473
https://blog.csdn.net/lazy_tiger/article/details/2150371
https://blog.csdn.net/leho666/article/details/89207865