语言规范

目前c语言的C89(C90) , C95(94),C99, 目前主要是C99, 并且C99提供了紧跟C99/C11/C14 标准的步伐。

编译时可以通过传递使用不同的语言规范进行编译,如下:
gcc –std=c99 test.c 表示采用c99的与语言规范编译该文件

gcc 与 gnu99

C99是直型C99,GNU99是带有gnu扩展名的C99

clang支持-std选项,该选项更改clang使用的语言模式。 C支持的模式为c89,gnu89,c94,c99,gnu99以及这些模式的各种别名。 如果未指定-std选项,则clang默认为gnu99模式

所有c *和gnu *模式之间的差异:

c *模式定义-fblocks。
在gnu *模式下定义没有下划线前缀的特定于目标的定义,例如“ linux”。
Trigraph默认在gnu *模式下关闭; 可以通过-fblocks选项启用它们。
解析器在gnu *模式下将“ asm”和“ typeof”识别为关键字; 在所有模式下都可以识别变体-fblocks和typeof
在某些平台上,默认情况下,在gnu *模式下可以识别Apple“阻止”扩展。 可以使用-fblocks选项在任何模式下启用它。

.h 和 .c文件

.h 和 .c 在项目中承担的角色不一样:
.c 文件主要负责实现,也就是定义函数和变量;
.h 文件主要负责声明(包括变量声明和函数声明)、宏定义、类型定义等。这些不是C语法规定的内容,而是约定成俗的规范,或者说是长期形成的事实标准

头文件被重复包含

使用宏保护解决:

#ifndef _XYZ_H
#define _XYZ_H
/* 头文件内容 */
#endif

第一次包含头文件,会定义宏 XYZH,并执行“头文件内容”部分的代码;第二次包含时因为已经定义了宏 XYZH,不会重复执行“头文件内容”部分的代码。也就是说,头文件只在第一次包含时起作用,再次包含无效

变量名冲突

通常将不需要被其他模块调用的全局变量或函数用 static关键字来修饰,static 能够将全局变量和函数的作用域限制在当前文件中,在其他文件中无效。

stdcall, cdecl,fastcall

stdcall、cdecl和__fastcall是三种函数调用协议,函数调用协议会影响函数参数的入栈方式、栈内数据的清除方式、编译器函数名的修饰规则等。

__stdcall: __stdcall是Pascal方式清理C方式压栈, 函数采用从右到左的压栈方式,自己在退出时清空堆栈

cdecl: __cdecl (The C default calling convention)即C调用约定按从右至左的顺序压参数入栈, 由调用者把参数弹出栈, 对于传送参数的内存栈是由调用者来维护的 。 __cdecl是C和C++程序的缺省调用方式。每一个调用它的函数都包含清空堆栈的代码,所以产生的可执行文件大小会比调用stdcall函数的大

fastcall : __fastcall调用的主要特点就是快,因为它是通过寄存器来传送参数的(实际上,它用ECX和EDX传送前两个双字(DWORD)或更小的参数,剩下的参数仍旧自右向左压栈传送,被调用的函数在返回前清理传送参数的内存栈),在函数名修饰约定方面,它和前两者均不同。fastcall方式的函数采用寄存器传递参数,VC将函数编译后会在函数名前面加上”@”前缀,在函数名后加上”@”和参数的字节数。

头文件

C89中标准的头文件:
<assert.h> 定义宏assert()
<ctype.h> 字符处理
<errno.h> 错误报告
<float.h> 定义与实现相关的浮点值勤
<limits.h> 定义与实现相关的各种极限值
<locale.h> 支持函数setlocale()
<math.h> 数学函数库使用的各种定义
<setjmp.h> 支持非局部跳转
<signal.h> 定义信号值
<stdarg.h> 支持可变长度的参数列表
<stddef.h> 定义常用常数
<stdio.h> 支持文件输入和输出
<stdlib.h> 其他各种声明
<string.h> 字符串函数
<time.h> 支持系统时间函数

C99新增的头文件
<complex.h> 支持复杂算法
<fenv.h> 给出对浮点状态标记和浮点环境的其他方面的访问
<inttypes.h> 定义标准的、可移植的整型类型集合,也支持处理最大宽度整数的函数
<iso646.h> 首先在此1995年第一次修订时引进,用于定义对应各种运算符的宏
<stdbool.h> 支持布尔数据类型类型,定义宏bool,以便兼容于C++
<stdint.h> 定义标准的、可移植的整型类型集合,该文件包含在<inttypes.h>中
<tgmath.h> 定义一般类型的浮点宏
<wchar.h> 首先在1995年第一次修订时引进,用于支持多字节和宽字节函数
<wctype.h> 首先在1995年第一次修订时引进,用于支持多字节和宽字节分类函数

文档更新时间: 2021-03-12 12:31   作者:周国强