C语言声明一览
来源:互联网 发布:奥数 高斯算法 教师版 编辑:程序博客网 时间:2024/05/23 15:16
C语言中有几个难点,声明、数组和指针等。本文先介绍一下声明问题。
1、几个关键字的用法。
static,const,extern,typedef。
static 在C语言中主要有两个意思,在函数体内,表示被修饰变量在调用期间保持值的延续性;在函数级别,表示该函数只对所在文件可见。
const 表示一个变量在所影响的作用域内不可变。如,函数的形参void foo(const char * s);表示s所指向的内存在foo函数体内不可被改变(在别处则没有这个限制);另外,const与指针同时使用时,有三种情况:
const char * s;//表示s所指向内存不可变char * const s;//表示指针s的值不可变,即s所指向的地址是固定的const char * const s;//表示s的值既不可变s所指内存也不可变。
extern 修饰函数时表示函数全局可见(实际上不加static修饰的函数都是全局可见的);作用于变量,表示该变量在其他地方定义;其实在C++中也有使用,extern “C”,使得C++的函数可以在C中调用。
typedef 为一个类型起一个新的名字(不是宏的文本替换),一旦确定之后,该类型不能有别的修饰:
typedef int myInt;unsigned myInt i; //errortypedef char * string;string dog, cat; //等效于:char * dog; char * cat;#define string char *string dog, cat; //等效于:char * dog; char cat;
typedef 可以简洁表示指向其他东西的指针,有点绕:
typedef void (*func)(int);/* 表示func是一个函数指针,接收一个int型参数,返回值是void */
2、复杂声明
结构体、联合体和枚举类型。
结构体与联合体接近。
在不使用typedef时,结构体声明方式有:
struct { 内容...}; //这种声明无法再次使用struct { 内容...} ele, book; //ele 和book表示的是变量struct tag { 内容...}; //struct tag 合起来当作一个类型
结构体有一些高级用法,比如数组不能直接值传递,但结构体可以,所以如果存在频繁对某个数组进行值传递的话,可以这样声明
struct int_tag {int value[100];};
struct int_tag 所占的内存为100个int型大小,可以直接赋值。
另外结构体里可以包含指向自身类型的指针。
如果只是声明了struct/union/enum,那在声明新的变量时需要将关键字带上,如:
struct int_tag a;
3、解释声明的优先级规则
一些复杂的声明:
char * const *(*next)();char *(* c[10])(int **p);void (*singal(int sig, void(*handle)(int)))(int);
如果下述的一套规则,那么上述几个声明分析起来就十分困难:
A. 声明从名字开始读取,然后按照优先级顺序依次读取
B. 优先级的顺序为:
B.1 声明中被括号括起来的部分
B.2 后缀操作符:
()表示这是一个函数;[]表示这是一个数组。
B.3 前缀操作符:
*表示“指向…的指针”
C. 如果const等关键字的后面紧跟类型说明符(int,long)那么它作用于类型说明符,其他情况下,作用于它左边紧邻的指针*符号
分析:
上述代码第一行
- 首先找到名字next,注意其被括号包围(A)
- 分析括号里的部分,*next,所以next是指向…的指针(B.1 B.3)
- 括号外有*前缀和()后缀(B)
- 取()后缀,所以next是一个指针函数,传入参数为空,并返回… (B.2)
- 取*前缀,表示返回的是一个指针 (B.3)
- 取出剩余前缀,char * const 解释为指向字符的常量指针(C)
所以,代码第一行的解释为:next是一个指针,该指针指向一个函数,该函数返回一个指针,该指针指向一个类型为char 的常量指针。(非常不标准的英语是:next is a pointer to a function which return a pointer to a const char type pointer)。
同理,第二行的声明:
- 找到c
- c是一个数组,大小为10
- 数组元素是指向…的指针
- 参数为int **的函数
- 函数返回值为char *
所以c是一个元素类型为 参数为int**且返回值为指向char的指针的函数指针,且大小为10的数组。
第三行的声明:
- 找到signal
- 是一个函数(参数先不管)
- 返回一个函数指针
- 返回的函数指针的参数是int,函数指针的返回值是void
- signal所传入的参数有两个,一个是整型,一个是void(*func)(int)
- func 也是一个指针,指向一个接收int参数并返回void的函数
发现signal返回值与所传递参数的一致性,
typedef void(*ptr_func)(int);ptr_func singal(int, ptr_func);
这样就能简化signal的定义了。
以上内容总结《C专家编程》。
4、typedef的困惑
自己在学习C语言的时候,不知道typedef的语法究竟是什么样的,在总结C语言的声明之后,便豁然开朗。
C语言声明一个变量的语句为statements V; 即V是某个类型的一个变量。如果在这个语句前加上typedef,即typedef statements V; 那么V就是这个类型的“别名”。
例:
unsigned int uintA; //uintA 是一个变量typedef unsigned int uintA; //uintA 是一个unsigned int的类型unsigned char name[20]; //name 是一个长度为20的字符数组(不能简单当作指针)typedef unsigned char name[20]; //name 是一个类型,可以声明一个长度为20的字符数组的变量void(*ptr_func)(int); //ptr_func 是一个函数指针,参数为int,返回空typedef void(*ptr_func)(int); //ptr_func 是一个函数指针类型,可以声明一个接收int型参数返回值为void的函数指针变量。
以上为个人理解。
- C语言声明一览
- C语言快捷键一览
- C语言未定义行为一览
- C语言未定义行为一览
- c语言的声明
- c语言声明
- C语言函数声明
- C语言声明语法
- C语言声明
- C语言复杂声明
- c语言的声明
- C语言复杂声明
- C语言 类型声明
- C语言声明
- C语言复杂声明
- C语言声明解析
- C语言的声明
- c语言的声明
- 各种极致的树莓派玩法
- CSS清除浮动大全共8种方法
- lucene4之后的近实时搜索实现
- nginx安装
- QGraphicsView 重写drawBackGround刷新问题
- C语言声明一览
- Linux下C编程知识整理
- 第12章:继承
- 我有个问题
- 用java实现 小孩围圈数三退一游戏
- Objective-C学习笔记(六)——运算符之一元运算符
- oracle数据库实战_如何利用PL/SQL远程登录oracle数据库
- 2015072201 - 越来越不像技术博客
- 沙盒获得根目录