基本术语:
声明符:“int a”就是一个声明符。
标识符: 定义的变量名字,如: int a,那么a就是一个标识符。
1.两个原则
始终从内往外读声明符,括号优先级高。即先定位用来声明的标识符,并且从此处的开始解释。
例1.声明 char *p。首先确定标识符为p;再解析*,它代表p是指针指向;再解析char,它表示指针指向char类型。即p是指向char类型的指针。
例2.声明 void (*pf)(int)。首先确定标识符为pf,在括号内解析*,pf是指针指向;其次(int),指针指向的类型是有int参数的函数;最后void,函数返回值是void。总结:pf是一个指针,它指向了一个参数是int,返回值是void的函数

在选择符号解析顺序时,始终是先[]和()后是*。如果"*“在标识符左边且”[]"在标识符右边(例如:*p[]),那么标识符表示的是数组,而不是指针。括号同理,它表示的是函数(例如:*p())。
例:void*pf(int)。首先先解析右边的(int),pf是函数,参数是int类型;其次void*,类型为void类型的指针。总结:pf是函数,函数有一个int类型的参数,返回值是void*

复杂点的例子:

int *(*x[10])(void)。首先解析括号内[10],x是数组;其次*,数组元素是指针指向;再解析(void),指针指向不带参数的函数;最后int *,函数返回值是int类型的指针。总结:x是有10个元素的数组,它的每个元素都是一个指针,指针指向参数为空并且返回值是int*的函数

2.typedef
我们定义一个无符号整型变量x,使用:unsigned long int x;。如果要简化unsigned long int 名称,可以使用typedef, 例如:把unsigned long int改名为x,则定义:

typedef unsigned long int x;

此时x不是一个变量,而是一个简化的unsigned long int别名,但也不能再用x做变量名。
简化别名后,下面两个语句作用相同:

x b;
unsigned long int b;

上面提到的int *(*x[10])(void)复杂的声明也同样适用,它要简化为别名x,则定义:

typedef int *(*x[10])(void);

x是个自定义类型。它的类型是有10个元素的数组,数组每个元素都是一个指针,指针指向参数为空并且返回值是int*的函数。下面两个语句作用相同。

x b;
int *(*b[10])(void);

3.const
const修饰变量。使变量的地址在只读段。const char a = ‘a’; 和char const a = 'a’是一样的效果。a初始化时被赋值,a的地址在只读段,a不能再被修改。
const修饰指针变量。既可以修饰指针指向的数据,也可修饰指针本身。直接说个技巧:当const在*右边并挨着标识符时,则修饰的是指针本身;当const在*左边时,修饰指针指向的数据。以程序举例证明:

#include <stdio.h>
const char *str = "abc";
const char * const const_p = str;
const char *p = str;int main(void)
{printf("const pointer address:%p, const_p:%p\n", &const_p,  const_p);printf("pointer p address:%p, p:%p\n", &p,  p);return 0;
}

输出内容如下:

const pointer address:0x400600, const_p:0x4005f8
pointer p address:0x601038, p:0x4005f8

查看ELF格式文件:

$ readelf -a a.out #
...[Nr] Name              Type             Address           OffsetSize              EntSize          Flags  Link  Info  Align
...[16] .rodata           PROGBITS         00000000004005f0  000005f0000000000000005a  0000000000000000   A       0     0     8
...[25] .data             PROGBITS         0000000000601028  000010280000000000000018  0000000000000000  WA       0     0     8

可以从地址分段中看出来:

const_p指向的内容在只读段。const_p的地址也被分配在只读段,所以const_p也不能再被赋值。
p指向的内容在只读段。p的地址被分配在数据段,所以p可以被修改。
注意:如果用win10的WSL运行的话,使用gdb查看运行结果。

C语言-解释复杂声明相关推荐

  1. 如何读懂 C 语言复杂的声明

    如何读懂 C 语言复杂的声明 作者能力有限, 如果您在阅读过程中发现任何错误, 还请您务必联系本人,指出错误, 避免后来读者再学习错误的知识.谢谢! 参考<<C专家编程>> 废 ...

  2. c语言数组的声明和初始化_C声明和初始化能力问题和解答

    c语言数组的声明和初始化 This section contains aptitude questions and answers on C language Declarations and Ini ...

  3. c语言函数调用必须声明void,函数声明-czysocket_dara-ChinaUnix博客

    看了C陷阱与缺陷,第一个给我震撼的就是理解函数声明了,下面是我的理解. 1.理解函数声明 为了模拟开机启动时的情形,我们必须设计出一个C语句,以显示调用位于地址0的子例程.调用语句如下: (*(voi ...

  4. c语言 函数的声明,C语言中的函数声明

    看了C陷阱与缺陷,第一个给我震撼的就是理解函数声明了,下面是我的理解. 1.理解函数声明 为了模拟开机启动时的情形,我们必须设计出一个C语句,以显示调用位于地址0的子例程.调用语句如下: (*(voi ...

  5. c语言里的负数用16进制表示什么,什么是十六进制表达式0x80000000在C语言的枚举声明中的含义...

    我正在阅读iPhone示例项目(Xcode IDE,Apple LLVM编译器4.2)的代码.在为iPhone样本项目的外部库(C语言编写)的头文件,有是在枚举类型中声明的一些事件:什么是十六进制表达 ...

  6. 生成跨语言的类型声明和接口绑定的工具(Djinni )

    Djinni 是一个用来生成跨语言的类型声明和接口绑定的工具,主要用于 C++ 和 Java 以及 Objective-C 间的互通. 示例接口定义文件: 1 # Multi-line comment ...

  7. r语言解释回归模型的假设_模型假设-解释

    r语言解释回归模型的假设 Ever heard of model assumptions? What are they? And why are they important? A model is ...

  8. 定义与声明c语言,c语言定义与声明.ppt

    c语言定义与声明 f 变量的定义与声明 什么是变量? 变量的分类 变量的属性 修饰符 变量的声明与定义的关系 变量的定义 变量的声明 总结 什么是变量? 在c语言中就是指内存或寄存器中用一个标识符命名 ...

  9. 数据结构 -- 魔王语言解释

    这是数据结构的实验~~ 这是实现一个魔王语言解释器. 这里是采用栈,队列,线性表的综合实现的. 这个程序没上交,所以是中文注释的. 其实这个程序本身实用性不强,但是是个很不错的题目. Experime ...

最新文章

  1. SpringBoot第十三篇:springboot集成spring cache
  2. Spring Boot 2.x基础教程:如何扩展XML格式的请求和响应
  3. 软件测试学习笔记:找代码中的fault,并设计特定的测试用例
  4. Lambda表达式常用代码示例
  5. 用html做一个发送邮件验证,邮件发送还有问题吗?送大家一个写好的类吧,支持stmp认证、HTML格式邮件-PHP教程,PHP应用...
  6. java mysql 占位符_在Java中编写带占位符的SQL语句
  7. Arduino--0.91寸OLED液晶屏
  8. IPV6迎来商业元年 运营商短期盈利模式成难点
  9. AGC027D - Modulo Matrix
  10. leetcode 451. 根据字符出现频率排序
  11. Oracle 20c 新特性:表空间缺省加密算法 TABLESPACE_ENCRYPTION_DEFAULT_ALGORITHM
  12. java注册系统服务_奇葩需求:springboot项目注册为windows系统服务并设置开机自启...
  13. 蚂蚁金服数据库性能超甲骨文引热议;三大运营商 5G 预约用户接近 930 万;苹果发布新版 Mac 系统| 极客头条...
  14. 古文(诗词文)—— 结构模式与复用
  15. PMP考试今年改革吗?
  16. Debian 8 安装BtSync
  17. ROS学习笔记14:ROS摄像头驱动及数据接口
  18. dne服务器没检测到有响应,设备或资源dns没检测到有响应 网络无法连接
  19. Fedora修复grub2启动项grub rescue
  20. 上车了!AR摩托车头盔了解一下?

热门文章

  1. 参观计算机实验室后的感想,参观实验室心得体会.doc
  2. SOLIDWORKS物料编码工具SolidKits Coding
  3. 尚硅谷python部分学习笔记
  4. Unity制作自定义消息提示框
  5. Android studio音乐播放器
  6. BP神经网络隐含层节点数的确定
  7. 交通灯控制系统c语言编程,基于单片机的交通灯控制系统设计(本科)毕业论文设计.doc...
  8. windows下mysql误删除数据恢复
  9. ionic3应该善用组件和指令 (实用、赞)
  10. 相关向量机(RVM)