• C语言中的声明解析规则——数组,指针与函数


    摘要:C语言的申明存在的最大问题是:你无法以一种人们所习惯的自然方式和从左向右阅读一个声明,在引入voliatile和const关键字以后,情况更加糟糕了。由于这些关键字只能出现在声明中,是的声明形式和使用形式完全对上号的例子越来越少了。而C语言中比较绕人的指针数组和数组指针的问题,int *ap[]和int (*ap)[]谁是指针数组,谁又是数组指针?这里面声明的解析规则是什么样的?本文主要为你解答这些疑惑。

          我们来看看下面的语句,和它们对应的编译结果:

    int (*ap)[2]={1,2};

    /*stringcat.c:6:3: warning: initialization makes pointer from integer without a cast [enabled by default]
    14 stringcat.c:6:3: warning: (near initialization for ‘ap’) [enabled by default]
    15 stringcat.c:6:3: warning: excess elements in scalar initializer [enabled by default]
    16 stringcat.c:6:3: warning: (near initialization for ‘ap’) [enabled by default]
    17 */

     int (*ap)[2]=int(*)[2]a;

    18 /*stringcat.c:7:16: error: expected expression before ‘int’

    20 */


    int a[2]={1,2}

     int (*ap)[2]=(int(*)[2])a;//注意,此处申明的不是一个数组而是一个指针

         注意,这个才是正确的,但是你能看出上面声明的是一个指针而不是一个数组吗?


          指针和数组之所以复杂,主要原因就再次:他们的声明和使用形似并不相同。来看看C语言的声明是如何形成的?

          声明器就是标识符以及与它组合在一起的任何指针,函数括号和数组下标等。

          构造声明要遵循以下条件:

    函数返回值不能是一个函数:foo()()

    函数返回值不能是一个数组:foo()[]

    数组里面不能有函数:foo[]()

          但可以这样:

    函数可以返回函数指针:int (*fun())()

    函数可以返回指向数组的指针:int(*foo())[]

    数组里面允许函数指针:int(*foo[])()

    数组里面允许其他数组:int foo[][]

          这里面,比较qipa的有三种类别,数组,函数,指针。

    一般定义:int a;

    数组:int a[5];

    函数:int fun();

    指针:int *p;

          尤其是数组和函数,我们可以认为他们的变量处在类型修饰符(不过把运算符也算作类型的话)的中间。


          我们接下来看看C语言的优先级规则

    A:声明从名字开始读取,然后按照优先级次序依次开始读取

    B:优先级从高到低的次序是

           B1:声明中被括号扩起来的部分

           B2:后缀操作符() []

           B3:前缀操作符*

    C:const和volatile关键字后面紧跟类型说明符的话(int,long),那么它作用与类型说明符号;反之,它作用与左边挨着的*

           如此,可以分析char * const * (*next)()

    具体的分析过程按照上述即可,结果是:next是一个指针,它指向一个函数,这个函数返回另一个指针,该指针是指向类型为char的常量指针。


          然后再来分析以往我们提出的例子就简单多了:int (*ap)[2],ap是一个指针,这个指针指向长度为2的int类型的数组;int *ap[2],ap是一个长度为2的数组,数组中的每个元素是指向int类型的指针。这样就明晰了数组指针和指针数组的区别。

  • 相关阅读:
    字符串算法—正则表达式
    字符串算法—字符串搜索
    字符串算法—字典树
    字符串算法—字符串排序(下篇)
    字符串算法—字符串排序(上篇)
    图表算法—最短路径
    基本算法——前缀和与差分
    图论——图的表示
    基本算法——康托展开与逆康托展开
    基本算法——离散化
  • 原文地址:https://www.cnblogs.com/james1207/p/3329138.html
Copyright © 2020-2023  润新知