直接先来一组代码辨析:
//字符数组:char 的数组,例如char arr[10];
* 字符串:用""包括的字符序列,如果字符数组有'\0'也是字符串
* '\0':字符串的结尾标记
*/
int main()
{
char arr[5] = { 'a','b','c','d','e' };//是字符数组,不是字符串
char brr[] = { 'a','b','c','d','e' };//是字符数组,不是字符串
char crr[10] = { 'a','b','c','d','e' };//是字符数组,是字符串
char drr[] = "abcde";//是字符数组,是字符串
char err[10] = "abcde";//是字符数组,是字符串
char frr[] = {'a','b','\0','c'};//是字符数组,是字符串
printf("%s\n",frr);//%s输出字符串
return 0;
}
简单粗暴的讲解(有'\0'或者有" "就是字符串):
char arr[5] = { 'a','b','c','d','e' };//是字符数组,不是字符串
没有'\0'不是字符串
char brr[] = { 'a','b','c','d','e' };//是字符数组,不是字符串
数组长度未定义,后面有值,长度为根据后面值的数量而设定,后面值的数量为5,则长度为5,没有'\0' ,不是字符串.
char crr[10] = { 'a','b','c','d','e' };//是字符数组,是字符串
数组长度为10,后面值的数量为5,多出来的五个长度会置为0,即'\0',是字符串.
char drr[] = "abcde";//是字符数组,是字符串
有" "是字符串
char err[10] = "abcde";//是字符数组,是字符串
有" "是字符串
char frr[] = {'a','b','\0','c'};//是字符数组,是字符串
//输出ab
有'\0'就是字符串,但是'\0'出现在c前面,程序就终止不继续读下去了,输出ab
再来看一组,你能辨析吗?
int main()
{
char str1[10];//字符数组,不是字符串
char str2[10] = "abcde";//字符数组,是字符串
char str3[] = "abcde";//字符数组,是字符串 长度是6,因为是字符串,有个隐藏的\0
char str4[] = { 'a','b','c','d','e' };//字符数组,不是字符串,无"",无\0(长度为5)
char str5[10]= { 'a','b','c','d','e' };//字符数组,是字符串,有\0
const char* str6 = "abcde";//字符串常量,不是字符数组,没有中括号,是字符串,因为有""
printf("%s\n", str1);//错,str1不是字符串
return 0;
详细讲解:
char str1[10];
• 这是字符数组,但未初始化,数组中的内容是随机的垃圾值。
• 不是字符串,因为不保证有 \0 终止符。
• printf("%s", str1); 会访问到未知数据,导致运行错误或不确定的输出。
char str2[10] = "abcde";
• 这是字符数组,长度 10,字符串 "abcde" 只占 6 个字节(包括 \0)。
• 是字符串,因为 "abcde" 自动添加 \0。
• 剩下的 4 个字节未初始化,可能是随机值。
存储结构:
'a' 'b' 'c' 'd' 'e' '\0' ? ? ? ?
(3)char str3[] = "abcde";
• 这是字符数组,长度为 6(abcde + \0)。
• 是字符串,因为 \0 结尾。
• 自动计算数组长度,等价于 char str3[6] = "abcde";。
存储结构:
'a' 'b' 'c' 'd' 'e' '\0'
char str4[] = {'a','b','c','d','e'};
• 这是字符数组,长度为 5。
• 不是字符串,因为没有 \0 终止符。
• printf("%s", str4); 可能导致内存越界,读取未知数据。
存储结构:
'a' 'b' 'c' 'd' 'e' (无 `\0`)
char str5[10] = {'a','b','c','d','e'};
• 这是字符数组,长度 10,初始化了 5 个字符,剩余部分自动填充 \0。
• 是字符串,因为自动填充 \0。
存储结构:
'a' 'b' 'c' 'd' 'e' '\0' '\0' '\0' '\0' '\0'
const char* str6 = "abcde";
• str6 是指向字符串常量的指针,而不是字符数组。
• 存储在常量区,不可修改(const)。
• 访问方式:指针 str6 指向 "abcde" 的首地址。
存储结构:
字符串 "abcde" 存储在常量区:
'a' 'b' 'c' 'd' 'e' '\0'
为什么 printf("%s", str1); 会出错?
printf("%s\n", str1);
错误原因:
• str1 未初始化,内容是随机值。
• printf("%s", str1); 会一直读取内存,直到找到 \0,但 str1 可能没有 \0,导致读取非法内存或崩溃。
总结:
有'\0'的就是字符串,用" "双引号就是字符串,数组长度有多余的,其余值为0,即'\0',也是字符串.数组没有初始化,如char str1[10];其值为随机值,不保证有 \0 终止符,也不是字符串
在C语言中,字符串(String) 本质上是 以' \0 '结尾的字符数组,C语言没有专门的 string 类型,而是使用 字符数组 或 字符指针 来表示字符串。 在C语言中,字符串必须以 \0 结尾,否则程序无法正确识别字符串的结束位置。
字符数组是由一组字符组成的数组,用于存储一串字符。字符数组的每个元素都是一个字符类型(char)。
字符数组是由一组字符组成的数组,用于存储一串字符。字符数组的每个元素都是一个字符类型(char)。
定义字符数组
char arr[5] = {'H', 'e', 'l', 'l', 'o'};
上面这个字符数组存储的是单个字符,并没有字符串终止符 \0(空字符)。如果要让它作为字符串使用,必须手动添加 \0:
char arr[6] = {'H', 'e', 'l', 'l', 'o', '\0'};
字符串终止符 \0
• 在C语言中,字符串必须以 \0 结尾,否则程序无法正确识别字符串的结束位置。
• \0 不是可见字符,但它的ASCII值为0,标志着字符串结束。
字符串本质上就是以 \0 结尾的字符数组,C语言没有专门的字符串类型,而是用字符数组来表示字符串。
定义字符串
char str1[] = "Hello"; // 自动在末尾添加 '\0'
char str2[6] = "Hello"; // 需要足够的空间存放 '\0'
等价于:
char str[] = {'H', 'e', 'l', 'l', 'o', '\0'};
字符串的存储
假设我们定义:
char str[] = "Hello";
内存布局如下:
H e l l o \0
实际上,字符串在内存中就是一个字符数组,唯一的区别是字符串必须以 \0 结尾。
3. 字符数组与字符串的区别
C 语言标准库
(1)计算字符串长度:strlen()
#include
#include
int main() {
char str[] = "Hello";
printf("字符串长度: %lu\n", strlen(str)); // 5,不包括 '\0'
return 0;
}
(2)复制字符串:strcpy()
#include
#include
int main() {
char src[] = "Hello";
char dest[20];
strcpy(dest, src); // 复制字符串
printf("复制后的字符串: %s\n", dest);
return 0;
}
注意:
• strcpy() 不能检查目标数组的大小,可能会导致 缓冲区溢出(Buffer Overflow)。
• 建议使用 strncpy() 来限制复制的字符数:
strncpy(dest, src, sizeof(dest) - 1);
dest[sizeof(dest) - 1] = '\0'; // 确保字符串以 `\0` 结尾
(3)连接字符串:strcat()
#include
#include
int main() {
char str1[20] = "Hello";
char str2[] = " World";
strcat(str1, str2); // 连接字符串
printf("连接后的字符串: %s\n", str1);
return 0;
}
注意:
• strcat() 可能会导致 缓冲区溢出,建议使用 strncat() 限制拼接的字符数:
strncat(str1, str2, sizeof(str1) - strlen(str1) - 1);
(4)比较字符串:strcmp()
#include
#include
int main() {
char str1[] = "apple";
char str2[] = "banana";
if (strcmp(str1, str2) == 0) {
printf("两个字符串相等\n");
} else {
printf("两个字符串不相等\n");
}
return 0;
}
返回值说明:
• strcmp(str1, str2) == 0:字符串相等
• strcmp(str1, str2) < 0:str1 小于 str2
• strcmp(str1, str2) > 0:str1 大于 str2
如果有疑问欢迎在评论区交流!