《指针的编程艺术(第二版)》一3.5 指向数组的指针

简介:

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

3.5 指向数组的指针

指针的编程艺术(第二版)
ptr[4] 和 (ptr)[4] 所表示的意义是不同的。ptr[4]已在前面讨论过了,而(ptr)[4]是指向数组的指针(pointer to array){XE "指向陣列的指標(pointer to array)"},表示ptr是一指针,指向一个有4个元素的数组,其实它也可视为是一个二维数组ptr[][4],因为*和[]是互通的,我们以范例pointerToArray-1来说明。

范例pointerToArray-1

/* pointerToArray-1.c */
#include <stdio.h>
#include <stdlib.h>

int main()
{
  int i[][3]={10, 20, 30, 40, 50, 60};
  int (*ptr)[3];
  int a, b, total=0;
  for(a=0; a<2; a++)
    for(b=0; b<3; b++)
      printf("&i[%d][%d]=%x\n", a, b, &i[a][b]);
   
  printf("\n");   
  for(a=0; a<2; a++)
    for(b=0; b<3; b++)
      printf("i[%d][%d]=%d\n", a, b, i[a][b]);
     
  ptr=i;
  printf("\n");
  printf("ptr=%x, *ptr=%x, i[0]=%x, i=%x, *i=%x\n", ptr, *ptr,   
    i[0], i, *i);
  for(a=0; a<2; a++) 
    for(b=0; b<3; b++)
       total += *(*(ptr+a)+b);
  printf("Sum of array = %d\n", total);  
  system("PAUSE");
  return 0;
}

输出结果


f71d6589ae5b31a1373213daa7baf215d4103cf1

程序中的循环

  for(a=0; a<2; a++) 
  for(b=0; b<3; b++)
     total += *(*(ptr+a)+b);

表示第一次,将第1行的3个元素相加;第二次,将第2行的3个元素相加。因为

  *(ptr+a) == ptr[a]```
所以上述的循环可以改为

  for(b=0; b<3; b++)
    total += *(ptr[a]+b);`
同理,*(ptr[a]+b) == ptra

所以上述的循环又可以改为

for(a=0; a<2; a++) 
  for(b=0; b<3; b++)
     total += ptr[a][b];```
请参阅范例pointerToArray-2。

范例pointerToArray-2

/ pointerToArray-2.c /

include

include

int main()
{
  int i[][3]={10, 20, 30, 40, 50, 60};
  int (*ptr)[3];
  int a, b, total=0;
  for(a=0; a<2; a++)
    for(b=0; b<3; b++)
      printf("&i%d=%xn", a, b, &ia);
  
  printf("n");  
  for(a=0; a<2; a++)
    for(b=0; b<3; b++)
      printf("i%d=%dn", a, b, ia);
     
  ptr=i; / 将 ptr 指向数组的第一个元素的地址 /
  for(a=0; a<2; a++)
    for(b=0; b<3; b++)
      total += *(ptr[a]+b);
  printf("Sum of array = %dn", total);
  
  total=0;
  printf("n使用另一种计算总和方法: n");
  for(a=0; a<2; a++)
    for(b=0; b<3; b++)
      total += ptra;
  printf("Sum of array = %dn", total);  
  system("PAUSE");
  return 0;
}

输出结果

<div style="text-align: center">
 <img src="https://yqfile.alicdn.com/acc40b7e8afd5c2185c3a648d41bf489eee42996.png" >
</div>

以ptr指针计算二维数组的元素和。再来看一个相似的范例,如范例pointerToArray-3所示。

范例pointerToArray-3

/ pointerToArray-3.c /

include

include

int main()
{
  int i3={{1,2}, {3,4}, {5, 6}};
  int k;
  int (*pi)[2];
  pi=i;
  
  for(k=0; k<3; k++)
    printf("pi+%d=%xn", k, pi+k);
   
  printf("pi=%xn", pi);
  printf("pi+1=%xn", pi+1);
  
  printf("pi0=%dn", pi0);
  printf("pi1=%dn", pi1);
  
  printf("(((pi+1)+1))=%xn", (((pi+1)+1)));
  printf("(pi+1)=%dn", (pi+1));
  getch();
  return 0;
}

输出结果

<div style="text-align: center">
 <img src="https://yqfile.alicdn.com/e59a40e959ebe8f6c8c2bda588c3b7816d98dc7a.png" >
</div>

指针之间的兼容性也是很重要的,我们以范例pointerTestCompatiable来说明。

范例pointerTestCompatiable

/ pointerTestCompatiable.c /

include

include

int main()
{
  int *pt;
  int (*pa)[3];
  int **p2;
  int arr12={0, 1, 2, 3, 4, 5};
  int arr23={10, 20, 30, 40, 50, 60};
  
  printf("&arr10=%pn", &arr10);  
  printf("&arr20=%pnn", &arr20);
  
  pt=&arr10;
  printf("pt=%p, &arr10=%pn", pt, &arr10);
  pt=arr1[0];  / 不要写成 pt=arr1 /
  printf("pt=%p, arr1[0]=%pn", pt, arr1[0]);
  pt=arr1[0];
  printf("pt=%dn", pt);
  pa=arr1; / 不要写成 pa=arr2 /
  printf("pa=%dn", pa);
  p2=&pt;  / 不要写成p2=pt /
  printf("p2=%dn", p2);
  p2=arr2[0]; / 要先将 p2指向某个变量的地址,如 p2=&pt */
  printf("p2=%p, arr2[0]=%pn", p2, arr2[0]);
  printf("p2=%dn", p2);

  getch();
  return 0;
}

输出结果

<div style="text-align: center">
 <img src="https://yqfile.alicdn.com/9dfb8d0d758e71f29806f7c49b37cf67b47102d8.png" >
</div>


程序定义以下的变量

int *pt;
  int (*pa)[3];
  int **p2;
  int arr12={0, 1, 2, 3, 4, 5};
  int arr23={10, 20, 30, 40, 50, 60};


pt为一个指向int的指针;pa是一个指针,它指向每一行含有3个元素的数组;p2是一个指向指针的指针;arr1是一个具有2行3列的数组;arr2是一个具有3行2列的数组。

程序首先输出arr1与arr2数组的第1行第1列元素的地址,分别是0022FF40和0022FF20。程序中要注意以下几个语句,

  pt=arr1[0];  / 不要写成 pt=arr1 /`
因为pt是一个指向int的指针,所以不可以写成pt=arr1。如果是这样的话,请问 pt与arr1会相等吗?答案是否定的,因为pt得到的应该是值(它只有一个),但*arr1所得到的还是一个地址,两边的答案不一致。

接下来,

  pa=arr1;   /* 不要写成 pa=arr2 */```
因为pa是一个指向每一行具有3个元素数组的指针,所以不要写成 pa=arr2,因为arr2是每一行有2个元素的数组。

最后,

  p2=&pt;   / 不要写成 p2=pt /`
因为p2是一个具有两个*的指针,所以不可以写成p2=pt,否则就无法实现p2是一个值的答案,而且pt是错误的写法。这个范例较难,要耐心的体会才能完全了解。

相关文章
|
7天前
|
算法 索引
单链表题+数组题(快慢指针和左右指针)
单链表题+数组题(快慢指针和左右指针)
15 1
|
17天前
|
存储
如何使用指针数组来实现动态二维数组
指针数组可以用来实现动态二维数组。首先,定义一个指向指针的指针变量,并使用 `malloc` 为它分配内存,然后为每个子数组分配内存。通过这种方式,可以灵活地创建和管理不同大小的二维数组。
|
17天前
|
存储
如何通过指针数组来实现二维数组?
介绍了二维数组和指针数组的概念及其区别,详细讲解了如何使用指针数组模拟二维数组,包括定义与分配内存、访问和赋值元素、以及正确释放内存的步骤,适用于需要动态处理二维数据的场景。
|
17天前
|
存储 算法 C语言
C语言:什么是指针数组,它有什么用
指针数组是C语言中一种特殊的数据结构,每个元素都是一个指针。它用于存储多个内存地址,方便对多个变量或数组进行操作,常用于字符串处理、动态内存分配等场景。
|
22天前
魔法指针 之 二级指针 指针数组
魔法指针 之 二级指针 指针数组
15 1
|
25天前
|
存储
一篇文章了解区分指针数组,数组指针,函数指针,链表。
一篇文章了解区分指针数组,数组指针,函数指针,链表。
17 0
|
1月前
|
编译器 C语言
【C语言】指针篇-深入探索数组名和指针数组- 必读指南(2/5)
【C语言】指针篇-深入探索数组名和指针数组- 必读指南(2/5)
|
25天前
|
C语言
无头链表二级指针方式实现(C语言描述)
本文介绍了如何在C语言中使用二级指针实现无头链表,并提供了创建节点、插入、删除、查找、销毁链表等操作的函数实现,以及一个示例程序来演示这些操作。
19 0
|
2月前
|
存储 人工智能 C语言
C语言程序设计核心详解 第八章 指针超详细讲解_指针变量_二维数组指针_指向字符串指针
本文详细讲解了C语言中的指针,包括指针变量的定义与引用、指向数组及字符串的指针变量等。首先介绍了指针变量的基本概念和定义格式,随后通过多个示例展示了如何使用指针变量来操作普通变量、数组和字符串。文章还深入探讨了指向函数的指针变量以及指针数组的概念,并解释了空指针的意义和使用场景。通过丰富的代码示例和图形化展示,帮助读者更好地理解和掌握C语言中的指针知识。
|
3月前
|
C语言
【C初阶——指针5】鹏哥C语言系列文章,基本语法知识全面讲解——指针(5)
【C初阶——指针5】鹏哥C语言系列文章,基本语法知识全面讲解——指针(5)