C 语言数组完全指南:定义、初始化与实战应用

76 阅读6分钟

C 语言数组完全指南:定义、初始化与实战应用

数组是 C 语言中存储多个相同类型数据的核心数据结构,凭借连续的内存布局和循环适配特性,成为批量数据处理的首选。本文基于 C 语言基础教程,系统拆解一维数组的定义、空间计算、初始化规则与实战用法,搭配常见坑点分析,帮助新手快速掌握数组的核心逻辑。

一、数组的核心概念:为什么需要数组?

1. 数组的本质

数组是 “相同数据类型 + 连续内存地址” 的集合,用于解决 “批量存储同类型数据” 的问题。

  • 场景示例:统计全班 40 名学生的成绩,若用单个变量定义(score1score2score40),会导致定义繁琐、操作重复;用数组int score[40]即可一次性声明,配合循环高效处理。

2. 数组的核心特点

  • 数据类型统一:所有元素必须是同一类型(如 int、float);
  • 内存地址连续:相邻元素的内存地址相差一个数据类型的大小(如 int 数组相邻元素差 4 字节);
  • 长度固定:数组长度一旦定义无法修改,需提前规划存储容量。

二、一维数组的定义与空间计算

1. 定义格式

c

运行

类型 标识符[长度];
  • 类型:支持所有 C 语言基础数据类型(int、char、float 等);

  • 标识符:变量名,遵循命名规则(字母 / 数字 / 下划线组成,非数字开头、非关键字、区分大小写);

  • 长度:表示数组可存储的元素个数,支持 3 种指定方式:

    1. 具体数值:int num[5];(存储 5 个 int 类型元素);
    2. 宏定义:#define S 5; int num[S];(通过宏定义灵活修改长度);
    3. 动态输入(GCC 兼容):int n; scanf("%d",&n); int num[n];(注意:动态数组不能同时初始化)。

2. 空间大小计算

数组总空间大小 = 单个元素类型大小 × 数组长度,可通过sizeof运算符精准计算:

c

运行

int num[5];
// 总空间大小:int占4字节 × 5 = 20字节
printf("数组总空间:%zu\n", sizeof(num)); 
// 单个元素大小:4字节
printf("单个元素空间:%zu\n", sizeof(num[0])); 
// 数组长度(通用计算方式):总空间 ÷ 单个元素空间
int len = sizeof(num) / sizeof(num[0]); 
printf("数组长度:%d\n", len);
  • 优势:sizeof(num)/sizeof(num[0])是通用长度计算方式,数组扩容时无需手动修改,降低出错概率。

三、数组的 3 种初始化方式(避坑重点)

数组初始化分为 “定义时初始化” 和 “后续赋值” 两类,核心规则如下:

1. 无初始化(不推荐)

c

运行

int num1[5];
  • 特点:元素默认值为随机数(内存中未初始化的垃圾值),直接使用可能导致程序异常;
  • 建议:即使暂时不赋值,也需初始化(如int num1[5] = {0};)。

2. 定义时初始化(推荐)

通过{}直接赋值,支持多种灵活形式:

c

运行

// 1. 完整初始化:赋值元素个数 = 数组长度
int num2[5] = {1,2,3,4,5}; 

// 2. 部分初始化:未赋值元素默认补0
int num3[5] = {1,2,3}; // 等价于{1,2,3,0,0}

// 3. 全0初始化:简洁高效
int num4[5] = {0}; // 所有元素均为0

// 4. 省略长度:数组长度由初始化元素个数决定
int num5[] = {1,2,3,4,5}; // 长度自动识别为5
  • 关键:省略长度时必须同时初始化,否则编译器无法确定数组大小。

3. 先定义后赋值(逐个赋值)

数组定义后不能直接用{}批量赋值,需通过数组下标逐个操作:

c

运行

int num6[5];
// 错误写法:定义后不能用{}批量赋值(编译报错)
// num6 = {1,2,3,4,5}; 

// 正确写法:通过下标逐个赋值(下标从0开始)
num6[0] = 1;
num6[1] = 2;
num6[2] = 3;
num6[3] = 4;
num6[4] = 5;
  • 数组下标规则:从 0 开始,最大值为 “数组长度 - 1”(如num6[5]是下标越界,属于非法操作)。

四、数组的实战应用:输入与输出

数组的核心优势是配合循环批量处理数据,以下是标准的 “输入 - 输出” 实战案例:

c

运行

#include <stdio.h>

int main() {
    // 定义数组并全0初始化
    int num[5] = {0};
    int len = sizeof(num) / sizeof(num[0]); // 计算数组长度

    // 循环输入数组元素(下标0~4)
    for(int i = 0; i < len; i++) {
        printf("请输入第%d个元素:", i+1); // 提示用户,下标转人类习惯的1起始
        // &num[i]:取第i个元素的地址,用于scanf输入
        scanf("%d", &num[i]); 
    }

    // 循环输出数组元素
    printf("\n数组元素为:\n");
    for(int i = 0; i < len; i++) {
        // 制表符\t分隔,格式整洁
        printf("%d\t", num[i]); 
    }
    printf("\n");

    return 0;
}
  • 运行流程:输入 5 个整数 → 存储到num[0]~num[4] → 循环遍历输出所有元素;
  • 关键:num[i]表示数组的第 i 个元素(空间),输入时需加取地址符&,输出时直接使用。

五、新手必避的 3 个核心坑点

1. 下标越界(最常见错误)

数组下标从 0 开始,最大值为 “长度 - 1”,超出范围会触发 “段错误(核心已转储)”:

c

运行

int num[5];
// 错误:num[5]是第6个元素,超出数组长度(0~4)
num[5] = 100; 
  • 规避:循环时用 “i < len” 代替固定数值(如i < 5),避免硬编码导致越界。

2. 动态数组初始化错误

动态输入长度的数组(如int num[n]),定义时不能同时用{}初始化:

c

运行

int n;
scanf("%d", &n);
// 错误:动态数组不能直接初始化
int num[n] = {1,2,3}; 
  • 规避:动态数组需定义后通过循环或下标逐个赋值。

3. 定义后批量赋值错误

数组定义后不能用{}批量赋值,只能逐个下标操作:

c

运行

int num[5];
// 错误:编译报错(expected expression before '{' token)
num = {1,2,3,4,5}; 
  • 规避:若需批量赋值,可使用循环遍历或 memcpy 函数。

六、数组的核心应用场景

  1. 批量数据存储:如学生成绩、员工工资、传感器采集数据;
  2. 循环批量处理:配合 for 循环实现数据的输入、输出、排序、查找;
  3. 函数参数传递:作为函数参数传递时,数组名退化为指针(传递首元素地址)。