说明:
本文章旨在总结备份、方便以后查询,由于是个人总结,如有不对,欢迎指正;另外,内容大部分来自网络、书籍、和各类手册,如若侵权请告知,马上删帖致歉。
QQ 群 号:513683159 【相互学习】
来源:
C语言中文网、《C语言核心技术》、《C和指针》
了解数组指针之前,先来复习一下数组的概念。
已经定义一个变量,就会在内存中分配对应数据类型大小的空间,若需要存储两个那么就需要定义两个变量,若n个需要定义n个变量,每次定义变量都需要取变量名。这就显得很繁琐,于是乎数组就孕育而生了(瞎扯的),简单来说,数组(Array) 就是一组相同数据类型的集合,而里面每个数据都叫做数组元素(Element),数组元素的个数就是数据长度(Length),每个元素都有一个序号(下标(Index)),注意:下标是从0开始的而不是1开始。
一维数组定义形式:
dataType arrayName[index];
dataType:数组类型
arrayName:数组名称
index:下标(从0开始)
注意事项:
①数组中每个元素的数据类型必须相同。
②数组长度最好是整数或常量表达式
③访问数组元素,下标的取值范围:0 <=i ndex < length
④数组内存是连续的(这是和定义多个变量最大的区别),意味着可用指针进行操作。
⑤一维数组初始化方式有多种:
1)部分元素赋值:int a[10]={1,2,3,4,5};
,a[0]~a[4]赋初值,后面5个初始化为0.
2)全部元素赋值:int a[]={1,2,3,4,5};
,可不给数组长度,会自动给值。
3)只可给元素逐个赋值,不可整体赋值。int a[5]={1,1,1,1,1};
不可:int a[5]=1
⑥数组名可认为是一个指针,指向数组的第0个元素。
二维数组定义形式:
dataType arrayName[length1][length2];
dataType:数组类型
arrayName:数组名称
length1:一维下标长度(从0开始,行数)
length2:二维下标长度(从0开始,列数)
注意事项:
①概念上的二维,内存中是连续存放的。
②在C语言中,二维数组是按行排列的,放完一行之后再放入第二行;
③二维数初始化:
1)按行分段赋值:int a[5][3]={ {80,75,92}, {61,65,71}, {59,63,70}, {85,87,90}, {76,77,85} };
2)按行连续赋值:int a[5][3]={80, 75, 92, 61, 65, 71, 59, 63, 70, 85, 87, 90, 76, 77, 85};
3)可以只对部分元素赋值,未赋值的元素自动取“零”值.int a[3][3] = {{1}, {2}, {3}};
,
4)如果对全部元素赋值,那么第一维的长度可以不给出.int a[][3] = {1, 2, 3, 4, 5, 6, 7, 8, 9};
④二维数组可以看作是由一维数组嵌套而成的;如果一个数组的每个元素又是一个数组,那么它就是二维数组。如,二维数组a[3][4]可分解为三个一维数组,它们的数组名分别为 a[0]、a[1]、a[2]。
#include
int main(){
int arr[] = {1,2,3,4,5,6,7,8,9,0}; /定义数组
int len = sizeof(arr)/sizeof(arr[0]); /计算数组长度:sizeof(arr)计算数组全长,sizeof(arr[0])计算一个元素长度
int i;
int *p = arr; /让 p 指向数组中的第二个元素: int *p = &arr[2]; 也可以写作 int *p = arr + 2;
printf("arr adress = %p\n",arr);
/arr 本身就是一个指针,可直接赋值给指针变量 p。
/arr 是数组第 0 个元素的地址,所以int *p = arr;也可以写作int *p = &arr[0];。
/即:arr、p、&arr[0] 这三种写法等价的,都指向数组第 0 个元素或指向数组的开头
for(i = 0; i < len;i++){
printf("arr[%d] = %d\n",i,arr[i]); / *(arr+i)等价于arr[i]等价于*(p+i)
printf("arr[%d] address = %p\n",i,&arr[i]);
}
/可修改为printf("arr[%d] = %d\n", *p++ );*p++ 应该理解为 *(p++),每次循环都会改变 p 的值(p++ 使得 p 自身的值增加),以使 p 指向下一个数组元素。
/该语句不能写为 *arr++,因为 arr 是常量,而 arr++ 会改变它的值,这显然是错误的
return 0;
}
实验结果:
arr adress = 0x7fff1e60c210
arr[0] = 1
arr[0] address = 0x7fff1e60c210
arr[1] = 2
arr[1] address = 0x7fff1e60c214
arr[2] = 3
arr[2] address = 0x7fff1e60c218
。。。略
数组指针:一个指针指向了数组。
数组指针指向的是:数组中的一个具体元素,而不是整个数组,所以数组指针的类型和数组元素的类型有关
* (arr+i)这个表达式,arr 是数组名,指向数组的第 0 个元素,表示数组首地址, arr+i 指向数组的第 i 个元素,*(arr+i) 表示取第 i 个元素的数据,它等价于 arr[i].
int arr[] = { 99, 15, 100, 888, 252 };
int *p = arr;
arr
本身就是一个指针,可以直接赋值给指针变量 p
。
arr
是数组第 0 个元素的地址,所以int *p = arr;
也可以写作int *p = &arr[0];
。
也就是说,arr、p、&arr[0]
这三种写法都是等价的,它们都指向数组第 0 个元素,或者说指向数组的开头
1) 使用下标
也就是采用 arr[i] 的形式访问数组元素。如果 p 是指向数组 arr 的指针,那么也可以使用 p[i] 来访问数组元素,它等价于 arr[i]。
2) 使用指针
也就是使用 *(p+i) 的形式访问数组元素。另外数组名本身也是指针,也可以使用 *(arr+i) 来访问数组元素,它等价于 *(p+i)。
提问:假设 p 是指向数组 arr 中第 n 位元素的指针,那么 p++、++p、(*p)++ 分别是什么意思呢?即:int *p=NULL; int arr[]; p=&arr[n];
回答:
*p++
等价于 *(p++)
,表示先取得第 n 个元素的值,再将 p 指向下一个元素。
*++p
等价于 *(++p)
,会先进行 ++p 运算,使得 p 的值增加,指向下一个元素,整体上相当于 *(p+1),所以会获得第 n+1 个数组元素的值。
(*p)++
就非常简单了,会先取得第 n 个元素的值,再对该元素的值加 1。