C语言——数组指针篇

说明
  本文章旨在总结备份、方便以后查询,由于是个人总结,如有不对,欢迎指正;另外,内容大部分来自网络、书籍、和各类手册,如若侵权请告知,马上删帖致歉。
  QQ 群 号:513683159 【相互学习】
来源
  C语言中文网、《C语言核心技术》、《C和指针》

文章目录

    • 概念
      • 数组
      • 数组指针(Array Pointer)
      • 两种方案访问数组元素:
      • 关于数组指针的谜题

概念

了解数组指针之前,先来复习一下数组的概念。

数组

  已经定义一个变量,就会在内存中分配对应数据类型大小的空间,若需要存储两个那么就需要定义两个变量,若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
。。。略

数组指针(Array Pointer)

  数组指针:一个指针指向了数组。
  数组指针指向的是:数组中的一个具体元素,而不是整个数组,所以数组指针的类型和数组元素的类型有关

   * (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。

你可能感兴趣的:(#,C语言,c语言)