通过指针引用数组

1、指针是什么?

  为了说清楚什么是指针,必须先弄清楚数据在内存中是如何存储的,又是如何读取的。

  如果在程序中定义了一个变量,在对程序进行编译时,系统就会给这个变量分配内存单元。编译系统根据程序中定义的变量类型,分配一定长度的空间。例如,Visual C++为整型变量分配4个字节,对单精度浮点型变量分配4个字节。内存区的每一个字节有一个编号,这就是“地址”,它相当于旅馆中的房间号。在地址所标志的内存单元中存放的数据则相当于旅馆房间中居住的旅客。由于通过地址可以找到所需的变量单元,可以说,地址指向该变量单元,也将地址形象化地称为“指针”,意思是通过它能找到以它为地址的内存单元。

  请务必弄清楚存储单元的地址和存储单元的内容这两个概念的区别,假设程序已定义了3个整型变量i,j,k,在程序编译时,系统可能分配地址为2000~2003的4个字节给变量i,2004~2007的4个字节给j,2008~2011的4个字节给k,如下图:


2、定义指针变量

  类型名 * 指针变量名;

  如:int * pointer_1, * pointer_2;

  也可在定义指针变量时,同时对它初始化,int * pointer_1=&a, * pointer_2=&b;

左端的int是在定义指针变量时必须指定的“基类型”。指针变量的基类型用来指定此指针变量可以指向的变量的类型。

 注意:

(1)指针变量前面的“*”表示该变量的类型为指针型变量指针变量名是pointer_1和pointer_2,而不是* pointer_1和* pointer_2。

(2)在定义指针变量时必须指定基类型。因为不同类型的数据在内存中所占的字节数和存放方式是不同的。后边还会讲到指针的移动和指针的运算(加减),例如“使指针移动一个位置”或“使指针值加1”,这个1代表什么呢?如果指针是指向一个整型变量的,那么“使指针移动1个位置”意味着移动4个字节,“使指针加1”意味着使地址值加4个字节。如果指针是指向一个字符变量的,则增加的不是4而是1.

(3)如何表示指针类型。指向整型数据的指针类型表示为“int * ”,读作“指向int的指针”或简称“int指针”,可以有int * ,float * ,char * 等指针类型。

(4)& 取地址运算符。&a是变量a的地址。

   * 指针运算符,* p代表指针变量p指向的对象。

3、通过指针引用数组

所谓数组元素的指针就是数组元素的地址。

引用数组元素可以用下标法(如a[3]),也可以使用指针法,即通过指向数组元素的指针找到所需的元素,使用指针法能使目标程序质量高,(占内存小,运行速度快)。

在C语言中,数组名代表数组中首元素(即序号为0的元素)的地址,因此,下面两个语句等价:

p = &a[0];   //p的值是a[0]的地址

p = a;    //p的值是数组a首元素(即a[0])的地址

注意:数组名不代表整个数组,只代表数组首元素的地址。

3.1在引用数组元素时指针的运算

在一定条件下允许对指针进行加和减的运算。在指针指向数组元素时,可以对指针进行以下运算:

  • 加一个整数(用+或+=),如p+1;
  • 减一个整数(用-或-=),如p-1;
  • 自加运算,如p++, ++p;
  • 自减运算,如p--,--p。
  • 两个指针相减,如p1-p2(只有p1和p2都指向同一个数组中的元素时才有意义)

分别说明如下:

(1)如果指针变量p已指向数组中的一个元素,则p+1指向同一个数组中的下一个元素,p-1指向同一个数组中的上一个元素。执行p+1时并不是将p的值(地址)简单地加1,而是加上一个数组元素所占用的字节数。例如,数组元素是float型,每个元素占用4个字节,则p+1意味着使p的值加4个字节,以使它指向下一个元素。

(2)如果p的初值为&a[0],则p+i和a+i就是数组元素a[i]的地址,或者说它们指向a数组序号为i的元素。

(3)*(p+i)和*(a+i)是p+i或a+i所指向的数组元素,即a[i]。例如,*(p+5)或*(a+5)就是a[5],即这三者等价。

(4)如果指针变量p1和p2都指向同一数组,如执行p2-p1,结果是p2-p1的值(两个地址之差)除以单个数组元素的长度。表示p1和p2所指元素的相对距离,两个地址不能相加,如p1+p2是无实际意义的。

例如:通过指针变量指向数组元素:

#include <stdio.h>
int main()
{
    int a[10];
    int * p, i;
    printf('Please enter 10 integer numbers:");
    for(i=0;i<10;i++)
      scanf("%d", &a[i]);
    for(p=a;p<(a+10);p++)
      printf("%d", * p);   //用指针指向当前的数据元素
    printf("\n");
    return 0;
}

4、二维数组a的有关指针

int a[3][4] = {{1,3,5,7},{9,11,13,15},{17,19,21,23}};

表示形式含义地址
a二维数组名,指向一维数组a[0],即0行首地址2000
a[0], * (a+0), * a0行0列元素地址2000

a+1,&a[1]

1行首地址2016
a[1], *(a+1)1行0列元素a[1][0]的地址2016
a[1]+2, * (a+1)+2, &a[1][2]1行2列元素a[1][2]的地址2024
*(a[1]+2), *(*(a+1)+2), a[1][2]1行2列元素a[1][2]的值元素值为13


  • 16
    点赞
  • 64
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值