指针(2)

8.4 指针与一维数组

8.4.1 指针与一维数组的关系

数组是最基本的构造类型,是相同类型数据的有序集合。数组中的元素按顺序存放在地址连续的内存单元中,每一个数组元素都有各自的地址,数组名是数组首元素的地址。对数组元素的访问,可以使用下标,也可以使用指针变量,移动指针可以指向数组中的任意一个元素。

例如,一维数组和指针的定义如下:

int a[5]={1,2,3,4,5},*p;

p=a;

则:p是指向一维数组的首元素的指针。由于数组名是数组首元素(a[0])的地址,因此上述定义等价于:

int a[5]={1,2,3,4,5},*p;

p=&a[0];

8.4.2 指针的运算

1. 指针加整数和指针减整数运算

int a[5]={1,2,3,4,5};

int *p1=a,*p2=p1+4;

2. 指针自加和自减运算

int a[5]={1,2,3,4,5};

int *p1=a,*p2=p1+4;

++p1;--p2;

3. 指针关系运算

两个指针的关系运算,只适用于两个指针所指对象在同一数组中的情况,当指针p和指针q指向同一数组中的元素时,则有:

当p>q时,p所指元素在q所指元素之前;

当p<q时,p所指元素在q所指元素之后;

当p==q时,p与q指向同一元素;

当p!=q时,p与q指向不同元素。

4. 指针相减运算

两个指针的减法运算,只适用于两个指针所指对象在同一数组中的情况,用于获得两个指针间有多少个数组元素。

5. 指针表达式

(1)*p++ 根据结合性,等价于*(p++)。

(2)*++p 根据结合性,等价于*(++p)。

(3)(*p)++ 执行该语句,等价于a[0]++。

(4)++*p 根据结合性,等价于++ (*p)。

8.5指针与二维数组

8.5.1 指针与二维数组的关系

C语言中,二维数组被看作元素为一维数组的一维数组。如图8.16所示,二维数组a的每一行都被看作是一个一维数组,其数组名分别为a[0]、a[1]和a[2]。a[0]数组是a数组的第0行,有a[0][0]、a[0][1]、a[0][2]三个元素,a[1]和a[2]则分别是a数组的第1行和第2行。二维数组a被看作由a[0]、a[1]和a[2]三个元素组成的一维数组。

二维数组名代表二维数组首元素的地址,由于二维数组被看作元素为一维数组的一维数组,a数组的首元素并不是一个数值,而是由a数组第0行所构成的一维数组,所以a代表的是第0行的首地址,其值为2000;a+1代表第1行所构成的一维数组a[1]的首地址,由于a数组的每一行都有3个元素,所以a+1的值为a+3*4=2012;同样,a+2代表第2行的首地址,其值为a+6*4=2024,如图8.17所示。二维数组名a、a+1及a+2所表示的地址,被称为行地址。

数组a由a[0]、a[1]和a[2]三个元素组成,a[0]是第一个一维数组的数组名,代表数组首元素的地址,所以,a[0]代表一维数组a[0]中第0列的地址,即为&a[0][0],值为2000。同样的,a[1]的值为2012,与&a[1][0]等价;a[2]的值为2024,与&a[2][0]等价。a[0]、a[0]+1及a[0]+2所表示的地址,被称为列地址。


对于二维数组a,虽然a与a[0]所代表的值都是2000,但两者的类型是不同的,数组名a为行地址,a[0]为列地址,行地址与列地址的区别如图8.18所示。

根据上述讨论,关于二维数组元素的首地址总结如下:

(1)“行地址+1”表示下一行,图8.18中,a指向第一行,一行有3个int类型元素,a代表的值为2000;a+1指向第二行,而a+1代表的值是2000+3*4=2012。

(2)“列地址+1”表示下一列,图8.18中,a[0]+1表示a[0]的下一列,就是跳过1个int类型元素,所以a[0]+1代表的值是2004,等价于&a[0][1]。同理,a[0]+2等价于&a[0][2],a[1]+1等价于&a[1][1],以此类推,a[i]+j等价于&a[i][j]。

8.5.2 指向二维数组元素的指针

二维数组的各个元素在内存中是连续存放的,存放方式与一维数组并无区别,可以将二维数组当做一维数组进行处理。

8.5.3指向二维数组的行指针变量

二维数组的每一行都被看作是一个一维数组,可以定义一个指针来指向每一行的一维数组,则行指针变量是指向一行数组元素的起始地址。声明行指针变量的一般格式为:

类型名  (*指针变量名)[n]

其中:类型名为指针变量名所指向数组的数据类型。n表示二维数组分解为多个一维数组的长度,也就是所指向的二维数组的列数。

8.6 指针与字符串

8.6.1 字符串与字符指针

C语言中,字符串在表示形式上分两种情况,字符数组或字符指针。

字符数组的表示方式如下:

char str[]="Turbo C2.0";

puts(str);

字符指针的使用方式如下:

char *str="hello";

puts(str);

8.6.2 使用字符数组和字符指针处理字符串的区别

(1)赋值方法不同。

(2)系统为其分配内存单元的方法不同。

(3)修改值(地址)的方法不同。

8.7 二级指针与指针数组

8.7.1 二级指针

指针可以指向任意类型的数据,包括指针类型。这种指向指针数据类型的指针就是二级指针(即指向指针的指针)。二级指针的定义格式如下:

类型名 **变量名

8.7.2 指针数组

指针数组的定义格式为:

类型名 *数组名[数组长度]

8.7.3 main函数的参数

在C语言中,main()函数通常是没有参数的,但可以有参数,带参数的main()函数声明方式为:

main(int argc, char *argv[])

其中:argc和argv为main()函数的形参,argc表示main()所接受的参数的个数;字符指针数组*argv[]指向命令行中的程序名和参数字符串,main()函数的参数需要在命令行给出。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

嘿哈小将

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值