在C语言中,数组和字符串是基础且重要的概念。它们用于存储和操作一系列相同类型的元素或字符序列。
数组
1. 数组定义与初始化
数组是一系列相同类型的数据项的集合,这些数据项可以通过一个共同的名字来引用。数组中的每个元素都有一个索引(也称为下标),从0开始计数。
定义:
type arrayName[arraySize];
示例:
int numbers[5];
定义了一个包含5个整数的数组。初始化:
- 在定义时初始化:
int numbers[] = {1, 2, 3, 4, 5};
- 或者指定大小并初始化:
int numbers[5] = {1, 2, 3};
剩余元素自动初始化为0。
- 在定义时初始化:
2. 访问数组元素
通过索引来访问数组中的元素,如 arrayName[index]
。例如,numbers[0]
返回数组的第一个元素。
3. 多维数组
C语言支持多维数组,最常见的是二维数组,可以将其视为表格形式。
- 定义与初始化:
int matrix[3][4] = {{1, 2, 3, 4}, {5, 6, 7, 8}, {9, 10, 11, 12}};
一维数组的遍历
#include <stdio.h>int main() {int arr[] = {10, 20, 30, 40, 50};int length = sizeof(arr) / sizeof(arr[0]); // 计算数组长度printf("数组元素为:\n");for (int i = 0; i < length; i++) {printf("arr[%d] = %d\n", i, arr[i]);}return 0;
}
数组可以分配在栈内存或堆内存中,具体取决于数组是如何声明和定义的。
栈内存中的数组
当你在一个函数内部直接声明一个数组时(即没有使用动态内存分配函数如 malloc
),这个数组是分配在栈内存上的。栈内存是由编译器自动分配和释放的,它的生命周期与变量的作用域紧密相关。一旦函数执行完毕,栈上的数组所占用的内存会自动被释放。
堆内存中的数组
如果你想在运行时确定数组的大小或者希望数组在其声明的作用域之外继续存在,你可以使用动态内存分配函数(如 malloc
, calloc
, realloc
)来在堆内存上分配数组。堆内存需要手动管理,意味着你需要明确地使用 free
函数来释放你分配的内存,否则可能会导致内存泄漏。
- 栈:适用于大小固定、生命周期与作用域相关的数组。栈上的分配和释放速度通常比堆快。
- 堆:适用于需要在运行时确定大小、或者希望其生命周期超出当前作用域的数组。不过,堆的分配和释放相对较慢,并且需要程序员手动管理内存。
字符串
在C语言中,字符串实际上是一个以空字符 \0
结尾的一维字符数组。
1. 字符串定义与初始化
- 直接定义:
char greeting[] = "Hello";
- 或者手动添加终止符:
char greeting[6] = {'H', 'e', 'l', 'l', 'o', '\0'};
2. 字符串处理函数
标准库提供了许多用于操作字符串的函数,需包含头文件 <string.h>
。
strlen(s)
:计算字符串s
的长度。strcpy(dest, src)
:将字符串src
复制到dest
。strcat(dest, src)
:将字符串src
连接到dest
后面。strcmp(s1, s2)
:比较两个字符串s1
和s2
。
3. 注意事项
- C语言不检查数组越界,因此编写代码时要特别小心不要超出数组界限。
- 对于字符串,忘记添加结束符
\0
可能会导致未定义行为。
中文处理
使用 char[]
+ UTF-8 编码(推荐)
UTF-8 是互联网通用编码,支持中文,且兼容 ASCII。
示例:
#include <stdio.h>
#include <windows.h> // Windows onlyint main() {SetConsoleOutputCP(65001); // 设置控制台输出为 UTF-8char str[] = "你好,世界!";printf("%s\n", str);for (int i = 0; str[i] != '\0'; i++) {printf("%02X ", (unsigned char)str[i]);}printf("\n");return 0;
}
- 你的源代码文件必须保存为 UTF-8 编码(否则中文会乱码)。
- 在 Windows 控制台中显示 UTF-8 中文时,可能需要设置控制台编码为 UTF-8:
- 在 编译选项里,添加utf-8
选择“配置属性”“C/C++”>“命令行”属性页>。
在“附加选项”中,添加 选项以指定首选编码。
/utf-8
选择“确定”以保存更改 。