学习笔记之C语言规范篇

C语言的规范涉及行文风格,语法规则。

行文风格:

1.空格的使用。

关键字与字符之间(否则语法错误),关键字与括号之间(行文更美观),字符与操作符之间(视情况而定);

2.tab键的使用。

换行时,使用,以使层次结构更清晰,如if .for.while的语句体以及函数体。

3.空行的使用。

不同的语句体之间,如定义与执行之间的等等

4.{}的使用。if.while.for.中的 { 与条件语句同行,} 换行对齐关键字。

5./* */的使用。用于注释,不可嵌套。

语法规则:

1. .h文件的编写

#include预处理指令,会在编绎的预处理阶段将include后的.h(用户定义用“”,库函数<>)文件自动展开,因此,在编写.h文件时,需作如下定义:

#ifndef **_H

#define **_H

/*文件内容*/

#endif

这样,当#include "**.h"嵌套多次出现在同一.c文件中时,才不会重复引用此文件中的内容。

由于#include "**.h"可能会被多个.c文件用到,因此不允许在.h文件中进行变量及函数的定义,因为任何变量和函数的定义只能有一次。可进行类型的定义,宏定义以及变量及函数的申明.

各种语句的编写顺序为:#ifndef  **.h  #define **.h  -》#include -》》 宏定义 -》》类型定义 -》》 变量申明  -》》函数申明(以防未定义即被使用)

 2..c文件的编写

同一类处理功能的函数写在一个文件内,每个函数的功能尽量单一,用提取公因式的方式编写函数,即将公因子提出来,独立成一个函数,如D = AB+ AC=A(B+C);那么可以将函数A独立封装出来。(即C语言的特性之可复用性的,其中A为可复用的)

在不同的平台实现同样的功能,函数的实现体可能会有不同,因此可以用宏定义来控制编绎器区分编绎,如#if (SYSTEM == _32bit) ......    #else (SYSTEM == _64bit)   .....#endif(即C语言特性之可移植性)

3.预处理

分为三类型:1包含文件#include;2宏定义#define;3条件编译#ifdef.#if.#elif .#endif

作用:编译时的预处理阶段进行的动作。

4.变量

任何变量都有两种属性:1.数据类型/*存放什么类型的数据:如int ,char,float,关系到占用空间的大小*/;2.存储类型/*数据存在什么类型的存储空间中如:静态存储区,动态存储区:堆或栈*,决定了变量的生存期,(静态存存储区中的变量,从开辟空间开始到程序运行结束,一直存在,;堆中的变量从用户开辟开始到用户释放掉结束;栈中的变量从函数调用时系统自动分配开始到函数调用结束系统自动收回结束),一般有两种方式决定存储类型:1通过用户定义如在变量前加auto,static等类型定义或者通过malloc分配的空间;2系统根据变量在代码中的位置,自动分配到相应的存储空间:如定义在函数体内的局部变量,系统将会在栈中给它分配空间;定义在函数体外的全局变量,系统会在静态存储区给它分配空间*/

全局变量:一般能用局部变量的地方尽量别用全局变量:1.全局变量一直占用着存储空间,比较消耗内存,不像局部变量用完了就释放掉;2.根据程序设计的思想:高内聚,低耦合,而全局变量加剧了模块之间的关联,即耦合度。当然,有时全局变量的使用不可避免,若是这种情况,使用时也要谨慎,首先,要给全局变量赋初值,可在定义的时候赋值,可以在程序开始时,专门写一个初始化函数,用于初始化全局变量。这一点,一定要注意,如果不赋值,在程序运行时,会是一些随机值,这样就有可能影响到涉及到全局变量的多模块的功能,特别是将它作为一个侦测条件时。当全局变量用作侦测条件时,(这个经常被用到),要弄清楚,当第一次侦测成功并做相应处理后,是否要改动此值,因为如果在循环里,如果不做变动的话,之后的每次都会侦测成功,持续做相同的处理(通常情况,这个值都会被复原,或是改动)。所以当使用全局变量作为侦测条件,每次使用,都要想一想,侦测成功,要不要改动。

5.常量

用const来定义的数据类型或者函数的返回地址(因此函数的返回值不能作为左值使用),存储在只读存储区rom(代码区),该存储区的特点是不允许对存储区的内容作改动,只可进行读取。一般将程序中的输入型数据定义为const类型。适当的使用常量可以给用户提供有用的信息,即这一段输入型数据,不会被改变,另外一个优点就是,使用常可以让编译器保护那些不能被改变的区域,三可能会增加代码的紧凑性(暂未接触).

6.宏和枚举常量

前面的变量和常量都可以用符号来表示数据,宏和枚举常量也有这样的作用,但不同的是,前者占用内存而后者不占用内存,

如#define MON 1

#define TUE 2

....

enum{

MON = 1,

TUE,

WEN,

.....

 

};

这里的MON和TUE在编绎时均只作符号的替换,不分配空间;

但相比变量和常量而言,其缺点也显而易见,即不能进行类型的定义,宏和枚举常量定义的数据都只能是整型的。

宏与枚举的区别:宏只是编译的时候单纯的将前面的字符替换成后面的字符;而枚举是一种类型,还可以用来定义变量。、

宏定义用法:与系统特性有关的,一旦系统定下来后,其值都不会发生改变量;

#if (SYSTEM == SYSTEM_32)

 typedef unsigned int u32bit;

#define CRY  _120MHZ

#elif ((SYSTEM == SYSTEM_16))

 typdef unsigned long u32bit;

#define CRY _60MHZ

#endif

枚举常量用法:一量系统定下来后,可能会出现不同的情况,对不同的情况用枚举一一列出来;

enum{

br_115200,

br_9600,

......

};

 

5.优先级

单目-〉算术运算->移位运算->关系运算->逻辑运算->逗号运算(双目:算一关喽)

6.循环

while .for .do- while(条件满足loop,一旦不满足break)

重点讲下do-while的用法,以前觉得跟while没什么区别,用这个能实现的这个同样能实现,而且这个用起来很别扭,所以几乎都没用过。

do{}while();别忘了,后面还有个封号,实现的功能是先将语句执行一遍后,再判断是否要继续执行,最大的用处在于(否则就可以直接用while了):当你的循环条件需要执行了do里面的语句后才能获得。比如,我在密箱里持续的摸球,直到摸到白球为止,首先我得摸出球来,再判断这个球是不是白球,(也就是先动作后才可以判断)不是白球就继续摸,那就是

do{

球 = 摸球(箱子);

}while(球 != 白球);                  /*哈哈,是不是很形象。。。。吐舌头*/

另外关于do{}while();还有一个秒用,相信有部分人在看代码时会看到#define  GET_MIN_VALUE do{ min = a>c?a:c; ......;}while(0);类似这样的语句,通常用在宏定义了多条语句的情况下,有人会说,不加do{} while(0);会有什么影响呢,举个例子

if (a == b) GET_MIN_VALUE;

 else ......

不果不加的话就是,if(a ==  b) min = a>c;.....else....这样宏里之后的语句都不在if条件成立的范围内,也许你说,那我把语句在宏定义里用括号括起来,这样同样会有问题,根据我们的习惯,在语句后都会习惯性的加一个;号,于是就成了if(a == b )min = a>c;;else ...还是错误,因此do{}while(0);能避免宏的副作用,在goto语句前使用可以避免一些危险的情况;

7.选择

if.else if.else /swith(){case:}/if goto

前面的都比较常用,条件满足continue,条件不满足break,后面的goto通常使用比较少,主要因为当goto到某特定语句时,中间会跳过多行语句未执行,如果其中刚好有对变量的定义,则会导致,后面语句出错。通常不会被使用到,除了在多重循环中,需要直接跳出所有循环,而频繁的使用break,造成不便,可使用goto直接跳出多重循环,另外,当多处条件满足,需要执行同一段语句时,可以使用goto让它们跳往一处执行即可,既可避免了通过函数调用方式实现时造成的压栈出栈的时间开销和内存开销,又避免了在每处都编写同样程序的代码开销。暂时只推荐这两种情况时使用goto,用法:

if(....){

goto erro;} 

  .....................

erro:  

   .............

 swith (0)

case A:;

....

break;

这里的case后面只能是宏,枚举常量,“”字符串,数字等类型的常量,不能使用用const定义的常量。

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值