c语言编程自我总结

2024-07-03

c语言编程自我总结(共8篇)

c语言编程自我总结 篇1

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)//定义性声明 { …… }

10、一般的,要尽量减少中断服务程序的内容和长度。因为在主程序中可以还需要随时响应其他的中断或事件。如果一个中断服务程序过程,很可能会影响到主程序对外部信号的检测和响应。通常,在中断程序中只是改变一些变量或标志位,在主程序中再根据变量或标志位的值进行判断,处理相应的事件。

11、在A/D和D/A转换电路中,电源电压和基准电压的稳定性,对转换的精度影响很大。另外,A/D和D/A转换电路中要特别注意地线的正确连接,否则转换结果将是不正确的,干扰影响将很严重。

12、根据C语言标准,左移“<<”和右移“>>”运算要求操作数至少是int,如果不满int,自动转换成int(C语言整型提升)。因此 uchar a=0x01;a<<8;实际运算,并不是8位数左移8位,而是int型左移8位。

13、在中断里调用其他函数,且要进行参数传递时,必须保证被调用函数所使用的寄存器组与中断函数一样,否则会产生不正确的结果。为了保证被调用的函数与中断函数使用的寄存器一致,可对被调用函数使用using,不过此函数只能被中断函数调用。

14、函数不使用using 时,所使用寄存器组保持与此函数被调用前相同,不对RS0和RS1的值进行修改;当使用了using 关键字后,此函数所使用的寄存器组与using所定义的一样。

15、当指定中断程序的工作寄存器组时,保护工作寄存器的工作就可以被省略。使用关键 字using 后跟一个0 到3 的数对应着4 组工作寄存器当指定工作寄存器组的时候默 认的工作寄存器组就不会被推入堆栈这将节省32 个处理周期,因为入栈和出栈都需要2 个处理周期。为中断程序指定工作寄存器组的缺点是所有被中断调用的过程都必须使用 同一个寄存器组否则参数传递会发生错误。

16、如何使用pdata 类型的变量?当要使用到pdata 类型的变量,如下: void main(void){ uchar pdata a;a=0x01;}

则需要进行如下设置,否则pdata 的变量a则会无效。

a、修改STARTUP.A51的内容。默认时,PPAGEENALBE为0,表示不允许pdata类型的变量,须将其值改为1;PPAGE表示pdata类型的变量存储在哪一页,01H表示存放在外部存储器的第1页,地址范围100H至1FFH,此时P2经STARTUP.A51处理后的值为0x01;此项设置需和BL51连接器的设置一致。

b、修改BL51连接器。根据STARTUP.A51中PPAGE所设置的值来填写Pdata的值,如下图。图中Pdata的值可以填写100H至1FFH中任意一个,表示pdata类型的变量从所填

写的值开始存储。例如,当Pdata填写的值为108H时,表示pdata类型的变量从108H开始存储,因此,存储范围变为了108H至1FFH。

另外,存储模式Compact的作用是将没有指定存储类型的变量定义为pdata类型,对uchar pdata a;变量的定义没有影响,但对uchar a;则有影响。

17、XBYTE的用法。XBYTE存在于#include 头文件中。

XBYTE[0x000F]=data; // 此语句表示将data写到外部RAM中的0x000F data=XBYTE[0x000F] // 此语句表示读取外部RAM中0x000F的数据 以下语句与上面的语句等效:

#define EX_RAM XBYTE[0x000F] //将EX_RAM定义为外部RAM的地址0x000F EX_RAM=data;// 此语句表示将data写到外部RAM中的0x000F data=EX_RAM // 此语句表示读取外部RAM中0x000F的数据

18、如何在keil中用汇编实现51中没有的指令

部分MCU与8051兼容,但会增加8051中没有的指令,如华邦的W77E58和N79E352等芯片,具有8051中没有的指令DEC DPTR。如何才Keil中实现此指令呢? 方法1:

在需要执行该指令的地方放置相应的机器码 MAIN:

MOV DPTR,#02H DB 0A5H;由于从数据手册上得知,DEC DPTR的机器码为0A5H,故此处相当于执行了DEC DPTR指令。

AJMP $ END

方法2:

使用宏定义的方法

/*宏定义,表示用DEC_DPTR代替MACRO与ENDM之间的内容*/ DEC_DPTR MACRO

DB 0A5H;此处不能与MACRO同一行 ENDM

MAIN: MOV DPTR,#02H DEC_DPTR;放置机器码0A5H,相当于执行DEC DPTR AJMP $ END

通过将以上两种方法生成的hex文件调入到编程器中,发现代码一样。经测试,同样可以用以上两种方法代替8051中已有的指令。

例如,从数据手册可知,MOV A,#0FH的长度为2字节,机器码的值为74H,0FH。因此,经验证,以下三个程序等效,产生的HEX文件一样 MAIN: MOV A,#55H DB 74H DB 0FH MOV P1,A AJMP $ END

MAIN: MOV A,#55H MOV A,#0FH MOV P1,A AJMP $ END

TEST MACRO DB 74H DB 0FH ENDM MAIN: MOV A,#55H TEST MOV P1,A AJMP $ END

18、汇编中包含头步骤:

例如,T2CON为定时器2的特殊功能寄存器,地址为0C8H,要对此寄存器赋值01H,除了

MOV 0C8H,#01H 和

T2CON EQU 0C8H MOV T2CON,#01H 外,还有用包含头文件的方法 #include MOV T2CON,#01H 此时,需要将A51中的“Defines 8051 SFR Names”的勾去掉。

19、指针

C51 提供一个3 字节的通用存储器指针。通用指针的头一个字节表明指针所指的存储 区空间,另外两个字节存储16 位偏移量。对于DATA IDATA 和PDATA 段只需要8 位偏移量。Keil 允许使用者规定指针指向的存储段,这种指针叫具体指针。使用具体指针的好处是节省了存储空间编译器不用为存储器选择和决定正确的存储器操作指令产生代码这样就使代码更加简短但你必须保证指针不指向你所声明的存储区以外的地方否则会产生错误而且很难调试。

由于使用具体指针能够节省不少时间所以我们一般都不使用通用指针。

20、EEPROM存放开关机(复位)次数方法:每次开机(复位)读取EEPROM存放开关机的数据,并加1后重新写入EEPROM。

21、C51中,将printf函数与串口输出结合注意事项:

a、关串口中断;

b、初始化串口,并使TI=1;

c、KEIL里扩展出了b(8位),h(16位),l(32位)来对输入字节宽的设置

在Keil C51中用printf输出一个单字节变量时要使用%bd,若使用%d,则默认为双字节宽度,输出可能会出错。如

unsigned char counter;printf(“Current count: %bdn”, counter);而在标准C语言中都是使用%d: printf(“Current count: %dn”, counter);d、输出数据类型的长度应与定义的数据类型长度一致,如:

uint tem2=97;

printf(“%c,%bdn”,tem2,tem2);第一个输出会出错。

22、我一般不刻意的注意这个,都是从软件自身找问题的。

我写程序时对于软件抗干扰都是在程序状态上考虑意外情况的,例如:

if(a == 1){...} else if(a == 2){....} else{//这个else 一定得加的,即使自己认为不可能出现的情况也要加上

..//经过好多程序走飞的情况发现:大多情况都是缺少这个语句条件的,这 //语句可以写成重新初始化a } 还有程序出现堆栈比较深的运算(例如浮点乘除法后)或中断比较深,我加2个_nop_();

23、STC12C5410AD外部RAM使用方法:

a.在Keil中设置外部RAM的起始地址和大小,如下图

b.将变量定义为xdata即可。

24、中断嵌套

当有外部中断0时,中断标志位IE0由硬件自动置1,进入中断服务程序后,IE0被自动清0。若外部中断0触发信号在执行完中断服务程序后仍没有撤除,就会再次使已经变0的中断标志位IE0置1,再次进入中断服务程序;若在响应中断服务程序期间,再次产生外部中断0触发信号时,此中断不能被识别,因为CPU在响应中断时会自动关闭同一中断。

如果外部中断0比外部中断1的优先级高,当在响应外部中断0期间产生外部中断1时,如果执行完外部中断0后,外部中断1的中断请求标志位IE1仍没有清除的话,将会响应外部中断1的请求;但是如果在响应外部中断0期间,外部中断1的触发信号产生后又撤除的话,IE1也会自动清除,也就是说,执行完外部中断0后,不会去响应外部中断1。

当多个中断源同时向CPU请求中断时,CPU就可以通过中断优先权电路率先响应中断优先权高的中断请求,而把中断优先权低的中断请求暂时搁置起来,等到处理完优先权高的中断请求后再来响应优先权低的中断。

如果某一中断源提出中断请求后,CPU不能立即响应,只要该中断请求标志位不被软件人为清除,中断请求的状态就将一直保持,直到CPU响应中断为止。但是对于串行口中断,即使CPU响应了中断,其中断标志位RI/TI也不会自动清零,而必须在中断服务程序中设置

清除RI/TI的指令后,才会再一次地提出中断请求。

25、在满足应用要求的前提下,选择配较低的单片机,较小的RAM/ROM、较低的ADC分辨率、较低的ADC速率,较少的IO管脚都可以降低单片机的整体功耗。当然了,这个得能满足你产品需求的前提下。

26、对于一个数字系统而言,其功耗大致满足公式:P=CV2f。其中C为系统的负载电容,V为电源电压,f为系统工作频率[2]。功耗与电源电压的平方成正比,因此电源电压对系统的功耗影响最大,其次是工作频率,再次就是负载电容。负载电容对设计人员而言,一般是不可控的,因此设计一个低功耗系统,在不影响系统性能的前提下,尽可能地降低电源的电压和工作频率。对于大多数低功耗单片机来说,工作频率越低,意味着消耗的电流也越小,但是不能认为频率越低,系统整体功耗越小,因为工作频率降低,意味着需要更长的处理时间,其他外围电路消耗的电能就越多。目前有很多单片机都允许有两个或者两个以上的时钟源,低频时钟作为如UART、定时器等外围功能器件的时钟源,高频时钟作为系统的主时钟。在不需要高速运行的场合下,低频时钟也可以作为系统主时钟使用。对于需要在工作状态与空闲状态之间频繁切换的应用,在考虑单片机本身低功耗的同时,应该考虑切换时间和切换电流。考虑到有些场合单片机的工作特点,选择单片机不光要关注工作电流,更应该关注单片机休眠时的静态电流。单片机丰富的低功耗模式和极低的静态电流,在满足特定应用功能的同时,有效降低系统的功耗。尽量关闭MCU内部不用的资源,比如ATmega8内部的模拟比较器,默认是开着的,还有ATmega88内部的大多数资源都可以在不用的时候用软件关闭。

27、定时/ 计数器的实时性

定时/ 计数器启动计数后,当计满回0 溢出向主机请求中断处理,由内部硬件自动进行。但从回0 溢出请求中断到主机响应中断并作出处理存在时间延迟,且这种延时随中断请求时的现场环境的不同而不同,一般需延时3 个机器周期以上,这就给实时处理带来误差差。大多数应用场合可忽略不计,但对某些要求实时性苛刻的场合,可采用动态补偿措施。

所谓动态补偿,即在中断服务程序中对THx、TLx 重新置计数初值时,应将THx、TLx 从回0 溢出又重新从0 开始继续计数的值读出,并补偿到原计数初值中去进行重新设置。可考虑如下补偿方法: CLR EA ;禁止中断

MOV A,T L x ;读TLx 中已计数值 ADD A,#LOW ;LOW 为原低字节计数初值 MOV T L x,A ;设置低字节计数初值 MOV A,#HIGH ;原高字节计数初值送A ADDC A,T H x ;高字节计数初值补偿 MOV T H x,A ;置高字节计数初值 SETB EA ;开中断

28、动态读取运行中的定时器/计数值

在动态读取运行中的定时/ 计数器的计数值时,如果不加注意,就可能出错。这是因为不可能在同一时刻同时读取THx 和TLx 中的计数值。比如,先读TLx 后读THx,因为定时/ 计数器处于运行状态,在读TLx 时尚未产生向THx 进位,而在读THx 前已产生进位,这时读得的THx 就不对了;同样,先读THx 后读TLx 也可能出错。

一种可避免读错的方法是:先读THx,后读TLx,将两次读得的THx 进行比较;若两次读得的值相等,则可确定读的值是正确的,否则重复上述过程,重复读得的值一般不会再错。此法的软件编程如下:

RDTM: MOV A,THx ;读取THx 存A 中 MOV R0,TLx ; 读取TLx 存R0 中

CJNE A,THx,RDTM ;比较两次THx 值,若相等,则读得的值正确,否则重读 MOV R1,A ;将THx 存于R1 中

29、掉电及空闲模式

掉电方式

当PCON中的第二位PD为1时,进入掉电模式,不会执行任何指令,外部时钟停振,片内所有功能部件停止工作,如定时器,串行口,外部中断(部分增强型8051的外部中断可以工作),但片内RAM和SFR的内容保持不变。标准8051从掉电状态退出的惟一方法是硬件复位(部分增强型8051还可以通过外部中断来退出掉电状态),复位后,SFR被重新初始化,但RAM的内容不变。因此,若要使得8051在供电恢复正常后继续执行掉电前的程序,那就必须在掉电前预先把SFR中的内容保护到片内RAM,并在供电恢复正常后为SFR恢复到掉电前的状态。

当PCON的第一位IDEL为1时,进入空闲模式,CPU停止工作,不会执行任何指令,但中断、串行口和定时器可以继续工作。此时,CPU现场(即SP、PC、PSW和ACC等)、片内RAM和SFR中其他寄存器内容均维持不变。退出空闲模式有两种方法:

一、被允许中断的中断源发出中断请求;

二、硬件复位。30、看门狗应用

将喂狗操作(取反指令,如 CPL P1.0)分成两步,放在主程序和中断里执行。如将SETB P1.0放在主程序中,将CLR P1.0放在中断里,这样可以避免主程序跑飞,中断功能正常或者主程序正常,而中断跑飞的情况导致看门狗失效。

31、volatile作用

如果将将变量加上volatile修饰,则编译器保证对此变量的读写操作都不会被优化(肯定执行)。此例中i也应该如此说明。

一般说来,volatile用在如下的几个地方:

1、中断服务程序中修改的供其它程序检测的变量需要加volatile;

2、多任务环境下各任务间共享的标志应该加volatile;

3、存储器映射的硬件寄存器通常也要加volatile说明,因为每次对它的读写都可能由不同意义;

另外,以上这几种情况经常还要同时考虑数据的完整性(相互关联的几个标志读了一半被打断了重写),在1中可以通过关中断来实现,2中可以禁止任务调度,3中则只能依靠硬件的良好设计了。32、51准双向口读取:

只有1条指令:

MOV A,P1为读端口寄存器 有两条指令: MOV A,#0FFH MOV A,P1为读引脚

33、采用C语言和汇编语言混合编程是最佳的选择;

34、系统投入运行的最初时刻,应对系统进行自检和初始化。开机自检在初始化前执行,如果自检无误,则对系统进行正常初始化,通常包括硬件初始化和软件初始化两个部分。硬件初始化是指对系统中的各种硬件资源设定明确的初始状态,如对各种可编程芯片进行编程、对各I/O端口设定初始状态和为单片机的硬件资源分配任务等。软件初始化包括,对中断的安排、对堆栈的安排、状态变量的初始化、各种软件标志的初始化、系统时钟的初始化和各

种变量储存单元的初始化等。

35、按键连击速度一般为3-4次/s。

36、复合键利用两个以上按键同时按下时产生的按键效果,但实际情况下,不可能做到真正的“同时按下”,它们的时间差可以长达50ms左右,故当检测到有KEY1按键按下时,还要等待超过50ms,再判断是否还有其他按键按下,再解析按键。

37、数码管显示闪烁效果时,一般闪烁速度为1-4次/s。

38、大电流和高电压设备的启动和关闭都是由软件指令来完成,这些指令执行后,必然引起强烈的干扰,这些干扰不能算随机干扰,它们与软件完全相关;可以在最后才执行这些可能引起强烈干扰的I/O操作,之后立即进入睡眠状态,这样就不会干扰到CPU,等CPU醒来后,干扰的高峰也基本过去。

39、用积分时间为20ms整数倍的双积分型A/D转换方式,能有效地抑制50Hz工频干扰。40、掉电检测电路必须在电压下降到CPU最低工作电压之前就提出中断申请,提前时间为几百us到数ms,以便掉电中断程序进行掉电保护。

41、用定时器作看门狗:当为专职看门狗时,在主程序中周期性清0定时器计数值,以使定时器中断不能产生,当产生定时器中断时,表明看门狗溢出,此时应执行出错处理程序或者进行复位。当为兼职看门狗时,可以在定时器中断程序对计数值进行加1,若计数值大于某值时,表明看门狗溢出,而主程序中应周期性地对计数值进行清0。

42、中断中,冲突发生的条件:

1)某一资源为中断程序和主程序所使用;该资源可以为1个变量,也可以为1个数组或者1个缓冲区。

2)中断程序或主程序对该资源进行了写操作;

3)主程序不能用一条指令对资源完成读或者写操作。(这条不对,参考深入浅出AVR单片机P100的例子)

当这三个条件均满足时,即有可能发生资源冲突,导致程序偶然运行不正常。为了避免发生冲突,可以在主程序中先关中断,再对资源进行读或写,结束后再开中断。

当主程序对资源的访问比较费时,长期关中断可能影响系统的实时性;解决的办法是尽可能缩短关中断的时间,将一边访问,一边处理的工作方式改为集中访问,分批处理。如果是读该资源,则关中断迅速将该资源的内容转移到缓冲区,再开中断,然后再对缓冲区中的信息进行处理;如果是写该资源,则先边运算边写缓冲区,全部写好后再关中断,然后迅速将缓冲区中的内容复制到该资源中,边可以开中断了。

43、A/B*C的运算方案不如(A*C)/B的运算方案精度高。因此,应尽可能将出现偏差的运算往后排,先进行无偏差或偏差小的运算。在定点运算系统中,加减法只要不超限,是没有偏差的,乘法运算的结果会使字长增加,如双字节乘双字节,积为四字节,如果保留全部结果,则没有偏差的。乘法运算的结果会使字长增加,如双字节乘双字节,积为四字节,如果保留全部结果,则没有偏差;如果受字长限制,则要舍去低位字节,从而产生舍入偏差。除法几乎都是有偏差的能够刚好整除的情况是很少的。在浮点运算系统中,加减法由于要进行对阶操作,当两操作数的阶码相差较大时,绝对值大的数有可能将绝对值小的数淹没,使运算的结果仍为绝对值大的数,一点儿也看不出绝对值小的数对结果的影响。相比之下,浮点乘法和浮点除法引起的偏差就比较小,它们能够保持一个比较稳定的运算精度。另外,不管在定点系统中还是在浮点系统中,都要尽可能避免两个数值相近的数过早相减,因为他们都可能是近似值,相减以后,差的有效数值大大减少,必然带来更大的相对误差。经过后续运算之后,结果可能离真实值相差甚远。再有,尽可能不要用绝对值小的数作分母,否则引起的误差也是很大的。

44、要对软件标志位的使用进行说明;对于全局定义的软件标志,它有惟一的定义;对于局

部定义的软件标志,必须注明其有效范围。

45、软件理论已经证明:任何一个程序(除某些短小的子程序外)都存在错误(缺陷),人们可以通过合理的测试来证明它仍然存在错误,却无法证明它已经没有错误。软件测试应该把发现错误作为目的,而不能把“程序调通”作为目的。

1.P0口能驱动8个TTL电路意思: 8051单片机P0口驱动8个TTL电路的意思,TTL电路输入悬浮时相当于输入高电平,因此P0口输出高电平驱动TTL电路几乎不需输出电流。TTL电路输入为低电平时最少要释放1mA电流,因此P0口输出低电平时吸收的电流大于8mA。TTL输出高电平最大1.6mA,输出低电平时吸收的最大电流 16mA。51输出最好用低电平有效,推动PNP管,因为51复位后IO为高电平,如果用高电平有效推N管的话上电复位后会先让外部电路动做。

2.在51里,有一条指令没有写进书本,机器码为A5,执行操作:将下一个字节跳过而不管它是单字节指令还是双字节或三字节指令的一部分.如果反汇编工具不识别A5指令的话,你在A5以后的程序反汇编后就错乱无章.当成个数据,用db a5 即可

3.有些51系统容易复位,一般是电路设计上的问题。很多电路介绍的复位电路都是10u和8.2k,但是在实践过程中我们发现该电路在电源不稳时很容易复位,特别是附近有大干扰时,如继电器动作等。我建议使用22u和1k的复位电路,有许多电路改为该数值后就工作稳定了。当然,最好的办法还是使用专用复位电路或三极管电路,但是那样要增加成本和体积。

4.电路中的滤波电容一定要注意加上,最好每个芯片都再加一个约0.1uf的电容,这样对电路的稳定性很有好处。如果使用了看门狗电路,就有可能是软件问题,程序工作到某些环节时忘记了复位看门狗,结果计数满了就复位了。

5.如果在中断程序中改变了多字节类型的变量,那么中断程序以外的程序中(主程序,子函数),读写前要关中断,读写后再开中断。举一反三:

其他的数据类型也可能有这种影响。例如:长整型、浮点型。

上面的例子是中断里写,主程序中读。相反主程序写,中断里读也可能出错。

6.教你一招,别说我损。。

写一个测试代码,反复向EEPROM中的某几个不用的空位字节写入0x55,直到把它干到寿命终结不能写为止,如果按照10MS写一个字节计算的话,大约只需要20分钟就能干掉它。然后向这个芯片中烧入你的正常代码,当然了,这个代码中应该有一段上电检测EEPROM这几个字节的代码,先尝试向它写入0Xaa,然后再读出来看看是否写入成功,如果没写入则再来两次,如果始终不能写入,这当作检查通过,如果就判断为检查失败,这个时候代码要装着‘不知情’继续执行正确代码,下面的‘破坏’行为应该如何做就不要我讲了把? 破坏行为要装的掩蔽一点,例如调一段代码檫除FLASH的代码,嘿嘿,那对方肯定以为CHIP质量不好容易出现FLASH数据丢失,如果对方使用了AD什么的,可以偶尔人为让它波动大一点,这样对方一般只会怀疑PCB和硬件电路弄的不好,而不会想到是代码动手脚了,长久以后他的用户肯定也会认为他们的产品质量不好,你这个时候就可以向他的客户推广你的产品了。。

上电写EEPROM的次数要在你自己的产品质量承诺的寿命时间之内,否则你自己的产品也

可能增加维修。。

这个方法特别适合在外接单挣钱的工程师,你可能给了对方几个CHIP做测试,对方测试通过偏说不行,就是不给你余款,然后把CHIP拿去CRACK,妄想省掉这个钱,NND,让他们见鬼去把,俺这招已经对付了不少不良分子。。

7.AD键盘

8.防解密高招

高招, 解密

使用一些带内部晶振和内部EEPROM的单片机,如PIC16F913和ATMEGA8等,带内部晶振的单片机有一个寄存器OSCTUNE(或OSCCAL),这个是芯片厂家用来校准内部晶振的,范围从0-31,出厂时同型号的单片机这个寄存器的值是不一样.我们可以利用一些隐藏功能,将OSCTUNE寄存器的值存入内部的EEPROM中,开机时读取EEPROM的值,再与OSCTUNE的值相比较, 若二者相同系统正常工作,若不

相同则不正常工作.解密者将解密的程序烧写进单片机中后,会发大部分的芯片不能正常工作,因为他们不知道这个隐藏的功能.举例说明: 芯片为PIC16F913,这个厂品有4个按键(KEY0、KEY1、KEY2、KEY3),内部我们可以设定这样子一个隐藏的功能,如果KEY0与KEY1同时按下3秒钟以上,会将OSCTUNE寄存器存入单片机的EEPROM中。

开机复位后,读取EEPROM中的数据,与OSCTUNE寄存器相比较,若二者相同系统正常工作,若不相同则不正常工作。以上有三个重点:

1、对于OSCTUNE寄存器不要进行写的操作,只进行读的操作,因为写了一次以后,就一直是你写的这个数据的。

2、刚才介绍的KEY0、KEY1同时按下3秒钟这个功能,可不能让解密者(包括产品的用户)知道,当然大家可以用别的隐藏的功能。

3、单片机中的OSCTUNE寄存器(或OSCCAL)的值,同一种型号的单片机不是每一个都是一样的,有32个数据,也就是说32个芯片中有一个是与解密的单片机是一样的。这样子造成的后果是:解密者解密了你的程序以后,却发现有些单片机可以正常工作,可有些单片机不能正常工作,可以说是大部分的单片机不能正常工作。

不过需要注意一下:要是遇到强干扰把EEPROM中的数据改变了看客户怎么收拾你!

9.PIC16F887A中,要求SLEEP指令后的下一条指令为NOP;不知51和AVR的芯片是否需要注意这一点。经查,AVR的datasheet无此要求,可能是其唤醒时,存在启动延时。

10.中断随时随刻都有可能产生,故编写程序时,需要时刻注意中断的影响。

11.注意以下语句在某些编译器下,结果可能出错:

unsigned char a,b;

unsigned int sum;

a=0x80;

b=0x80;

sum=a+b;

12.编程序最重要是好维护。几个执行时间和程序的可读性比,和开发时间比,我认为是不用考虑的。为了几个机器周期而把程序搞得很复杂,是非常愚蠢的行为。可是很多人多乐此不疲啊。总体系统的算法是要考虑优化的问题的,这点我是赞同的。天天在技术上对着几行程序去优化,而导致开发速度减慢,是非常愚蠢的行为。

13.串口通信协议:引导码/识别码+长度+命令字+data+校验

通过引导码/识别码、长度、校验三步检测 每当出错则丢弃当前数据并还原接收状态和空间…………

14.当准备调试一块板的时候,一定要先认真的做好目视检查,检查在焊接的过程中是否有可见的短路和管脚搭锡等故障,检查是否有元器件型号放置错误,第

一脚放置错误,漏装配等问题,然后用万用表测量各个电源到地的电阻,以检查是否有短路,这个好习惯可以避免贸然上电后损坏单板。调试的过程中要有平和的心态,遇见问题是非常正常的,要做的就是多做比较和分析,逐步的排除可能的原因,要坚信“凡事都是有办法解决的”和“问题出现一定有它的原因”,这样最后一定能调试成功。

做一个硬件设计人员要锻炼出良好的沟通能力,面对压力的调节能力,同一时间处理多个事务的协调和决断能力和良好平和的心态,还有细心和认真等等。

对初学者来说,在新的领域面前一穷二白,要学的东西太多太多,一味机械地试图学习这些“高深的语法”和“看不懂的技巧”,胡乱模仿些别人的“优秀风格”,不能说完全无所得,只能说会学得很累,而且往往事倍功半---久而久之,信心丧失殆尽,半途而废。学习编程,做自己便好。学习眼前能够看懂的内容,多写自己会写的程序。对于已经学到的东西,仔细地体会、思考,发掘其中的发展;学会用一种研究的心态去考察你的每一个疑问;不可以轻易地人云亦云,在网上看了别人无责任的经验,甚至是写错了,丢在一边,懒得改的东西之后,就放弃了自己的探索;要学会坚持自我,遇到别人先进的做法,在自己还没有体会到自己当前这种做法的劣势之前,不要轻易盲从;同样,使用了先进的方法,在没有同时理解这种做法的优点和缺点之前,请不要轻易地感叹“这种方法好,跟帖顶一下!”“大师高手宁有种乎?”坚持“体会到了才是学到了”的态度,最终形成自己的风格,形成自己的技巧。

c语言编程自我总结 篇2

数据排序是计算机编程过程中经常会遇到的一个问题,同样C语言中关于排序问题的算法也有多种。本文主要对一些常见的排序算法进行一个归纳总结,方便初学者对这一问题有一个全面的了解。

所谓数据排序,就是将一组无序的数据,按照其中的某个关键字的大小,递增或递减的排列成有序的数据序列。在C语言的学习过程当中,经常会碰到关于整数、浮点数、字符以及字符串的排序问题。一般的排序方法有:冒泡排序、选择排序、插入排序、shel(希尔)排序、快速排序、堆排序等。下面就通过具体的例子,对这些排序方法的基本思想、执行过程、算法代码进行一个总结分析。

2 各种排序算法的分析

2.1 冒泡排序

冒泡排序法是C语言当中最为常见和通用的一种排序方法。

2.1.1 基本思想

在待排序的一组数中,相邻的两个数两两比较后发现它们的顺序与排序要求相反时,就将它们互换(即:如果从小到大排序,则两两比较时,让较大的数往下沉,较小数往上冒)。如此下去,直至最终完成排序。冒泡排序过程中,如果对N个数进行排序的话,需要进行比较的轮数是N-1轮,每轮进行N-1-i次。由于在排序过程中,它的工作看起来像冒泡,所以称作冒泡排序。

2.1.2 算法代码

例:对数组aa[5]={8,5,10,7,3}的元素从小到大进行排序。

该例子用冒泡法实现的代码段如下:

2.1.3 执行过程

第一轮:8,5,10,7,3->5,8,10,7,3->5,8,7,10,3->5,8,7,3,10(交换3次)

第二轮:5,8,7,3,10->5,7,8,3,10->5,7,3,8,10(交换2次)

第三轮:5,7,3,8,10->5,3,7,8,10(交换1次)

第四轮:5,3,7,8,10->3,5,7,8,10(交换1次)

2.1.4 分析

在程序执行过程中,关系到算法性能的主要因素是循环和交换的次数,次数越多,性能越差。

对上面这个例子中包含5个元素的数组采用冒泡法进行排序,总共进行交换的次数是3+2+1+1=7次。冒泡法的特点是原理简单,但其缺点是交换次数多、效率低。

2.2 选择排序

2.2.1 基本思想

在待排序的一组数中,每轮将首数与后数进行两两比较,按大小进行交换,选出待排序数组中最小(或最大)的一个元素,放在已经排好序的数列的最后。如此下去,直至最终完成排序。冒泡排序过程中,如果对N个数进行排序的话,需要进行比较的轮数是N-1次,每轮从i+1开始到N-1为止。

2.2.2 算法代码

同上例:对数组aa[5]={8,5,10,7,3}的元素从小到大进行排序。

2.2.3 执行过程

第一轮:8,5,10,7,3->3,5,10,7,8(交换1次)

第二轮:3,5,10,7,8(交换0次)

第三轮:3,5,10,7,8->3,5,7,10,8(交换1次)

第四轮:3,5,7,10,8->3,5,7,8,10(交换1次)

2.2.4 分析

对上面这个例子中包含5个元素的数组采用冒泡法进行排序,总共进行交换的次数是1+0+1+1=3次。选择法的循环过程与冒泡法一致,它定义了作为记号的变量k赋初值为i,依次把a[k]同后面元素比较,若有元素比a[k]小,则将该元素下标赋值给k,使得变量k当中存放的永远是最小元素的下标。最后再a[k]与a[i]交换,这样就比冒泡法省下许多无用的交换,提高了效率。

2.3 直接插入排序

2.3.1 基本思想

在待排序的一组数中,先比较前两个数,按大小顺序排列好,然后每次从后面的无序数中取出第一个元素,把它插入到前面有序数的合适位置,使有序数组仍然有序,把数组元素插完也就完成了排序。

2.3.2 算法代码

同上例:对数组aa[5]={8,5,10,7,3}的元素从小到大进行排序。

2.3.3 执行过程

第一轮:8,5,10,7,3->5,8,10,7,3(交换1次)

第二轮:5,8,10,7,3(交换0次)

第三轮:5,8,10,7,3->5,7,8,10,3(交换1次)

第四轮:5,7,8,10,3->3,5,7,8,10(交换1次)

2.3.4 分析

对上面这个例子中包含5个元素的数组采用冒泡法进行排序,总共进行交换的次数是1+0+1+1=3次。直接插入排序的特点是算法简单、容易实现。它是采用逐步增加有序元素想法,直至所有元素排列完成。如果待排序数组元素不是特别多的时候,该算法的效率快是较佳的排序方法。但对于大数组,这种算法比较慢就不大适用了。

2.4 shell排序

2.4.1 基本思想

希尔算法的本质是缩小增量排序,是对直接插入排序算法的改进。先取一个小于N的整数p作为第一个增量,将待排序的一组数按增量p分割成多个组,对每个组分别进行一趟直接插入排序。然后缩小增量p的值(一般取其一半)再排序,直到p=1时完成排序。

2.4.2 算法代码

同上例:对数组aa[5]={8,5,10,7,3}的元素从小到大进行排序。

2.4.3 执行过程

第一轮:8,5,10,7,3->8,5,3,7,10(交换1次)

第二轮:8,5,3,7,10->3,5,8,7,10(交换1次)

第三轮:3,5,8,7,10->3,5,7,8,10(交换1次)

2.4.4 分析

对上面这个例子中包含5个元素的数组采用冒泡法进行排序,总共进行交换的次数是1+1+1=3次。Shell排序的优点是不管待排序数组长度多长,在分组增量p的切割下每个子组的规模都不会太大,然后用直接插入排序效率较高。后来增量p的逐渐递减,分组数逐渐减少,而各组的记录数目逐渐增多,但由于排过序,整个数组的有序性越来越清晰,所以排序的效率依然较高。所以,希尔排序在效率上比直接插人排序有很大的改进。

2.4.5 快速排序

2.4.5. 1 基本思想

在待排序的一组数中,先选择其中一个元素作为分隔点(一般选取数组中间的那个元素),然后把比该元素小的数据放在左边,大的放在右边。再按此方法对两边的数据分别再快速排序(也就是递归调用),直到整个数组有序为止。

2.4.5. 2 算法代码

同上例:对数组aa[5]={8,5,10,7,3}的元素从小到大进行排序。

2.4.5. 3 执行过程

第一轮:8,5,10,7,3->8,5,3,7,10(交换1次)

第二轮:8,5,3,7,10->3,5,8,7,10(交换1次)

第三轮:3,5,8,7,10->3,5,7,8,10(交换1次)

2.4.5. 4 分析

对上面这个例子中包含5个元素的数组采用冒泡法进行排序,总共进行交换的次数是1+1+1=3次。快速排序是对冒泡排序的一种本质改进,其优点是运算速度快,数据移动少。缺点是算法稍复杂。快速排序法中关键是对三个参数的设定,即待排序数组元素的起始下标、最后一个元素下标以及分隔元素下标的确定。

3 总结

除了上述分析的五种常见的排序方法外,还有堆排序、归并排序等。在选择排序算法的时候,要根据待排元素数目N的大小以及元素本身的初始状态来做最佳的抉择。如果N数较小,则可采取直接插入排序或选择排序;若数组本身初始状态局部或整体有序时,则可采取冒泡排序或插入排序;若N数较大,则可采取快速排序、堆排序或归并排序。

参考文献

[1]谭浩强.C程序设计[M].3版.北京:清华大学出版社,2005.

[2]谭浩强,张基温,唐永炎.C程序设计教程[M].北京:高等教育出版社,1992.

c语言编程自我总结 篇3

关键词:C语言;编程技巧;应用

中图分类号:G642 文献标识码:B 文章编号:1002-7661(2014)24-002-01

C语言属于一种程序设计类语言,其使用在数据处理方面有突出作用,在很多的学习工作领域都有大规模的应用,像是软件开发、科研建设等都离不开C语言的利用。C语言编程,就是用C语言进行相应计算机代码的编写,C语言的学习,需要掌握一定的技巧,不然没有头绪的学习是得不到良好学习效果的,掌握了C语言的学习技巧,才能够更好的促进C语言的学习[1]。

一、C语言与C语言的优势

当下世界上使用范围最广,流行度最高的计算机编程语言便是C语言,要想良好的学习和使用C语言,必须加深对C语言的了解。C语言发源于上个世纪60年代,成熟在70年代,最近半个世纪的使用过程中,C语言表现了如下几种优势:第一,C语言简洁紧凑,使用方式灵活方便,且语法运用宽松不受限制,书写方式自由随意,结合了高级编程语言的结构性与实用性的特点,组成了一种全新式的有强大使用功能的编程语言;第二,C语言有广泛的应用层面,且可植性强,C语言在各种系统中都能够被兼容使用;第三,C语言的运算符丰富多样,各种数据结构类型的使用,除了C语言可以将各种复杂的数据运算完成外,还具有强大的图形功能;第四,结构式的语言特点分割了代码和数据,其中的程序表现层次条理清楚,后期的使用和维护工作便利,使用C语言可以访问物理地址[2]。从中可知,C语言具有强大的功能,因此在信息技术的领域中,C语言所占据的地位是非常高的。

二、C语言学习难度大的原因

因为C语言所具备的各种强大功能,因此人们对其的关注程度也越来越高,想要学会并且全面掌握C语言技术的人也越来越多。可是大部分在刚刚接触C语言的时候,觉得C语言过于枯燥乏味,学习了一段时间后都没有掌握到多少知识,也没有一个清楚全面的认识对于C语言,觉得十分的茫然。出现这种情况的原因还是因为C语言是一种高级语言,这种语言和面向对象的语言之间存在较大的差别,在C语言的学习过程中,学习者难以从中看到形象的画面,只能够在编程程序成功后,经过调试才可以看到效果。在编程的过程中,只要出现一点粗心错误,就会让整个编程无法成功调试,出现一些错误的现象,除此之外,C语言的使用过程中,包含了大量的算法与数据组成结构,这些没有任何的技巧,就是要死记硬背,所以很多学习者在遇到这些枯燥晦涩的问题时,就会丧失学习兴趣,降低学习效率和学习质量。

三、C语言编程技巧的应用

1、用空间换时间

例如对字符串进行赋值,方法有以下几种:

(1)基础方法:

#define LEN 32

Char string I[LEN];

memset(string 1,0,LEN);

ctrcpy(string 1,“this is a example”) ;

(2)方法2:

const char string2[LEN]=“this is a example”;

char*cp;

cp=string2;

从这个案例中可以发现,方法(1)与方法(2)在电脑上的执行效率是不一样的,第一种方法必须使用两个字符函数才可以完成,而第二种方法直接使用指针就可以完成了。但是第二种方法相比第一种方法灵活性欠缺,如果这个字符串有不断变化的要求,那么第一种方法就有很大的使用优势了,第二种方法要占用较大的内存,但是效率比第一种更高[3]。

2、位运算掌握

在利用位运算的时候,能够让代码变得更加的简洁,提升运算效率,让问题得到顺利解决。在所有的计算机程序之中,最小的数据单位就是位,无特殊情况的话,所有的数据运算和操作都可以使用“位运算”方式完成,从这里就就可以看出,在编程语言之中,“位”有多么重要了。“位”使用在C语言的运算过程中,可以提升工作效率,顺利的将更多难度大的问题解决。

3、C语言特有函数掌握

很多时候进行编程,都需要使用C语言的特有函数,函数不是一种数据,而是一种功能,每一个函数都能够执行一定的功能建设,而相对应的函数名称中也将函数的功能反映了出来。开展函数定义的时候,要求操作者包含名字、参数名、类型和函数返回类型的数据,编译过程中,数据库系统是之前被定义好了的,使用过程中只要通过#include这项指令,把各种相关的头文件包含在本文件当中就可以了。

但是不管在C语言编程过程中使用怎样的技巧,还是需要做到具体问题具体分析,以上各种技巧使用起来因人而异,整体是能够提升编程效率,在学习过程中使用会获得一定的成效,而降低学习的枯燥感,拓宽C语言的使用范围。

C语言的学习过程中,每一位学习者都应该对C语言的特性有充分的了解,学习并且掌握每一种编程技巧,学习好了C语言的编程技巧,可以帮助学生提升C语言的学习兴趣,让学生的学习目的性更强,提升学生的C语言学习效率与学习质量。

参考文献:

[1] 余 勍.王 捷.浅谈C语言编程技巧在C语言学习中的应用[J].信息通信,2013,07:108.

[2] 赵 黎.范君君.C语言编程技巧在C语言学习中的应用研究[J]. 信息与电脑(理论版),2014,09:252.

C语言实习总结 篇4

通过实践可以使我们从理论高度上升到实践高度,更好地实现理论和实践的结合,为我们以后的工作和学习奠定初步的知识。以下是C语言实习总结,欢迎阅读!

C语言实习总结1

在科技高度发展的今天,计算机在人们之中的作用越来越突出。而c语言作为一种计算机的语言,我们学习它,有助于我们更好的了解计算机,与计算机进行交流,因此,c语言的学习对我们尤其重要。

在这个星期里,我们专业的学生在专业老师的带领下进行了c语言程序实践学习。在这之前,我们已经对c语言这门课程学习了一个学期,对其有了一定的了解,但是也仅仅是停留在了解的范围,对里面的好多东西还是很陌生,更多的在运用起来的时候还是感到很棘手,毕竟,万事开头难嘛。

由于时间的关系,我们的这次实践课程老师并没有给我们详细的介绍,只是给我们简单的介绍了几个比较重要的实际操作。包括了程序模块处理。简单界面程序。高级界面程序。程序的添加修改。用程序做一元线性回归处理以及用c语言程序来画粒度分布图等这几样比较重要的时间操作。

上机实验是学习程序设计语言必不可少的实践环节,特别是c语言灵活、简洁,更需要通过编程的实践来真正掌握它。对于程序设计语言的学习目的,可以概括为学习语法规定、掌握程序设计方法、提高程序开发能力,这些都必须通过充分的实际上机操作才能完成。

学习c程序设计语言除了课堂讲授以外,必须保证有不少于课堂讲授学时的上机时间。因为学时所限,课程不能安排过多的统一上机实验,所以希望学生有效地利用课程上机实验的机会,尽快掌握用c语言开发程序的能力,为今后的继续学习打下一个良好的基矗为此,我们结合课堂讲授的内容和进度,安排了12次上机实验。课程上机实验的目的,不仅仅是验证教材和讲课的内容、检查自己所编的程序是否正确,课程安排的上机实验的目的可以概括为如下几个方面:

1.加深对课堂讲授内容的理解

课堂上要讲授许多关于c语言的语法规则,听起来十分枯燥无味,也不容易记住,死记硬背是不可取的。然而要使用c语言这个工具解决实际问题,又必须掌握它。通过多次上机练习,对于语法知识有了感性的认识,加深对它的理解,在理解的基础上就会自然而然地掌握c语言的语法规定。对于一些内容自己认为在课堂上听懂了,但上机实践中会发现原来(转载自第。)理解的偏差,这是由于大部分学生是初次接触程序设计,缺乏程序设计的实践所致。

学习c语言不能停留在学习它的语法规则,而是利用学到的知识编写c语言程序,解决实际问题。即把c语言作为工具,描述解决实际问题的步骤,由计算机帮助我们解题。只有通过上机才能检验自己是否掌握c语言、自己编写的程序是否能够正确地解题。

通过上机实验来验证自己编制的程序是否正确,恐怕是大多数同学在完成老师作业时的心态。但是在程序设计领域里这是一定要克服的传统的、错误的想法。因为在这种思想支配下,可能你会想办法去掩盖程序中的错误,而不是尽可能多地发现程序中存在的问题。自己编好程序上机调试运行时,可能有很多你想不到的情况发生,通过解决这些问题,可以逐步提高自己对c语言的理解和程序开发能力。

2.熟悉程序开发环境、学习计算机系统的操作方法

一个c语言程序从编辑、编译、连接到运行,都要在一定的外部操作环境下才能进行。所谓环境就是所用的计算机系统硬件、软件条件,只有学会使用这些环境,才能进行程序开发工作。通过上机实验,熟练地掌握c语言开发环境,为以后真正编写计算机程序解决实际问题打下基矗同时,在今后遇到其它开发环境时就会触类旁通,很快掌握新系统的使用。

3.学习上机调试程序

完成程序的编写,决不意味着万事大吉。你认为万无一失的程序,实际上机运行时可能不断出现麻烦。如编译程序检测出一大堆错误。有时程序本身不存在语法错误,也能够顺利运行,但是运行结果显然是错误的。开发环境所提供的编译系统无法发现这种程序逻辑错误,只能靠自己的上机经验分析判断错误所在。程序的调试是一个技巧性很强的工作,对于初学者来说,尽快掌握程序调试方法是非常重要的。有时候一个消耗你几个小时时间的小小错误,调试高手一眼就看出错误所在。

通过这次为数不多的几天计算机实践学习,我们了解了一些关于c语言的知识,理解巩固了我们c语言的理论知识,着对我们将来到社会工作将会有莫大的帮助。同时它让我知道,只要你努力,任何东西都不会太难。

C语言实习总结2

在初学C语言的一个学期后,我们进行了C语言实训阶段,尝试编写一个比较复杂的程序系统。在为期一周的时间中,我们同组的同学共同的感受是:C语言实训和平时上课所接触的程序是有很大不同的,所经受的考验和克服的困难是平时所无法比拟的。好在同组的搭档们精诚合作,分工明确,有问题共同解决,攻克了C语言实训的复杂程序。在这里,我作为其中的参与者,感触良多。

在这次实训中,我对对C语言有了一个更深的了解认识,也对这个学期学的知识得到巩固,还尝试运行编程,每次运行程序成功,让我对下面的项目就充满信心。通过自己与同学合作编写程序,最终把最初的理论知识转化基本技能。这次的实训,使我对C语言的学习产生浓厚的兴趣。

还是这次实训,最令人激动的就是合作做项目,虽然那只是一个很小很小的项目。每天大家来得很早,大家在一起学习,取长补短,我们很好的在实训中长知识,提高我们的学习热情。实训中深切体会到了老师认真负责的伟大的精神和热情为同学指导的促学方式,虽然对有些时候老师没给我们指出解决问题的方法有些小抱怨,但是到了结束时才知道,这种教学让我们自己学会了自学,学会了去看懂别人的代码。更多是老师给的感动,每天在我们来之前就到了教室,在讲课中海给我们分享他在公司上班的一些心得和体会,还有那些我们应该注意的事项,这些是平时上课时无法学到的,是更深层次的巨大收获。

通过这次实训,也使我们发现了许多问题。

在实训中,我们认识到自己还有很多的知识没学好,基础知识没理清,而且许多东西还要去翻书,去上网搜索。而且遇到一些小错误运行不出来,就会烦躁不安,觉得有些自暴自弃或者抱怨项目的变态,以后要克服,尽量保持一颗良好的心态,学好C语言,也学好用C语言编写一个按要求的系统。

还有就是对于未来,近程就是下学期,我觉得我还有许多方面需要提高。

首先我要继续学习好C语言的基础知识,然后能在电脑上熟练的运用。然后每天都能写一些程序,上网时候多看一些优秀的教程和优秀的代码。遇到问题时多和同学讨论,并且多弄出几套方案,多锻炼自己结局问题的能力和与同学合作的能力。

总之,这一切都成为我记忆里面的一个篇章,更是在C语言编程上的一个里程碑。

C语言实习总结3

一周的C语言实训,虽然时间略显仓促,但却让我学到了很多实际运用的技能!

首先,在实训中的第一步是编写功能较为单一的小程序,虽然是小程序,但所用的知识却都是我们本学期学习的重点知识。在做题的过程中让我们把这些知识复习了一遍,强化了知识!

其次,这次作中所碰到的题目,在实训中已经接触过,所我们都比较深知这些题目的要求和算法,因次在编写小程序时比较快,而且算法也是比较简化,运算准确。鉴次我明白很多编程题要经过多次编写修改与调试,才会得到最简略的算法。

再次,平时我们学C语言视乎都是为了考试或者做一些比较常规的题目,而这次实训却给我们的将所学知识运用于解决实际问题的机会,让人更有激情,这就是编写软件的在雏形,也让我们感受到了编写软件程序的乐趣。但是不仅仅是如此,更为重要的是在运用所学知识的过程中,记住这些知识,并能够广泛的运用!

虽然我这次是编写一个菜单的程序,但是如果我么留心的话,我们身边有许多电子设备都是内置有程序的,我们也可以在此次专题实训过后,自行确定其他的专题进行编写程序,这样可以让我们的知识更加深化丰富!

这次实训似乎是对我巨大的考验,程序在不慌不忙的进行着,按照我自身的进度,提前完成是没有问题的,但是很多客观条件让我不得不在最后的时间里才上交的作业。每当我把程序写完以后,却由于每一台电脑的识别格式不一样而导致我所写的文件一次次的被损坏,尽管这样,我仍然没有放弃,最后还赶在截止时间到来之前上交了我的作业!

这一次编写大作业的程序又让我感受到学程序可以锻炼缜密的思维了。因为平时练习的都是小程序,所以句段比较少,一些错误都很容易被检查出来,但是这次实训却是上百段的语句,难以检查,似乎也没有经验去怎么检查,那一刹那感觉到很急,但又不知如何是好,可是又不轻易的向老师询问,因为好像蛮简单,相信自己能够检查出来,所以我一般都是独立思考的完成的,只有少部分是在老师和与同学讨论下完成的。

c语言数组方法总结 篇5

1.输入元素的值:

inti,a [10];

for(i = 0;i < 9;i ++);

a[i] = i;

(1)正序排列:(2)倒序排列:

for(i =0;i < 10;i ++)for(i = 9;i >= 0;i--)printf(“%d”, a[i]);printf(“%d”, a[i]);

2.初始化元素的值:

(1)在定义时,将数组元素一次放在一对花括号里;

eg: int a[10]={1,2,3,4,5,6,7,8,9,0};

(2)可以只给一部分元素赋值:

eg: int a[10]={1,3};

(3)使数组全部元素为0:

eg: int a[10]={0,0,0,0,0,0,0,0,0,0};或者 int a[10]={0};

(4)在对全部元素赋初值的时候,由于元素数已经确定,因此,可以不指定数组长度。(注:数组长度与提供初值个数不相同时,则长度不可以省略。)

3.巧妙地将两个元素列在一个循环中输出:(用for循环处理fobonacci数列); eg:int f[20]={1,1};

for(i=2;i<20;i++)

f[i]=f[i-1]+f[i-2];

4. 数列Fobonacci数列核心:

int f[20]={1,1};

for(i=2;i<20;i++)

f[i]=f[i-1]+f[i-2];

5.换行操作:

for(i=0;i<=20;i++)/*当然也可以在for循环中处理,直接将{if(i%5= =0)printf(“n”);if(i%5= =0)printf(“n”);插入换行*/Printf(“%12ld”,f[i]);

}

6.起泡法:

int a[10];

for(j=0;j<9;j++)/*进行n-1趟比较*/

for(i=0;i<9-j;i++)/*在j趟比较中,比较n-1次*/

if(a[i]>a[i+i])/*由小到大排列,if(a[i]

7.初始化二维数组:

 分行给二维数组赋初值;

 将所有的元素都写在一个花括号里;

 对部分元素赋值:

1)int a[3][3]={{3},{5},{9}};只讲0列元素赋值

2)int a[3][3]={{1}, {0,6},{0,0,11}};对部分元素赋值,对非0元素少使用方便

3)int a[3][3]={{1}, {5,6}};只对几行元素赋值

4)int a[3][3]={{1}, {},{9}};对第二行元素赋值

 对全部元素赋值可以省略一维长度:

 对部分元素赋初值,在省略一位长度时,应分行赋值:

8.二维数组的输入输出:

 输入:直接定义

 输出:

for(i=0;i<=2;i++)

{for(j=0;j<=1;j++)

printf(“%5d”,b[i][j]);

printf(“n”);

}

9.二维数组的行列转换:

b[j][i]=a[i][j];

10.数组中求最大值并输出行列号:

Eg:inti,row=0,colum=0,max;

inta[3][4]={1,2,3,4,5,6,7,8,9,10,11,12};

max=a[0][0];

for(i=0;i<=2;i++)

for(j=0;j<=3;j++)

if(a[i][j]>max)

{max=a[i][j];

row=i;

colum=j;}

11.字符数组的初始化方法:

 逐个字符初始化:

eg:char c[10]={„I‟, „‟, „a‟, „m‟, „‟, „h‟, „a‟, „p‟, „p‟, „y‟};

1)在定义字符数组时,不初始化,则数组中的各元素的之不可预料;

2)如果花括号中提供的初值个数(即字符个数)大于数组的长度,则按语法错误

处理;

3)如果花括号中提供的初值个数(即字符个数)小于数组的长度,其余元素自动

定为空字符即(„‟);

 如果提供的初值个数与数组长度相同,则在定义时可以省略数组长度;  也可以定义一个二维数组:

eg:char diamond[5][5]={{},{},{},{},{}}; 用字符串常量,使字符数组初始化:

eg: char c[ ]={“I am happy”};或char c[ ]= “I am happy”;

12.字符数组的输出:

一维:二维:

for(i=0;i<=11;i++)for(i=0;i<=11;i++)

printf(“%c”,c[i]);for(i=0;i<5;i++)

printf(“n”);printf(“%c”,diamond[i][j]);

13.字符数组输出最大值:

eg:if(strcmp(string,str[1]>0)

strcpy(string,str[0]>0);

else

strcpy(string,str[1]);

if(strcmp(str[2],string>0)

strcpy(string,str[2]);

c语言基础总结 篇6

1.使用未初始化和未赋值的变量

描述:非全局变量和静态变量在定义时不自动进行初始化,初值为一个与该程序运行环境有关的随机数。不赋值或没有显示初值就直接使用这样的变量是错误的。

解决:所有变量都显示地进行初始化,建议数值变量初始化为0,指针变量初始化为NULL

2.不考虑数值溢出的可能

描述:当赋值超过此范围数值,就会产生数值溢出,得到不正确的值。

解决:预先估算运行结果的可能范围,采用可能范围更大的,不处理负数,就用无符号类型。运算还没开始前,判断运算数是否在合理取值的范围内,超出则停止运算。采用第三方无取值范围的运算库。

3.不用sizeof()获得类型或变量的字长

描述:相同类型在不同平台上占得字节数不同。Int在16位,32位,64位系统分别占2,4,8个字节。结构体所占字节也不是所有成员字长的简单相加,而是和平台与编译器,编译项都有关系。

解决:用且只用sizeof获得字长

Intwriteint(intfh ,inti)

{

Returnwrite(fh ,&i,sizeof(i));

}

4.假定类型的取值范围

描述:类型的取值范围与程序编译息息相关。

解决:使用limits.h和float.h定义的宏(INT--MAX,INT----MINULONG--MAXFLT---MAX

5.期望两个整数的运算自动获得浮点数的结果

描述:两个数运算的结果还是整数,不是浮点数

方案:强制转换为浮点数,再运算

例:voidfunc(void)voidfunc(void)

{{

Floatf=0.0;floatf=0.0;

Inta =3,b=2;int a=3,b=2;

f=a/b;f=a/(float)b;

printf(“%f,f);printf

}

6.不预先判除除数是否为0

编译器反应:直接写入inti=100/0,编译器会报错,编译器对此问题沉默

解决方案:先判断除数是否为0,若是0则不运算。

7.混淆“&,|”与“&&,||”

说明:他们是两种不同的运算符,有人总是弄错

8使用依赖编译器求值顺序的语句

描述:printf(“%d,%d,%d,i++,i++,i++);i=0可能输出 0.1.20.0.0.2.1.0方案:按期望的顺序分别求职,再综合运算

Voidfunc(void)

{

Int a,b,c ,i=0;

a=i++;

b=i++

C=i++

Printf(“%d,%d,%d”,a,b,c)

9.使用依靠算符优先级的表达式

描述;没有记住优先级,容易出错。

解决:用括号明确优先计算的部分

10.表达式过于复杂

描述:(a>b||b>c)&&(o>P||q>p)?(a-b)*c+(o-p)*q:(a*b*c)-(o*p*q)

11.用“==”时误用“=”

12.用“==”比较两个浮点数

描述;两个数值表面相等或者非常接近的浮点时用“==”比较,结果可能不同

解决;不用float用double在精度运算中两个浮点数的差的绝对值只要小于一个

精度范围,就可以相等

13.使用幻数

描述:直接使用的常数

解决;把幻数定义为宏或枚举,建议使用枚举。编译提示会更清晰,准确

#definearray-srze10

Enum(array-size=10)printf()和scanf()中格式控制字符串与参数类型不匹配

15.循环或判断语句以“;”结尾

描述:分别表示循环和判断语句的终结,后面的代码不算循环体或分支,而是循环和判断

平行的代码

解决:禁止在循环判断语句末尾出现分号,循环体为空的情况下,While(.........)

{

}

16.在循环体内改变循环结束条件

例如:voidfunc(void)

{

Int a,end:

-------

While(a

{

在这里修改end的值

}

}

17.case分支不用break结束

规定每个case分支必须用break结束,两个分支用同样的代码,就把代码定义为函数

基本概念

函数是c的基本单位,必须有且仅有一个main函数。一个c可以包含一个到多个函数,在函数中可以调用系统提供的库函数

函数首部:函数返回值类型,函数名,形参类型,形参名的说明

函数

函数体:大括号中的内容,包括变量声明(对象)语句和执行(动作)语句c程序书写规则;以分号结束,并且书写注释;“/**/,注释之间不能留有空格常见关键字:asmautobreakcasecdeclchar

Constcontinuedefaultdodoubleelse

Enumexternfarfloatforgoto

Hugeifinterruptintlongnear

Pascalregisterreturnshortsigned

Sizeofstaticstructswitchtypedef

Unionunsignedvoidvolatilewhile

标识符:系统自定义标识符,用户自定义标识符

运算符:算数运算符:+—*/%关系运算符: >>==<<=!=

逻辑运算符:!&&||

赋值运算符:=

复合的赋值运算符:+=-=*=/=%=&=!=^=<=>=

增一减一的运算符:++--

条件运算符:?:

强制类型转换运算符:

指针和地址运算符:*&

计算字节数运算符:sizeof

下标运算符:[]

结构体成员运算符:->

位运算符:<<>>|^&~

逗号运算符:,分隔符:相邻保留字,标识符之间由空格或回车换行做分隔符:相邻同类项之间用逗号分隔

声明相同类型的变量之间可用逗号分离,向屏幕输出的变量中各变量表达式之间用

逗号分离。

常见的转义字符:n 换行r回车(不换行) 字符串结束t 水平制表

v 垂直制表b退格f走纸换页a响铃报警

” 双引号’单引号 一个反斜线?问号

常见错误

数组;数组的下标都是从0开始的,访问时发生下标多1或者少1都会越界访问内存错误

用变量来定义数组长度会导致语法错误,应该用整型常量或整型常量表达式定义

用a[x,y]而不是a[x][y]的形式来访问二维数组中的元素,将导致语法错误

(数组的第1个元素的下标是0,数组元素1是指数组元素的下标为1,是数组的第二个元素)

忘记对需要进行初始化的元素初始化,导致运行结果错误

对数组初始化的过程中,提供的初值个数多于数组所能容纳的元素个数定义字符数组长度时,必须要多留一个字节的存储单元,存放结束标志打印一个不包括字符串结束标志的,导致运行结果错误

直接使用赋值运算符对字符串赋值是错误的,必须用strcpy()赋值

直接使用关系运算符比较字符串大小是错误的,必须使用strcpy()比较

字符串必须使用双引号括起来,单引号括起来是错误的。

一对双引号将一个字符常量括起来,产生一个指向包含两个字符的字符串指针(把字符当做实参去调用形参是字符串的函数;把字符串当做实参去调用形参是字符的函数,都会导致语法的错误!)

误以为在函数中定义的静态局部数组元素中的元素,在每次函数调用时都初始化0(函数原型,函数定义的头部和函数调用语句三者,在形参和实参的数量,类型和顺序,以及返回值的类型上没有严格保持一致,将导致语法错误。)

指针:误以为用来声明指针变量的星号(*)会对同一个声明语句中的所有指针变量都起作用,而省略了其他指针变量名前的星号。实质是每一个每一个变量名前的星号都不能省略。

没有对指针变量进行初始化,或没有将指针变量指向内存中某一个确定存储单元的情况下,就利用这个指针变量去访问它所指向的存储单元,将导致严重的运行错误。没有意识到某些函数形参是属于“传地址掉调用”而数值不是指针当做实参赋值给这形参。

对没有指向数组中的某个元素的指针变量进行算数运算,是无意义的。

对并非指向同一数组中元素的两个指针进行相减或比较运算。是无意义的。每个数组都有上,下边界,指针超出了边界就会造成越界访问内存错误。

除非两个指针类型都是void,否则将一种类型的指针赋值给其他类型的指针,造成语法错误。

试图用一个void的指针变量去访问内存,是一个语法错误。

试图以指针运算的方式来改写一个数组名所代表的地址,是一个语法错误

内存分配不成功的话会导致非法内存访问错误,只要运行前检查指针是否为空指针,可以避免错误发生。

如果内存分配成功,但是没有初始化,将会导致非法内存访问错误。

向系统申请了一块内存,结束后忘了释放内存,造成内存泄露。

释放了内存,但却仍然使用,会产生“野指针”

结构体,共用体:定义一个结构体时,忘记最后加上一个分号,导致语法错误

将一种类型的结构体赋值给另一种类型的结构体,导致语法错误

对两个结构体或者共用体进行比较,导致语法错误

在结构体指向运算符的两个组成符号“-” 和“>”之间插了空格,或者写成“→”导致语法错误

只使用成员变量名访问结构体的一个成员,导致语法错误

直接使用结构体的每个成员类型所占内存字节数的“和”作为一个结构体实际所占的字节数。是错误的。

没有标明结构体数组下标 就访问其中一个结构体数组元素,导致语法错误。

函数

递归函数是需要返回值的,在递归函数中忘记返回数值,是错误的忘记了编写递归终止条件的分支语句,写错了递归步骤,都会导致递归函数不能收敛到递归的终止条件,引起无穷递归

定义函数指针时,忘记将函数指针变量名及前面的星号用圆括号括起来,使得本应声明函数指针变量的变量声明变成了一个函数声明语句。

将函数指针作为函数参数时,不在函数指针变量名后的一对圆括号中列出各函数参数的类型,导致编译错误。

实施细则

1.函数

1.函数指针:通式:数据类型(*指针名)()int(*p)()

错误:忘记前一个()意义是声明一个函数,函数名为P,返回值是一个指向整型变量的指针

忘记了后一个(),意义是定义了一个指向整型变量指针。使用:1.定义过程 2.函数指针赋值过程3.调用过程

2.递归:一个对象部分地由它和自己组成或它自己定义,称它是递归的。

3.返回指针值的函数:通式:数据类型*函数名(参数名){}

区别;不带*的函数值,函数值只能是一个数据,不能是一组带*的函数值,不仅是一个数据,还能是一组数据。

2.结构体,共用体

位段:指定了存储位数的结构体或共用体的成员叫位段

优点:用最少的位数存储数据注意:必须声明为int或unsigned型使用:用struct作为关键字,定义了unsigned 的三个位段

“:”代表位段宽度的整数常量,访问位段成员的方法与访问结构体成员的方法基本一致,用“圆点运算符”或“箭头运算符”

共用体:将不同的数据类型组合在一起,共占有同一段内存的用户自定义数据类型注意:必须有足够大的内存空间将占据最大内存空间的成员存储在内,内存空间的大小由占据内存空间成员所占的空间数决定。

动态数据结构:在结构体类型中,如果包含了本结构体类型的成员,由于本结构所占的内存字节数无法确定,系统无法正常分配内存。

声明结构体类型是不能包含自我,但可以包含指向本结构体类型的指针域。操作:

Structtemp

{

Intdata;

Structtemp*temp;

};

利用函数malloc()申请一个结构体的内存

Structtemp

{

Intdata;

Charname[10];

};

Structtemp *p;

P=(struct temp*)malloc(10*sizeof(structtemp));利用函数calloc()申请一个结构体内存

Structtemp *p

P=(struttemp*)calloc(10*sizeof(struct 利用函数free()释放申请的内存空间,链表的定义

c语言编程自我总结 篇7

关键词:汇编语言,C/C++语言

在计算机系统的应用程序中, 所有汇编任务都由汇编语言来完成, 这样虽然完成任务的效率很高, 但是工作量却非常大, 会影响到对于应用程序的维护。若是所有的程序都是由C/C++语言进行编程, 虽然执行过程比较的简单, 但是这种方式却导致了目标代码的执行任务效率低, 实时性很差。所以在嵌入式系统中, 主要采用的编程方式是汇编语言与C/C++语言混合编程形式, 在编程过程中, 初始化任务由汇编语言来完成, 主要的任务则是由C/C++语言来完成, 从而达到了最大的效果。

1 ARM处理器

ARM处理器主要是利用编译器将汇编语言以及C/C++语言进行相互的切换, 并且ARM制定了相关标准, 来保障切换过程中的顺利实施。

1.1 寄存器使用规则

ATPCS为ARM寄存器进行不同命名, 从而在编程的过程中来利用ATPCS寄存器进行编程。

1.2 堆栈的使用规则

在ATPCS中规定, 堆栈的主要类型是FD, 被称为满递减堆栈, 所以必须要利用STMFD/LDMFF进行堆栈的操作。

1.3 参数传递规则

参数传递的规则不一样, 利用参数的数量可以将子程序分为参数数量固定, 以及参数数量不固定的子程序, 对于参数变化的子程序, 若参数的数量少于四个, 那么要利用寄存器来进行参数的传递, 若参数的数量多余四个, 那么必须要利用堆栈来进行参数的传递, 所以参数之间传递的规则不同。

2 C语言

2.1 汇编语言调用C语言

在对计算机程序的开发中, 前期由汇编语言进行初始化的编程, 然后在进行C语言之间的切换, 对于C语言的切换, 主要是通过BL来实现的。以下是调用的字符:

汇编语言的集成环境如图1所示。

2.2 C语言调用汇编语言

在程序中, 使用“C++”程序来调用C程序, 以下是调用C程序的字符:

2.3 汇编程序调用C++程序

在汇编语言与C++程序的切换时, 必须要利用关键词进行声明, 在C++程序的结构中, 如果没有基类, 则要使相应的存储结构与ARMC相同。并且在汇编过程中将参数的数据放在数据栈中, 只有这样才能使被调用的C++程序访问到相应的参数。

3 混合编程

在进行混合编程的过程中, 若汇编代码较短, 那么可以利用内嵌汇编的方式进行混合编程, 不会直接指定寄存器, 而是直接利用编译器进行分配。主要的内嵌汇编语言如下:

以下是利用字符串复制的方式实现混合汇编:

4 结语

在计算机系统嵌入式应用程序的开发中, 利用ARM汇编语言与C/C++语言相互结合的混合编程方式, 可以在很大程度上提高编程的最佳效果。本文主要举出了ARM汇编语言以及C/C++语言汇编中的实例, 提出了设计的方法, 阐述了ARM汇编语言与C/C++语言相互结混合编程方式的实现。

参考文献

[1]翟乃强, 隋树林.汇编语言与C语言及Visual C++混合编程[J].青岛科技大学学报 (自然科学版) , 2003.

[2]王付山.汇编语言程序设计教学初探[J].福建电脑, 2005.

高职C语言教学浅析 篇8

【关键词】C语言;学生兴趣;教学方法

现在计算机已普及到各行各业,深入到各级层次。在我国高职院校教育中,C语言不但成为计算机专业的必修课,而且也成为非计算机专业的学习课程。做好该门课程的教学具有非常重要而深远的社会意义,现将我在C语言程序设计课程中教学内容、教学手段、教学方法等方面的改革与取得的教学效果与大家做一探讨

一、努力培养学生的学习兴趣及正确的思维摸式

兴趣是学习的关键,兴趣决定了教学效果的好坏。初学C语言时,很多学生感到新奇、好玩,这不能说是兴趣,只是一种好奇。随着课程的不断深入,大量的规则、定义、要求和机械的格式出现,很容易使一部分学生产生枯燥无味的感觉。为了把学生的好奇转化为学习兴趣,授课时我改变过去先给出定义和规则的讲授办法,而是演示一些由前几届学生自己编写的、有趣的程序,从而吸引学生,并告诉他们学习了C语言程序设计的内容后,大家都能够编出这些小程序。努力把枯燥无味的“语言”讲的生动、活泼。

二、循序渐进

高职学生第一次接触计算机语言,“通俗性、可接受性”的教学原则同样适合于这门课的教学。在课程讲授过程中,我没有把重点放在语法规则的叙述上,而是放在算法和程序设计方法上,通常由几个例题引出一种语法规则,通过一些求解具体问题的程序来分析算法,介绍程序设计的基本方法和技巧,既注重教材的系统性、科学性,又注意易读性和启发性。从最简单的问题入手,一开始就介绍程序,要求学生编写程序,通过反复编写、运行程序来掌握语言的规定和程序设计的方法。同一个语法规则、同一种算法,在选择例题时也是由简到难,逐步呈现给学生。在学习上不要求学生死记语法规则,而是要求学生能把各个孤立的语句组织成一个有机的、好的程序。注意培养学生良好的编程风格,让学生在编制程序过程中不断总结、巩固,达到学会方法、记住语法规则,提高设计技巧的目的。

三、改进授课方法、实现教学相长

(一)采用启发、引导的教学方法

(1)教师在教学过程中,应当注意设置疑难问题,引导学生思考和探索,让他们的思想活跃起来。我教学时发现,学生问不出问题的原因往往在于没有真正学好。实际上,问题是最好的老师,是学生学习的引导者,没有问题便没有深入。在教学过程中,引导学生在问题解决中学习,即提出问题,给时间让学生思考、讨论、解决问题,从而更深入地展开学习。实践证明,这种教学方法充分调动了学生学习的积极性和主动性。例如 ,在讲数组的概念时,我先设置问题:编程计算10个人的英语平均成绩。根据以前所学,学生会想到:需要说明10个类型相同的变量用于存放10个人的英语成绩。进一步要求:计`算50个人的英语平均成绩,这时候如再说明50个变量,则会将问题麻烦化,学生此刻需要讨论该如何合理说明变量。再深入一步:求100个人的英语平均成绩。此时,当教师引出数组的概念、分析数组的性质时,学生不仅能够记住数组的性质,还能够知道在什么情况下使用数组类型,达到事半功倍的效果。

(2)教给学生正确的学习方法,引导学生掌握程序设计的思想和方法。经验丰富的软件设计者都知道程序设计的关键在于找到解决问题的方法,即算法。根据软件工程的思想,当拿到一个任务时,首先应将这个问题自顶向下逐步细化,逐层向下分解,直到满足每一个要求。实现时,可以先用流程图描述出算法,进而写出合理的算法,再将之转化成程序。

(二)采用目标教学法,使学生明确目的,确立主题

学生是认知主体,是信息的主动接受者,但也并不能否定教师的指导作用,教师作为知识的先知者,自然清楚所学内容哪些是重点及难点,哪些是只需一般掌握的,如果脱离了这一点,学生有可能会不加区分地对所学内容完成认知,进而导致其知识主结构的无法确定,所以教师在进行教学设计的第一步还是要进行目标分析,指导学生确立主题。

四、校企结合,加强实践教学环节

高职教育着重培养具有实际工作能力的技术型和应用型人才。为了使学生学习到的知识与社会接轨,可以创建校企结合的课程建设方法。听取企业家对C语言程序设计教学改革的意见、由企业向学校提供实验(实习)条件、以企业作为学生的校外实习基地,通过这些方法使学生熟悉公司内的编程环境。学校还可以邀请企业家为学生开讲座,派遣青年教师到企业去实习,使教学的内容与企业的实际更为贴近。高职院校作为企业的人才培育基地,发挥技术和设备的优势,为企业提供支持,向企业输送合格毕业生,校企结合实现双赢。

上一篇:回味无穷下一篇:家庭助廉工作总结