字符串在内存中的存储——C语言进阶

    字符串是以ASCII字符NUL结尾的字符序列。

ASCII字符NUL表示为.字符串通常存储在数组或者从堆上分配的内存中。只是,并不是全部的字符数组都是字符串,字符数组可能没有NUL字符。

字符数组也用来表示布尔值等小的整数单元,以节省内存空间。

    C中有两种类型的字符串:

     单字节字符串

     由char数据类型组成的序列

     宽字符串

     由wchar_t数据类型组成的序列

     wchar_t数据类型用来表示宽字符,要么是16位宽。要么是32位宽。这两种字符串都以NUL结尾。能够在string.h中找到单字节字符串函数。而在wchar.h中找到宽字符串函数。宽字符主要用于非拉丁字符集,对于支持外语的应用程序非常实用,

     字符串的长度是字符串中除了NUL字符外的字符数。为字符串分配内存的时候,要记住为全部的字符加上NUL字符分配足够的空间。

     NULL和NUL不一样。NULL用来表示特殊的指针,通常定义为((void*)0)。而NUL是一个char,定义为,两者不能混用!

    字符常量是单引號引起来的字符序列。

字符常量通常由一个字符组成。也能够包括多个字符,比方转义字符。

在C中,它们的类型是int,例如以下所看到的:

printf("%d
",sizeof(char));
printf("%d
",sizeof('A'));

//output
//1
//4


字符串声明

    声明字符串的方法有三种:字面量,字符数组。和字符指针。

   

字符串字面量是用双引號引起来的字符序列,经常使用来进行初始化,他们位于字符串字面量池中。<span style="color:#ff0000;">这和单引號引起来的字符不一样!</span>

   以下是一个字符数组的样例:

char header[32];


    以下是字符指针:

char *header;


字符串字面量池

    定义字符量一般会将其分配到字面量池中。这个内存区域保存了组成字符串的字符序列。

多次会用到同一个字面量时,字面量池一般会仅仅有一个副本。这样能够降低应用程序占用的内存。

通常觉得字面量是不可变的,因此仅仅有一份副本不会有什么问题。

   字符串字面量一般分配在仅仅读区域中,所以是不可变的。字符串字面量在哪里使用。或者他是全局,静态或者局部都无所谓,从这个角度讲。字符串字面量不存在作用域的概念。

   在大部分编译器中。我们将字符串字面量看做常量。无法改动字符串。

可是GCC编译器容许字符串字面量能够改动。

char *header = "Sound";
*header = 'L';
printf("%s
",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操作符会返回数组和指针的长度,而不是字符串的长度。

 

  

原文地址:https://www.cnblogs.com/brucemengbm/p/6739855.html