跳到主要内容

C 数组

C 一维数组

1. 基本概念

数组就是存储一个固定大小的相同类型元素的地方。

2. 定义数组

类型 数组名[常量表达式];

int a[6]; // 定义一个整型数组,总共存放6个元素
char b[24]; // 定义一个字符型数组,总共存放24个元素
float c[3]; // 定义一个单精度浮点型数组,总共存放3个元素

3. 访问数组

数组名[下标]

a[0]; // 访问 a 数组中的第 1 个元素
b[1]; // 访问 b 数组中的第 2 个元素
c[5]; // 访问 c 数组中的第 6 个元素

// 注意:

int a[10]; // 创建一个具有 10 个元素的数组
a[0]; // 访问第 1 个元素的下标是 0,不是 1
a[10]; // 报错,因为第 10 个元素的下标是 a[9]

ZVgIh0.png

4. 数组的初始化

在定义数组的同时对其各个元素进行赋值,将其称之为数组的初始化。

数组的初始化有几种方式:

  • 将数组中的所有元素统一初始化为某个值
int a[10] = {0}; // 将数组中所有元素初始化为0
  • 赋予不同的值,则用逗号分隔开来
int a[10] = {0,1,2,3,4,5,6}; // 表示为前边 6 个元素赋值,后边 4 个元素系统自动初始化为 0
  • 有时候还可以只给出各个元素的值
int a[ ] = {0,1,2,3,4,5,6,7,8,9,0}; 
  • C99中还可以指定初始化数组中的元素
int a[10]={[3] = 3, [5] = 5, [8] = 8};

5. 字符数组

  • 专门用来存放字符的数组称为字符数组。
char s1[5] = {'h', 'e', 'l', 'l', 'o'};       // s1存放的是字符序列
char s2[6] = {'h', 'e', 'l', 'l', 'o', '\0'}; // s2存放的是一个字符串
char s3[6] = {"hello"}; // 使用字符串直接初始化数组
char s4[6] = "hello"; // 大括号可以省略

6. 变长数组

  • 概念:定义时使用变量作为元素个数的数组。
  • 要点:变长数组仅仅指元素个数在定义时是变量,而绝非指数组的长度可长可短。
  • 不管是普通数组还是所谓的变成数组,数组一旦定义完毕,其长度则不可改变。
int len = 5;
int a[len]; // 数组元素个数 len 是变量,因此 a 是变长数组。

int x = 2, y = 3;
int b[x][y]; // 数组元素个数 x、y 是变量,因此数组 b 是变长数组
int b[2][y]; // 数组元素个数 y 是变量,因此数组 b 是变长数组
int b[x][3]; // 数组元素个数 x 是变量,因此数组 b 是变长数组
  • 变长数组不可以初始化
int len = 5;
int a[len] = {1,2,3,4,5};

C 二维数组

1. 二维数组的定义

定义二维数组的方法跟一维数组是相似的

类型 数组名[常量表达式] [常量表达式]

int a[6][6]; // 6*6 6行6列
char b[4][5]; // 4*5 4行5列
float c[6][3]; // 6*3 6行3列

2. 二维数组的访问

数组名[下标] [下标]

a[0][0]; // 访问 a 数组中第 1 行第 1 列的元素
b[1][3]; // 访问 b 数组中第 2 行第 4 列的元素
c[3][3]; // 访问 c 数组中第 4 行第 4 列的元素

3. 二维数组的初始化

// 二维数组在内存中是线性分布的
int a[3][4] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12};
// 更直观的表示元素的分布
int a[3][4] = {{1, 2, 3, 4}, {5, 6, 7, 8}, {9, 10, 11, 12}};
// 更加清晰的表示元素的分布
int a[3][4] = {
{1, 2, 3, 4},
{5, 6, 7, 8},
{9, 10, 11, 12}
};

ZVgD05.png

  • 二维数组也可以仅对部分元素赋初值:
int a[3][4] = {{1}, {5}, {9}};// 这样写是只对各行的第 1 列元素赋初值,其余元素初始化为 0。
  • 如果希望整个二维数组初始化为 0,那么直接在大括号里写一个 0 即可:
int a[3][4] = {0};
  • C99 同样增加了一种新特性:指定初始化的元素。这样就可以只对数组中的某些指定元素进行初始化赋值,而未被赋值的元素自动初始化为 0:
int a[3][4] = {[0][0] = 1, [1][1] = 2, [2][2] = 3};
  • 二维数组的初始化也能偷懒,让编译器根据元素的数量计算数组的长度。但只有第 1 维的元素个数可以不写,其他维度必须写上:
int a[][4] = {{1, 2, 3, 4}, {5, 6, 7, 8}, {9, 10, 11, 12}};

4. 数组万能拆解法

  • 任意的数组,不管有多复杂,其定义都有两部分组成。
    • 第1部分:说明元素的类型,可以是任意的类型(除了函数)。
    • 第2部分:说明数组名和元素个数。
int a[2];                      // 第2部分:a[2];第1部分:int
int b[3][4]; // 第2部分:b[3];第1部分:int [5]
int c[4][5][6]; // 第2部分:c[4];第1部分:int [5][6]
int *d[5]; // 第2部分:d[5];第1部分:int *
int (*e[6])(int, float); // 第2部分:e[6];第1部分:int (*)(int, float)
  • 注解:
    • a[2]、b[3]、c[4]、d[5]、e[6] 本质上没有区别,它们都是数组。
    • a[2]、b[3]、c[4]、d[5]、e[6] 唯一的不同,是它们所存放的元素不同。