摘要: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. hdu2768-Cat vs. Dog:图论:二分匹配

    Cat vs. Dog Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total ...

  2. [WPF] 将普通的Library工程,改造成WPF Custom Control 的Library

    1. 添加References PresentationCore PresentationFramework System.Xaml WindowsBase2. 修改AssemblyInfo.xsus ...

  3. 第24讲 UI_布局 之帧布局 表格布局 绝对布局

    第24讲 UI_布局 之帧布局 表格布局 绝对布局 3. FrameLayout(帧布局) 帧布局是从屏幕的左上角(0,0)坐标开始布局,多个组件层叠排序,后一个组件总会将前一个组件所覆盖,除非最后一 ...

  4. js简易猜数字

    Title #div1{ width:400px; height:400px; border:1px solid red; } h1{ width:400px; height:20px; } b#co ...

  5. 自定义jquery插件

    参考:http://blog.csdn.net/bao19901210/article/details/21540137/ 自己看代码理解: <!DOCTYPE html> <htm ...

  6. 区间DP(初步了解)

    区间动态规划问题一般都是考虑.对于每段区间,他们的最优值都 是由几段更小区间的最优值得到,是分治思想的一种应用,将一个区间 问题不断划分更小的区间直至一个元素组成的区间,枚举他们的组合  .求合并后的 ...

  7. Java ------------获取不会重复的随机数

    import java.util.UUID; public class UTest {    public static void main(String[] args) { //UUID通过rand ...

  8. UITableView 总结

    http://my.oschina.net/iq19900204/blog/292125

  9. javaScript中获取鼠标位置的理解

    获取鼠标坐标值的总结为了避免混淆知识点 通过<javaScript高级程序设计>查到这些 event.clientX event.clientY event.pageX event.pag ...

  10. C++中的数组和指针

    #include <iostream> #include <set> using namespace std; int main() { ] = {,,,,,}; ]; p = ...