鱼C论坛

 找回密码
 立即注册
查看: 19333|回复: 139

[技术交流] 初学者或是开发人员常遇到的c语言陷阱

  [复制链接]
发表于 2012-12-11 19:57:32 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
本帖最后由 消失在黑暗中 于 2012-12-12 19:32 编辑

参考《C语言编程之道》-明日科技,《c++程序设计》-谭浩强
原文:第四章 开发人员不可忽视的22个技术陷阱-《C语言编程之道》。版权是他们的,我借来与大家一起学习,并加入自己的一些总结。
我最近想找明日科技的一本书《c++程序实例1200题》,我这边新华书店没卖,共两本,求电子版。我买过他们几本书,很贵(想图个便宜),他们出的书很实用。

正题:

陷阱1:忽略大小写的区别
  1. #include<stdio.h>
  2. void main()
  3. {
  4.   int a=10;
  5. a+=a;
  6. printf("%d\n",A);
  7. }
复制代码
这个很简单,是基础,c语言变量区分大小写。代码中的a与A不是同个变量,编译出现A没定义的错误。

陷阱2:“{}”与“()”使用不当造成错误
  1. #include <stdio.h>
  2. void main()
  3. {
  4. int i,j;
  5. int a[2][3]={(1,2,3),(4,5,6)};
  6. printf("array a:\n");
  7. for(i=0;i<=1;i++)
  8. {
  9. for(j=0;j<=2;j++)
  10. {
  11. printf("%d",a[i][j]);
  12. }
  13. printf("\n");
  14. }
  15. }

  16. }
复制代码
程序结果不能正常输出数组每个元素,编译{(1,2,3),(4,5,6)};时,先进行括号内的逗号运算(取逗号最后的数值),编译生成{3,6};其它元素为0。正确的写法:{{1,2,3},{4,5,6}};

陷阱3:在if,while,#include,#define,for后直接加分号,如for(int a=1;a<10;a++);

如果是while,程序一般执行死循环,int a=1;while(a);

如果是if,判断语句无效果,比如。if(a>0);a=-1;无论a是否大于0,结果都是a=-1;

如果是#include,程序编译的时候提示错误,无法引用库文件;

如果是#define,比如#define a 200;程序在预编译的时候,200;包括分号一同被替换进程序,程序不可能正常编译

如果是for循环,跟if一样,事与愿违,循环做无用功,本想循环的printf语句只执行一次。for(int a=1;a<10;a++);printf("%d",a);程序只输出一次a值。

陷阱4:使用循环语句不慎产生死循环
  1. #include<stdio.h>
  2. void main()
  3. { unsigned int i;
  4. for(i=10;i>=0;i--)
  5. printf("%d",i);
  6. printf("\n");
  7. }
复制代码
i被定义为无符号整型变量,i的值永远大于等于0;i>=0永远成立;

陷阱5:do....while与while之间的区别

do....while先执行再判断条件是否成立;无论条件是否成立,do....while至少执行一次;
while 先判断,再执行;条件不成立,就不执行,可能执行0次;

陷阱6:数据溢出产生的错误
  1. #include<stdio.h>
  2. void main()
  3. {
  4. int i,rst;
  5. i=32767;//这里是turbo c中int类型为16位,c++为32位
  6. rst=i+1;
  7. printf("%d,%d",i,rst);
  8. }
复制代码
c语言中int占两个字节,数据最大支持补码正数值32767,加1溢出。

陷阱7:除号/用法导致的错误

如果除号的两边都为整数,结果为整数;两边有一个实数,结果为实数;
  1. #include<stdio.h>
  2. void main()
  3. {
  4. double i;
  5. i=9.5+1/2;
  6. printf("%f",i);

  7. }
复制代码
结果输出9.500000;这里的1/2运算符两边为整数,1/2=0;正确的输出:i=9.5+1.0/2;

陷阱8:变量未定义

虽说是人人都清楚的问题,但是还是会出现。

陷阱9:用scanf输入数据时忘记加&符号

  1. #include<stdio.h>
  2. void main()
  3. {
  4. int a,b;
  5. printf("输入两个整数\n");
  6. scanf("%d%d",a,b);
  7. printf("%d%d\n",a,b);

  8. }
复制代码

scanf第二个参数必须为地址。正确的写法:scanf("%d%d",&a,&b);

陷阱10:使用scanf函数输入格式不符

  1. #include<stdio.h>
  2. void main()
  3. {
  4. int a,b;
  5. scanf("%d,%d",&a,&b);
  6. printf("%d,%d",a,b);

  7. }
复制代码
凡是学c语言都遇到过这问题,错在输入a和b时,忘了在ab之间输入逗号。
不是任何的场合适合用其他符号用作数据输入分割。比如scanf(“%s,%d,%s”,&a,&b,&c);a得到的是整个语句的内容。
我提议用空格取代其他符号分隔数据,可以减少不必要的错误。

陷阱11:输入的数据类型不符的陷阱

比如在上代码程序输入字符'a','b'.输出不是想要的结果。改成scanf("%c%c",&a,&b),输入字符用%c。

陷阱12:switch语句中忘记使用break;

  1. #include <stdio.h>
  2. void main()
  3. {
  4. char grade;
  5. scanf("%c",&grade);
  6. switch(grade)
  7. {
  8. case 'a':printf("90-100\n");
  9. case 'a':printf("80-100\n");

  10. }

  11. switch中忘记用break;则每种情况都判断,满足条件都执行

  12. }
复制代码

陷阱13:指针没被初始化

指针是存放地址的变量,与其他变量相同的是,变量未被赋值时,变量存放着内存上原本的值(内存的释放与文件的删除相类似,内存上的数据不改动,除非其他数据覆盖上去),变量的赋值就是数据的覆盖,内存上保存了上次运行的数据。未被赋值的指针,不知指向哪里。
  1. #include<string>
  2. #include<stdlib.h>
  3. #include<stdio.h>
  4. using namespace std;

  5. int main()
  6. {
  7. char*str;
  8. strcpy(str,"good");
  9. printf("%s",str);
  10. retrun 0;
  11. }


复制代码
代码中的str指针未被赋值而使用,程序无法编译。

陷阱14:超出动态分配的内存

  1. #include<string>
  2. #include<stdlib.h>
  3. #include<stdio.h>
  4. using namespace std;

  5. int main()
  6. {
  7. char*str=malloc(5);
  8. strcpy(str,"goodluck");
  9. printf("%s",str);
  10. free(str);
  11. retrun 0;
  12. }
复制代码
程序动态分配5字节的内存空间,但是赋值超过了5字符,错误为赋值的数据超过动态分配的空间。

陷阱15:使用内存后未释放


  1. #include<string>
  2. #include<stdlib.h>
  3. #include<stdio.h>
  4. using namespace std;

  5. int main()
  6. {
  7. char*str=malloc(20);
  8. strcpy(str,"goodluck");
  9. printf("%s",str);
  10. retrun 0;
  11. }
复制代码
有必要在这里说说动态内存怎么释放:


内存未释放在程序运行时,开始不出现错误,过多占用内存时会造成内存空间不足而死机的现象。












全部手打,继续更新,如有错误,谢谢提醒!


评分

参与人数 5荣誉 +9 鱼币 +16 贡献 +10 收起 理由
♂我是上帝♂ + 2
懒家大少 + 1 感谢楼主无私奉献!坐等更新
feitianqu + 2 + 5
小布丁 + 4 + 6
Whisper微风 + 5 + 5 + 5 很适合初学者!

查看全部评分

本帖被以下淘专辑推荐:

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
发表于 2012-12-11 20:14:22 | 显示全部楼层
{:2_31:}不错啊,支持
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
发表于 2012-12-11 20:30:54 | 显示全部楼层
期待更多!谢谢分享!
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
发表于 2012-12-13 00:09:09 | 显示全部楼层
初学者一定顶
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
发表于 2012-12-13 17:06:59 | 显示全部楼层
先收下  在慢慢看
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
发表于 2012-12-25 13:35:00 | 显示全部楼层
真好!!!!!!!!!!
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
发表于 2012-12-25 21:27:13 | 显示全部楼层
谢谢,手打很辛苦!
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
发表于 2012-12-27 00:11:49 | 显示全部楼层
不错啊,支持
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
发表于 2012-12-27 13:21:52 | 显示全部楼层
楼主辛苦了,谢谢分享
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
发表于 2013-1-25 11:15:34 | 显示全部楼层
楼主真神人也,这些错误我全部都犯过:L
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
发表于 2013-1-27 00:15:23 | 显示全部楼层
很不错的帖子,是该加精置顶的,,看了几个,困了,明天再看~~
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
发表于 2013-2-4 23:44:21 | 显示全部楼层
这个不错{:1_1:}
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
发表于 2013-2-5 00:24:47 | 显示全部楼层
不错啊 kkkkkkkkkkkkkkkkk
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
发表于 2013-3-15 10:07:29 | 显示全部楼层
期待更多!谢谢分享!
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
发表于 2013-4-1 20:03:13 | 显示全部楼层
楼主善良高尚
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
发表于 2013-4-1 23:04:22 | 显示全部楼层
有时间看看.............
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
发表于 2013-4-1 23:30:33 | 显示全部楼层
楼主辛苦了。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
发表于 2013-4-2 12:35:56 | 显示全部楼层
楼主好强悍
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
发表于 2013-4-4 18:22:04 | 显示全部楼层
激动人心,无法言表!
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
发表于 2013-4-14 23:11:44 | 显示全部楼层
学习了 真是难得给力的帖子啊。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-3-29 13:10

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表