字符串在内存中的存储——C语⾔进阶
字符串是以ASCII字符NUL结尾的字符序列。
ASCII字符NUL表⽰为\0.字符串通常存储在数组或者从堆上分配的内存中。只是,并不是全部的字符数组都是字符串,字符数组可能没有NUL字符。
字符数组也⽤来表⽰布尔值等⼩的整数单元,以节省内存空间。
C中有两种类型的字符串:
单字节字符串
由char数据类型组成的序列
宽字符串
由wchar_t数据类型组成的序列
wchar_t数据类型⽤来表⽰宽字符,要么是16位宽。要么是32位宽。这两种字符串都以NUL结尾。能够在string.h中到单字节字符串函数。⽽在wchar.h中到宽字符串函数。宽字符主要⽤于⾮拉丁字符集,对
于⽀持外语的应⽤程序⾮常实⽤,
字符串的长度是字符串中除了NUL字符外的字符数。为字符串分配内存的时候,要记住为全部的字符加上NUL字符分配⾜够的空间。
NULL和NUL不⼀样。NULL⽤来表⽰特殊的指针,通常定义为((void*)0)。⽽NUL是⼀个char,定义为\0,两者不能混⽤!
字符常量是单引號引起来的字符序列。
字符常量通常由⼀个字符组成。也能够包括多个字符,⽐⽅转义字符。
在C中,它们的类型是int,例如以下所看到的:
printf("%d\n",sizeof(char));
printf("%d\n",sizeof('A'));
//output
//1
//4
字符串声明
声明字符串的⽅法有三种:字⾯量,字符数组。和字符指针。
字符串字⾯量是⽤双引號引起来的字符序列,经常使⽤来进⾏初始化,他们位于字符串字⾯量池中。<span >这和单引號引起来的字符不⼀样!</span>以下是⼀个字符数组的样例:
char header[32];
以下是字符指针:
char *header;
字符串字⾯量池
定义字符量⼀般会将其分配到字⾯量池中。这个内存区域保存了组成字符串的字符序列。
多次会⽤到同⼀个字⾯量时,字⾯量池⼀般会仅仅有⼀个副本。这样能够降低应⽤程序占⽤的内存。
通常觉得字⾯量是不可变的,因此仅仅有⼀份副本不会有什么问题。
字符串字⾯量⼀般分配在仅仅读区域中,所以是不可变的。字符串字⾯量在哪⾥使⽤。或者他是全局,静态或者局部都⽆所谓,从这个⾓度讲。字符串字⾯量不存在作⽤域的概念。
在⼤部分编译器中。我们将字符串字⾯量看做常量。⽆法改动字符串。
可是GCC编译器容许字符串字⾯量能够改动。
char *header = "Sound";
*header = 'L';
printf("%s\n",header);
//output
//Lound
这样就会改变字符串,不是我们预期的结果。因此应该避免这样做。像以下这样把变量声明为常量能够解决⼀部分问题。不论什么改动都会造成编译时错误:
const char *header = "Sound";
字符串初始化
初始化字符串採⽤的⽅法取决于变量是被声明为字符数组还是字符指针,字符串所⽤的内存要么是指针指向的⼀块内存。我们都能够⽤字符串字⾯量或者⼀些列字符初始化字符串,或者从别的地⽅(标准输⼊)得到字符。
初始化char数组
字符串长度和占用内存字节我们能够⽤初始化操作符初始化char数组。在下例中。header数组被初始化为字符串字⾯量中所包括的字符:
char header[] = "Media Player";
字符量"Media Player"的长度为12,表⽰这个字⾯量须要13个字节,我们就要为数组分配13个字节来持有字符串。初始化操作会把这些字符拷贝到数组中,以NUL结尾。
我们也能够⽤strcpy函数来初始化数组。
初始化char指针
⽤动态内存分配来初始化char指针。
char *header;
char *header = (char*)malloc(strlen("Media Player")+1);
注意不要⽤sizeof操作符,⽽要⽤strlen函数来确定已有字符串的长度,sizeo操作符会返回数组和指针的长度,⽽不是字符串的长度。
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论