首页 | 编程语言 | 网站建设 | 游戏天堂 | 冲浪宝典 | 网络安全 | 操作系统 | 软件时空 | 硬件指南 | 病毒相关 | IT 认证
软讯网络 > 编程语言 > C/C++ > C编码时易犯的错误
【标  题】:C编码时易犯的错误
【关键字】:
【来  源】:http://blog.chinaunix.net/article.php?articleId=48561&blogId=10259

C编码时易犯的错误

C编码时易犯的错误

查找连接错误
(在建设和不断修改中,欢迎提出意见)
学生: 我的程序编译没错,为什么系统说不能连接,不能产生可执行程序?
老师: 那说明程序的外部变量、函数的名字方面出了些问题。这些问题比较简单,但修改时也要特别小心,不要把其他正确的东西改错了。




--------------------------------------------------------------------------------

连接是编译完成后的下一个程序加工步骤。在这个步骤中,连接程序的工作对象是:1)由你所编写的程序源文件产生的目标文件(一个或者几个);2)语言系统提供的一些目标代码文件,包括基本运行模块(也称为运行系统)和库文件。

连接程序的工作包括两部分:1)将所有需要的目标代码拼装到一个文件中(这是最后可执行文件的基础);2)将外部对象的使用和定义连接起来,包括所有函数调研的实际调用代码的建立,正确设置所有外部变量的使用。

连接错误有两类:

1)缺定义。当程序中出现对某个外部对象的使用,而连接程序找不到对应的定义时,将产生这个错误。
2)重复定义。当被连接的各个部分中出现某个名字的多个定义时,将产生这个错误。



--------------------------------------------------------------------------------

缺定义错误的常见原因:
1)名字拼写错误。例如将 main 拼写为 mian,连接时就会产生缺定义的连接错误。因为程序的基本允许模块里有一个对 main 的调用,连接程序需要找它的定义而没有找到。调用自己的函数名字写错的情况也很常见。

2)真的就是没有定义。例如你想调用一个非标准的C库函数,而你所用的系统里没有。或者是你要调用的自定义函数忘了定义。有时也有这样的情况,系统里有这个函数,但需要特别设置才能够找到它(因为函数放在某个非标准的库文件里),解决这种问题需要查阅有关的系统手册,这里不讨论了。

如果真是缺了定义,那就只能设法补上。



--------------------------------------------------------------------------------

重复定义错误的常见原因:
1)重复定义可能是自己(在不同源文件里)定义的两个东西采用了同样的名字,或者是自己定义的东西恰好与C语言系统内部定义的某个东西重名。这时都需要改名字。

2)可能你在一个文件里定义了某个变量,而在另一个文件里需要使用它,但却忘记在变量说明前加 extern 关键字。

3)有些连接程序只按照外部名字的前X个(常见的是前6个,这是C语言标准的最低要求)字符考虑连接问题。如果你程序里有多个对象前6个字符相同,或者恰好某个对象名字的前6个字符与编译系统所提供模块里的某个名字相同,那么就可能出问题。

解决办法:找出出现冲突的名字,系统地将它们改为另外的名字。请注意,在改名字时一定要特别小心,如果更改不当或者不彻底,就会引进错误(某个使用实际用的可能不是你所希望的东西)。

利用C语言的static功能,将所有只在一个文件里使用的外部对象定义为static,可以避免自己在多个文件里定义的东西互相冲突(即使是用同样的名字,如果都是static也不会冲突,因为static的外部名字只在本文件里可以看见)。

查找和排除程序运行中发现的错误(debugging)
(在建设和不断修改中,欢迎提出意见)
学生: 我的程序编译连接都通过了,为什么运行中系统还会报出错误?
老师: 这一般说明你的程序在某些方面做了违反C语言规定(违规)的事情,而这种情况是在运行的动态过程中出现的。你现在用的系统能够检查出这个问题,所以就报了错误。

学生: 我的程序编译运行都正常,怎么就是结果不对?(怎么就不能完成我想做的事情?)
老师: 出现这种问题的可能原因很多,解决起来也比较困难些。你最好首先认真读一读你的程序,想一想它可能存在什么问题,然后再…………




--------------------------------------------------------------------------------

从外面看,运行时发现的错误可以分为两类:一类是系统能够检查并产生信息的错误;另一类是系统不检查也不产生运行错误信息的错误。不同的系统在检查哪些问题方面可能差别很大。

抽象地看,运行时发现的程序错误可以分为两类:一类是程序中某些地方执行了违反语言规定的操作,由此产生某种影响导致程序出错;另一类问题出在程序本身,例如程序的算法不对,或者是程序写的不对(没有表达你所想说的东西),这些一般称为逻辑错误。这种问题分类只有提示性,并不是绝对的,有时也很难划分清楚。



--------------------------------------------------------------------------------

违规型的错误
最常见的违规错误是非法地址访问。有些系统(例如DOS)对这类错误完全不检查,可能造成很严重的后果,常常会破坏系统,造成死机或者非常奇怪的系统行为。有些系统(例如 Windows NT)管理比较严格,可能确认程序非法访问而将其kill掉。

1)对空指针、未初始化的指针的间接访问。这涉及到对指针值所确定地址的访问,常常是非法的。

2)把整数或者其他变量当作指针使用,造成访问非法地址的情况,例如,假定 n 和 x 分别是整的和双精度的变量;下面语句将它们的值当作指针值使用,形成非法访问:
scanf("%d %lf", n, x);

3)数组的越界访问。效果无法预料,有时可能被系统检查出来,有时可能检查不出来,造成奇怪的程序行为。




--------------------------------------------------------------------------------

逻辑型的错误(语义错误)
一类常见错误是计算溢出、除零等。C语言对于无符号数的上溢出(超出表示范围)自动丢掉最高位,对于一般整数类型、浮点数类型,语言的标准本身并没有明确规定,不同C语言系统的处理方式可能不同。大部分C语言系统忽略整数溢出的情况。无论如何,出现溢出往往会造成结果与预想的东西不符。




--------------------------------------------------------------------------------

排除程序错误的基本方法





--------------------------------------------------------------------------------

排错系统(debugger)的使用,原理、技术、方法。局限性。



--------------------------------------------------------------------------------

参考材料:《程序设计实践》第5章:排错。

Turbo C(TC)系统的浮点连接错误
用TC-2.0系统编写小的C程序,如果程序里用到浮点输入,有时运行中会出现下面错误信息:

scanf : floating point formats not linked
Abnormal program termination

这个错误信息的意思是:scanf的浮点格式转换程序没有连接。

TC开发时(80年代)DOS下的存储资源紧缺,因此TC在编译时尽量不加入无关部分。在没发现需要做浮点转换时,就不将这个部分安装到可执行程序里。但有时TC不能正确识别实际确实需要浮点转换,因此就会出现上面错误。

解决方法:设法告诉TC需要做浮点数输入转换。下面例子里增加了一个double变量并用它输入。

大程序里由于变量很多,只要有了线索,TC就会把浮点转换连上,因此反而不常遇到这个问题。



--------------------------------------------------------------------------------

/* 能导致出现运行错误的程序例子。
在这里用的一个结构数组,结构里面有double类型的成分,TC不能正确识别和处理,因此会导致上述问题。*/
#include <stdio.h>
#define NUM 4

struct entry {
int inum; /* 商品编号 */
int pc; /* 件数 */
double price;/* 价钱 */
} st[NUM]; /* st是个商品表 */

int main () {
int i;
for (i = 0; i < NUM; i++)
scanf("%d %d %lf", &st[i].inum, &st[i].pc, &st[i].price);

for (i = 0; i < NUM; i++)
printf("total price of item %d: %f\n",
st[i].inum, st[i].pc * st[i].price);
return 0;
}

/* 这个程序编译正常,运行中会出现上面错误信息 */



--------------------------------------------------------------------------------

/* 修改的程序,其中增加了一个double变量x。问题就解决了 */
#include <stdio.h>
#define NUM 4

struct entry {
int inum;
int pc;
double price;
} st[NUM];

int main () {
int i;
double x;
for (i = 0; i < NUM; i++) {
scanf("%d %d %lf", &st[i].inum, &st[i].pc, &x);
st[i].price = x;
}

for (i = 0; i < NUM; i++)
printf("total price of item %d: %f\n",
st[i].inum, st[i].pc * st[i].price);
return 0;
}

C语言中判断文件大小:【上一篇】
查找和排除程序编译中的错误:【下一篇】
【相关文章】
没有相关文章
【随机文章】
  • 用linux构建路由器(转载)
  • Game Programming with DirectX -- 03[谁把我挡住了]
  • Delphi防止程序被重复执行
  • 今天是我的第一博
  • Fedora Core 1安装手记
  • 《Effective C#》Item 7:推荐使用不可改变的原子值类型
  • 如何看ERP软件?
  • 实战讲解网络钓鱼技术大全(1)
  • Deep Thinking in Patterns--工厂方法模式(Factory Method)
  • 进入应用程序所在目录
  • 【相关评论】
    没有相关评论
    【发表评论】
    姓名:
    邮件:
    随机码*
    评论*
          
    |  首 页  |  版权声明  |  联系我们   |  网站地图  |
    CopyRight © 2004-2007 软讯网络 All Rigths Reserved.