C语言中字符串与字符数组分析
字符串与字符数组的区别在过去我一直是处于一知半解的状态,字符串是通常被认为是常量,是保存在一段固定的内存中的,这段内存是以为结束符,这段内存通常只能通过一个指针来找到。字符数组其实和其他数组没什么区别,只是保存的数据类型是字符类型(char),它没有强制要求最后的元素是否是。字符数组的数组名是指向第0个字符的指针,而不是指向这个字符串的。这与我前期博客中对数组的分析结论是相同的,数组名并不像指针存在一个地址来保存指针名,数组名可以看做是汇编程序中的一个标号,并没有专门的地址来保存数组名。
但是字符串和字符数组又有很多相似的地方,特别是当我们结合指针操作字符数组时候,就会导致错误的产生,我觉得只有搞清楚一些概念就能较好的避免这种错误的产生。这个概念就是指针就是指针,数组就是数组,两个搞混只是因为某些巧合使我们误以为指针和数组是等值的。两者实质上是不相同的。
字符数组和字符串的定义如下:
1. //字符串
2. char *str = "string is a constant";
3. //字符数组
4. char strarray[] = {s,t,r,i,n,g, ,i,s, ,a, ,c,o,n,s,t,a,n,t,};
5. //或者
6. char strarray[] = "string is a constant";
7. char strarray[] = {"string is a constant"};
其中从上面的定义可以知道字符串实质上一块内存,其中保存的值是常量,常量其实就是不能采用程序对内存中的值进行修改,当然只是程序不能,我认为就像嵌入式C语言中的const类型一样,虽然我们通常认为这个变量是常量,但实质上是只读性变量,只是不能通过程序修改,还可以通过其他的方式修改。这时候str指向的内存空间中保存的数据是不能被程序修改的,也只能通过str指针对这段内存进行访问。
如果字符数组定义成单个的字符,我们也许还能较好的分别,但如果是如第二种定义、第三种形式定义,我们可能就会产生很大的不理解,这与字符串的类型基本上没有什么差别,只是多了一个数组符号[ ],但是这个数组符号就意味着数据类型的改变,我们可以知道数组中的值是可以改变的,不是常量,说明strarray是一个数组变量,而str却是一个字符串常量指针。Strarray是一个标号,存储器中并没有专门分配内存空间存储strarray的值。但是指针和数组名很多时候的一些相似性使得我们在处理的时候很难去判断,比如下面这段代码:
char * str = "Constant String";
char strarray[] = "Constant String";
int str_len,size_str,array_len,size_array;
str_len = strlen(str);
array_len = strlen(strarray);
size_str = sizeof(str);
size_array = sizeof(strarray);
size_str = sizeof(*str);
如果知道其中的一些数组与指针的一些区别可以较好的得到这些值,首先strlen(str)是指求解字符串的长度,但是不包含,因此str_len就是字符串的长度,也就是str_len = 15,array_len也是求解字符串长度的值,我们前面已经指出数组和字符串存在差别,但为什么还可以这样做呢。我们暂且认为包含的字符数组可以看做是字符串或者伪字符串,两者非常的相似,都是存在一段内存,保存一段数据,格式也非常的相似,所以strlen认为两者是相同的,但实质上还是存在差别的,但是采用strlen求解字符串长度时,array_len和str_len 是相同的。
size_str 和size_array这两个变量的值是我写这篇文章的初衷,因为我之前根本没有起分析其中的一些差别,理所当然的认为两者是相同的,但细细比较发现两者确实存在问题。size_str = sizeof(str)的值是多少?sizeof是指对变量或者类型求解存储空间,是C语言中不被重视的关键字,被大多数人认为是一个函数,实质上是一个关键字。这样我们就能比较快速的确定后面三个变量的值啦,size_str = sizeof(str)是指对str的存储器长度进行计算,str是一个字符型指针,我们知道,指针类型的变量实质上就是一个地址,在32机中,地址通常需要4个字节的内存空间来存储,因此,size_str = 4;知道了sizeof的意义,size_array就比较简单了,strarray是一个数组变量,是一段内存空间的标示,sizeof(strarray)是指上就是求解数组的内存大小,这时候的内存大小包含,因此size_array的值应该是15+1=16。而接下来的size_str = sizeof(*str)就更加简单了,因为我们知道对于字符串指针而言,指向的只是字符串的第0个元素,而不是整个字符串,这时候又会和数组的数组名有一定的交叉,数组的数组名我们通常被认为是一个常量指针(左值右值的差别),也就是指向的起始地址是不变的,但是通常被认为是指向数组首个元素的常指针,不能进行++,--操作。接着说明sizeof(*str),*str是指指向字符串的第0个元素的指针的值,也就是说*str是指上就是字符串的第0个元素,也就是一个字符类型,字符类型的大小也就是1字节了,因此这时候的size_str = 1。
上面的分析说明了在字符串和数组的相关操作中使用strlen的安全性总是比sizeof好,特别是不清楚sizeof的一些意义的情况下。
C语言字符串字符数 相关文章:
- Windows CE 进程、线程和内存管理(11-09)
- RedHatLinux新手入门教程(5)(11-12)
- uClinux介绍(11-09)
- openwebmailV1.60安装教学(11-12)
- Linux嵌入式系统开发平台选型探讨(11-09)
- Windows CE 进程、线程和内存管理(二)(11-09)