摘要: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类型的指针。这样就明晰了数组指针和指针数组的区别。

C语言中的声明解析规则——数组,指针与函数的更多相关文章

  1. C++ —— 返回数组指针的函数 和 返回指向函数的指针的函数

    返回数组指针的函数 基础知识:数组不能被拷贝,函数不能返回数组,只能返回数组的指针或者引用. 定义一个 返回数组指针的函数 的方法,以 一个接收参数为 含有10个整型元素的数组的引用  和 返回一个含 ...

  2. C语言中如何将二维数组作为函数的参数传递

    今天写程序的时候要用到二维数组作参数传给一个函数,我发现将二维数组作参数进行传递还不是想象得那么简单里,但是最后我也解决了遇到的问题,所以这篇文章主要介绍如何处理二维数组当作参数传递的情况,希望大家不 ...

  3. 以杨辉三角为例,从内存角度简单分析C语言中的动态二维数组

    学C语言,一定绕不过指针这一大难关,而指针最让人头疼的就是各种指向关系,一阶的指针还比较容易掌握,但一旦阶数一高,就很容易理不清楚其中的指向关系,现在我将通过杨辉三角为例,我会用四种方法从内存的角度简 ...

  4. [笔记]C++声明返回数组指针的函数

    数组指针的声明:type (*name)[size]; 由于数组不能拷贝,所以函数不能返回数组.但是函数可以返回指针和引用,所以函数可以返回数组指针或引用. 和数组指针的声明类似: type (*fu ...

  5. go语言基础之数组指针做函数参数

    1.数组指针做函数参数 示例: package main //必须有个main包 import "fmt" //p指向实现数组a,它是指向数组,它是数组指针 //*p代表指针所指向 ...

  6. Z :彻底了解指针数组,数组指针以及函数指针 [复

    原创 :彻底了解指针数组,数组指针以及函数指针 [复制链接] 00 roking 白手起家 帖子 60 主题 16 精华 0 可用积分 74 专家积分 0 在线时间 0 小时 注册时间 2003-10 ...

  7. C语言中复杂声明的解读和简化

    code[class*="language-"], pre[class*="language-"] { color: rgba(51, 51, 51, 1); ...

  8. C语言中的位段----解析

    有些信息在存储时,并不需要占用一个完整的字节, 而只需占几个或一个二进制位. 例如在存放一个开关量时,只有0和1 两种状态, 用一位二进位即可. 为了节省存储空间并使处理简便,C语言又提供了一种数据结 ...

  9. go语言中常用的文件和文件夹操作函数

    package main; import ( "os" "log" "time" "fmt" ) //一些常用的文件操作 ...

随机推荐

  1. V$LATCH_PARENT和V$LATCH_CHILDREN

    V$LATCH_PARENT contains statistics about parent latches. The columns of V$LATCH_PARENT are identical ...

  2. usaco silver

    大神们都在刷usaco,我也来水一水 1606: [Usaco2008 Dec]Hay For Sale 购买干草   裸背包 1607: [Usaco2008 Dec]Patting Heads 轻 ...

  3. 2013 长沙网络赛 B 题 Bizarre Routine

    题解 http://blog.csdn.net/u010257508/article/details/11936129 #include <iostream> #include <c ...

  4. BuguMongo是一个MongoDB Java开发框架,集成了DAO、Query、Lucene、GridFS等功能

    http://code.google.com/p/bugumongo/ 简介 BuguMongo是一个MongoDB Java开发框架,它的主要功能包括: 基于注解的对象-文档映射(Object-Do ...

  5. Android实现左右滑动效果

    本示例演示在Android中实现图片左右滑动效果.   关于滑动效果,在Android中用得比较多,本示例实现的滑动效果是使用ViewFlipper来实现的,当然也可以使用其它的View来实现.接下来 ...

  6. 【精品】Android游戏类源码大集合

    Android自定义效果——随机抽奖 一个模拟抽奖的效果,用户设定若干个选项,添加之后,就可以通过程序,来帮助随机选择其中一项出来.这个类似超市里面那种指针转盘抽奖,run之后是一个动态效果图,初始快 ...

  7. Hacker(19)----检测Windows系统漏洞

    想完全掌握Windows中存在的漏洞需要使用专业的漏洞扫描软件.目前常用的有MBSA(MircosoftBaselineSecurityAnalyzer).360安全卫士等. 一.使用MBSA检测系统 ...

  8. Layer中自定义属性的动画

    转载自:http://blog.jobbole.com/69211/ 默认情况下,CALayer 及其子类的绝大部分标准属性都可以执行动画,无论是添加一个 CAAnimation 到 Layer(显式 ...

  9. ado.net数据库操作(1)

    这些都是网上搜索到的,我把他放在自己的博客里,作为笔记 1.1创建数据库连接(sqlserver) <%@ Import Namespace="System.Data" %& ...

  10. JavaScript split()

    http://www.w3school.com.cn/jsref/jsref_split.asp