数组

数组的概念

数组是若干相同类型的数据的在内存中有序存储的集合。

  • 数组用于存储一组数据。
  • 数组中存储的数据类型必须相同。
  • 数组会在内存开辟一块连续的空间。

例如:

1
int a[10]

定义了一个整型数组 a,a 是数组名,数组中每个元素类型都是 int,而且在内存中连续储存,这 10 个元素分别是:a[0]、...、a[9],数组索引从 0 开始。

数组的分类

按元素类型分类

  1. 字符数组:char s[10];
  2. 短整型数组:short int a[10];
  3. 整形数组:int a[10];
  4. 长整型数组:long int a[5];
  5. 浮点型数组:float a[6];double a[8];
  6. 指针数组:char *a[10];int *a[10];
  7. 结构体数组:struct stu boy[10];

按维数分类

  • 一维数组:int a[30];
  • 二维数组:int a[2][30];,有行有列,是一维数组的数组。
  • 多维数组:int a[4][2][10];,三维数组由多个相同的二维数组构成。

数组的定义

一维数组的定义

语法:

1
2
数据类型 数组名[数组元素个数];
数据类型 数组名[] = {元素1, 元素2, 元素3, ...}

定义数组是数组元素个数必须为整型常量。

1
2
3
4
5
6
7
8
9
10
11
#include <stdio.h>

int main(int argc, char *argv[]) {

int a[10];
printf("sizeof(a) = %lld %lld\n", sizeof(a), 10 * sizeof(int));
int b[] = {10, 20, 30};
printf("sizeof(b) = %lld\n", sizeof(b));

return 0;
}

输出结果:

image

二维数组的定义

语法:

1
2
数据类型 数组名[行数][列数];
数据类型 数组名[][列数] = {元素1, 元素2, 元素3, ...};

二位数组的行数可以省略,但列数不能省略。

1
2
3
4
5
6
7
8
9
10
11
12
13
#include <stdio.h>

int main(int argc, char *argv[]) {

int c[2][4];

printf("sizeof(c) = %lld %lld\n", sizeof(c), 2 * 4 * sizeof(int));
int d[][4] = {1, 2, 3, 4, 5};
printf("sizeof(d) = %lld\n", sizeof(d));

return 0;
}

输出结果:

image

定义并初始化

一维数组的初始化

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
#include <stdio.h>

int main(int argc, char *argv[]) {

// 以一维数组的初始化
// 如果不初始化,直接使用会是随机值
// int a[4];

// 初始化方式1:全部初始化

// int a[4] = {123, 78, 666, 476};
// 如果是全部 初始化,可以不指定数组元素的个数,系统会自动分配
// int a[] = {10, 20, 30, 40};

// 初始化方式2:局部初始化
// 未初始化的位置的元素自动赋值为0

int a[4] = {10, 20};
printf("%d\n", a[0]);
printf("%d\n", a[1]);
printf("%d\n", a[2]);
printf("%d\n", a[3]);

return 0;
}

输出结果:

image

一维数组还可以按位置初始化:

1
2
3
4
5
6
7
8
9
10
11
12
13
#include <stdio.h>

int main() {

int i = 0;
int arr[5] = {[1] = 10, [3] = 20};

printf("count: %ld", sizeof(arr) / sizeof(arr[0]));
for (int i = 0; i < sizeof(arr) / sizeof(arr[0]); ++i) {
printf("arr[%d] = %d\n", i, arr[i]);
}
return 0;
}

二维数组的初始化

按行初始化

1
2
3
4
5
6
7
8
// 全部初始化
int a[2][2] = {
{1, 2}, {4, 5}
};
// 部分初始化
int a[3][3] = {
{1, 2}, {1}
};

逐个初始化

1
2
3
4
// 全部初始化:
int a[2][3] = {2, 5, 4, 2, 3, 4};
// 部分初始化:
int a[2][3] = {3, 5, 6, 8};

按钮:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
#include <stdio.h>

int main(int argc, char *argv[]) {

// 二维数组的初始化
// int a[2][3];

// 初始化方式1:按行初始化
// 全部初始化
// int a[2][3] = {{10, 20, 30}, {666, 777, 888}};
// 局部初始化
// 没有赋值的位置的元素自动为0
// int a[2][3] = {{10, 20}, {666}};

// 初始化方式2:逐个初始化
// 全部初始化
// int a[2][3] = {1, 2, 3, 4, 5, 6};
// 局部初始化
// 没有赋值的位置的元素自动为0

int a[2][3] = {1, 2, 3};
printf("%d\n", a[0][0]);
printf("%d\n", a[0][1]);
printf("%d\n", a[0][2]);
printf("%d\n", a[1][0]);
printf("%d\n", a[1][1]);
printf("%d\n", a[1][2]);

return 0;
}

输出结果:

image

数组元素的引用方法

一维数组元素的引用方法:

1
数组名[索引];

二维数组元素的引用方法:

1
数组名[行索引][列索引];
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
#include <stdio.h>

int main(int argc, char *argv[]) {

int a[6] = {111, 222, 333, 444, 555, 666};
a[3] = 10000;

for (int i = 0; i < sizeof(a) / sizeof(int); i++) {
printf("a[%d] = %d\n", i, a[i]);
}

printf("**********************\n");

int b[3][4] = {1, 2, 3, 4,

5, 6, 7, 8,

9, 10, 11, 12};

b[2][0] = 666;

for (int m = 0; m < 3; m++) {

for (int n = 0; n < 4; n++) {
printf("%-4d", b[m][n]);
}
printf("\n");
}

return 0;
}

输出结果:

image

字符数组的定义和初始化问题

1
2
3
4
char c1[] = {'c', ' ', 'p', 'r', 'o', 'g'};
char c2[] = "c prog";
char a1[][5] = {{'B', 'A', 'S', 'I', 'C'}, {'d', 'B', 'A', 'S', 'E'}};
char a2[][6] = {"hello", "world"};

字符数组的引用:

  1. 用字符串方式赋值比用字符逐个赋值要多占 1 个字节,用于存放字符串结束标志 \0.
  2. 上面的数组 c2 在内存中的实际存放情况为:
image
  1. 由于采用了 \0 标志,字符数组的输入输出将变得简单方便。
1
2
3
4
5
6
7
8
9
10
11
#include <stdio.h>

int main(int argc, char *argv[]) {

char ch[32] = "";
scanf("%s", ch);
printf("ch = %s\n", ch);

return 0;
}

输出结果为:

image