内存条被程序员人为的分为五大区进行管辖,五大区分别是:1.栈 2.堆 3.文字常量区 4.全局变量区 5. 代码区
本文章仅涉及文字常量区以及栈区
- 文字常量区是存储字符串的区域,只能写入一次,从写入开始直到程序运行结束不能进行修改。将该字符串作为常量使用
- 栈区是执行函数时,将函数写入栈区进行运算的区域,可较自由进行读,写操作。
直接进入主题:
字符串的定义
- C语言中通过
""
符号标识,将其中字符串写入文字常量区,并在字符串的结尾自动添加一个字符'\0'
,并且返回一个指向该字符串首地址的指针。
eg:
"asd"[0]; //值为'a';
"asd"[1]; //值为's';
//因此可以定义一个字符型指针接收返回的指针
char * p = "asd";
PS:
1. 由于存储在文字常量区的字符串是只读的
2. 由于文字常量区的字符串作为常量, 故相同的字符串指针引用相同的常量区的内容
因此
p[0] = 'f'; //因为此时指针 p 指向文字常量区,不能进行赋值修改,故会报错
"asd" == "asd" //两边的"asd"返回的指针指向相同的文字常量区的字符串,故返回true
- 而如果定义字符型数组
char str[] = ""
,则会在栈区开辟一个连续的空间存储""
中的字符串,并且在末尾自动添加字符'\0'
。
PS:
- 应当注意
char str[] = {'a', 's', 'd'}
, 不会自动在末尾处自动添加字符'\0'
。 - 数组成功定义之后,数组名是一个指针常量,即一经定义,不再更改其指向的地址。
- 由于数组定义在栈区,故仍可对其元素进行修改。
因此:
//1.
char str[];
str = "asd"; /*1. "asd" 返回一个指向首地址的指针,
2.由于 str 已经定义,故不能更改 指针常量str的指向,
所以会报错*/
//正确代码如下
char str[] = "asd";
//2.
char * p = "asd";
char str[] = p; //报错,因为str是一个指向栈区的指针常量,不能修改其指向
//正确代码如下
char str[] = *p;
//3.
char str[] = "asd";
str[0] = 'f';
//由以上可以得到一个结论:字符数组只能在其定义时整体赋值,再赋值时只能逐个元素进行赋值。
字符串的输出
- 当输出和使用字符串时,事实上是从传入的字符的地址开始逐个读取,直至读到
\0
为止。
eg:
printf("%s", "asd"); //输出 asd, "asd"传入的是a的地址
printf("%s", &"asd"[1]); //输出 sd , &“asd”[1] 传入的是 s 的地址
//同样的
puts("asd"); //输出asd
puts("asd" + 1); //输出 sd
strlen("asd"); //值为 3 ,从 a 开始直到 \0 不计 \0
strlen("asd" + 1); //值为 2, 从 s 开始直到 \0 不计\0
小结:
“” | char str[] = “” |
---|---|
字符串写入文字常量区 | 字符串写入栈区 |
返回一个指向该字符串的首地址的指针 | 将字符串的首地址存入 str |
不能再赋值 | 可再赋值 |
以上是我的一些拙见, 若有谬误,望读者斧正。