数组是最基本的构造类型,它是一组相同类型数据的有序集合。数组中的元素在内存中连续存放,每个元素都属于同一数据类型,用数组名和下标可以唯一确定数组元素。
数组创建
一维数组创建
int a[10];
char a[10];
double a[5];
二维数组创建
int a[3][4];
char a[3][4];
double a[2][4];
数组的定义与引用
定义一维数组的一般形式为:类型名 数组名[常量表达式];类型名指定数组中每个元素的类型;数组名是一个地址常量,存放数组内存空间的首地址;数组长度是一个常量,设定数组的大小。例如:
int a[10]; //定义一个有10个整形元素的数组a
char c[200]; //定义一个有200个字符型元素的数组c
float f[5]; //定义一个有5个单精度浮点型元素的数组f
数组的引用
对于一维数组的引用,只能逐个引用数组元素的值而不能一次引用整个数组中的全部元素的值。数组元素的表达形式为:数组名[下标],下标可以是整型常量或者整形表达式。例如:
int k, a[10];
k = 3;
a[0] = 23;
a[k - 2] = a[0] + 1;
对于二维数组的定义,一般形式为:数组名[下标][下标]
int a[3][4]; //定义3行4列的二维数组,共12个元素
引用二维数组的元素要指定两个下标,即行下标与列下标,形式为:数组名[行下标][列下标],行下标的合理取值范围是[0,行长度-1],列下标的合理取值范围是[0,列长度-1]。对前面定义的数组a,其元素分别为:a[0][0],a[0][1],a[0][2],a[0][3],a[1][0],a[1][1],a[1][2],a[1][3],a[2][0],a[2][1],a[2][2],a[2][3],表示3行4列的矩阵。
二维数组的元素在内存内按行/列方式存放,即先存放第0行的元素,再存放第1行的元素.....其中每一行的元素再按照列的顺序存放。
数组的存储
在定义数组之后,系统根据数组元素的类型及个数在内存中分配了一段连续的存储单元用于存放数组中的各个元素,并对这些单元进行连续编号,即下标,以区分不同的单元。每个单元所需的字节数由数组定义时给定的类型确定。数组名表示该数组所分配连续内存空间中第一个单元的地址,即首地址。由于数组空间一经分配后在运行过程中不会改变,因此数组名是一个地址常量,不允许修改。
一维数组的存储
#include<stdio.h>
#include<stdlib.h>
int main()
{
int a[10] = { 0 };
int i = 0;
for (i = 0; i < sizeof(a) / sizeof(a[0]); ++i)
{
printf("&a[%d]=%p\n", i, &a[i]);
}
system("pause");
return 0;
}
输出结果为:&a[0]=0079FB74
&a[1]=0079FB78
&a[2]=0079FB7C
&a[3]=0079FB80
&a[4]=0079FB84
&a[5]=0079FB88
&a[6]=0079FB8C
&a[7]=0079FB90
&a[8]=0079FB94
&a[9]=0079FB98
可看出:随着数组下标的增长,元素的地址,也在有规律的递增。即数组在内存中是连续存放的。
二维数组的存储
#include<stdio.h>
#include<stdlib.h>
int main()
{
int a[3][4];
int i = 0,j=0;
for (i = 0; i < 3; i++)
{
for (j = 0; j < 4; j++)
{
printf("&a[%d][%d]=%p\n", i,j, &a[i][j]);
}
}
system("pause");
return 0;
}
输出结果为
&a[0][0]=003EF7F4
&a[0][1]=003EF7F8
&a[0][2]=003EF7FC
&a[0][3]=003EF800
&a[1][0]=003EF804
&a[1][1]=003EF808
&a[1][2]=003EF80C
&a[1][3]=003EF810
&a[2][0]=003EF814
&a[2][1]=003EF818
&a[2][2]=003EF81C
&a[2][3]=003EF820
可看出二维数组也是连续存储。
数组的初始化
一维数组初始化,有以下方法实现。
(1)在定义数组时对全部数组元素赋予初值。如:
int a[10] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
经过定义与初始化后,
a[0]=1,a[1]=2,a[2]=3,a[3]=4,a[4]=5,a[5]=6,a[6]=7,a[7]=8,a[8]=9,a[9]=10
(2)可以只给一部分元素赋值。如:
int a[10]={1,2,3,4,5}
定义a数组10个元素,只给前面5个元素赋初值,后5个元素默认为0.
(3)在对全部元素赋初值时,可以不指定数组长度。如:
int a[10] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
可以写成
int a[ ] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
二维数组初始化,有以下方法实现。
(1)按行给二维数组全部元素赋初值。如:
int a[2][3]={{1,2,3},{4,5,6}};
第一个花括号的数据为第一行的元素,第二个花括号的数据为第二行的元素......即按行赋初值。
(2)将所有数据写在一个花括号内,按数组排列的顺序对全部元素赋初值。如:
int a[2][3]={1,2,3,4,5,6},与前一种方法相同。
(3)对部分元素赋初值。如:
int a[2][3]={{1},{3}};
只对各行第一列元素赋初值,其余元素值为0。赋初值后数组各元素为
1 0 0
3 0 0
也可只对某几行赋初值:
int a[3][4]={{1},{2.3}};
数组元素为
1 0 0 0
2 3 0 0
0 0 0 0
(4)提供全部初始数据,定义数组时对第1维的长度可以不指定,但2维的长度不能省。如:
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};
数组的指针访问
如果一个数组,其元素均为指针类型数据,该数组称为指针数组。也就是说指针数组中的每一个元素相当于一个指针变量,它的值都是地址。
一维数组的指针访问
一维指针数组的定义形式为:类型名*数组名[数组长度];例如:
#include<stdio.h>
#include<stdlib.h>
int main()
{
int a[10] = {0};
int i = 0;
int *p = a;
for (i = 0; i < sizeof(a) / sizeof(a[0]); ++i)
{
*(p + i) = i;
}
for (i = 0; i < sizeof(a) / sizeof(a[0]); ++i)
{
printf("%d\n", *(p + i));
}
system("pause");
return 0;
}
通过对数组名+整数的运算,可以获得数组每个元素的地址。
二维数组的指针访问
#include<stdio.h>
#include<stdlib.h>
int main()
{
int a[2][3] = {0};
int *p = &a[0][0];
int i, j;
for (i = 0; i < 2 * 3; i++)
{
p[i] = i;
}
for (i = 0; i < 2; i++)
{
for (j = 0; j < 3; j++)
{
printf("%d", a[i][j]);
}
}
system("pause");
return 0;
}