之前有一篇文章是学习了字符和字符串的,可以与之结合学习:【C语言进阶深度学习记录】十二 C语言中的:字符和字符串
1 字符串的概念
字符串与字符数组很像,但是有差别,注意留意它们的差别。
- 字符串是有序字符的集合
- C语言中,没有字符串的概念(没有string这个关键字,C++中才有)
- 但是C语言中,必须使用字符串
- 所以C语言通常都是使用特殊的字符数组来模拟字符串
- C语言中的字符串,是以’\0’ 结尾的字符数组。也就是说只有字符数组结尾是 ‘\0’ 该字符数组才是字符串,否则该字符数组就是普通的字符数组。这一点很重要!!!
1.1 字符串与字符数组
在C语言中,双引号引用的单个或多个字符是一种特殊的字面量
- 字面量存储于程序的全局只读存储区
- 它的本质是字符数组,编译器自动在结尾加上 ‘\0’ 字符。注意,只有双引号下的字面量,编译器才会自动在后面加上’\0’字符。如果是一个普通的字符数组,是要自己在最后加的,否则无法成为字符串。
比如下面哪些是字符串的定义?
- 第一个ca不是字符串,它是普通的字符数组。
- sa 也是字符数组,但是由于它末尾加了’\0’,所以它也是一个字符串
- ss是用双引号初始化的,编译器会默认在最后加上’\0’,所以ss也是字符串
- 同理str也是字符串
1.2 字符数组与字符串代码分析
- 代码: 30-1.c
#include <stdio.h>
int main(){
char ca[] = {'H', 'e', 'l', 'l', 'o'};
char sa[] = {'H', 'e', 'l', 'l', 'o', '\0'};
char ss[] = "Hello,World";
char* str = "Hello,World";
printf("%s\n", ca);
printf("%s\n", sa);
printf("%s\n", ss);
printf("%s\n", str);
return 0;
}
- 编译运行结果如下:
- 可以看出,只有第一个ca打印出来是乱码,后面三个都是正常的。因为ca并不是字符串,我们以 ‘%s’ 打印的话,是类型不对应的,导致打印不对。(深层次原因的话是因为打印字符串都是遇到字符串的结尾’\0’就算打印一个字符串,但是ca中没有’\0’ 字符)
2 字符串字面量
对于字符串的字面量,需要掌握几点:
- 字符串字面量的本质是一个数组
- 字符串字面量可以看做常量指针,代表存储该字符串的地址
- 字符串字面量中的字符不可改变(位于全局只读存储区)
- 字符串字面量至少包含一个字符(至少有一个’\0’)
类似于这种 “Hello,world” 是一种无名的字符数组
看一下下面三个表达式是正确的么?如果正确,值是多少?
我们以代码来验证即可:
2.1 字符串字面量的本质的代码分析
- 代码:30-2.c
#include <stdio.h>
int main(){
char a = "abc"[0]; //==>a='a'
char b = *("123"+1); //==>b='2'
char c = *""; //==>c='\0' 它的ASCII码是 0
printf("%c\n", a);
printf("%c\n", b);
printf("%d\n", c);
printf("%s\n", "Hello");
printf("%p\n", "Hello");
char* p = "def";
p+=1;
// *p = 'g'; //error 字符串字面量不能更改
return 0;
}
- 编译运行上述代码结果如下:
可以看出:
- 字符串字面量,的确是一个无名数组
- 字符串字面量,可以代表它自身的内存地址
- 字符串至少包含一个字符’\0’
- 字符串字面量存储于全局的只读存储区,不可修改
3 字符串的长度
这是一个比较重要的知识点:
- 字符串的长度,是指第一个’\0’ 出现之前的所有字符的个数
- 函数strlen用于返回字符串的长度
如:
3.1 strlen 的使用代码分析
- 代码30-3.c
#include <stdio.h>
#include <string.h>
int main(){
char s[] = "Hello\0World";
int i = 0;
for(i=0; i<sizeof(s)/sizeof(char); i++){
printf("%c\n",s[i]);
}
printf("sizeof(s) = %d\n", sizeof(s));
printf("%s\n", s);
printf("%d\n", strlen(s));
printf("%d\n", strlen("123"));
return 0;
}
- 编译运行结果为:
可以看到:
- sizeof求解字符串的大小时,会将最后的隐藏字符’\0’ 也算进去
- strlen求解字符长度时,是求解的字符串中第一个’\0’ 之前的所有字符的个数
4 总结
- C语言中可以通过字符数组模拟字符串
- C语言中的字符串是以 ‘\0’ 作为结尾字符
- 字符串字面量的本质是一个无名的字符数组
- 字符串的相关函数都依赖于最后的结束符 ‘\0’