C语言基础---数组
C语言基础---数组
一、一维数组
1>一维数组的定义:
类型名 数组名[元素个数];
例 int a[3];
C语言数组定义的写法和java中的写法有所区别,C语言中[]只能放在数组名后面
int[3] a; //错误写法
注: 定义数组时,[]里面数组元素的个数不可以使用变量或者变量表达式,必须是个固定数值,可以是常量或者常量表达式,且不能省略
例:
int a[]; //错误,不能省略元素个数(没有写元素个数,系统怎么知道分配多少内存空间给这个数组呢?)
int b=3;
int a[b]; //错误,[]内的元素个数不能用变量或者变量表达式
int a[3]; //正确,[]内的元素个数可以是常量(整型常量)
int a['a']; //正确,[]内的元素个数可以是常量(字符常量) 等价于int a[97];
int a[3+3]; //正确,[]内的元素个数可以是常量(常量表达式)
2>一维数组在内存中的存储形式
定义一个一维数组变量的时候,系统就会(根据数组元素类型和元素个数)分配一段连续的内存空间给它。数组所占内存空间大小为:元素类型所占字节数*元素个数。因为数组的特性是:只能存放相同数据类型的元素。
例:
char c[5];
系统会分配5个字节连续的存储空间(一个字符占一个字节的存储空间),在内存中表示如下(代码打印真实内存地址,然后用表格展示存储细节):
注: 数组名表示数组的地址,也表示数组的起始地址,即首元素地址
怎么理解上面这句话的意思呢?看如下代码:
int main()
{
int a[3];
printf("数组名 = %0x\n , a");
printf("数组的地址 = %0x\n , &a");
printf("数组的起始地址 = %0x\n , &a[0]");
return 0;
}
程序结果为:
因此 a==&a==&a[0]
3>一维数组的初始化
类型名 数组名[元素个数]={元素1, 元素2,...};
int a[3]={1, 2, 3}; //定义数组的同时进行初始化
等价于
int a[3]; //先定义再初始化
a[0]=1;
a[1]=2;
a[2]=3;
定义的同时初始化时,当实际元素个数少于[]内的数值时,后面未初始化的元素值默认为0
例: int a[5]={1, 2, 3}; 等价于 int a[5]={1, 2, 3, 0, 0};
定义数组的同时进行全部元素的初始化赋值时,可以省略元素个数
int a[]={1, 2, 3}; //正确写法,此时元素个数为3,系统也知道该分配多少字节给该数组了
注:如果数组定义与初始化分开,那么初始化的时候只能一个元素一个元素的进行赋值。
例:
int a[3]; //定义数组,并未进行初始化
a[3]={1, 2, 3}; //错误,因为a[3]表示数组a的第4个元素,表示的是一个元素,应该赋值一个int型的整数,而且数组a只有3个元素,数组下标越界
a={1, 2, 3}; //错误,数组名a表示的数组的地址,是个常量,怎么可以赋值呢
4>一维数组作为函数实参
1.一维数组元素作为函数实参(值传递,数组本身内容不会发生改变)
普通的数值传递,形参的改变不影响实参
2.一维数组名作为函数实参(地址传递,数组本身内容会发生改变)
二、二维数组
1>二维数组的定义:
类型名 数组名[行数][列数];
int a[2][3]; //2行3列,2*3=6个元素
其实,二维数组没什么大不了,说白了,就是把多个一维数组当做一个整体,即数组的数组。
二维数组也是数组,可以看做是一种特殊的一维数组,只是这个特殊的一维数组的每一个元素也是一个一维数组。
由上面这句话,和已有的知识,可以推导出二维数组定义与初始化可以是:
int a[2][3]={ {1 ,2 ,3 },{4 ,5 ,6 } };
画个内存图直观一点展示如下:
2>二维数组的初始化
1. int a[2][3]={ {1 ,2 ,3 },{4 ,5 ,6 } }; //定义二维数组的同时进行初始化
2. int a[2][3]={1, 2, 3, 4, 5, 6}; //等价于 int a[2][3]={ {1 ,2 ,3 },{4 ,5 ,6 } };
3. int a[2][3]={{1},{2, 3}}; //等价于 int a[2][3]={{1, 0, 0},{2, 3, 0}};
int a[3][3]={{ },{ , ,1},{ , 2, 3}}; //等价于 int a[3][3]={{0, 0 ,0 },{ 0, 0,1},{ 1, 2, 3}};
4. int[][3]={ 1 ,2 ,3, 4 ,5 ,6 }; //等价于 int a[2][3]={ {1 ,2 ,3 },{4 ,5 ,6 } };
int[][3]={ {1 ,2 ,3}, {4 ,5} ,{6} }; //等价于 int a[3][3]={ {1 ,2 ,3 },{4 ,5 ,0 },{6, 0, 0} };
5. int[2][]={1, 2, 3, 4, 5, 6}; //错误写法,因为有很多种可能。比如:{{1}, {2, 3, 4, 5, 6}}; {{1, 2}, {3, 4, 5, 6}}; {{1, 2, 3}, {4, 5, 6}};
注:定义并初始化二维数组的时候,可以省略行数,不能省略列数。试想一下:当省略行数,列数明确的时候,初始化的时候,把每行的列数填充满,不够就另起一行,补0就可以; 但是如果只有行数,没有列数,那么就有多种可能,根本不能确定。 因此,列数一定不能省略