C语言的声明
来源:互联网 发布:阿里云免费架设https 编辑:程序博客网 时间:2024/04/29 19:31
C语言中变量的声明一般特指以extern
修饰的变量,表明该变量在其他文件中定义。这里声明是更一般的概念,包括变量的定义、声明和函数的原型等。
声明的通用格式
声明的通用格式如下:
[存储类型] [类型限定符] [类型说明符] 声明符;
- 存储类型。包括四种,
auto
、static
、extern
和register
。可选,但在声明中最多只能有一种存储类型。若使用,必须放在整个说明式的最前面。若是函数原型,则可用的只有static
和extern
,且默认为extern
。 - 类型限定符。包括
const
和volatile
两类。可选的,可同时使用,也可以只使用其中一个。 - 类型说明符。基本类型、结构体类型、联合类型和枚举类型及用
typedef
定义的类型的类型名。类型说明符和类型限定符的先后顺序没有严格限制,一般是将限定符放于说明符前面。
声明符包括以下四种:
- 标识符,表示声明的是一般变量,标识符为一般变量的名称。
- 标识符后面跟随
[]
,表示声明的是数组,标识符表示数组变量的名称。 - 标识符前面加
*
,表示声明的是指针变量,标识符是指针变量的名称。 - 标识符后面跟随
()
,表示函数原型。
声明符号也可能是上述四种的混合,对于复杂的声明符(例如int *(*x[10])(void)
,采用以下原则:
- 首先定位声明的标识符,然后从此处向外开始解释
- 优先选择
[]
数组和()
函数后是*
指针。
为了避免这种复杂性,最好使用类型定义来简化声明。
声明符之间与逗号分开。表示变量的声明符可以后接初始化式。建议在定义变量的同时将其初始化。
存储类型
C语言中变量的特性
- 存储期限。变量的存储期限决定了为变量分配内存和释放内存间的时间,有自动存储期限和静态存储期限两类。具有自动存储期限的变量在块(函数体或符合语句)内变量定义处获得内存空间,而当块结束时释放内存空间。静态存储空间的变量在变量定义处获得存储空间,直到程序运行结束才释放内存空间。具有静态存储期限的变量的初始化必须使用常量。
- 作用域。有块作用域和文件作用域两种。块作用域是从变量声明的地方开始,到块的结束处为止。文件作用域是从变量声明的地方开始,直到文件结尾。
- 链接。变量的链接决定了变量在程序内的共享范围,有外部链接、内部链接和无链接三类。具有外部链接的变量可以被程序内的多个文件共享,而具有内部链接的变量只能属于单独一个文件,可在文件内的各个函数间共享,无链接的变量属于单独一个函数,不能共享。
其中在块(函数体或复合语句)中不声明存储类型的变量默认使用auto
存储类型,具有自动存储期限、块作用域,并且无链接。在所有函数的最外层,不声明存储类型的变量默认使用extern
存储类型,具有静态存储期限、文件作用域和外部链接。
auto
存储类型
auto
存储类型只对块内的变量有效,声明的变量具有自动存储期限、块作用域,且无链接。不需明确指出,在块内不指明存储类型的变量都默认是auto
型的。
static
存储类型
当static
用于所有函数的最外层的变量时,该变量具有静态存储期限、文件作用域和内部链接。利用这个性质,可以利用static
进行信息隐藏。
当static
用于块内变量时,说明该变量具有静态存储期限、块作用域且无链接。
extern
存储类型
extern
使多个文件共享同一个变量,当编译器编译到这里是,就会知道不用给这个变量分配空间,这个变量的定义是在外部的某个文件内。注意:在程序内可以多次声明同一个变量,但只能有一次定义。
register
存储类型
register
存储类型的变量要求把变量存储在寄存器中,而不是像其他存储类型的变量保存在内存中。但这只是一种请求,实际上由编译器来决定实际使用哪种方式。
register
存储类型只对块(函数体或复合语句)内的变量有效,具有自动存储权限、块作用域、无链接,但是由于不存在内存中,所以没有地址就不能使用取地址符&
获取地址。常用于频繁访问和更新的变量。
当前编译器已非常强大,可自动选择内存和寄存器来作为变量的保存方式,register
已不再常用。
函数的存储类型
函数的存储类型只能使用extern
和static
,extern
是其默认的存储类型,说明函数是外部链接的,而static
说明函数是内部链接的,只能在定义函数的文件内使用该函数。
类型限定符
类型限定符包括const
和volatile
两种。
const
声明一些只读变量,可以访问但是不能改变它们的值。
volatile
用于指向那些“易变”的存储空间。所谓易变的存储空间,是指该内存空间可能在程序自身并未试图存放新值的情况下在运行期间改变内容,例如保存来自输入设备数据的内存空间。volatile
的一个用途是用于避免编译器的不适当的优化。
/*************************************** * different_declarations.c * * * * C语言中的不同的声明 * ***************************************/#include <stdio.h>typedef char * Name;static void SayHello();int main(){ static int x = 10.0f; printf("x = %d,", x); const char month[] = "January"; printf("month = %s,", month); static const char *p = "Hello"; printf("p = %s\n", p); SayHello(); Name names[3] = {"Tom", "Jim", "Jammy"}; int i = 0; for (; i < 3; i++) printf(",%s", names[i]); printf("\n"); return 0;}void SayHello(){ printf("Hello");}
参考文献
1.K.N. King 著,吕秀峰 译. C语言程序设计-现代方法. 人民邮电出版社
- c语言的声明
- c语言的声明
- C语言的声明
- c语言的声明
- C语言的声明
- C语言的声明
- 奇怪的c语言声明
- 分析C语言的声明
- 分析C语言的声明
- 20100623--C语言的声明
- C语言声明的理解
- C语言奇特的声明
- C语言的复杂声明
- 分析C语言的声明
- 复杂的C 语言声明
- C语言声明的解析
- C语言的声明分析
- 分析C语言的声明
- POJ 1188 解题报告
- LeetCode Reverse Linked List II
- Unity Manual之Network 网络
- mysql视图
- ODOO8按钮权限更改(2)
- C语言的声明
- VirtualBox的四种网络接入方式
- 黑马程序员-oc-一些关键字区别(APD)
- 【LeetCode-面试算法经典-Java实现】【160-Intersection of Two Linked Lists(单链表的交集)】
- 【LeetCode-面试算法经典-Java实现】【165-Compare Version Numbers(比较版本号)】
- 子类化Button[Control.OnMouseMove 方法]
- 【LeetCode-面试算法经典-Java实现】【168-Excel Sheet Column Title(Excell列标题)】
- leetcode 10 Regular Expression Matching
- MSDN How to