怎样编写高质量的C代码—-你真的会么???
1:编码规范介绍:
2:宏观上的高质量编码规范
3:微观上的高质量的编码规范
编码规范:
编码规范的重要性:
程序员的态度
1:不太愿意测试自己的代码
2:不愿意REVIEW其他团队的代码
专业的程序员:
专业的程序员和业余程序员主要在于态度:
专业的程序员很注重自己的形象,专业的程序员表现在代码风格上面,
专业程序员才能写出人能懂的代码,作为专业程序员,每当写下一行代码的时候,首先记住这是给人读的,其次是给机器读的
保证自己的代码尽量少的BUG
业余程序员向专业程序员的转变(不做业余程序员)
1:改变自己的态度
2:从编码规范开始
3:养成一种严谨的工作态度
仔细设计,编写代码,单元测试,功能测试,代码REVIEW
宏观上的高质量的编码规范:
版本和版权的申明
头文件的结构
源文件的结构
工程目录的结构
命名规则
程序的版式
版权和版本的申明:
版权和版本的申明位于头文件和定义文件的开头,如下:
1:版权信息
2:文件名称,标识符,摘要
3:当前版本好,作者/修改者,完成日期
4:版本历史信息
头文件:
头文件开头出的版权和版本申明
预处理快
函数和结构体申明等
头文件注意点;
1:为了防止头文件被重读引用,应当用ifndef/define/endif结构产生预处理块
2:引用头文件
3:头文件中只存在申明不存在定义(变量的声明定义尽量放在源文件中)
4:不提倡使用全部变量 extern int value;
源文件结构:
1:版权或版本申明
2:头文件引用
3:程序的实现体,包括数据和代码
工程目录结构
特点:便于维护
将头文件和定义的文件分别保存在不同的目录
加强信息隐蔽:
NetWork工程 ——->source
lib
include
命名规则
根据每个公司具体的要求
一般分为驼峰命名法,如:testUi();
和小写下划线连接命名法 test_ui();
排版
每行控制在70-80个字符以内
微观上的高质量的编码规范
1:程序的健壮性
2:编程的优化
程序的健壮性:
1:使用断言
程序一般分为debug和release版本断言assert是仅仅在debug版本中起作用的宏。
#include<assert.h>
void assert(scalar expression);
参数是假定的表达式;
assert是一个带参数的宏,假定的意思;
assert(sp != NULL);//假设sp不为null,如果为null,就会产生错误,程序终止运行;
使用断言的好处:
帮助我们跟踪程序运行和调试
输出一些错误的原因
我们可以自定义一些假定的条件
它可以捕捉到一些我们不应该发生的非法情况
注意:在函数的入口处我们可以检查一些参数的有效性和合法性
简单实例代码:
#include<stdio.h>
#include<assert.h>
#include<stdlib.h>
void out(FILE *spIn)
{
assert(spIn != NULL);
}
int main(void)
{
FILE *spIn;
spIn = fopen("src/a.txt","r");
assert(spIn != NULL );//为NULL的时候,在断言这个用法就会终止程序并且会输出错误信息,捕捉到不应该发生的非法的情况
out(spIn);
return 0;
}
2:复合的表达式
在程序中尽量使用类似
a = b = c = 1;
优势:
书写简洁
提高编译效率
注意:
不要使用太过于复杂的表达式
不要使用多用途的表达式; d = (a = b +c)+r;
3:if语句中:
布尔变量与零数值比较
在C语言中,非0为真,0为假
if(flag) //为真
整型变量与0比较,使用==号进行比较
指针变量与NULL比较,
if(sp == NULL){}
4:使用const提高函数的健壮性:
定义只读变量 const int a = 10;
可以修饰函数的参数 const struct *stu------>常量指针
函数返回值使用const修饰
const int* getConstInt(){}//指针函数返回的是常量指针
5:内存的管理规则;
使用malloc的时候,返回的是void *,但是是需要去检查是否为NULL
不要忘记 给数组和动态内存赋予初始化数值,防止将未被初始化的内存使用
避免数组或指针的下表越界
动态内存的申请和释放必须要去成对出现
free完了之后,需要立即将指针设置为NULL
6:指针参数的内存传递
如果函数的参数是一个指针,不要指望用该指针去申请动态内存
如void getmemory(char *p,int num){
p = (char*)malloc(sizeof(char)* num); //错误的使用
}
不要用return去返回指向"栈内存"的指针
char *getString(){
char *p = "hello";
return p; //错误的使用,因为函数内部的局部变量是存放在栈中的,函数在调用完了之后,会将函数栈给释放,这个时候,释放出来之后,指针指向内存空间的数值的具体是多少就是不可以控制的;
}
7:常量的使用
常量的数值在运行期间是恒定不变的
学会使用宏#define来解决常量修改的问题,
8:循环语句的效率:
在多重循环中,如果有可能,应当将最长的循环放在最内存,最短的循环放在最外层,以减少CPU跨切循环层的次数;
尽量将逻辑判断放在循环体的外面;