《指针的编程艺术(第二版)》一3.4 为什么parr等同于 *parr?

本节书摘来自异步社区《指针的编程艺术(第二版)》一书中的第3章,第3.4节,作者 蔡明志,更多章节内容可以访问云栖社区“异步社区”公众号查看

3.4 为什么parr等同于 *parr?

指针的编程艺术(第二版)
因为一个指针相当于一维数组,所以可将上述的数组指针

char *parr[4] = {“Department”, “of”, “Information”, “Management”};

改为以二维数组的方法表示,如下语句所示。

char parr[4][12] = {“Department”, “of”, “Information”, “Management”};

其示意图如下。


eb1305d796ebabc6fe5f0ba628429a18ecae4ee5

系统分配了48(4 ×12)个空间,每一个空间为1字节(因为char数据类型占1字节),parr为数组名,所以“Department”字符串中‘D’字符的地址,也就是&parr0。

由于parr是二维数组,所以parr[0]和parr具有相同的功能。以数组指针表示时,parr是指向“Department”字符串中‘D’字符的地址,因此parr和 parr是相同的。parr和 *parr怎么会相同呢?这是因为二维数组可以使用两种不同的表示方法。

以纯二维数组表示可能会浪费较多的空间,因为已经限制每一行要多少列,因此将以数组中最长的字符串作为其长度,而数组指针较有弹性,字符串有多长,就会分配多少的长度,只不过需要额外分配一个数组存放指针,指针类型的大小为4字节。因此,在使用上,数组指针很受大家的喜爱。

了解指向char指针的数组后,接着来看看数组的每一个元素都指向int指针。如果程序片段如下。

  int arr2[3][4] = {0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22};
  int *parr[3] = {arr2[0], arr2[1], arr2[2]};

请问:

1.如何得到数组的元素值18?

2.下列表达式哪些是address,哪些是value?如果是address,请写出它是哪一个元素的地址。

(a) *(parr+1)

(b) *(parr[1]+1)

(c) parr[2]+3

(d) arr2[1]+3

(e) *(arr2[2]+2)

我们以范例pointerOfArray-10来说明。

范例pointerOfArray-10

/* pointerOfArray-10.c */
#include <stdio.h>
#include <stdlib.h>

int main()
{
  int arr2[3][4] = {0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22};
  int *parr[3] = {arr2[0], arr2[1], arr2[2]};
  printf("&arr2[0][0] = %p\n\n", &arr2[0][0]);
  printf("*(parr + 1) = %p\n", *(parr + 1));
  printf("*(parr[1] + 1) = %d\n", *(parr[1] + 1));
  printf("parr[2] + 3 = %p\n", parr[2] + 3);
  printf("arr2[1] + 3 = %p\n", arr2[1] + 3);
  printf("*(arr2[2] + 2) = %d\n", *(arr2[2] + 2));
  system("PAUSE");
  return 0;
}

输出结果


cf5cfaaccaec5b9f540d47b9f1709f4c000af049

根据题意,arr2与parr分别用图表示如下。


4c1ed52a028e7054c11ff0e7acb322a177633de5

1.如果要得到18,则可使用arr22、(parr[2]+1)、((parr+2)+1)和(arr2[2]+1)。用两个中括号或一个中括号搭配一个,或两个,这3种表示方法中的任意1种,都可以得到数组的元素值。

2.各项答案如下:

(a) *(parr+1)是8的地址;

(b) *(parr[1]+1)是10;

(c) parr[2]+3是22的地址;

(d) arr2[1]+3是14的地址;

(e) *(arr2[2]+2)是20。

使用数组指针要注意的是,起作用的点在哪里。如(parr[2]+1)与parr[2]+1所得到的结果是不一样的,(parr[2]+1) == 18,而*parr[2]+1是先获取parr[2]里面的内容为16,然后再加1,得到的答案是17。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值