例.
#include <stdio.h>
#include <string.h>
int main()
{
char a[1000];
int i;
for(i=0;i<1000;i++)
{
a[i]=-1-i;
}
printf("%d\n",strlen(a));
return 0;
}
输出结果是:255
分析:
char的取值范围是-128~127,在这之间循环往复,即-128再减一就变成127,127再加一就变成-128:
i | -1-i | a[i] |
0 | -1 | -1 |
1 | -2 | -2 |
2 | -3 | -3 |
3 | -4 | -4 |
... | ... | ... |
126 | -127 | -127 |
127 | -128 | -128 |
128 | -129 | 127 |
129 | -130 | 126 |
... | ... | ... |
254 | -255 | 1 |
255 | -256 | 0 |
256 | -257 | -1 |
... | ... | ... |
strlen()是函数,当它读到‘\0’,即数值0时就结束。即就算其中有多个\0,读到第一个\0就结束。如果一个char数组中放的是0123,它读到0是就结束,也就是对它调用strlen()得到的结果是0。换种意思是,这道题中的strlen()就是看a这个数组第一次出现0时,到第几位,根据列出的表可知,i为255。
网上找到的一些解释:
strlen的结果要在运行的时候才能计算出来,是用来计算字符串的长度,不是类型占内存的大小。
它的功能是:返回字符串的长度。该函数实际完成的功能是从代表该字符串的第一个地址开始遍历,直到遇到结束符NULL(标准点应该是'\0'或0,‘\0'的ASCII码就是0)。返回的长度大小不包括NULL。 --------> 这也可以解释为什么i是从0到255共256个,但输出是255因为没有把0计算在里面?
strlen() | sizeof() |
需插入头文件string.h | 不需要包含头文件,是基本运算符 |
是函数 | 是运算符 |
要在运行时才能计算 | 其值在编译时即计算好 |
功能是:从该字符串的第一个地址开始遍历,直到遇到结束符NULL。返回的长度大小不包括NULL。 | 功能是:获得保证能容纳实现所建立的最大对象的字节大小 |
只能用字符型指针char*做参数,且必须是以''\0''结尾的。当数组名作为参数传入时,实际上数组就退化成指针了。 | 参数可以是数组、指针、类型、对象、函数等。数组做sizeof的参数不退化。sizeof后如果是类型必须加括弧,如果是变量名可以不加括弧。这是因为sizeof是个运算符不是个函数。 |
计算字符串的长度,以结束符 0x00 为字符串结束。 | 数组——编译时分配的数组空间大小; 对象——对象的实际占用空间大小; |
参考:https://www.cnblogs.com/carekee/articles/1630789.html
整理的很全面!一定要看例题!!!
例1. char arr[10] = "What?";
int len_one = strlen(arr);
int len_two = sizeof(arr);
cout << len_one << " and " << len_two << endl;
输出结果为:5 and 10
点评:sizeof返回定义arr数组时,编译器为其分配的数组空间大小,不关心里面存了多少数据。strlen只关心存储的数据内容,不关心空间的大小和类型。
例2. char * parr = new char[10];
int len_one = strlen(parr);
int len_two = sizeof(parr);
int len_three = sizeof(*parr);
cout << len_one << " and " << len_two << " and " << len_three << endl;
输出结果:23 and 4 and 1
点评:第一个输出结果23实际上每次运行可能不一样,这取决于parr里面存了什么(从parr[0]开始知道遇到第一个NULL结束);第二个结果实际上本意是想计算parr所指向的动态内存空间的大小,但是事与愿违,sizeof认为parr是个字符指针,因此返回的是该指针所占的空间(指针的存储用的是长整型,所以为4);第三个结果,由于*parr所代表的是parr所指的地址空间存放的字符,所以长度为1。
例3. 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
例4. int A[10];
int* B=new int[10];
cout<<"数组名"<<sizeof(A)<<endl;
cout<<"指针"<<sizeof(B)<<endl;
结果输出:数组名40,指针4
数组名并不是完全等同于指针。虽然它们都可以通过指针方式访问数组。在这个博客看到他们的区别: http://blog.csdn.net/ljob2006/article/details/4872167
但是数组在作为函数参数传递过程中,会退化成指针。这也是为什么指针作为参数传递时,经常要一个长度。