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" ) //一些常用的文件操作 ...
随机推荐
- SQL Server 通过一个表和另一个表联合 批量更新这个表的字段
UPDATE OutPzPersonSet SET cPerson = a.AAA --SELECT * FROM OutPzPersonSet d INNER JOIN AAAA a ON d.cz ...
- Ext.window的close的问题
以前每次都是用的hide,关闭后隐藏窗体,下一次点击再打开,这种方法在我的随笔里面有,可是现在遇到一个问题,我的窗体里面有个formpanel,formpanel每一项都有一个默认值,意思就是修改的时 ...
- 原生javascript 获得css样式有几种方法?
css 样式分为行内样式和 外部样式: 1.javascript 获得行内样式 : 可以使用 ele.style."属性名称"(如果遇到属性名称带有"-", ...
- (转)Building MariaDB on Mac OS X using Homebrew
https://kb.askmonty.org/en/building-mariadb-on-mac-os-x-using-homebrew/ Work has been done to provid ...
- struts1配置文件之input
<action path="/*Person" type="cn.itcast.PersonAction" scope="request&quo ...
- [RxJS] Resubscribing to a Stream with Repeat
When you complete a stream, there’s no way to restart it, you must resubscribe. This lesson shows ho ...
- 内存测试工具memtester
Memtester是用户态工具,用于测试内存子系统的故障.非常方便,支持32位 或64位Unix-like系统.对于硬件开发开发者来说,memtester可以定位到物理地址. 1. 安装 下载地址ht ...
- CodeSmith使用总结--读取一个表试试
我感觉CodeSmith对于我的最大用途是不用我手动创建每个表的Model.BLL和DAL了,那些繁琐的工作真的让我很无语. CodeSmith要读取数据库中的表就要先连接数据库. 新建一个数据库连接 ...
- Android开发_关于中英文切换
开发APP过程中可能要有中文模式和英文模式,切换后控件要随着进行更改,以下代码可以很好的实现: public static int getResourcesId(Context context, St ...
- Understanding JavaScript Function Invocation and "this"
Understanding JavaScript Function Invocation and "this" 11 Aug 2011 Over the years, I've s ...