数组
数组
part1
一维数组的定义与初始化
1.定义
当数组中每个元素只带有一个下标时,称这样的数组为一维数组。在C语言中,定义一维数组的语句一般形式如下:
类型名 数组名[整型常量表达式], ....;
2.初始化
当系统为所定义的数组在内存中开辟一串连续的存储单元时,这些存储单元中并没有确定的值。可以采用以下形式,在定义语句中为所定义数组的各元素赋初值
int a[8] = {0, 1, 2, 3, 4, 5, 6, 7};
3.可以通过赋初值来定义数组的大小
这时数组说明符的一对方括号中可以不指定数组的大小
int a[] = {0, 0, 0, 0, 1, 1, 1, 1}
它隐含地定义了a数组中含有8个元素
part2
一维数组元素的引用
引用形式如下:
数组名[下标表达式]
1.一个数组元素实质上就是一个变量名,占用内存中的一个存储单元
2.c语言中,一个数组不能整体引用。比如,数组x,不能用x代表数组中的所有元素。数组名代表是一个地址常量,它代表数组的首地址
3.数组元素的下标表达式的值必须是整数,下限为0
part3
一维数组和指针
C语言中,数组名可以认为是一个存放地址值的指针变量名,其中的地址值是数组第一个元素的地址,也就是数组所占一串连续存储单元的起始地址,定义数组时的类型即是此指针变量的基类型
注意,这个指针变量中的地址值不可改变,也就是说,不可以给数组名重新赋值,因此,也可以认为数组名是一个地址常量
1.通过数组首地址引用数组元素
可以通过“间接访问运算符*”来引用地址所在的存储单元,因此对于数组元素a[0],可以用表达式*&a[0]来引用,也可以用*(a + 0)来引用,对此也可写成:*a
2.通过指针引用一维数组元素
p=a;或p=&a[0];后,p指向了a数组的首地址,因此,也可以使用“间接访问运算符”,通过指针变量p来引用a数组中的元素。对于数组元素[0],可以用表达式*(p+0),即*p来引用
3.用带下标的指针变量引用一维数组元素
当p指向s数组的首地址时,表示数组元素s[k]的表达式应当有s[k]、*(s+k)、*(p+k)、p[k]
part4
函数对一维数组和元素的引用
数组名也可以作为实参传送,但数组名本身是一个地址值,因此,对应的形参就应当是一个指针变量
当数组名作为实参时,对应的函数首部为以下3种形式
1.fun(int *a)
2.fun(int a[])
3.fun(int a[M])
part5
二维数组的定义和初始化
1.二维数组的定义
当数组中每个元素带有两个下标时,称这样的数组为二维数组
类型名 数组名[常量表达式1][常量表达式2]
2.二维数组的初始化
2.1 所赋初值个数与数组元素的个数相同,可以在定义二维数组的同时给二维数组的各元素赋初值
2.2 每行所赋初值个数与数组元素的个数不同,系统给该行后面的元素补初值0
2.3 所赋初值行数少于数组行数,系统自动给后面各行补0
2.4 赋初值时省略花括号对
int c[][3] = {1, 2, 3, 4, 5};
第一维的大小按以下规则决定
当初值的个数能被和第二维的常量表达式的值除尽时,所得商数就是第一维的大小
当初值的个数不能被第二维的常量表达式的值除尽时,则:第一维的大小=所得的商数+1
part6
二维数组和数组元素的地址
1.二维数组由若干个一维数组组成
a[0]、a[1]、a[2]都是一维数组名,同样也代表一个不可变的地址变量。其值依次为二维数组每行第一个元素的地址,其基类型就是数组元素的类型。因此对于二维数组,a[0]++这样的表达式是非法的。若有表达式a[0] + 1,表达式中1的单位应当是2个字节。
在以上的定义中,指针变量p的基类型与a[i]相同,因此赋值语句p=a[i];是合法的。
因为a[i]也可写成*(a+i),故:p=*(a+i);合法
2.二维数组名也是一个地址常量
二维数组名也是一个存放地址常量的指针,其值为二维数组中第一个元素的地址
数组名a的仩与a[0]的值相同,只是其基类型为具有4个整型元素的数组类型。即a+0的值与a[0]的值相同,a+1的值与a[1]相同。它们分别表示a数组中第一、第二行的首地址。二维数组名应理解为一个行指针。在表达式a+1中,数值1的单位应当是4x2个字节,而不是2个字节。赋值语句p = a是不合法的,因为p和a 的基类型不同。同样,对于二维数组名a,也不可以进行a++,a=a+i等运算
3.二维数组元素的地址
二维数组元素的地址可以由表达式&a[i][j]求得
其他方法有a[i]+j、*(a+i)+j、&a[0][0]+4*i+j、a[0]+4*i+j
part7
通过地址引用二维数组元素
part8
建立指针数组引用二维数组元素
若有以下定义
int *p[3],a[3][2],i,j;
在这里,说明符*p[3]中,也遵照运算符的优先级,一对[]的优先级高于*号,因此p首先与[]结合,构成p[3],说明了p是一个数组名,系统将为它开辟3个连续的存储单元;在它前面的*号则说明了数组p是指针类型,它的每个元素都是基类型为int的指针
0<=i<3,则p[i]和a[i]的基类型相同p[i]=a[i]是从合法的赋值表达式。若有以下循环
for(i=0;i<3;i++) p[i]=a[i]
建立行指针引用二维数组元素
若有以下定义
int a[3][2],(*p)[2];
在说明符(*p)[2]中,由于一对圆括号的存在,所以*号首先与p结合,说明p是一个指针变量,然后再与说明符[2]结合,说明指针变量p的基类型是一个包含有两个int元素的数组。在这里,p的基类型与a的相同,因此p=a;是合法的赋值语句。p+1等价于a+1,等价于a[1]。当p指向a数组开关时,可以通过以下形式来引用a[i][j]
1.*(p[i]+j)
2.*(*(p+i) + j)
3.(*(p+i))[j]
4.p[i][j]
在这里,p是一个指针变量,它的值可变,而a是一个常量