字符串是以空字符(\0)结尾的char数组
在程序中定义字符串
1)字符串常量
字符串常量(字符串文字):位于一对双引号中的任何字符
双引号里的字符加上编译器自动提供的结束标志\0字符,作为一个字符串被存储在内存里
还可以用#define定义字符串常量
如果字符串文字之间没有间隔或者间隔的是空格符,ANSI C会自动将其串联起来
// 两种写法等效
char str1[80] = "hello, what" "is your" "name?";
char str2[80] = "hello, what is your name?"
如果需要在字符串中使用双引号,需在双引号之前加一个反斜线符号
printf("\"this is a quote.\"\n");
字符串常量数据静态存储(static storage)类,如果在一个函数中使用字符串常量,即使是多次调用该函数,该字符串在程序的整个运行过程中只存储一份
整个引号中的内容作为指向该字符串存储位置的指针,与把数组名作为指向数组存储位置的指针类似
示例代码:
#include <stdio.h>
int main(void)
{
printf("%s, %p, %c\n", "Welcome", "to", * "China!");
return 0;
}
运行结果:
2)字符串数组
定义一个字符串数组时,必须让编译器知道其需要占用多大空间
方法一:指定一个足够大的数组以容纳字符串
char str1[80] = "an array to store a string";
指定数组大小时,一定要确保数组元素比字符串长度至少多1(用于容纳空字符),未被使用的元素均被自动初始化为0(这里的0是char形式的空字符\0,不是数字字符0)
方法二:初始化时省略数组大小,由编译器自动决定
char str1[] = "an array to store a string";
字符串处理函数一般能够简单地通过查找空字符来确定字符串结束,所以不需要知道字符串大小,因此由编译器决定字符数组大小具有优势
可以使用指针符号建立字符串,与使用字符串数组声明的作用几乎相同
char * str1 = "hello world";
char str1[] = "hello world";
3)数组与指针在声明字符串数组时的不同
数组形式(str1[]):
在计算机中分配一个有12个元素的数组(每个元素对应一个字符,还有一个附加的元素对应空字符\0)
每个元素都被初始化为相应的字符
通常被引用的字符串存储在可执行文件的数据段部分,当程序被加载到内存中时,字符串也被同时加载,被引用的字符串位于静态存储区
在程序开始运行后才为数组分配存储空间,此时把被引用的字符串复制到数组中,此后编译器会把数组名str1看作是数组首元素的地址&str1[0]的同义词
重点是,在数组形式中str1是一个地址常量,不能更改,因为这意味着更改数组存储的位置(地址);可使用str1+1来标识数组里的下一个元素,但是不允许使用++str1,增量运算符只能用于变量,不能用于常量
指针形式(*str1):
也在静态存储区为字符串预留12个元素的空间
一旦程序开始执行,还要为指针变量str1另外预留一个存储位置,以在该指针变量中存储字符串的地址,该变量初始时指向字符串的第一个字符,但是它的值是可以改变的,因此可以对其使用增量运算符
结论:数组初始化是从静态存储区把一个字符串复制给数组;而指针初始化只是复制字符串的地址