C语言32个关键字详解.docx
《C语言32个关键字详解.docx》由会员分享,可在线阅读,更多相关《C语言32个关键字详解.docx(16页珍藏版)》请在冰点文库上搜索。
C语言32个关键字详解
C语言32个关键字详解
C语言中32个关键字详解
由ANSI标准定义的C语言关键字共32个:
autodoubleintstructbreakelselongswitch
caseenumregistertypedefcharexternreturnunion
constfloatshortunsignedcontinueforsignedvoid
defaultgotosizeofvolatiledoifwhilestatic
根据关键字的作用,可以将关键字分为数据类型关键字和流程控制关键字两大类。
1数据类型关键字
A基本数据类型(5个)
void:
声明函数无返回值或无参数,声明无类型指针,显式丢弃运算结果
char:
字符型类型数据,属于整型数据的一种
int:
整型数据,通常为编译器指定的机器字长
float:
单精度浮点型数据,属于浮点数据的一种
double:
双精度浮点型数据,属于浮点数据的一种
B类型修饰关键字(4个)
short:
修饰int,短整型数据,可省略被修饰的int。
long:
修饰int,长整形数据,可省略被修饰的int。
signed:
修饰整型数据,有符号数据类型
unsigned:
修饰整型数据,无符号数据类型
C复杂类型关键字(5个)
struct:
结构体声明
union:
共用体声明
enum:
枚举声明
typedef:
声明类型别名
sizeof:
得到特定类型或特定类型变量的大小
D存储级别关键字(6个)
auto:
指定为自动变量,由编译器自动分配及释放。
通常在栈上分配
static:
指定为静态变量,分配在静态变量区,修饰函数时,指定函数作用域为文件内部
register:
指定为寄存器变量,建议编译器将变量存储到寄存器中使用,也可以修饰函数形参,建议编译器通过寄存器而不是堆栈传递参数
extern:
指定对应变量为外部变量,即在另外的目标文件中定义,可以认为是约定由另外文件声明的韵蟮囊桓觥耙谩?
const:
与volatile合称“cv特性”,指定变量不可被当前线程/进程改变(但有可能被系统或其他线程/进程改变)
volatile:
与const合称“cv特性”,指定变量的值有可能会被系统或其他进程/线程改变,强制编译器每次从内存中取得该变量的值
2流程控制关键字
A跳转结构(4个)
return:
用在函数体中,返回特定值(或者是void值,即不返回值)
continue:
结束当前循环,开始下一轮循环
break:
跳出当前循环或switch结构
goto:
无条件跳转语句
B分支结构(5个)
if:
条件语句
else:
条件语句否定分支(与if连用)
switch:
开关语句(多重分支语句)
case:
开关语句中的分支标记
default:
开关语句中的“其他”分治,可选。
C循环结构(3个)
for:
for循环结构,for(1;2;3)4;的执行顺序为1->2->4->3->2...循环,其中2为循环条件
do:
do循环结构,do1while
(2);的执行顺序是1->2->1...循环,2为循环条件
while:
while循环结构,while
(1)2;的执行顺序是1->2->1...循环,1为循环条件
以上循环语句,当循环条件表达式为真则继续循环,为假则跳出循环。
C99和C89标准对比多了些什么
1、restrict:
指针类型修饰符
C99中增加了公适用于指针的restrict类型修饰符,它是初始访问指针所指对象的惟一途径,因此只有借助restrict指针表达式才能访问对象。
restrict指针指针主要用做函数变元,或者指向由malloc()函数所分配的内存变量。
restrict数据类型不改变程序的语义。
如果某个函数定义了两个restrict指针变元,编译程序就假定它们指向两个不同的对象,memcpy()函数就是restrict指针的一个典型应用示例。
C89中memcpy()函数原型如下:
代码:
--------------------------------------------------------------------------------
void*memcpy(void*s1,constvoid*s2,size_tsize);
--------------------------------------------------------------------------------
如果s1和s2所指向的对象重叠,其操作就是未定义的。
memcpy()函数只能用于不重叠的对象。
C99中memcpy()函数原型如下:
代码:
--------------------------------------------------------------------------------
void*memcpy(void*restricts1,constvoid*restricts2,size_tsize);
--------------------------------------------------------------------------------
通过使用restrict修饰s1和s2变元,可确保它们在该原型中指向不同的对象。
2、inline(内联)关键字
内联函数除了保持结构化和函数式的定义方式外,还能使程序员写出高效率的代码.函数的每次调用与返回都会消耗相当大的系统资源,尤其是当函数调用发生在重复次数很多的循环语句中时.一般情况下,当发生一次函数调用时,变元需要进栈,各种寄存器内存需要保存.当函数返回时,寄存器的内容需要恢复。
如果该函数在代码内进行联机扩展,当代码执行时,这些保存和恢复操作旅游活动会再发生,而且函数调用的执行速度也会大大加快。
函数的联机扩展会产生较长的代码,所以只应该内联对应用程序性能有显著影响的函数以及长度较短的函数。
3、新增数据类型
_Bool
值是0或1。
C99中增加了用来定义bool、true以及false宏的头文件夹,以便程序员能够编写同时兼容于C与C++的应用程序。
在编写新的应用程序时,应该使用
头文件中的bool宏。
_Complexand_Imaginary
C99标准中定义的复数类型如下:
float_Complex;float_Imaginary;double_Complex;double_Imaginary;longdouble_Complex;longdouble_Imaginary.
头文件中定义了complex和imaginary宏,并将它们扩展为_Complex和_Imaginary,因此在编写新的应用程序时,应该使用头文件中的complex和imaginary宏。
longlongint
C99标准中引进了longlongint(-(2e63-1)至2e63-1)和unsignedlonglongint(0-2e64-1)。
longlongint能够支持的整数长度为64位。
4、对数组的增强
可变长数组
数组声明中的类型修饰符
在C99中,如果需要使用数组作为函数变元,可以在数组声明的方括号内使用static关键字,这相当于告诉编译程序,变元所指向的数组将至少包含指定的元素个数。
也可以在数组声明的方括号内使用restrict,volatile,const关键字,但只用于函数变元。
如果使用restrict,指针是初始访问该对象的惟一途径。
如果使用const,指针始终指向同一个数组。
使用volatile没有任何意义。
5、单行注释
引入了单行注释标记"//",可以象C++一样使用这种注释了。
6、分散代码与声明
7、预处理程序的修改
a、变元列表
宏可以带变元,在宏定义中用省略号(...)表示。
内部预处理标识符__VA_ARGS__决定变元将在何处得到替换。
例:
#defineMySum(...)sum(__VA_ARGS__)语句MySum(k,m,n);
将被转换成:
sum(k,m,n); 变元还可以包含变元。
例:
#definecompare(compf,...)compf(__VA_ARGS__)其中的compare(strcmp,"small","large");将替换成:
strcmp("small","large");
b、_Pragma运算符
C99引入了在程序中定义编译指令的另外一种方法:
_Pragma运算符。
格式如下:
_Pragma("directive")
其中directive是要满打满算的编译指令。
_Pragma运算符允许编译指令参与宏替换。
c、内部编译指令
STDCFP_CONTRACTON/OFF/DEFAULT若为ON,浮点表达式被当做基于硬件方式处理的独立单元。
默认值是定义的工具。
STDCFEVN_ACCESSON/OFF/DEFAULT告诉编译程序可以访问浮点环境。
默认值是定义的工具。
STDCCX_LIMITED_RANGEON/OFF/DEFAULT若值为ON,相当于告诉编译程序某程序某些含有复数的公式是可靠的。
默认是OFF。
d、新增的内部宏
__STDC_HOSTED__若操作系统存在,则为1
__STDC_VERSION__199991L或更高。
代表C的版本
__STDC_IEC_599__若支持IEC60559浮点运算,则为1
__STDC_IEC_599_COMPLEX__若支持IEC60599复数运算,则为1
__STDC_ISO_10646__由编译程序支持,用于说明ISO/IEC10646标准的年和月格式:
yyymmmL
8、for语句内的变量声明
C99中,程序员可以在for语句的初始化部分定义一个或多个变量,这些变量的作用域仅于本for语句所控制的循环体内。
比如:
代码:
--------------------------------------------------------------------------------
for(inti=0;i<10;i++){
//dosometing...
}
--------------------------------------------------------------------------------
9、复合赋值
C99中,复合赋值中,可以指定对象类型的数组、结构或联合表达式。
当使用复合赋值时,应在括弧内指定类型,后跟由花括号围起来的初始化列表;若类型为数组,则不能指定数组的大小。
建成的对象是未命名的。
例:
double*fp=(double[]){1.1,2.2,3.3};
该语句用于建立一个指向double的指针fp,且该指针指向这个3元素数组的第一个元素。
在文件域内建立的复合赋值只在程序的整个生存期内有效。
在模块内建立的复合赋值是局部对象,在退出模块后不再存在。
10、柔性数组结构成员
C99中,结构中的最后一个元素允许是未知大小的数组,这就叫做柔性数组成员,但结构中的柔性数组成员前面必须至少一个其他成员。
柔性数组成员允许结构中包含一个大小可变的数组。
sizeof返回的这种结构大小不包括柔性数组的内存。
包含柔性数组成员的结构用malloc()函数进行内存的动态分配,并且分配的内存应该大于结构的大小,以适应柔性数组的预期大小。
11、指定的初始化符
C99中,该特性对经常使用稀疏数组的程序员十分有用。
指定的初始化符通常有两种用法:
用于数组,以及用于结构和联合。
用于数组的格式:
[index]=vol;其中,index表示数组的下标,vol表示本数组元素的初始化值。
例如:
intx[10]={[0]=10,[5]=30};其中只有x[0]和x[5]得到了初始化.用于结构或联合的格式如下:
member-name(成员名称)
对结构进行指定的初始化时,允许采用简单的方法对结构中的指定成员进行初始化。
例如:
structexample{intk,m,n;}object={m=10,n=200};
其中,没有初始化k。
对结构成员进行初始化的顺序没有限制。
12、printf()和scanf()函数系列的增强
C99中printf()和scanf()函数系列引进了处理longlongint和unsignedlonglongint数据类型的特性。
longlongint类型的格式修饰符是ll。
在printf()和scanf()函数中,ll适用于d,i,o,u和x格式说明符。
另外,C99还引进了hh修饰符。
当使用d,i,o,u和x格式说明符时,hh用于指定char型变元。
ll和hh修饰符均可以用于n说明符。
格式修饰符a和A用在printf()函数中时,结果将会输出十六进制的浮点数。
格式如下:
[-]0xh,hhhhp+d使用A格式修饰符时,x和p必须是大写。
A和a格式修饰符也可以用在scanf()函数中,用于读取浮点数。
调用printf()函数时,允许在%f说明符前加上l修饰符,即%lf,但不起作用。
13、C99新增的库
C89中标准的头文件
定义宏assert()
字符处理
错误报告
定义与实现相关的浮点值勤
定义与实现相关的各种极限值
支持函数setlocale()
数学函数库使用的各种定义
支持非局部跳转
定义信号值
支持可变长度的变元列表
定义常用常数
支持文件输入和输出
其他各种声明
支持串函数
支持系统时间函数
C99新增的头文件和库
支持复数算法
给出对浮点状态标记和浮点环境的其他方面的访问
定义标准的、可移植的整型类型集合。
也支持处理最大宽度整数的函数
首先在此1995年第一次修订时引进,用于定义对应各种运算符的宏
支持布尔数据类型类型。
定义宏bool,以便兼容于C++
定义标准的、可移植的整型类型集合。
该文件包含在中
定义一般类型的浮点宏
首先在1995年第一次修订时引进,用于支持多字节和宽字节函数
首先在1995年第一次修订时引进,用于支持多字节和宽字节分类函数 14、__func__预定义标识符
用于指出__func__所存放的函数名,类似于字符串赋值。
15、其它特性的改动
2006/06/14/795910.aspx
c99是在c89的基础上发展起来的,增加了基本数据类型,关键字和一些系统函数等。
其实在初学阶段C89(ANSIC)和C99的区别是不易察觉的,所以不必太在意这个。
C99有一部分是对于大字符集的优化(很多资料上写的是ANSI标准化),还加入了一些数据库函数,是C89之后的标准,我们用的C是C89标准的,C++是C89编写的,目前的C99标准其实在以前的编译器中就或多或少的支持了,目前完全支持的有这些:
MinGW、BorlandC++、dev-C++。
C99标准的新特性
在ANSI标准化后,C语言的标准在一段相当的时间内都保持不变,尽管C++继续在改进。
(实际上,NormativeAmendment1在1995年已经开发了一个新的C语言版本。
但是这个版本很少为人所知。
)标准在90年代才经历了改进,这就是ISO9899:
1999(1999年出版)。
这个版本就是通常提及的C99。
它被ANSI于2000年3月采用。
在C99中包括的特性有:
对编译器限制增加了,比如源程序每行要求至少支持到4095字节,变量名函数名的要求支持到63字节(extern要求支持到31)。
预处理增强了。
例如:
宏支持取参数#defineMacro(...)__VA_ARGS__
使用宏的时候,参数如果不写,宏里用#,##这样的东西会扩展成空串。
(以前会出错的)
支持//行注释(这个特性实际上在C89的很多编译器上已经被支持了)
增加了新关键字restrict,inline,_Complex,_Imaginary,_Bool
支持longlong,longdouble_Complex,float_Complex这样的类型
支持<:
:
><%%>%:
%:
%:
,等等奇怪的符号替代,D&E里提过这个
支持了不定长的数组。
数组的长度就可以用变量了。
声明类型的时候呢,就用inta
这样的写法。
不过考虑到效率和实现,这玩意并不是一个新类型。
所以就不能用在全局里,或者structunion里面,如果你用了这样的东西,goto语句就受限制了。
变量声明不必放在语句块的开头,for语句提倡这么写for(inti=0;i<100;++i)就是说,inti的声明放在里面,i只在for里面有效。
(VC没有遵守这条标准,i在for外也有效;但vc2005里已经默认是i在外面不可见了,但有编译选项可以设置。
)
当一个类似结构的东西需要临时构造的时候,可以用(type_name){xx,xx,xx}这有点像C++的构造函数
初始化结构的时候现在可以这样写:
struct{inta[3],b;}hehe[]={[0].a={1},[1].a=2};
struct{inta,b,c,d;}hehe={.a=1,.c=3,4,.b=5}//3,4是对.c,.d的赋值
字符串里面,\u支持unicode的字符
支持16进制的浮点数的描述
所以printf和scanf的格式化串多了支持ll/LL(VC6里用的I64)对应新的longlong类型。
浮点数的内部数据描述支持了新标准,这个可以用#pragma编译器指定
除了已经有的__line____file__以外,又支持了一个__func__可以得到当前的函数名
对于非常数的表达式,也允许编译器做化简
修改了对于/%处理负数上的定义,比如老的标准里-22/7=-3,-22%7=-1而现在-22/7=-4,-22%7=6
取消了不写函数返回类型默认就是int的规定
允许struct定义的最后一个数组写做[]不指定其长度描述
constconstinti;将被当作constinti;处理
增加和修改了一些标准头文件。
比如定义bool的,定义一些标准长度的int的,定义复数的定义宽字符的有点泛型味道的数学函数跟浮点数有关的。
里多了一个va_copy可以复制...的参数。
里多了个structtmx对structtm做了扩展
输入输出对宽字符还有长整数等做了相应的支持
相对于c89的变化还有
1、增加restrict指针
C99中增加了公适用于指针的restrict类型修饰符,它是初始访问指针所指对象的惟一途径,因此只有借助restrict指针表达式才能访问对象。
restrict指针指针主要用做函数变元,或者指向由malloc()函数所分配的内存变量。
restrict数据类型不改变程序的语义。
如果某个函数定义了两个restrict指针变元,编译程序就假定它们指向两个不同的对象,memcpy()函数就是restrict指针的一个典型应用示例。
C89中memcpy()函数原型如下:
代码:
void*memcpy(void*s1,constvoid*s2,size_tsize);
如果s1和s2所指向的对象重叠,其操作就是未定义的。
memcpy()函数只能用于不重叠的对象。
C99中memcpy()函数原型如下:
代码:
void*memcpy(void*restricts1,constvoid*restricts2,size_tsize);
通过使用restrict修饰s1和s2变元,可确保它们在该原型中指向不同的对象。
2、inline(内联)关键字
内联函数除了保持结构化和函数式的定义方式外,还能使程序员写出高效率的代码。
函数的每次调用与返回都会消耗相当大的系统资源,尤其是当函数调用发生在重复次数很多的循环语句中时。
一般情况下,当发生一次函数调用时,变元需要进栈,各种寄存器内存需要保存。
当函数返回时,寄存器的内容需要恢复。
如果该函数在代码内进行联机扩展,当代码执行时,这些保存和恢复操作旅游活动会再发生,而且函数调用的执行速度也会大大加快。
函数的联机扩展会产生较长的代码,所以只应该内联对应用程序性能有显著影响的函数以及长度较短的函数。
3、新增数据类型
_Bool
值是0或1。
C99中增加了用来定义bool、true以及false宏的头文件夹,以便程序员能够编写同时兼容于C与C++的应用程序。
在编写新的应用程序时,应该使用
头文件中的bool宏。
_Complexand_Imaginary
C99标准中定义的复数类型如下:
float_Complex;float_Imaginary;double_Complex;double_Imaginary;longdouble_Complex;longdouble_Imaginary。
头文件中定义了complex和imaginary宏,并将它们扩展为_Complex和_Imaginary,因此在编写新的应用程序时,应该使用头文件中的complex和imaginary宏。
longlongint
C99标准中引进了longlongint(-(2e63-1)至2e6