C语言数组详解
-
- [1. 什么是数组?](#1. 什么是数组?)
- [2. 数组的声明和初始化](#2. 数组的声明和初始化)
- [3. 访问数组元素](#3. 访问数组元素)
- [4. 数组在内存中的存储](#4. 数组在内存中的存储)
- [5. 一维数组的完整示例](#5. 一维数组的完整示例)
- [6. 多维数组](#6. 多维数组)
- [7. 字符数组(字符串)](#7. 字符数组(字符串))
- [8. 数组作为函数参数](#8. 数组作为函数参数)
- [9. 常见数组操作](#9. 常见数组操作)
- [10. 重要注意事项](#10. 重要注意事项)
-
- [1. 数组越界](#1. 数组越界)
- [2. 数组大小必须是常量](#2. 数组大小必须是常量)
- [3. 数组名是首元素地址](#3. 数组名是首元素地址)
- [11. 综合实战示例](#11. 综合实战示例)
- 小结
1. 什么是数组?
想象一下你有一个能放多个相同类型物品的盒子,这个盒子就是数组。比如:
- 一个能放10个整数的盒子 → 整型数组
- 一个能放20个字符的盒子 → 字符数组
官方定义:数组是相同类型数据元素的有序集合。
2. 数组的声明和初始化
基本语法
c
数据类型 数组名[数组大小];
示例
c
// 声明一个能存放5个整数的数组
int numbers[5];
// 声明时直接初始化
int scores[5] = {85, 90, 78, 92, 88};
// 可以不指定大小,编译器会自动计算
int ages[] = {18, 20, 22, 19, 21}; // 自动创建大小为5的数组
// 部分初始化,未初始化的元素自动为0
int data[10] = {1, 2, 3}; // 前3个是1,2,3,后面7个都是0
3. 访问数组元素
重要概念:下标(索引)
- 数组下标从 0 开始,不是1!
- 如果有5个元素,下标是:0, 1, 2, 3, 4
c
int numbers[5] = {10, 20, 30, 40, 50};
// 访问单个元素
printf("第一个元素: %d\n", numbers[0]); // 输出10
printf("第三个元素: %d\n", numbers[2]); // 输出30
// 修改元素
numbers[1] = 25; // 第二个元素变成25
// 错误示例:数组越界
printf("%d", numbers[5]); // 错误!只有0-4是有效的
4. 数组在内存中的存储
数组元素在内存中是连续存储的:
假设 numbers[3] = {10, 20, 30}
内存地址: 1000 1004 1008
值: 10 20 30
[0] [1] [2]
5. 一维数组的完整示例
c
#include <stdio.h>
int main() {
// 声明并初始化数组
float temperatures[7] = {25.5, 26.0, 24.8, 27.2, 26.5, 25.0, 24.3};
// 计算平均温度
float sum = 0;
for(int i = 0; i < 7; i++) {
sum += temperatures[i];
printf("第%d天温度: %.1f°C\n", i+1, temperatures[i]);
}
float average = sum / 7;
printf("\n周平均温度: %.1f°C\n", average);
return 0;
}
6. 多维数组
二维数组(最常用)
想象成一个表格或棋盘:
c
// 声明一个3行4列的二维数组
int matrix[3][4];
// 初始化二维数组
int chessboard[3][3] = {
{1, 2, 3},
{4, 5, 6},
{7, 8, 9}
};
访问二维数组元素
c
// 访问第2行第3列的元素
int value = chessboard[1][2]; // 值是6
// 修改元素
chessboard[0][1] = 10; // 第一行第二列变成10
二维数组示例:学生成绩表
c
#include <stdio.h>
int main() {
// 3个学生,每个学生4门课的成绩
int grades[3][4] = {
{85, 90, 78, 92},
{88, 76, 95, 89},
{92, 84, 79, 96}
};
// 计算每个学生的平均分
for(int student = 0; student < 3; student++) {
int sum = 0;
for(int subject = 0; subject < 4; subject++) {
sum += grades[student][subject];
}
float average = sum / 4.0;
printf("学生%d的平均分: %.2f\n", student+1, average);
}
return 0;
}
7. 字符数组(字符串)
在C语言中,字符串就是用字符数组存储的:
c
// 两种方式声明字符串
char name1[6] = {'J', 'o', 'h', 'n', '\0'}; // 手动添加结束符
char name2[6] = "John"; // 自动添加结束符,更常用
// 更简单的方式(编译器自动计算大小)
char greeting[] = "Hello, World!";
字符串操作示例
c
#include <stdio.h>
#include <string.h>
int main() {
char firstName[20] = "张";
char lastName[20] = "三";
char fullName[40];
// 字符串拼接
strcpy(fullName, firstName); // 复制firstName到fullName
strcat(fullName, lastName); // 把lastName连接到fullName后面
printf("全名: %s\n", fullName);
printf("姓名长度: %lu\n", strlen(fullName));
return 0;
}
8. 数组作为函数参数
数组可以作为参数传递给函数:
c
#include <stdio.h>
// 函数声明:参数中的[]表示数组
void printArray(int arr[], int size) {
for(int i = 0; i < size; i++) {
printf("%d ", arr[i]);
}
printf("\n");
}
// 修改数组元素的函数
void doubleArray(int arr[], int size) {
for(int i = 0; i < size; i++) {
arr[i] *= 2; // 会修改原数组
}
}
int main() {
int numbers[] = {1, 2, 3, 4, 5};
int size = 5;
printf("原数组: ");
printArray(numbers, size);
doubleArray(numbers, size);
printf("加倍后: ");
printArray(numbers, size);
return 0;
}
9. 常见数组操作
查找最大值
c
int findMax(int arr[], int size) {
int max = arr[0];
for(int i = 1; i < size; i++) {
if(arr[i] > max) {
max = arr[i];
}
}
return max;
}
数组反转
c
void reverseArray(int arr[], int size) {
for(int i = 0; i < size/2; i++) {
// 交换对称位置的元素
int temp = arr[i];
arr[i] = arr[size-1-i];
arr[size-1-i] = temp;
}
}
10. 重要注意事项
1. 数组越界
c
int arr[5] = {1, 2, 3, 4, 5};
printf("%d", arr[5]); // 错误!越界访问
后果:可能程序崩溃,或读取到垃圾数据
2. 数组大小必须是常量
c
int size = 10;
int arr[size]; // C99之前是错误,C99支持变长数组
3. 数组名是首元素地址
c
int arr[3] = {1, 2, 3};
printf("%p", arr); // 输出数组首地址
printf("%p", &arr[0]); // 同上
11. 综合实战示例
c
#include <stdio.h>
#define STUDENTS 5
#define SUBJECTS 3
// 计算每个学生的平均分
void calculateAverages(int scores[][SUBJECTS], float averages[]) {
for(int i = 0; i < STUDENTS; i++) {
int sum = 0;
for(int j = 0; j < SUBJECTS; j++) {
sum += scores[i][j];
}
averages[i] = (float)sum / SUBJECTS;
}
}
// 找到最高分的学生
int findTopStudent(float averages[]) {
int topIndex = 0;
for(int i = 1; i < STUDENTS; i++) {
if(averages[i] > averages[topIndex]) {
topIndex = i;
}
}
return topIndex;
}
int main() {
// 5个学生的3门课成绩
int scores[STUDENTS][SUBJECTS] = {
{85, 90, 78},
{92, 88, 95},
{76, 82, 80},
{88, 90, 92},
{95, 87, 91}
};
float averages[STUDENTS];
// 计算平均分
calculateAverages(scores, averages);
// 输出结果
printf("学生成绩统计:\n");
for(int i = 0; i < STUDENTS; i++) {
printf("学生%d: 数学=%d, 语文=%d, 英语=%d, 平均分=%.2f\n",
i+1, scores[i][0], scores[i][1], scores[i][2], averages[i]);
}
// 找到最高分学生
int top = findTopStudent(averages);
printf("\n最高分学生: 学生%d, 平均分: %.2f\n", top+1, averages[top]);
return 0;
}
小结
数组是C语言中最重要的数据结构之一,要点记住:
- 声明 :
数据类型 数组名[大小] - 下标从0开始 :第一个元素是
arr[0] - 连续存储:元素在内存中挨着存放
- 多维数组:像表格一样组织数据
- 字符数组:用来存储字符串
- 函数参数:传递数组时实际传递的是地址
- 注意越界:不要访问超出数组范围的元素