关键字:
C语言关键字32个:
关键字 意 义
auto 声明自动变量,缺省时编译器一般默认为 auto
int 声明整型变量
double 声明双精度变量
long 声明长整型变量
char 声明字符型变量
float 声明浮点型变量
short 声明短整型变量
signed 声明有符号类型变量
unsigned 声明无符号类型变量
struct 声明结构体变量
union 声明联合数据类型
enum 声明枚举类型
static 声明静态变量
switch 用于开关语句
case 开关语句分支
default 开关语句中的“其他”分支
break 跳出当前循环
register 声明寄存器变量
const 声明只读变量
volatile 说明变量在程序执行中可被隐含地改变
typedef 用以给数据类型取别名(当然还有其他作用)
extern 声明变量是在其他文件正声明(也可以看做是引用变量)
return 子程序返回语句(可以带参数,也可不带参数)
void 声明函数无返回值或无参数,声明空类型指针
continue 结束当前循环,开始下一轮循环
do 循环语句的循环体
while 循环语句的循环条件
if 条件语句
else 条件语句否定分支(与 if 连用)
for 一种循环语句(可意会不可言传)
goto 无条件跳转语句
sizeof 计算对象所占内存空间大小
auto:编译器在默认的缺省情况下,所有变量都是auto的。
register:这个关键字请求编译器尽可能的将变量存在 CPU 内部寄存器中而不是通过内
存寻址访问以提高效率。
register 变量必须是一个单个的值,并且其长度应小于或等于整型的长度。 而且 register 变量可能不存放在内存中, 所以不能用取址运算符“ &”来获取 register 变量的地址。
static:这个关键字在 C 语言里主要有两个作用。
第一个作用:修饰变量。变量又分为局部和全局变量,但它们都存在内存的静态区。
静态全局变量,作用域仅限于变量被定义的文件中,其他文件即使用 extern 声明也没法
使用他。准确地说作用域是从定义之处开始,到文件结尾处结束,在定义之处前面的那些
代码行也不能使用它。想要使用就得在前面再加 extern ***。
静态局部变量,在函数体里面定义的,就只能在这个函数里用了,同一个文档中的其他
函数也用不了。由于被 static 修饰的变量总是存在内存的静态区,所以即使这个函数运行结束,这个静态变量的值还是不会被销毁,函数下次使用时仍然能用到这个值。
第二个作用:修饰函数。函数前加 static 使得函数成为静态函数。函数的作用域仅局限于本文件(所以又称内部函数)。使用内部函数的好处是:不同的人编写不同的函数时,不用担心自己定义的函数,是否会与其它文件中的函数同名。
【规则 1-1】命名应当直观且可以拼读,可望文知意,便于记忆和阅读。
【规则 1-2】命名的长度应当符合“min-length && max-information”原则。
【规则 1-3】当标识符由多个词组成时,每个词的第一个字母大写,其余全部小写。
【规则 1-4】尽量避免名字中出现数字编号,如 Value1,Value2 等,除非逻辑上的确需要编
号。比如驱动开发时为管脚命名,非编号名字反而不好。
【规则 1-5】对在多个文件之间共同使用的全局变量或函数要加范围限定符(建议使用模块名(缩写)作为范围限定符)。
【规则 1-6】标识符名分为两部分:规范标识符前缀(后缀) + 含义标识 。非全局变量可以不用使用范围限定符前缀。
【规则 1-7】作用域前缀命名规则。
【规则 1-8】数据类型前缀命名规则。
【规则 1-9】含义标识命名规则,变量命名使用名词性词组,函数命名使用动词性词组。
【规则 1-10】程序中不得出现仅靠大小写区分的相似的标识符。
【规则 1-11】一个函数名禁止被用于其它之处。
【规则 1-12】所有宏定义、枚举常数、只读变量全用大写字母命名,用下划线分割单词。
风格这些应与项目中一致,与项目开发成员共同约定并在详细设计文档中给出
【规则 1-13】考虑到习惯性问题,局部变量中可采用通用的命名方式,仅限于 n、 i、 j 等作为循环变量使用。
【规则 1-14】定义变量的同时千万千万别忘了初始化。定义变量时编译器并不一定清空了
这块内存,它的值可能是无效的数据。
【规则 1-15】不同类型数据之间的运算要注意精度扩展问题,一般低精度数据将向高精度
数据扩展。
sizeof:sizeof 在计算变量所占空间大小时,括号可以省略,而计算类型(模子)大小时不能省略。
sizeof(int) *p的意思是sizeof(int)的值乘于p
int a[100] sizeof(a) = 400 sizeof(&a) = 400 sizeof(&a[0]) = 4
&a不是指向指针的指针,因为&a和a的值相等,但是*&a和*a的值不相等。*&a和a的值一样,说明*&a仅仅是对这个数组指针进行了取值,取得的是数组的值,即数组首元素的地址,而不是对&a这个地址进行了取值。这个应该是c语言中针对数组指针运算的规定。
Signed + unsigned = unsigned
空指令尽量用NULL;而不是一个分号;要让人知道这里不执行如何操作。
【规则 1-17】先处理正常情况,再处理异常情况。
在编写代码是,要使得正常情况的执行代码清晰,确认那些不常发生的异常情况处理
代码不会遮掩正常的执行路径。这样对于代码的可读性和性能都很重要。
case 后面只能是整型或字符型的常量或常量表达式
【规则 1-21】按字母或数字顺序排列各条 case 语句。
【规则 1-22】把正常情况放在前面,而把异常情况放在后面。
【规则 1-23】按执行频率排列 case 语句
【规则 1-24】简化每种情况对应的操作。
continue语句只用在for、while、do-while等循环体中, 常与if条件语句一起使用, 用来加速循环。不能应用在switch中。
【规则 1-34】如果函数无参数,那么应声明其参数为 void 因为有的编译器无参数可以编译通过
void *pvid; pvoid++;ANSI错误 GNU正确
【规则 1-38】 return 语句不可返回指向“栈内存”的“指针”,因为该内存在函数体结束时被自动销毁。
return; 在ARM里面返回的r是r0,其它芯片不知道,需要查一下寄存器程序调用规则,
int a = return ; 那么a = r0的值。
const: 定义 const 只读变量,具有不可变性。
case 语句后面是不可以可以是 const 修饰的只读变量
节省空间,避免不必要的内存分配,同时提高效率,(不分配存储空间,是一个编译期间的值)
const 定义的只读变量在程序运行过程中只有一份拷贝(因为它是全局的只读变量,存放在静态区),而#define 定义的宏常量在内存中有若干个拷贝。
const int *p; //const 修饰*p,p 是指针, *p 是指针指向的对象,不可变
int const *p; //const 修饰*p,p 是指针, *p 是指针指向的对象,不可变
int *const p; //const 修饰 p, p 不可变, p 指向的对象可变
const int *const p; //前一个 const 修饰*p,后一个 const 修饰 p,指针 p 和 p 指向的对象
都不可变
volatile :const volatile int i= 10;实际上此声明表示的申明了一个const int型的变量,所以i是只读变量,不能被修改。同时i又被volatile修饰了,意思就是说不允许编译器优化代码,在代码中每次用到i时都要直接从内存中去取数。
所以,虽然const volatile int i = 10;定义没错,但是这样的定义没有什么实际的意义。
extern int i; //写成 i = 10;行吗? 全局可以,全局变量默认是extern 局部不行
extern void fun( void);//两个 void 可否省略?可以,函数默认是int
int j = 1; extern double j; //这样行吗?为什么? 可以,extern只是声明
struct: 空结构 sizeof为1;
C99 中,结构中的最后一个元素允许是未知大小的数组,这就叫做柔性数组成员,但结
构中的柔性数组成员前面必须至少一个其他成员。柔性数组成员允许结构中包含一个大小可
变的数组。sizeof 返回的这种结构大小不包括柔性数组的内存。包含柔性数组成员的结构用
malloc ()函数进行内存的动态分配,并且分配的内存应该大于结构的大小,以适应柔性数组
的预期大小。typedef struct
{
char c;
int a[];
}aa;
sizeof(aa)为4;
union大小端模式判断:
int checkSystem( )
{
union check
{
int i;
char ch;
} c;
c.i = 1;
return (c.ch ==1);
}
const Stu_pst stu3; Stu_pst是类型省略,修饰指针。
编译器用空格代替原来的注释