0. 一个问题
int a,b; 如果我们要定义100个整型变量呢? int a0,a1,a2,a3,...,a99;
很显然上面的这种定义多个变量的方法,不科学, 不人道.
有没有办法可以一次定义一组相同类型的变量呢?
数组
1 什么是数组?
数组是一组具有相同数据类型的有序集合.
"有很多个数据" "相同的数据类型" "有序集合"
在C语言中数组有 :
一维数组
二维数组
三维数组
四维数组
.....
但是 , 有人(游铭)说 : "C语言中只有一维数组"
2 一维数组
2.1 一维数组定义格式
元素的类型 数组名[元素个数] {= {初始值列表}};
"元素类型" :
指定数组中元素的类型, 而不是数组的类型!!!
可以是C语言中, 任意合法的类型(基本类型,构造类型,指针类型)
"数组名" :
一个数组的名字 , "标识符"
"元素个数"
整型表达式(一般为常量),指定数组中元素的个数.
C语言中规定定义数组时,需要指定(隐含指定 : 可以由编译器推断出)数组元素的个数.
为什么要指定个数呢? 定义数组时, 就需要分配空间给数组.
例子 :
int a[10];//定义了一个数组, 名为a ,里面有10个int类型的元素 //a 是一个有 10个int类型元素的 数组 typeof(a) : int[10] int a[4] = {1,2,3,4}; //定义了一个数组,名为a,里面有4个int类型的元素. //而且这4个元素的初始值分别为 : 1,2,3,4 typeof(a) : int[4] int a[100];
2.2 数组元素的引用
语法 :
数组名[下标];
在C语言中数组的==下标是从 0 开始== , 0 ,1,2,3,4,5,...,n-1
例子 :
int a[10];//这里面有10个int类型的元素 分别是 : a[0] a[1] a[2] ... a[9] //a[10] 特别强调 没有a[10] 这个元素,数组越界. typeof(a[0]) : int typeof(a[1]) : int typeof(a[2]) : int ... typeof(a[9]) : int a[0] a[1] a[2] ... a[9] 就是一个普通的int类型的变量!!!
int a[10]; int b; 引用数组元素 和 引用普通变量是一样的,数组元素也有左值,也有右值. a[0] = 100;//a[0] 代表 数组元素a[0] 的地址("a[0]的左值") x = a[0];//a[0] 代表数组元素 a[0] 的值("a[0]的右值")
scanf("%d",&b); scanf("%d",&a[0]); //scanf("%d",&a);//"一次性输入整个数组" ,可以吗? 不可以的, error
2.3 一维数组在内存中存放
在 C 语言中, 用一组地址连续的存储空间, 从低地址到高地址依次存放数组中的每个元素.
先存放a[0] , a[0] 这个元素的后面是 a[1] ,a[1] 后面是a[2] ...
例子 : 假设 int 占 32bits(4bytes)
int a[10]; //运行时,系统会为数组a分配 10*sizeof(int) = 40 bytes a[0] a[1] a[2] a[3] |----------|----------|---------|---------|... 0x3000 0x3004 0x3008 0x300c ... &a[0] == 0x3000 &a[1] == 0x3004 &a[2] == 0x3008 ...
练习 :
循环输出 int a[10]中每个元素的额地址
printf("%p\n",&a[0]);//%p 把后面的那个值,当做一个地址,unsigned, 十六进制输出 for(int i = 0;i < 10;i++) { printf("%p\n",&a[i]); }
2.4 初始化数组
数组的初始化用 { }
初始化 : 是指定义他的时候, 就给他值, 就是初始化.
(1) 给每一个元素初始化
如 :
int a[10] = {1,2,3,4,5,6,7,8,9,10}; //初始化 : 定义数组对象时,就给他值 int b[10]; b = {1,2,3,4,5,6,7,8,9,10};//error //定义完数组,后面就只能给元素一个一个赋值,就不能对数组整体赋值啦. b[0] = 1; b[1] = 2; ...
(2) 可以只对部分元素初始化,后面的元素自动初始化为 0
如 :
int a[5] = {1,2};//只初始化了前面两个元素 ==> a[0] = 1; a[1] = 2; a[2] = 0; a[3] = 0; a[4] = 0;
(3) 如果对全部元素都赋初值,在定义数组时,可以不指定"元素个数"
why? 因为编译器这个时候, 很聪明, 他可以推断出你数组的元素个数.
int a[] = {1,2,3,4,5,6,7,8,9,10}; //编译器推断 数组a中有 10个元素
练习 :
(1) 定义一个一维数组,并通过键盘一一对每个元素进行赋值,并且输出.
int a[10];
scanf("%d",&a[0]);
scanf("%d",&a[1]);
scanf("%d",&a[2]);
...
==>
int i;
for(i = 0;i < 10;i++)
{
scanf("%d",&a[i]);
}
for(i = 0;i < 10;i++)
{
printf("a[%d] = %d\n",i,a[i]);
}
(2) 遍历数组 : 访问数组中的每一个元素一次仅一次.
求一个int类型数组中的最大值,最小值,以及所有元素的和.
int a[10]; int max;//保存数组a中的最大值 int min;//保存数组a中的最小值 int sum; max = a[0];//假设 a[0]最大 int i; if a[1] > max max = a[1] if a[2] > max max = a[2] if a[3] > max max = a[3] if a[4] > max max = a[4] .... printf("max = %d\n",max); ==> if(a[i] > max) { max = a[i]; } i++; for() { if(a[i] > max) { max = a[i]; } i++; }
#include <stdio.h> int main() { int a[10]; int max;//保存数组a中的最大值 int min;//保存数组a中的最小值 int sum;//保存数组的和 int i; //从键盘上输入数组元素的值 for(i = 0;i < 10;i++) { scanf("%d",&a[i]); } max = a[0];//假设a[0] 最大 for(i = 1;i < 10;i++) { if( a[i] > max ) { max = a[i]; } } min = a[0];//假设a[0] 最小值 for(i = 1;i < 10;i++) { if(a[i] < min) { min = a[i]; } } sum = 0; for(i = 0;i < 10;i++) { sum = sum + a[i]; } printf("max = %d\n",max); printf("min = %d\n",min); pintf("sum = %d\n",sum); return 0; }
3 二维数组
0 回顾下一维数组
定义格式 :
元素的类型 数组名[元素个数];
int a[4];//定义了一个数组 ,名为a,里面含有4个int类型的元素 //a是一个含有4个int类型元素的数组 //上面的这条语句,不仅定义了一个数组a,同时还声明了一个新的类型 //"像 a 这样的类型" //typeof(a) : int[4] 定义一个里面包含 3个a这样的类型的数组,该如何定义呢? typeof(a) b[3]; ==> int[4] b[3] ==> int b[3][4];//二维数组
1 二维数组"矩阵"
由上面的推导的过程可以提出 :
C语言中,二维数组实际就是一个一维数组,只不过这个一维数组中的每一个元素又是一个数组.
int b[3][4];//int[4] b[3]; 数组b中,含有3个元素 b[0] -> b[0] 里面又包含4 int b[1] -> b[1] 里面又包含4 int b[2] -> b[2] 里面又包含4 int "矩阵" : 把b看做一个 3行4列 的矩阵
2 二位数组的定义
类型说明符 数组名[行数][列数];//从"矩阵"角度来看二维数组
"类型说明符" : 二维数组中元素的类型, C语言中任意合法的类型都可以
"行数" "列数" : 常量 或者 常量表达式
例子 :
int a[3][4];//里面有 3*4 int int[4] a[3]
(3) 二维数组元素的引用
数组元素的引用 : 数组名[下标] int a[3][4];//int[4] a[3] a[0] ___ ___ ___ ___ //这一行,又是一个数组,数组名为a[0] a[1] ___ _x_ ___ ___ //这一行,又是一个数组,数组名为a[1] a[2] ___ ___ ___ ___ //这一行,又是一个数组,数组名为a[2] 引用元素x , x是数组a[1] 中的第1个元素,数组名[1] ==> a[1][1] 并且引用二维数组中元素和引用普通变量是一样的,也有左值,也有右值. a[1][1] = 150;//a[1][1]是左值,a[1][1]的地址 int b = a[1][1];//a[1][1] 是右值,a[1][1]的值
(4)二维数组的存放
按行存放,即先顺序存放第一行元素,然后再存放第二行的元素,.....
why? ??
因为二维数组就是一维数组
int a[3][4];//int[4] a[3] a[0] a[1] a[2] |---------------|--------------|------------| a[0][0]-a[0][3] a[1][0]-a[1][3] a[2][0]-a[2][3]
#include <stdio.h> int main() { int a[3][4]; printf("a[0][3] = %p\n",&a[0][3]); printf("a[1][0] = %p\n",&a[1][0]); return 0; }
(5) 二维数组的初始化
二位数组的初始化是指 定义二位数组时,就赋初值.
数组的初始化 用 {}
可以指定每个元素的值,也可以只指定部分元素的值.
<1> 分行给二维数组赋初始值
int a[3][4] = { {1,2,3,4},//a[0] {5,6,7,8},//a[1] {9,10,11,12}//a[2] };
<2> 将所有的元素写在一个{}内,按数组元素的顺序一次对各元素初始化.
int a[3][4] = {1,2,3,4,5,6,7,8,9,10,11,12};
<3> 对部分元素赋初始值,其余元素自动置 0
int a[3][4] = { {1,2},//a[0] ==> {1,2,0,0} {3}, //a[1] ==> {3,0,0,0} {5} //a[2] ==> {5,0,0,0} };
<4> 如果对全部元素都赋初值,定义时元素个数可以省略(第一维),第二维不能省略.
int a[][4] = {1,2,3,4,5,6,7,8,9,10,11,12};
练习 :
1.定义一个二维数组,从键盘上按行输入每一个元素的值,再输出.
int a[3][4];
//i表示行数
for(i = 0; i < 3;i++)
{
//j表示列数
for(j = 0 ; j < 4 ;j++)
{
scanf("%d",&a[i][j]);
}
}
//再按行打印每一个元素,每行后面输出一个 \n
for(i = 0; i < 3;i++)
{
//j表示列数
for(j = 0 ; j < 4 ;j++)
{
printf("%d ",a[i][j]);
}
printf("\n");
}
【文章原创作者:站群服务器 http://www.558idc.com/mggfzq.html 欢迎留下您的宝贵建议】