关于学习C语言的一些建议
在mikroE的技术论坛上看到有一个网友Jack这样问道:
在被尝试着要教我学会ASM的人抛弃之后,我采取另一种办法来学习C语言,但是我也遇到了跟学习ASM遇到的问题同样的问题。程序已经写完,也基本可以理解,但是当我跑代码的时候,我又不明白其中原理,利用谷歌有时候也找到了我需要的东西和其他的一些说法,但是最后都只是一个死胡同。那里的大部分的教程已经是很长时间之前的了,而且教程的作者已经转移到其他的事情上面去了。我想弄一个简单的程序,是否有人可以给我解释我不理解的步骤?
下面是一个程序,我发现了并与其他人一样从相同的网站copy下来。这是一个简单的二进制计数器,我改为以开关来控制连续计数的功能。当它可以工作后,我开始注释掉一些东西去发现什么是应该做的,比如我发现开关反弹就是不需要的。我想理解程序中的一切,想了解我删除的东西。在这一个唯一的谜团是为什么如果我注释掉顶部的”count = 0”,在最后一次计数后复位或断电它依然能记住这个操作。
我花了几个星期的时间仅仅是通过除去一个个单一的指令得到一个使用EEPROM在ASM 4位计数器。一个简单的问题是在SBIT线后的计数。原来的程序显示“无符号短整型数”。我想我知道无符号短整型数,但是不知道为什么它提前计数。
代码如下:
**************************************************************************
/* continuous count with sw down for 100 ms.
removed all code not needed to do this
remembers count after reset of pw dwn JS 6/24/14
Lab 3: 4-bit up counter
Internal Clock @ 4MHz, MCLR Enabled, PWRTEnabled, WDT OFF
Copyright @ Rajendra Bhatt
Nov 6, 2010
*/
sbit Switch at Rb4_bit; //switch is rb4
count;
void main() {
CMCON = 0x07 ; // Disable comparators
TRISb = 0b00010000; // PORTB all output exceptRB4
TRISA = 0b00001000; // PORTA All Outputs,Except RA3
// count = 0;
PORTb = count;
do {
Next:
if (!Switch) { //DOWN BTFSs
count ++;
if (count ==16) count =0;
PORTb = count;
}
Delay_ms (500) ;
goto Next;
} while(1); // Infinite Loop
}
****************************************************************************
网友Janni回复说:
复位不影响RAM(预设只有一些特殊寄存器),并且功率下降可能是不完整的,因为这取决于供电部分和电路(CMOS技术的处理器和逻辑集成电路是由具有非常小的电流,如果上面没有其他损耗,低于操作电压使用的电源电压趋于停滞在1V)。PIC芯片可能有相当低的内存保持电压,这意味着如果电源电压是否完全不下去了,内存将被保留。
另外,当声明变量应该定义变量类型(如“无符号短整型”),但有C默认类型和当一个省略类型声明的时候,变量将被认为是int类型。
网友Daflory回复说:
作为一般规则,你应该总是声明的变量的类型,这有助于如果你需要的时候,编译器捕获错误,使您的代码更容易理解,也更容易串联你的代码。例如,大多数编译器,包括MikroC,定义一个默认的“int”作为一个标识的16位变量。那在一个16位或32位的处理器是很合理的做法。在一个8位的CPU,一个8位的变量可以工作的时候,它使用16位的变量时,会造成不必要的缓慢和浪费的内存。”无符号短整型”是理想的写/读端口或LATC,以为它不超过255。
我强烈建议你买一本书,叫做《C语言程序设计》,是由 Kernighan和里奇编写的第二版。(DeinisRitchie发明了C)它是非常紧凑的,明确的,写得很好,而且是标准的书,可以教你如何学好C语言。它非常适合那些已经可以写工作程序,但要学会如何使用语言的特征以及如何以最有效和可读的风格写代码。你只需要标准控制台写编译程序(mikroC \openwatcom或GCC可能是理想的),这样你的技能很容易转移到好的单片机编程。
我在你的代码做了一些简洁的UPS的例子:
****************************************************************************
sbit Switch at Rb4_bit; //switch is rb4
void main()
{
unsigned short int count = 0; //only main() uses this variable, so it canbe defined locally.
CMCON = 0x07 ; // Disable comparators
TRISb = 0b00010000; // PORTB all output exceptRB4
TRISA = 0b00001000; // PORTA All Outputs,Except RA3
PORTb = count;
while(1) //Easiest and and standard way to make aninfinite loop
{
if (!Switch)
{
//DOWN BTFSs
count ++;
if (count ==16)
count =0;
PORTb = count;
}
Delay_ms (500) ;
}
}//*Goto* is evil--avoid it if atall possible. It's very rare to actuallyneed it.
*****************************************************************************
注:以上内容由不要发广告Andy翻译自mikroE的论坛,如有差错,有请指正!