C语言编程自我总结
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
1.编译器选择8级优化时,可能会出现错误。刚写好的程序,建议先用0级优化看能否正
常运行,再用更高的优化等级进行优化。
2.a、写中断程序一定要用using语句指定寄存器组。第1、2、3组都可以,不能是0,否
则可能会main()函数冲突。从一个中断程序中调用函数必须和中断使用相同的寄存器组(摘自《Keil Cx51 编译器用户手册中文版》P129)。建议把原本中断函数需要调用的函数直接写在中断函数里,无须调用。
b、51单片机的中断有两个优先级。一个中断不会打断另一个相同优先级的中断。这样
相同级别中断可以使用同一个组。比如:低优先级的中断函数都用using 1,高优先级的中断都用using 2 。这样不会冲突。
3.C语言无符号数容易犯的错误。若定义成有符号数char,则不会陷入死循环。
main()
{
unsigned char i;
for (i = 2; i>=0; i--)
{
printf("%d",i);
}
}
4.C51忌讳使用绝对定位_at_,因为只要定义变量和变量的作用域,编译器就会把一个固
定地址给这个变量,无须人工将其绝对定位,这样可能引发其他问题。
5.bit与sbit的区别:bit定义的位标量的地址是随机的,而sbit定义的位标量的地址是确
定的。bit只能访问芯片内部RAM中的可寻址位20H-2FH,而sbit可以访问芯片内部RAM中的可寻址位和特殊功能寄存器中的可寻址位。注意不能直接在程序里用P1^0等位变量,需要经过sbit定义才可以使用。
例如:
bit tem ;
sbit led=P1^0 ;
tem的地址是随机分配的,而led的地址则固定为0x90.0 。sbit变量后面需要跟等号=。
6.为了避免由于使用参数宏而带来意外的错误,需要注意以下几点:
6.1宏的参数必须带括号,例如#define CIRCLE_SQUARE(R)3.141*(R)*(R)
6.2对所使用的参数宏进行简单地展开检查;
6.3使用简单表达式、对参数加括号、避免节外生枝的使用方式(例如“++”、“--”一
类都属于不必要的附件运算);
6.4在参数宏定义时,对于运算顺序通过括号进行明确的限定,只要遵循以上几点,就
可以避免大多数应用场合的意外错误。
手把手教你写程序
内容:从最简单的程序入手,手把手教你写程序,让同学们拿到一个复杂的程序或者任务,能快速找到切入点,写出程序,再在此基础上优化程序。当拿到一个单片机任务时,不要急于动手写程序,先仔细分析它的以下几个点:
1、它要单片机整体实现什么功能
2、功能细分(模块化),先干什么,再干什么,最后干什么
3、画初步流程图,(把几个模块画出即可)
4、模块之间的分析:一个模块到另一个模块之间,怎么变换,怎么连接(优化流程图)
5、单个模块分析:每个模块要做什么(流程图细化)
6、所有模块结合连接,细化所有流程图
7、分析单个模块每步要用到的方法或者指令
8、总流程图定型
9、纸上写程序,对照流程图分析其可行性,若不可行则返回
10、上机调试,加注释
11、从小到大,一个功能一个功能地调试;
以上十一步,缺一不可(小程序例外)
切记:流程图的确定很重要,需反复修改
大忌:拿到任务,不仔细分析就写程序。即使是小程序,我们也要养成良好的编程习惯,不要一味的追求结果。写小程序可能比别人快,若是大程序,一旦出现思维混乱,或者出现程序调试不出结果,那么你花在调试上的时间,要比别人的多。 !!!!!!磨刀不误砍柴工!!!!!! 程序的优化:属于后期工作,只有调试出来后,才去优化,如果一开始优化和写程序同时进行,一是加重你的思考量,二是出现问题无从下手。无疑增加了写程序的难度。对于一个初学者,写一个程序,本身头脑就处于紧张的状态,思考的问题就很多,如果此时把优化程序也考虑进去,你脑袋的负荷无疑加重,若你头脑精明,你可以把优化的地方,先在纸上记下来,等到调试结果正常,再把你想到的,优化的地方加进去。
7、如果在中断程序中改变了多字节类型的变量,那么中断程序以外的程序中(主程序,子函数)要使用该多字节类型变量的话,读写前要关中断,读写后再开中断。否则会导致偶尔读写错误。(实质为资源冲突)
举一反三:
其他的数据类型也可能有这种影响。例如:长整型、浮点型。
例如:
unsigned int ms_counter;
void T0()
{
//定时器程序每100毫秒中断一次,程序略
if (ms_counter<1000) ms_counter++;
}
void main(void)
{
//初始化定时器程序每100毫秒中断一次,程序略
unsigned char tt;
ms_counter=0;
tt=0;//用tt控制只响一次
while(1)
{
if (ms_counter<400)
{
if (tt==0)
{
tt=1;
Sound_on();
}
}
else
{
Sound_off();
}
//其他程序
}
}
8、sbit变量不能使用extern关键字,使其在不同的文件中被使用,如要在led.c和main.c文件中使用同一个变量led0,有以下下两种办法:
1.在各种文件中重复定义变量,如在led.c中定义sbit led0=P1^0;同样在main.c中定义sbit led0=P1^0;这样,led0就变成了全局变量,可以在两个文件中使用。
2.将sbit led0=P1^0定义到led.h头文件中,均在led.c和main.c中包含led.h这个头文件。
9、在多文件的程序中声明外部变量(extern和)
如果一个程序包含两个文件,在两个文件中都要用到同一个外部变量Num,不能分别在两个文件中各自定义一个外部变量Num,否则在进行程序的连接时会出现“重复定义”的错误。正确的做法是:在任一个文件中定义外部变量Num,而在另一个文件中用extern对Num 作“外部变量声明”。即extern Num;注意若Num为uchar类型,应当写为“extern uchar Num”,否则会当为int,而导致出错。
当使用static声明变量和函数时,需要在定义变量和函数的基础上加上此关键字,而不能单独使用。例如:
static int a; //定义性声明,需要时,直接使用变量a即可
a = 0x01;
static int funA(int a, int b); //声明,且static不起作用
int funA(int a ,int b) //定义,即使funA有static关键字修饰,但由于static不能单独使用,
//故funA仍为外部函数。
{
……
}
extern对变量进行声明时,如没有初始化,则为引用性声明,不含定义,如需使用此变量,需要进行定义。例如:
extern int a; //引用性声明,不含定义
extern int a = 0x01; //定义性声明,需要时,直接使用变量a即可
int a; //定义
extern对函数进行声明时,如没有函数体,则为引用性声明,不含定义。
extern int funB(int a ,int b); //引用性声明,不含定义,且extern声明可以省略
extern int funC(int a, int b) //定义性声明
{
……
}