16. C语言 字符串详解
本章目录:
- 前言
- C 字符串的基础概念
- 字符串的定义
- 字符串的内存表示
- 常见的字符串操作函数
- 示例代码
- 深入探讨字符串长度计算
- `strlen` 与 `sizeof` 的区别
- 字符串操作的注意事项
- **1. 字符数组的大小**
- 2. 字符数组和字符指针的区别
- 3. 使用安全函数
- 字符串的遍历与格式化输出
- **遍历字符串**
- 格式化输出
- 总结
前言
在 C 语言中,字符串是一种特殊的数据类型,它实际上是以空字符 \0
结尾的一维字符数组。本文将从基本概念、常见函数使用、字符数组与字符指针的区别等多个角度深入探讨 C 语言字符串操作,帮助开发者更高效地掌握这一核心内容。
C 字符串的基础概念
字符串的定义
- 字符串的本质:以空字符
\0
结束的字符数组。 - 字符串字面量:例如
"hello world"
是常量,在编译时会自动添加\0
。
###字符串初始化
C 提供了两种主要方式初始化字符串:
- 字符数组:
char site[7] = {'R', 'U', 'N', 'O', 'O', 'B', '\0'}; char site[] = "RUNOOB"; // 编译器自动添加 \0
- 字符指针:
char *greeting = "Hello";
注意:使用字符指针时,字符串内容存储在只读存储区,不能直接修改。
字符串的内存表示
字符串存储在内存中时,每个字符占据一个字节,末尾以 \0
标志结束。
常见的字符串操作函数
C 标准库 <string.h>
提供了一系列用于操作字符串的函数:
函数 | 描述 |
---|---|
strcpy(s1, s2) | 将字符串 s2 复制到 s1 。 |
strcat(s1, s2) | 将字符串 s2 连接到 s1 的末尾。 |
strlen(s1) | 返回字符串 s1 的长度(不包括 \0 )。 |
strcmp(s1, s2) | 比较字符串 s1 和 s2 ,返回值根据大小关系为 0 、正值或负值。 |
strchr(s1, ch) | 返回指向字符串 s1 中字符 ch 第一次出现位置的指针。 |
strstr(s1, s2) | 返回指向字符串 s1 中子串 s2 第一次出现位置的指针。 |
示例代码
以下代码演示了这些函数的基本使用:
#include <stdio.h>
#include <string.h>
int main() {
char str1[20] = "Hello";
char str2[] = "World";
char str3[20];
int len;
// 复制字符串
strcpy(str3, str1);
printf("strcpy(str3, str1): %s\n", str3);
// 连接字符串
strcat(str1, str2);
printf("strcat(str1, str2): %s\n", str1);
// 计算字符串长度
len = strlen(str1);
printf("strlen(str1): %d\n", len);
return 0;
}
输出结果:
strcpy(str3, str1): Hello
strcat(str1, str2): HelloWorld
strlen(str1): 10
深入探讨字符串长度计算
strlen
与 sizeof
的区别
功能 | strlen | sizeof |
---|---|---|
计算内容 | 字符串的实际长度(不包括 \0 )。 | 字符数组的大小(包括 \0 )。 |
作用范围 | 仅适用于字符串。 | 可用于任何类型的变量和数据结构。 |
计算方式 | 遍历字符串,遇到 \0 时停止计数。 | 在编译时直接得出分配的内存大小。 |
示例:
#include <stdio.h>
#include <string.h>
void demo() {
char s[] = "hello, world!";
printf("sizeof(s): %lu\n", sizeof(s)); // 包括 '\0'
printf("strlen(s): %lu\n", strlen(s)); // 不包括 '\0'
}
int main() {
demo();
return 0;
}
输出:
sizeof(s): 14
strlen(s): 13
字符串操作的注意事项
1. 字符数组的大小
在明确指定字符数组大小时,请务必为 \0
预留空间:
char greeting[6] = {'H', 'e', 'l', 'l', 'o', '\0'};
如果未包含 \0
:
char greeting[5] = {'H', 'e', 'l', 'l', 'o'};
printf("%s\n", greeting); // 可能导致未定义行为
2. 字符数组和字符指针的区别
- 字符数组:可修改内容;声明后占用固定内存。
- 字符指针:内容存储在只读存储区,尝试修改会导致运行错误。
3. 使用安全函数
在 MSVC 编译器中,推荐使用安全函数 strcpy_s
和 strcat_s
,这些函数多了一个缓冲区大小参数,可以避免缓冲区溢出问题:
#include <stdio.h>
#include <string.h>
int main() {
char dest[50];
strcpy_s(dest, sizeof(dest), "Hello");
strcat_s(dest, sizeof(dest), ", Secure World!");
printf("%s\n", dest);
return 0;
}
字符串的遍历与格式化输出
遍历字符串
char str[] = "Hello";
for (int i = 0; str[i] != '\0'; i++) {
printf("%c ", str[i]);
}
格式化输出
%s
用于输出字符串:printf("Greeting: %s\n", str);
总结
- 字符串的本质是以
\0
结束的字符数组。 - 熟练掌握字符串操作函数,如
strcpy
、strcat
、strlen
。 - 注意
strlen
与sizeof
的区别。 - 使用安全函数(如
strcpy_s
)确保代码的安全性。
通过灵活运用 C 语言中的字符串操作,开发者可以高效地处理文本数据,提高代码的健壮性和安全性。