数组的定义
在C语言中支持数组这种数据结构,其是存储具有固定长度的相同元素类型的顺序集合.
数组的声明
- 类型说明符 数组名[常量表达式];
//声明一个长度为5存储整型变量的数组a
int a[5];
//声明一个长度为4存储char类型变量的数组b
char b[4];
//声明一个长度为6存储浮点型变量的数组c
float c[6];
//声明一个长度为7存储double类型变量的数组d
double d[7];
数组的初始化
//声明一个长度为5存储整型变量的数组a,并初始化
int a[5] = {1,2,3,4,5};
//声明一个长度为4存储char类型变量的数组b,并初始化
char b[4] = {'a','b','c','c'};
//声明一个长度为4存储浮点型变量的数组c,并初始化
float c[6] = {1.2,1.3,1.4,1.5};
初始化数组,若元素个数小于数组长度,其余元素默认会以0补齐.
数组元素的访问
//声明一个长度为5存储整型变量的数组a,并初始化
int a[5] = {1,2,3,4,5};
//通过数组下标访问指定的数组元素
for (int i = 0; i < 5; i++) {
printf(" a[%d] = %d\n",i,a[i]);
}
通过数组下标访问指定的数组元素,即
一维数组和指针
//声明一个长度为5存储整型变量的数组a,并初始化
int a[5] = {1,2,3,4,5};
NSLog(@" a = %p\n",a);
for (int i = 0; i < 5; i++) {
printf("a[%d] = %d %p \n",i,a[i],&a[i]);
}
Snip20201215_8.png
可以看出数组名本质上是一个指针,是一个内存地址且与数组首元素的地址相同即
NSLog(@" a = %p\n",a);
NSLog(@" a+0 = %p\n",a+0);
NSLog(@" &a[0] = %p\n",&a[0]);
NSLog(@" a+1 = %p\n",a+1);
NSLog(@" &a[0]+1 = %p\n",&a[0]+1);
Snip20201215_10.png
a / a+0 / &a[0] 三者之间等价均表示数组首元素指针;
a+1 / &a[0]+1等价均表示数组第二个元素的指针;
指针可以进行加减法运算,在数组中指针+1表示,访问当前元素后面的一个元素.
int *ptr = (int *)(&a+1);
NSLog(@" *(a+1) = %d,*(ptr-1) = %d",*(a+1),*(ptr-1));
Snip20201215_15.png
,a+1表示数组第二个元素指针,那么(a+1)取数组第二个元素的值即(a+1) = 2;
,&a+1跨越了整个数组即指向当前数组末尾元素的下一个数组的指针;定义了一个指针变量ptr并初始化为&a+1;则ptr-1就表示为当前数组末尾最后一个元素的指针,那么*(ptr-1) = 5
数组指针和指针数组
首先说明一个.
int m = 10;
int n = 20;
int * q[2] = {&m,&n};
q首先与[]结合表明q是一个数组,数组中存放的是int类型的指针,则q是一个指针数组.
int k[2] = {1,2};
int (*p)[2] = &k;
(*p)表明p是一个指针变量,然后再与[]结合表明p是一个指向数组的指针变量.
二维数组的声明与初始化
- 类型说明符 数组名[行数][列数];
//二维数组的声明与初始化
int a[2][4] = {1,2,3,4,5,6,7,8};
二维数组元素的访问
int a[2][4] = {1,2,3,4,5,6,7,8};
for (int i = 0; i < 2; i++) {
for (int j = 0; j < 4; j++) {
NSLog(@"a[%d][%d] = %d\n",i,j,a[i][j]);
}
}
通过嵌套循环与数组下标依次访问数组中的元素.
二维数组与指针
int a[2][4] = {1,2,3,4,5,6,7,8};
for (int i = 0; i < 2; i++) {
for (int j = 0; j < 4; j++) {
NSLog(@" a[%d][%d] = %d -- %p\n",i,j,a[i][j],&a[i][j]);
}
}
NSLog(@" a = %p ",a);
NSLog(@" a+1 = %p ",a+1);
NSLog(@" &a = %p ",&a);
NSLog(@" &a+1 = %p ",&a+1);
NSLog(@" a[0] = %p",a[0]);
NSLog(@" a[0]+1 = %p ",a[0]+1);
NSLog(@" &a[0] = %p ",&a[0]);
NSLog(@" &a[0]+1 = %p ",&a[0]+1);
Snip20201216_19.png
- 首先a是二维数组的数组名,其包含两个行元素分别为a[0]与a[1],每个行元素可以看成是含有4个元素的一维数组,在C语言中规定a[0],a[1]分别是这两个一维数组的数组名.
- 因为在一维数组中,其数组名就是数组首元素的地址,那么a[0]与a[1]就分别为a[0][0]和a[1][0]元素的地址,即a[0]等价于&a[0][0];
- 因为a[0]是指针,所以支持加法运算则a[0]+1,就表示a[0]数组中第二个元素的地址也就是a[0][1]元素的地址,即a[0]+1等价于&a[0][1];
- 在二维数组中,其数组元素是为多个一维数组;先前我们知道在一维数组中,数组名是数组首元素的地址;以此类推二维数组的数组名是其数组首元素的地址,即一维数组a[0]的地址,即a等价于&a[0];
- 因为a=&a[0],那么a+1表示二维数组a中的第二个元素的地址为&a[1];
- &a表示整个二维数组的地址;&a+1就表示下一个二维数组的地址,其内存地址的跨度为整个二维数组的内存空间长度;
- 因为a[0]是一维数组的数组名,则&a[0]就表示为a[0]整个数组的地址,&a[0]+1就表示为下一个一维数组的地址,其内存地址的跨度为整个一维数组的内存空间长度;
网友评论