计算机科学类专升本复习之“C语言数组指针”详解(初稿)

C语言数组指针(指向数组的指针)详解

数组(Array)是一系列具有相同类型的数据的集合,每一份数据叫做一个数组元素。数组中的所有元素在内存中是连续排列的,整个数组占用的是一块内存。

定义数组时,要给出 "数组名"和"数组长度", 数组名可以认识是一个"指针",它指向数组的第0个元素。

在C语言中我们将数组的"第0个元素"的地址 称为"数组的首地址"。

//下面的例子演示了如何以指针的方式遍历数组元素:

#include<stdio.h>

int main()

{

    int kangkang[] = {99,88,66,55,44,33,222};

    int len = sizeof(kangkang)/sizeof(int); //求数组的长度

    int i;

    for(i=0;i<len;i++)

    {

        printf("%d",*(kangkang+i)); // *(kangkang+i) 等价于kangkang[i]

    }

    printf("\n");

    return 0;

}

结果:

99 88 66 55 44 33 222

解析:

1. 本程序的第5行代码用来求 数组长度,sizeof(kangkang)会获取"整个数组所占的字节数",

sizeof(int)会获取到"一个数组元素所占的字节数",它们相除的结果就是"数组包含的元素个数"即数组长度。

2. 本程序的第8行代码中 我们使用了 *(kangkang+i)这个表达式,kangkang是数组名,指向数组的第0个元素。

它表示"数组首地址", kangkang+i指向数组的第i个元素, *(kangkang+i) 表示获取第i个元素的数据,等价于kangkang[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 个元素,或者说指向数组的开头。


 

如果一个指针指向了数组,我们就称它为"数组指针"


 

数组指针指向的是数组中的一个具体元素,而不是整个数组,所以数组指针的类型和数组元素的类型有关,上面的例子中,p 指向的数组元素是 int 类型,所以 p 的类型必须也是int *。

反过来想,p 并不知道它指向的是一个数组,p 只知道它指向的是一个整数,究竟如何使用 p 取决于程序员的编码。

更改上面的代码,使用数组指针来遍历数组元素:

#include<stdio.h>

int main()

{

    int kangkang[] = {99,88,66,55,44,33,222};

    int i ,*p = kangkang,len = sizeof(kangkang)/sizeof(int);

    for(i=0;i<len;i++)

    {

        printf("%d",*(p+i));

    }

    printf("\n");

    return 0;

}


 

"数组"在内存中 只是 数组元素的简单排序,没用开始和技术标志,在求数组的"长度"时不能使用sizeof(p)/sizeof(int),因为p只是一个指向int类型的指针。

编译器并不知道它到底指向的是"一个整数"还是"一系列整数(数组)",所以 sizeof(p) 求出来的是 p这个指针变量"本身所占用的字节数",而不是整个数组的字节数。

也就是说,根据数组指针"不能逆推出"整个数组元素的个数,以及数组从哪里开始、到哪里结束等信息。不像字符串,数组本身也没有特定的结束标志,如果不知道数组的长度,那么就无法遍历整个数组。



 

引入数组指针后,我们就有两种方案来访问数组元素了,一种是使用下标,另外一种是使用指针。

1. 使用下标

也就是采用 arr[i] 的形式访问数组元素。如果 p 是指向数组 arr 的指针,那么也可以使用 p[i] 来访问数组元素,它等价于 arr[i]。

2. 使用指针

也就是使用 *(p+i) 的形式访问数组元素。另外数组名本身也是指针,也可以使用 *(arr+i) 来访问数组元素,它等价于 *(p+i)。


 

不管是数组名还是数组指针,都可以使用上面的两种方式来访问数组元素。

不同的是,数组名是常量,它的值不能改变,而数组指针是变量(除非特别指明它是常量),它的值可以任意改变。

也就是说,数组名只能指向数组的开头,而数组指针可以先指向数组开头,再指向其他元素。

更改上面的代码,借助自增运算符来遍历数组元素:

#include <stdio.h>

int main(){

    int arr[] = { 99, 15, 100, 888, 252 };

    int i, *p = arr, len = sizeof(arr) / sizeof(int);

    for(i=0; i<len; i++){

        printf("%d  ", *p++ );

    }

    printf("\n");

    return 0;

}

结果:

99  15  100  888  252

本程序第 8 行代码中,*p++ 应该理解为 *(p++),每次循环都会改变 p 的值(p++ 使得 p 自身的值增加),以使 p 指向下一个数组元素。

该语句不能写为 *arr++,因为 arr 是常量,而 arr++ 会改变它的值,这显然是错误的。


 

//关于数组指针的谜题:

假设p是针向数组kangkang中第n个元素的指针, 那么 *p++、*++p、(*p)++ 分别是什么意思?

1. *p++等价于*(p++),表示"先取得第n个元素的值"再将p指向下一个元素。

2. *++p等价于*(++p),表示"先进行++p的运算,使得p的值增加",指向下一个元素,整体上相当于*(p+1),所以会获得第n+1个数组元素。

3. (*p)++就非差简单了,它"先取得第n个元素的值",再对该元素的值+1,假设p指向第0个元素,并且第0个元素的值为99,执行完该语句后,第0个的值就变成100.


 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值