《指针的编程艺术(第二版)》一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;
}

输出结果


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

程序中的循环

  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是错误的写法。这个范例较难,要耐心的体会才能完全了解。

上一篇:使用Web Scraper 插件,不需要编程,也能爬网


下一篇:Dubbo Provider export过程分析