字符串长度 数组长度具体区分

char a[]={‘a’,’b’,’c’}; 数组长度为3,字符串长度不定。sizeof(a)为3。

char a[5]={ ‘a’,’b’,’c’} 数组长度为5,字符串长度3。sizeof(a)为5。

能不能结合这个例子具体讲讲啊……

你好!!!
我们还是先来看看一个例子:
代码:
#include <iostream.h>
#include<string.h>
int main()
{
char a[]={'a','b','c'};
cout<<"字符串a:"<<a<<endl;
cout<<"数组的大小:"<<sizeof(a)<<endl;
cout<<"数组的大小:"<<strlen(a)<<endl;
cout<<endl;

char b[5]={ 'a','b','c'};
cout<<"字符串b:"<<b<<endl;
cout<<"数组的大小:"<<sizeof(b)<<endl;
cout<<"数组的大小:"<<strlen(b)<<endl;
return 0;

}
结果:
字符串a:abc汤�
数组的大小:3
数组的大小:7

字符串b:abc
数组的大小:5
数组的大小:3
Press any key to continue

首先要知道:sizeof()求的是在内存中的分配的长度(暂且这样讲)
strlen()是求内存中实际已经使用的空间,也就是说虽然分配了很多空间,但是好多空间都没有用到,都是空的。
还要知道字符串的结束标志是‘\0’即空字符!!!

char a[]={ ‘a’,’b’,’c’};表示给数组的第一,第二,第三个字节的元素是a,b,c,而此时的数组的大小不是知道的,也就是系统已经在栈里至少分配了3个字节大的内存,要是数组在栈里是连续存放的,因此数组的后面还有多少个字节谁也不知道,要是此时输出字符串,输出a,b,c后由于赋值的后没有赋结束标志(一个字符一个字符的赋值系统不会自动的在最后添加结束标志),所以数组会一直向后面移动,知道遇见结束标志,此题可以看出字符串a:abc汤�
a,b,c,空格 中5个字节,还有一个汉字是2个字节所以数组的大小是7个字节,但是实际赋值的字符只有3个字节!!

而数组b:char b[5]={ 'a','b','c'};数组的大小是5个字节,实际只用到了3个字节,至于后面的字节则是‘\0’输入输出都是正确的。
不理解我们再联系!!!
温馨提示:内容为网友见解,仅供参考
第1个回答  2010-09-01
由于C语言中字符串是连续的字符以NUL(注意不是NULL,也没在标准C/C++库中有定义;对于char字符串是'\0',对于wchar_t字符串是L'\0',两者在数值上都是零,可以和int类型的字面量0互相隐式转换)结尾,字符串长度就是连续的非NUL字符的个数。在运行期可以用库函数strlen取char字符串的长度,wcslen取wchar_t字符串的长度。这两个库函数的工作原理(可以说是所有实现)是根据给定的指针参数顺序地查找NUL,如果找到了NUL的话计算和给定参数之间距离的元素数。由于数组等对象类型信息仅在编译期保存,运行期无效,所以数组怎么定义本身是和字符串长度无关的。但是可能有因为出现越界而意外查找到NUL的情况。如LS所说,
char a0 = 0;
char a[] = {'a', 'b', 'c'};
char b0 = 0;
这样在运行期执行函数表达式strlen(a)时,内部的查找指针指向的对象会超出数组a的边界(这里a的长度等于3,关于数组长度以下另外讨论),直到遇到数组外部的NUL。如果是函数内的非静态局部变量,由于对于一般实现,栈的地址生长方向是向下的,因此找到的值等于NUL的char对象就是a0。对于静态存储类(全局或静态变量),一般是顺序地遇到值等于NUL的b0。如果没有这种特殊的保护,strlen有可能一直不能找到NUL直到越界到非法访问内存导致程序崩溃之类的问题为止。
数组长度就是数组定义时元素的个数。注意定义和声明的区别。在没有extern时声明的同时数组被初始化,那么数组声明就同时是定义。数组的初始化有两种形式,一种是隐式初始化,仅适用于全局或静态数组,即没有初始化列表,所有元素被value-initialized(C++的说法),对于整型元素(注意这里包括了char),就是数组的每个元素被zero-initialized(初始化为0)(对于局部非静态数组,这样的语法形式并不初始化数组,元素的值为随机值;如果后面使用了未初始化的数组元素,可能会出现莫名其妙的错误;编译程序可能会填充未初始化的元素,例如Microsoft C&C++ Debugger填充每个未被初始化的栈字节为0xCC,所以用VC++调试可能会发现“烫烫烫烫……”的情况,0xCCCC是“烫”的GBK编码)。另一种是显式初始化,也就是后面跟随={...}这样的列表,其中...表示多个初始化的元素。如果数组定义时不指定长度,那么长度等于初始化列表中元素的个数。如果数组定义时指明了长度,就以[]中的为准。这里要避免初始化列表元素个数不大于[]里的长度,否则C出现未定义行为,C++中是非法的。如果元素个数小于长度,剩余元素被隐式地value-initialized。
(另外,类似char a[];这样声明了一个数组,它的长度是未知的,类型是不完整类型,只能出现在结构体末尾等特殊上下文中(C99支持),可以不讨论。)
char a[]={'a','b','c'};由于后面有初始化列表进行了显式初始化,那么a的长度就由初始化列表中的元素个数给出,等于3。
char a[5]={'a','b','c'};的长度是[]之间的5。由于初始化列表元素数只有3,剩余两个元素被初始化为0。因此实际上等价于char a[5]={'a','b','c',0,0};。而0可以隐式转化为'\0',因此a作为字符串的长度就是'a'到'c'之间的字符数,也就是3.
sizeof在编译期计算一个表达式表示的对象或者一个类型占用存储期空间(以字节计量)。对于数组,sizeof给出整个数组占用的字节数,除以元素字节数就是数组长度了。这里由于sizeof(char)等于1,数组的长度就等于sizeof的结果。
====
[原创回答团]

参考资料:原创 + 引用

第2个回答  2010-09-03
首先你要明确一个字符串的结束符 是‘\0’
在没有指定数组长度的情况下,数组长度以其存储数据的个数为定,
所以char a[]={‘a’,’b’,’c’};数组长度为3,但是数组中并没有空间再存储'\0',所以字符串长度不定。
而char a[5]={ ‘a’,’b’,’c’};你已经指定数组长度为5,所以数组长度为5,而数组中只存了3个字符,后面两个字符默认为‘\0’,则字符串长度为3。
字符串长度是用strlen()计算的,它不包含‘\0’。
第3个回答  2010-09-01
这个就是数组初始化的问题。
char a[]={‘a’,’b’,’c’}; 定义时没有说明数组长度,按照初始化列表的长度定;
char a[5]={ ‘a’,’b’,’c’} 定义时明确了数组长度,前3个按照给定的值初始化,后两个元素初始化为零。
第4个回答  2010-09-01
字符串长度不定是因为字符串长度的判断和你的内存分配没有关系
它只是从你的首字节开始一直判断到'\0'结束

也就是说,如果你用数组保存字符串,而没有用'\0'做字符串的结束标志
那么当你调用strlen时,判断函数会越过数组,可能把数组外的字节也计算到
字符串长度中

你在程序里这样做

char a0 = 0;
char a[] = {'a', 'b', 'c'};
char b0 = 0;

你再判断一下a的字符串长度

再来

char aa[] = {'a', 'b', 0};
char a[] = {'a', 'b', 'c'};
char bb[] = {'a', 'b', 0};

你再判断一下a的字符串长度
相似回答