最近做了个小项目,按键+数码管显示+SPI通信,对于参数设置和通信颇多感触,这两个看似简单,做起来一点都不简单,要是做的可靠全面更是不简单,不管是工作量和对c的要求一点都不比控制的核心少和浅。现把做项目的过程中遇到的几个问题摘出来,做个总结,也方便以后看。
1,永远不要把外部函数和变量的声明放到.c文件中,而是要:
c源文件要包涵自己的头文件,目的就是让编译器检查定义和声明的一致性,如下
a.c
#include <a.h>
int sum(int a,int b)
{
……
}
a.h
int sum(int a,int b);
这样在a.c中包含自己的头文件a.h,在a.c中的函数sum修改时,编译器在编译时就会检查函数的定义和声明是否一致性。在其他比如b.c源文件中,如果要用到a.c中的sum函数时,在b.c的源文件中包涵a.h即可。
2,最好不要在头文件中定义变量
定义变量和声明变量的区别在于定义会产生内存分配,是汇编阶段的概念;而声明则只是告诉包含该声明的模块在链接阶段从其他模块寻找外部函数和变量。
全局变量如果在头文件中定义,如下:
#ifndef _XXXX_H
#define _XXXX_H
int A;
……
#endif
那么,如果这个头文件被引用的话,变量A会被重复定义,显然语法上就错了。只不过有了这个#ifndef的条件编译,所以能保证你的头文件只被引用一次,在编译时会通过。不过若多个c文件包含这个头文件时,还是会出错,因为宏明的有效范围仅限于本c源文件,所以在多个c文件编译时是不会出错的,但在链接时就是报错,多出定义了同一个变量。
3,关于switch语句中变量的定义
switch(i)
{
case 1:
static char s_u8AA; //错,编译不通过
//………
}
应该把变量定义`static char s_u8AA`放在switch前面。之所以在switch中最好不要定义变量,是因为这样可以避免出现下面的情况:
case 1:
int x;
case 2:
x = 0;
4,位变量必须是全局变量或static变量。
a.可以放在源文件的开始bit g_bFlag;
b.也可以放在源文件的中间,比如函数中,但是static类型,比如static bit s_bFlag
c.但不允许在函数内部这样定义bit b_Flag
,这违反了位变量必须是全局变量或static变量的原则。
5,条件与&&
中,最好不要有函数,特别是需要执行到条件与&&
每次都要运行的函数,比如与程序的时钟滴答TickTime
有关的函数。
u8FlagDisPosFlash = u8FlagDisPosFlash && LedStateChange();
其中,LedStateChange()与TickTimer有关,程序运行与预期不符。推测是,编译器在编译时,当u8FlagDisPosFlash = 0
时不执行LedStateChange()
,导致运行效果和预期不符。修改如下:
char aa = 0;
aa = LedStateChange();
u8FalgDisPosFlash = u8FlagDisPOsFlash && aa;
这样修改,达到预期效果!
总结,永远不要把外部函数和变量的声明放到.c源文件中,不要在头文件中定义变量,头文件只放声明即可。swithc语句中不要定义变量,而要在其前面定义;bit位变量必须是全局变量或static变量;条件与&&
中最好不要出现函数,因为可能不被执行。