在编程中,经常需要处理一组相同类型的数据,比如一个班50名学生的成绩、一个矩阵的元素等。如果为每个数据单独定义变量,不仅繁琐而且难以维护。 数组正是为了解决这一问题而设计的——它是一组具有相同数据类型的有序集合,通过统一的数组名和下标(索引)来访问各个元素。 本章将详细介绍C语言中数组的使用方法。
{{-- 1. 一维数组 --}}一维数组是最简单的数组形式,可以看作是一个线性的数据序列。
类型 数组名[元素个数];
例如:int scores[10]; 定义一个包含10个整数的数组,索引从0到9。
可以在声明时初始化:
int arr1[5] = {1, 2, 3, 4, 5}; // 完全初始化
int arr2[5] = {1, 2, 3}; // 部分初始化,其余元素自动为0
int arr3[] = {1, 2, 3, 4, 5}; // 省略长度,编译器自动计算
int arr4[5] = {0}; // 将所有元素初始化为0
int arr5[5] = {[2]=10, [4]=20}; // C99指定初始化器,将索引2设为10,索引4设为20
通过下标(索引)访问数组元素,下标从0开始。语法:数组名[下标]
#include <stdio.h>
int main() {
int scores[5] = {85, 92, 78, 90, 88};
// 访问第三个元素(索引2)
printf("第三个成绩: %d\n", scores[2]); // 输出78
// 修改第一个元素
scores[0] = 95;
printf("修改后第一个成绩: %d\n", scores[0]); // 输出95
return 0;
}
通常使用for循环遍历数组元素:
#include <stdio.h>
int main() {
int scores[] = {85, 92, 78, 90, 88};
int length = sizeof(scores) / sizeof(scores[0]); // 计算数组元素个数
for (int i = 0; i < length; i++) {
printf("scores[%d] = %d\n", i, scores[i]);
}
return 0;
}
sizeof(数组名) / sizeof(数组元素类型),此方法只能在数组定义的作用域内有效,当数组作为函数参数传递时会退化为指针,无法计算长度。
#include <stdio.h>
int main() {
int arr[] = {23, 45, 12, 67, 34, 89, 21, 54, 76, 33};
int n = sizeof(arr) / sizeof(arr[0]);
int max = arr[0], min = arr[0];
int sum = 0;
for (int i = 0; i < n; i++) {
sum += arr[i];
if (arr[i] > max) max = arr[i];
if (arr[i] < min) min = arr[i];
}
double avg = (double)sum / n;
printf("最大值: %d\n", max);
printf("最小值: %d\n", min);
printf("平均值: %.2f\n", avg);
return 0;
}
{{-- 2. 二维数组 --}}
二维数组可以看作是一个表格或矩阵,由行和列组成。
类型 数组名[行数][列数];
初始化方式:
// 方式1:按行初始化
int matrix[2][3] = {{1, 2, 3}, {4, 5, 6}};
// 方式2:逐个元素初始化(按行优先存储)
int matrix2[2][3] = {1, 2, 3, 4, 5, 6};
// 方式3:部分初始化,未指定的元素为0
int matrix3[2][3] = {{1, 2}, {4}}; // 第一行第三列为0,第二行后两列为0
// 方式4:省略行数(必须指定列数)
int matrix4[][3] = {{1, 2, 3}, {4, 5, 6}}; // 编译器自动计算行数
#include <stdio.h>
int main() {
int matrix[3][4] = {
{1, 2, 3, 4},
{5, 6, 7, 8},
{9, 10, 11, 12}
};
// 遍历二维数组
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 4; j++) {
printf("%3d ", matrix[i][j]);
}
printf("\n");
}
// 访问单个元素
printf("matrix[1][2] = %d\n", matrix[1][2]); // 输出7
return 0;
}
#include <stdio.h>
int main() {
int A[2][3] = {{1, 2, 3}, {4, 5, 6}};
int B[3][2] = {{7, 8}, {9, 10}, {11, 12}};
int C[2][2] = {0}; // 结果矩阵
// 矩阵乘法:C[i][j] = sum(A[i][k] * B[k][j])
for (int i = 0; i < 2; i++) {
for (int j = 0; j < 2; j++) {
for (int k = 0; k < 3; k++) {
C[i][j] += A[i][k] * B[k][j];
}
}
}
// 输出结果
printf("矩阵乘积结果:\n");
for (int i = 0; i < 2; i++) {
for (int j = 0; j < 2; j++) {
printf("%4d ", C[i][j]);
}
printf("\n");
}
return 0;
}
{{-- 3. 字符数组与字符串 --}}
C语言中没有专门的字符串类型,字符串是通过字符数组来存储的,以空字符 '\0' 结尾。
// 方式1:指定长度,并留出'\0'的位置
char str1[6] = {'H', 'e', 'l', 'l', 'o', '\0'};
// 方式2:使用字符串常量(自动添加'\0')
char str2[6] = "Hello"; // 等价于上面的写法
char str3[] = "Hello"; // 编译器自动计算长度(6)
// 方式3:只初始化部分,其余为0(即'\0')
char str4[10] = "Hello"; // 前5个字符是Hello,第6个是'\0',后面全是0
#include <stdio.h>
#include <string.h>
int main() {
char name[50];
printf("请输入姓名: ");
fgets(name, sizeof(name), stdin); // 安全读取一行,包含换行符
// 移除换行符
size_t len = strlen(name);
if (len > 0 && name[len-1] == '\n') {
name[len-1] = '\0';
}
printf("你好, %s\n", name); // %s 会输出直到'\0'
// 使用puts输出(自动换行)
puts("欢迎学习C语言");
return 0;
}
| 函数 | 功能 | 示例 |
|---|---|---|
strlen(str) | 返回字符串长度(不含'\0') | len = strlen("Hello"); → 5 |
strcpy(dest, src) | 将src复制到dest(不安全,可能溢出) | strcpy(str1, "World"); |
strncpy(dest, src, n) | 最多复制n个字符,更安全 | strncpy(str1, "Hello", 5); |
strcat(dest, src) | 将src追加到dest末尾 | strcat(greeting, "!"); |
strcmp(str1, str2) | 比较字符串,返回0表示相等 | if (strcmp(s1, s2) == 0) |
#include <stdio.h>
#include <string.h>
int main() {
char str1[20] = "Hello";
char str2[] = "World";
// 连接
strcat(str1, " "); // 注意确保空间足够
strcat(str1, str2);
printf("拼接结果: %s\n", str1); // "Hello World"
// 复制
char str3[20];
strcpy(str3, str1);
printf("复制结果: %s\n", str3);
// 比较
if (strcmp(str1, str3) == 0) {
printf("str1 和 str3 相等\n");
}
return 0;
}
{{-- 4. 数组作为函数参数 --}}
当数组作为函数参数时,实际上传递的是数组首元素的指针,因此在函数内部无法直接获取数组的长度,需要额外传递长度参数。
#include <stdio.h>
// 函数声明:接收一个整型数组和数组长度
void printArray(int arr[], int size) {
for (int i = 0; i < size; i++) {
printf("%d ", arr[i]);
}
printf("\n");
}
void doubleElements(int arr[], int size) {
for (int i = 0; i < size; i++) {
arr[i] *= 2; // 修改会影响原数组
}
}
int main() {
int nums[] = {1, 2, 3, 4, 5};
int len = sizeof(nums) / sizeof(nums[0]);
printf("原数组: ");
printArray(nums, len);
doubleElements(nums, len);
printf("翻倍后: ");
printArray(nums, len);
return 0;
}
int arr[] 实际上等同于 int *arr,所以对形参的修改会影响实参数组。
printf("%s")等函数会继续读取内存直到遇到'\0',造成不可预知的结果。&arr和arr的值相同,但类型不同(指针与数组指针),需注意区别。sizeof获取数组长度: 因为数组参数退化为指针,sizeof(arr)得到的是指针大小,而不是数组大小。数组是C语言中最常用的数据结构之一,它为批量处理同类型数据提供了方便。一维数组、二维数组以及字符数组(字符串)是后续学习指针、动态内存分配等高级特性的基础。 下一章我们将学习函数,将程序分解为可重用的模块。
{{-- 章节导航按钮 --}}