C语言中的声明解析规则——数组,指针与函数
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语言中的声明解析规则——数组,指针与函数的更多相关文章
- C++ —— 返回数组指针的函数 和 返回指向函数的指针的函数
返回数组指针的函数 基础知识:数组不能被拷贝,函数不能返回数组,只能返回数组的指针或者引用. 定义一个 返回数组指针的函数 的方法,以 一个接收参数为 含有10个整型元素的数组的引用 和 返回一个含 ...
- C语言中如何将二维数组作为函数的参数传递
今天写程序的时候要用到二维数组作参数传给一个函数,我发现将二维数组作参数进行传递还不是想象得那么简单里,但是最后我也解决了遇到的问题,所以这篇文章主要介绍如何处理二维数组当作参数传递的情况,希望大家不 ...
- 以杨辉三角为例,从内存角度简单分析C语言中的动态二维数组
学C语言,一定绕不过指针这一大难关,而指针最让人头疼的就是各种指向关系,一阶的指针还比较容易掌握,但一旦阶数一高,就很容易理不清楚其中的指向关系,现在我将通过杨辉三角为例,我会用四种方法从内存的角度简 ...
- [笔记]C++声明返回数组指针的函数
数组指针的声明:type (*name)[size]; 由于数组不能拷贝,所以函数不能返回数组.但是函数可以返回指针和引用,所以函数可以返回数组指针或引用. 和数组指针的声明类似: type (*fu ...
- go语言基础之数组指针做函数参数
1.数组指针做函数参数 示例: package main //必须有个main包 import "fmt" //p指向实现数组a,它是指向数组,它是数组指针 //*p代表指针所指向 ...
- Z :彻底了解指针数组,数组指针以及函数指针 [复
原创 :彻底了解指针数组,数组指针以及函数指针 [复制链接] 00 roking 白手起家 帖子 60 主题 16 精华 0 可用积分 74 专家积分 0 在线时间 0 小时 注册时间 2003-10 ...
- C语言中复杂声明的解读和简化
code[class*="language-"], pre[class*="language-"] { color: rgba(51, 51, 51, 1); ...
- C语言中的位段----解析
有些信息在存储时,并不需要占用一个完整的字节, 而只需占几个或一个二进制位. 例如在存放一个开关量时,只有0和1 两种状态, 用一位二进位即可. 为了节省存储空间并使处理简便,C语言又提供了一种数据结 ...
- go语言中常用的文件和文件夹操作函数
package main; import ( "os" "log" "time" "fmt" ) //一些常用的文件操作 ...
随机推荐
- spring framework 4 源码阅读(1) --- 前期准备
在开始看代码之前,需要做的第一件事是下载代码. 在这里:https://github.com/spring-projects/spring-framework 下载完成了发现使用gradle做的源代码 ...
- NOI2012 骑行川藏
http://www.lydsy.com/JudgeOnline/problem.php?id=2876 表示完全不会...... 还是跪拜大神吧 http://www.cnblogs.com/Ger ...
- 轻量级开源嵌入式关系数据库sqlite基本使用及接口初识
preface,先闲来扯下蛋: 嵌入式数据库,NoSQL的是BerkeleyDB和InnoDB,leveDb.TC(个人较不熟悉),关系型嵌入式是SQLite; 服务器性质的NoSQL服务器,如Red ...
- c语言结构体数组引用
struct dangdang { ]; ]; ]; int num; int bugnum; ]; ]; double RMB; }dbdd[]={{,,}, {,,} };//初始化 void m ...
- 关于ionic的一些坑(2)
如果你通过查阅相关文档,ionic的项目框架已经搭好,下面我来总结一下我在项目中所遇到的坑,给还没踩过的人以方便,给自己以勉励: (1)关于android和ios的适配 因为ionic默认的tabs状 ...
- Java操作属性文件,支持新增或更新多个属性
Java操作属性文件.支持新增或更新多个属性 一.更新或新增单个属性的方法 /** * 写入properties信息 * @param filePath 绝对路径(包含文件名称和后缀名) * @par ...
- windows下批量杀死进程
有时候因为病毒或其它原因,启动了一系列的进程,而且有时杀了这个,又多了那个.使用命令taskkill可将这些进程一下子所有杀光: C:\Users\NR>taskkill /F /im fron ...
- Java反射举例
本文參考:http://www.cnblogs.com/yydcdut/p/3845430.html 1.Java反射的基本介绍 Java的反射很强大,传递class. 能够动态的生成该类.取得这个类 ...
- SDK命令行操作
* 使用前需要先在path中添加Android SDK的环境变量,跟Java JDK的配置相同 我当前目录如下:F:\Program\Android SDK\tools:F:\Program\Andr ...
- 操作Action
Action就是Controller的一个方法 包含对应请求的最终结果 Action里代码从Model层拿到数据 最后把数据结果Actionresult 返回用户