嵌入式Linux C语言: 5.数组
int a ,b;
定义100个变量,有两种方式
a、int a0, a1, a2, …, a99;
b、数组 int a[100]; a[0], a[1], a[2], … a[99]
1. 数组
数组: 一组具有相同类型的数据元素的有序集合
在C语言中,数组可分为:
- 一维数组
- 二维数组
- 三维数组
…
其实,任意数组都是一维数组
2. 一维数组
2.1 一维数组的定义
类型数名符 数组名[整型表达式] { = { 初始化列表 } };
类型说明符
指定数组中 元素的类型 并不是数组的类型
可以是C语言中任意合法的类型(基本类型、自定义构造类型、指针类型)
数组名: 表示符
对象的名字
要符合C语言表示符的规定(只能由数字、字母、下划线组成,下划线不能开头)
整型表达式
指定数组中元素的个数
C语言中规定在定义数组时,需要指定(隐含指定 -> 编译器可以识别)数组元素的个数
常量表达式: int a[2*3]; // TRUE
int a[10]; //定义一个数组,数组名为a,里面含有10个int类型的元素。
int 是数组元素的类型,不是数组的类型
tepeof(a); //求a的类型
a 是一个含有10个int类型元素的 数组
上面的例子,不仅仅定义了一个数组a,同时还声明了一个新的类型
自定义类型 (构造类型)
typeof(a) => int [10] (C语言中并没有int[10] 类型, 只是方便表示,意思是含有10个int类型元素的数组)
定义一个和a一样类型的对象b
对象的类型 对象名
typeof(a) b;
=> int[10] b; == int b[10];
2.2 一维数组元素引用
int a[10]; //定义了一个数组,数组名为a,里面含有10个int类型的元素
a中有10个int类型的元素,对a中元素进行访问
引用数组元素: 数组名[下标]
下标: C语言约定数组元素的下标从0开始
假设数组有N个元素,数组对应的下标范围[0, N-1]
0, 1, 2, 3, …, N-1
如:
int a[10];
a[0]
a[1]
…
a[9]
a[10] // 数组越界
typeof(a[0]) => int
引用数组元素和引用普通变量是一样的,数组元素也有左值和右值
int a[10];
int b;
a[0] = 1024; //把数组1024赋值给 元素a[0]
//把数组1024存放到元素a[0] 的地址中去
//a[0] 代表的是元素a[0] 的地址
//lvalue
b = a[0]; //把元素a[0]的值,赋值给b
//a[0] 代表的是元素a[0]的值 rvalue: 对象的地址
scanf("%d", &b);
scanf("%d", &a[0]);
2.3 一维数组在内存中的存放
在C语言中,用一组地址连续的存储空间,从第地址到高地址一次来存放数组中的每一个元素
a[0]的后面是a[1]
a[1]的后面是a[2]
a[2]的后面是a[3]
…
int a[10];
0x3000 |_ _ _ _| a[0]
0x3004 |_ _ _ _| a[1]
0x3008 |_ _ _ _| a[2]
假设在64bit机器上,int占32bits
int a[10];
&a[0] == 0x4008
&a[1] == 0x400C
&a[2] == 0x4010
&a[i] = &a[0] + i*sizeof(int)
2.4 一维数组的初始化
初始化: 在定义对象时,就指定对象的值
数组的初始化使用: {}
(1) 依次对每一个数组元素赋初始值
int a[10] = {1, 2, 3, 4, 5, 6, 7, ,8 ,9, 10};
=> a[0] = 1
a[1] = 2
…
a[9] =10
(2) 可以只对前面的元素进行初始化,后面的元素自动初始化为0
int a[10] = {1, 2, 3};
=> a[0] = 1
a[1] = 2
a[2] = 3
a[3] = 0
…
a[9] = 0
(3) 如果对全部数组元素都赋初始值,在定义数组时,可以不用指定数组的元素个数
int a[] = {1, 2, 3, 4, 5}; <=> int a[5] = {1, 2, 3, 4, 5}
=> 数组a有5个int类型的元素
int a[5] = {1, 2, 3, 4, 5}; //TRUE
int a[5];
a[5] = {1, 2, 3, 4, 5}; //ERROR
a = {1, 2, 3, 4, 5}; //ERROR
不能对数组进行整体赋值,只允许在定义数组时对数组全部元素赋值,否则只能一个一个去指定
一维数组
定义格式
元素类型 数组名[元素个数];
int a[4]; // 定义了一个数组, 数组名为a, 里面含有4个int类型的元素
3. 二维数组
在C语言中,二维数组实际上就是一个一维数组, 不过该一维数组中每一个元素又是一个一维数组
int b[3][4];
数组名为b,里面含有三个元素:
b[0]: _ _ _ _ 里面含有4个int类型的元素, b[0]是一个一维数组
b[1]: _ _ _ _ 里面含有4个int类型的元素, b[1]是一个一维数组
b[2]: _ _ _ _ 里面含有4个int类型的元素, b[2]是一个一维数组
“三行四列” => 矩阵
3.1 二维数组的定义
从矩阵角度来二维数组:
类型说明符 数组名 [行数][列数] = { = {初始化列表} };
类型说明符: 二维数组中, 元素的类型, 并不是数组的类型 C语言中任意合法的类型
从一维数组角度来看二维数组:
元素类型 数组名[元素个数];
3.2 二维数组的引用
一维数组:
数组名[下标]
#include <stdio.h>
int main()
{
int a[3][4]; // int[4] a[3]
//a[0] _ _ X _ a[0] 是一个数组名, 里面含有4个int类型的元素
//a[1] _ _ _ _ a[1] 是一个数组名, 里面含有4个int类型的元素
//a[2] _ _ _ _ a[2] 是一个数组名, 里面含有4个int类型的元素
int x;
x = a[0][2]; //a[0][2] 代表元素值 rvalue
a[0][2] = x; //a[0][2] 代表元素的地址 lvalue
return 0;
}
二维数组
数组名[行标][列标]
int b[4][5];
行标: [0, 3]
列标: [0, 5]
_ _ _ _ _
_ _ _ _ _
_ _ X _ _
_ _ _ _ Y
X => b[2][2]
Y => b[3][4]
3.3 二维数组的存放
#include <stdio.h>
int main()
{
int a[3][4]; //=> int[4] a[3]
//a[0]: _ _ X Y
//a[1]: Z _ _ _
//a[2]: _ _ _ _
return 0;
}
开辟了一个连续的存储空间,逐个按行存放
从低地址到高地址,逐个按行存放,先顺序存放第一行的元素,
然后存放第二行元素, … ,
X和Y的地址是相邻的,大4字节
Z和Y的地址是相邻
3.4 二维数组的初始化
在定义二维数组时, 可以指定每个元素或者部分元素的初始值
二维数组的初始化 => { }
- 分行给二维数组赋初始值
int a[3][4] = {
{1, 2, 3, 4}, // a[0] 也是一个数组
{5, 6, 7, 8},
{9, 10, 11, 12}
};
- 将所有元素写在一个{ }内, 按数组的顺序一一对各个元素进行初始化
int a[3][4] = {1, 2, 3, 4, 5, 6, 7, ,8 ,9 ,10, 11, 12};
=>
a[0][0] = 1
a[0][1] = 2
...
a[1][0] = 5
...
a[2][0] = 9
...
a[3][0] = 12
- 对部分元素赋初始值, 其余的元素会自动初始化为0
int a[3][4] = {1, 2};
=>
a[0][0] = 1
a[0][1] = 2
a[0][2] = 0
...
a[1][0] = 0
...
a[2][0] = 0
...
a[3][4] = 0
int a[3][4] = {0};
int a[3][4] = {
{1, 2},
{5},
{9, 10, 11}
};
<=>
int a[3][4] = {
{1, 2, 0, 0},
{5, 0, 0, 0},
{9, 10, 11, 0}
};
- 如果对全部元素都赋初始值,则定义二维数组时对第一维(行号)的长度可以省略,但是二维(列数)不能省略
int a[][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[][4] = {{1, 2 ,3, 4}, {5, 6, 7, 8}, {9, 10, 11, 12}};
只有在定义数组时, 才能对全部的元素赋值
int a[3][4];
a[3][4] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12}; //ERROR
a = {1, 2, 3, 4,5 ,6 7, 8, , 9, 10, 11 ,12}; //ERROR
4. 关于数组的类型
int a[4];
typeof(a) // a是一个数组, 含有4个int类型元素
<=> int[4] 里面含有4个int类型元素的数组类型
float b[10];
typeof(b) // b是一个数组, 含有10个float类型元素
<=> float[10
char a[3][4]; //=> char[4] a[3]
typeof(a) // a是一个 里面含有3个元素, 并且每一个元素含有4个char类型元素 的数组
<=> char[4][3]