当前位置:主页 > 论文百科 > 英文数据库 >

Clang Array And Pointer

发布时间:2017-03-09 16:45

  本文关键词:C语言点滴,由笔耕文化传播整理发布。


layout: post title: “C语言的指针与数组种种关系” category: “c/c++” tags: [sizeof] —

此篇为《C语言点滴》关于指针的总结

一. 指针与数组关系

指针 数组

指针 指针指针 指针数组

数组 数组指针 数组数组

表1 指针与数组的组合

假设以int类型测试:

指针 数组

指针 指针指针: int **pp 指针数组: int *pa[5]

数组 数组指针: int (*ap)[5] 数组数组: int aa[2][3]

表2:四个概念的定义

真理:
  • 指针真理:一个xx 型指针应该指向一个xx 型地址。
  • 数组真理:xx 型数组变量就是一个xx 型地址。
  • 真理推导:
  • 根据真理1可知:一个 指针型 指针指向一个 指针型 地址;一个 数组型 指针指向一个 数组型 地址
  • 根据真理2可知: 指针型 数组变量就是一个 指针型 地址; 数组型 数组变量(二维数组)就是一个 数组型 地址。
  • 综上推导:
  • 一个 指针型指针 可以指向一个 指针型数组变量 , 上表第一行 pp = pa
  • 一个 数组型指针 可以指向一个 数组型数组(二维数组) , 上表第二行 ap = aa
  • 指针变量 数组变量

    char 类型 char *p char a[5]

    指针类型 int **pp int *pa[5]

    数组类型 int (*ap)[5] int aa[2][3]

    表3 指针变量可指向对应数组变量

    二. 指针指针、指针数组、数组指针 2.1 指针型指针

    关于指针型指针,如:

    int i = 5; printf("i=%d, &i=%p\n", i, &i); int *p = &i; printf("*p=%d, p=%p, &p=%p\n", *p, p, &p); int **pp = &p; printf("*pp=%d, pp=%p, &pp=%p\n", **pp, pp, &pp);

    打印输出:

    i=5, &i=0x004f5a6c *p=5, p=0x004f5a6c, &p=0x004f5a5a *pp=5, pp=0x004f5a5a, &pp=0x004f5a4c 每个变量,无论它保存的是什么,它本身也都有地址:
  • 指针变量p 保存的是变量i 的地址0x004f5a6c,但是p 本身的地址是0x004f5a5a。
  • 指针变量pp 中保存的是指针变量p 的地址0x004f5a5a。为了保存指针型变量p 的地址,我们必须定义一个指针型指针,那就是 int **pp
  • 如下图示:

    Clang Array And Pointer

    图1:示意图

    2.2 指针数组

    对于一个指针数组,数组中保存的都是指针,数组名就是指针型地址。为了保存这种指针型地址,根据指针真理,我们自然应该用指针型指针了。

    如 int *p[3] ,这是因为 [] 的优先级比 * 号高,所以 int *p[3] 会被编译器解释为 int *(p[3]) 。这就是指针数组

    见下:

    char *a[] = {"人生苦短", ":grin:", "Python当歌", NULL}; // 指针数组 char **p; // 指针指针 for (p = a; *p != NULL; p++) { printf("%s\n", *p); }

    打印输出:

    人生苦短 :grin: Python当歌 2.3 数组指针

    如何定义一个数组型的指针?不能写成 int *p[3] ,这是因为 [] 的优先级比 * 号高,所以 int *p[3] 会被编译器解释为 int *(p[3]) 。这其实就是上面介绍过的指针数组,而不是我们要定义的数组指针。为了解决这个问题,我们用括号改变它的优先级,写成 int (*p)[3] 。这时 (*p) 是一个指针,指针指向的类型为 int[3] ,这是一个一维数组型变量,符合我们的定义。

    Clang Array And Pointer

    图2:对比一维和二维的数组指针实例

    有了 int (*p)[3]=array[2][3] 的写法,我们对二维数组也可以利用指针来进行访问了,如下面所示:

  • p 即 &array[0]
  • 代表二维数组的首地址,,第0 行的地址
  • 代表一维int 数组型变量int[]的地址
  • p+i 即 &array[i]
  • 代表第i 行的地址
  • 一维int 数组型变量int[]的地址
  • *(p+i) 即 array[i]
  • 代表第i 行第0 列的地址
  • 一维int 数组型int[]变量,等价于int 类型的地址
  • *(p+i)+j 即 &(array[i][j])
  • 代表第i 行第j 列的地址
  • int 类型的地址
  • *(*(p+i)+j ) 即 array[i][j]
  • 代表第i 行第j 列的元素
  • int 类型的值”
  • 还是看代码测试吧:

    int array[2][3] = { {101, 102, 103}, {201, 202, 203} }; int (*p)[3] = array; printf("p=%p, &array[0]=%p\n", p, &array[0]); printf(p == &array[0] ? "true\n" : "false\n"); /* * out: * p=0x7fff5cfa2540, &array[0]=0x7fff5cfa2540 * true */ printf("p+1=%p, &array[1]=%p\n", p+1, &array[1]); printf(p+1 == &array[1] ? "true\n" : "false\n"); /* * out: * p+1=0x7fff5cfa254c, &array[1]=0x7fff5cfa254c * true */ printf("*(p+1)=%p, array[1]=%p\n", *(p+1), array[1]); printf(*(p+1) == array[1] ? "true\n" : "false\n"); /* * out: * *(p+1)=0x7fff5cfa254c, array[1]=0x7fff5cfa254c * true */ printf("*(p+1)+2=%p, &(array[1][2])=%p\n", *(p+1)+2, &(array[1][2])); printf(*(p+1)+2 == &(array[1][2]) ? "true\n" : "false\n"); /* * out: * *(p+1)+2=0x7fff5cfa2554, &(array[1][2])=0x7fff5cfa2554 * true */ printf("*(*(p+1)+2)=%d, array[1][2]=%d\n", *(*(p+1)+2), array[1][2]); printf(*(*(p+1)+2) == array[1][2] ? "true\n" : "false\n"); /* * out: * *(*(p+1)+2)=203, array[1][2]=203 * true */

    关键部分就是 优先级 , 如 () > [] > *

    下面两篇文章基本搞定:

  • 数组指针和指针数组的区别
  • 指针数组和数组指针
  • 如果还不清楚,就看《深入理解C指针》这本不到200页的书。


      本文关键词:C语言点滴,由笔耕文化传播整理发布。



    本文编号:249784

    资料下载
    论文发表

    本文链接:https://www.wllwen.com/wenshubaike/mishujinen/249784.html


    Copyright(c)文论论文网All Rights Reserved | 网站地图 |

    版权申明:资料由用户9d2ad***提供,本站仅收录摘要或目录,作者需要删除请E-mail邮箱bigeng88@qq.com