注册 登录
电子工程世界-论坛 返回首页 EEWORLD首页 频道 EE大学堂 下载中心 Datasheet 专题
lw209的个人空间 https://home.eeworld.com.cn/space-uid-345120.html [收藏] [复制] [分享] [RSS]
日志

C语言的常见错误分析

已有 1604 次阅读2012-8-27 01:37 |

语法错误和语义错误:
1,误认'='为'==';
2,误认&等于&& |等于||;
&&和||为逻辑运算符,&,|为位运算符 ,
3,输入输出的数据类型与所用的格式说明符不一致
例如:int a,float b;
a=3,b=4.5;
printf("%f,%d\n",a,b);
编译不给出出错信息
4,未注意int型数的数值范围,-32768~32767
例如:
int num;
num=89101;
printf("%d\n",num);
输出为23565
原因:89101-65536=233565
有时候还会出现负数
5,在输入语句的时候忘记使用变量的地址符
scanf("%d%d",a,b);
编译出错
应写:scanf("%d%d",&a,&b);
数据间应该用空格或回车符或tab键分开
scanf函数的格式字符串中除了格式说明符外
对其他字符必须按原样输入
6,误把'='作为等号处理
7,不该加分号的地方加了分号
例如:
if(a>b);
  printf("a>b\n");
8,应该有花括号的复合语句,忘记加花括号
9,括号不匹配
10,引用数组时误用圆括号
11,忘记了大小字母的区别
12,对二维数组定义错误,引用错误
13,误以为数组名代表数组中的全部元素
14,忘记字符数组和字符指针的区别
15,在引用指针变量之前没有对它赋值
16,switch case语句忘记break
17,字符和字符串区别
'x'为一个字符的时候 -->x
“x”为一个字符串的时候 -->x\0
 18,
continue 不是跳出,而是跳过本次循环体尚未执行的语句,立即开始下一次循环。
continue 是作用于其所在的那层循环,而不是分支语句。
19,一条语句后忘记加分号,例如:unsinged int i 正确的写法:unsinged int i ;
20,优先级高低忘记了,导致程序并不能实现自己想要的结果。
21,指针理解不清楚,导致程序不能实现自己想要的结果。
22,switch()的参数不能是实型,只能为字符型或整型。
23,宏不是函数 ,宏不是类型定义
24,字符和字符串理解不清,例如:
char hello[]={"Hello world"};
char hello[] = { 'H', 'e', 'l', 'l', 'o', ' ', 'w', 'o', 'r', 'l', 'd'};
第一个字符数组比第二字符数组,会多一个'\0';
25,当无符号和有符号的负数相加或减,把有符号的负数转换为无符号,然后进行加减,
 unsigned int a = 6;
 int b = -20;
 (a+b > 6) ? puts("> 6") : puts("<= 6");输出的结果:”>6“;
26,结构体字节对齐问题,理解不清楚。
27,字符数组和字符指针的区别,例如:
char* p="test";//字符指针
char p[]="test";//字符数组
//解释:指针是不分配内存的,它指向的是系统的只读的内存,而数组是分配内存的,就是将系统的只读的内存里面的值复制到它的内存里面,因此可读写.
28,指针变量 :指针就是地址
存储类型 指针类型 * 指针变量
指针占4个字节 内存是32位的
32位  2^32=4G
指针是一个通配符
 

代码的优化:
    一、程序结构的优化
 
    对于一个表达式中各种运算执行的优先顺序不太明确或容易混淆的地方,应当采用圆括号明确指定它们的优先顺序。一个表达式通常不能写得太复杂,如果表达式太复杂,时间久了以后,自己也不容易看得懂,不利于以后的维护。
   
    2、程序的书写结构
   
    虽然书写格式并不会影响生成的代码质量,但是在实际编写程序时还是应该尊循一定的书写规则,一个书写清晰、明了的程序,有利于以后的维护。在书写程序时,特别是对于While、for、do…while、if…elst、switch…case等语句或这些语句嵌套组合时,应采用"缩格"的书写形式,
   
    3、减少判断语句
   
    能够使用条件编译(ifdef)的地方就使用条件编译而不使用if语句,有利于减少编译生成的代码的长度,能够不用判断语句则少用判断用语句。
   
    4、标识符
   
    程序中使用的用户标识符除要遵循标识符的命名规则以外,一般不要用代数符号(如a、b、x1、y1)作为变量名,应选取具有相关含义的英文单词(或缩写)或汉语拼音作为标识符,以增加程序的可读性,如:count、number1、red、work等。
   
    5、定义常数
   
    在程序化设计过程中,对于经常使用的一些常数,如果将它直接写到程序中去,一旦常数的数值发生变化,就必须逐个找出程序中所有的常数,并逐一进行修改,这样必然会降低程序的可维护性。因此,应尽量当采用预处理命令方式来定义常数,而且还可以避免输入错误

    二、代码的优化
1、使用自加、自减指令
   
    通常使用自加、自减指令和复合赋值表达式(如a-=1及a+=1等)都能够生成高质量的程序代码,编译器通常都能够生成inc和dec之类的指令,而使用a=a+1或a=a-1之类的指令,有很多C编译器都会生成二到三个字节的指令。在AVR单片适用的ICCAVR、GCCAVR、IAR等C编译器以上几种书写方式生成的代码是一样的,也能够生成高质量的inc和dec之类的的代码。
   
    2、查表
   
    在程序中一般不进行非常复杂的运算,如浮点数的乘除及开方等,以及一些复杂的数学模型的插补运算,对这些即消耗时间又消费资源的运算,应尽量使用查表的方式,并且将数据表置于程序存储区。如果直接生成所需的表比较困难,也尽量在启动时先计算,然后在数据存储器中生成所需的表,后以在程序运行直接查表就可以了,减少了程序执行过程中重复计算的工作量。
   
    3、使用尽量小的数据类型
   
    能够使用字符型(char)定义的变量,就不要使用整型(int)变量来定义;能够使用整型变量定义的变量就不要用长整型(long int),能不使用浮点型(float)变量就不要使用浮点型变量。当然,在定义变量后不要超过变量的作用范围,如果超过变量的范围赋值,C编译器并不报错,但程序运行结果却错了,而且这样的错误很难发现。在ICCAVR中,可以在Options中设定使用printf参数,尽量使用基本型参数(%c、%d、%x、%X、%u和%s格式说明符),少用长整型参数(%ld、%lu、%lx和%lX格式说明符),至于浮点型的参数(%f)则尽量不要使用,其它C编译器也一样。在其它条件不变的情况下,使用%f参数,会使生成的代码的数量增加很多,执行速度降低。
   
    4、选择合适的算法和数据结构
   
    应该熟悉算法语言,知道各种算法的优缺点,具体资料请参见相应的参考资料,有很多计算机书籍上都有介绍。将比较慢的顺序查找法用较快的二分查找或乱序查找法代替,插入排序或冒泡排序法用快速排序、合并排序或根排序代替,都可以大大提高程序执行的效率选择一种合适的数据结构也很重要,比如你在一堆随机存放的数中使用了大量的插入和删除指令,那使用链表要快得多。数组与指针语句具有十分密码的关系,一般来说,指针比较灵活简洁,而数组则比较直观,容易理解。对于大部分的编译器,使用指针比使用数组生成的代码更短,执行效率更高。但是在Keil中则相反,使用数组比使用的指针生成的代码更短
评论 (0 个评论)

facelist doodle 涂鸦板

您需要登录后才可以评论 登录 | 注册

热门文章