Visual C++6.0中的调试工具使用及常见错误
合集下载
相关主题
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
(例如:下边的例子中,有些同学经常忽略了 birthday) 2、 结构体类型名和结构体变量名混淆。例如:
struct STU {….
Struct data {int year,month,day; }birthday
}; struct STU a; struct STU 是类型名称,而且不分配空间,且不能直接引用。只有定义了结 构体类型 struct STU 的变量 a 以后,才为 a 分配相应的内存空间,引用时也要是 a.??? 3、 结构体变量的成员引用不正确,尤其是当结构体类型中有嵌套定义的时候。一定要一级 一级的引用。例如:上边的例子:如果引用其中的年的话,一定是 a.birthday.year. 不 能直接 a.year. 4、 对结构体变量进行输入输出的时候,整体输入或整体输出。除作为函数参数外,不能对 结构体变量整体操作,只能一个成员一个成员地输入、输出。 5、 不理解共用体的“共占内存”。对共用体中的成员变量,一定要靠一个标记区别它们, 并分别按不同类型引用它们。切记:共用体变量不能做函数形参。
三、数组与指针 1、 字符串的输入有错误:主要表现在使用 scanf()或 gets()时加了&,或输入字符串时用循
环,(这样的话,字符个数无论多长,都不会为自动加\0,将来引用的时候也就不能以 字符串的形式引用。) 2、 对字符串的处理中,循环条件仍然写成 I<N。由于字符串是不定长的,所以循环条件一 般为 str[I]!=’\0’ 或 I<strlen(str) 3、 而输入所对应的变量是指针时(常见的有:输入的变量是字符数组名或指向字符串的指 针)不能加&。 4、 指针定义后未赋值就引用。如果在定义时不知道赋什么值,可以用 p=NULL 赋初值,以 避免引起的灾难性错误。 5、 分不清 p 和*p。前者是指针,即地址,后者表示指针所间接引用的数据,但如果是二 级指针或多级指针,取*以后得到的仍然可能是地址。
四、函数 1、 函数定义的时候,函数头部加分号,而函数声明的地方忘了加分号 2、 函数实参格式不对,主要表现在:给出实参时,多给出数组类型,或者,形参是数组 int
a[];的时候,给出的 a[]或 a[I]. 3、 递归时忘了设置边界条件,这样易造成死循环调用。 4、使用函数之前未声明(包括 C 库函数的声明)。建议大家,将所定义的一切函数都在程 序开始的预处理命令后加上函数原型的声明,这样做不仅可以避免错误,而且整个程序的结 构看起来更清楚。 五、结构体共用体 1、 结构体类型定义有误,主要表现在:结构体类型里还有嵌套的时候,忘记了成员名称。
运行时错误(Run-time errors)是在程序的运行阶段出现的,当运行环境检测到程序 的某些操作无法执行,例如除数为零时,就会出现运行时错误。当运行环境检测到程序的某 些操作是被禁止的,也会产生运行时错误。例如,访问数组时超越数组的边界,空指针引用 (NULL pointer assignment,空指针赋值,即有指针未赋具Baidu Nhomakorabea地址就使用了)等等。
显示出 a=0.00000 或者提示其它运行错误)。基本原则是:float 对应%f, int 对应%d, char 对应%c。 个数不匹配。无论是哪个函数,都可以有 n 个参数,第一个永远是“”括起来的内容, 表示输出格式。剩下的 n-1 个是输出的变量或者输入的变量的地址。需要注意的是,如 果后边有 n-1 个参数,那么前边一定对应 n-1 个%f 一类的格式说明符。 scanf()中变量前忘了加&。记住:scanf()中变量前要有&(但后边学到的字符数组名和指 针前不用加) 6、 定义标识符的时候经常出现使用非法字符的情况,例如:标识符中不能用空格,也就是 说不能有这样的定义:int radium of circle;一般情况下可用下划线将三个单词连接在一 起。 7、 在使用变量前未定义,或未初始化。例如:若下边的 sum 未定义,则在编译时会提示相 应的错误信息,而若未初始化为 0,则求和的结果一定是错误的。 void main() { int I,a[10], sum=0; /*只要下边要用,这个定义就必须要有,一般情况下也要有初始值*/ for(I=0;I<10;I++) sum+=a[I]; printf(“%d”,sum); } 8、 符号常量定义错误。例如:#define PI=3.14159,这里的=应该换成空格。 9、 计算错误。主要注意:++,――和其它运算符一起运算时,除根据优先级进行计算时, 还要考虑先后位置的特殊含义;数据类型不一致时发生的自动转换也会导致计算的误 差;还要注意求模结果的符号与被除数相同;某些特殊情况下 使用懒惰求值法。 10、 不能除以 0,要做合法性检查; 11、类型溢出。记住每种数据类型的取值范围,确保数据在所定义类型范围之内; 12、 数学表达式的格式有误。常见的有:(1)数学与 C 语言运算表达式的混淆(例如: =表示赋值,而= =才表示我们数学中的相等关系)。(2)、忽略了运算的优先级。解决 这个问题的最好方法就是写数学表达式时不要从左到右,而是按优先级的顺序写,写完 优先级高的一个表达式后加上()再写下一级的表达式,例如:计算梯形的面积时,要 s=((a+b)*h)/2,不要 1/2*a+b*h. (3)忽略了计算和赋值时的自动转换。例如:float half=1/2; 这样,因为=右边是整数相除的结果为整数 0,不会得到 0.5 存入 half,进而会影响下边 的计算结果。要想不在这儿绊跟头,当计算不同类型的数据时,一定注意会不会出现引 起错误的自动转换,建议最好加上强制转换。(4)赋值号左边不是变量,例如:若有#define PI 3.14,程序中又出现 PI=3.14159。又例如:f(n)=f(n-1)*n(这是典型的数学语言,在 C 语言中右边的乘积不能正确存储,而左边又是一个函数调用)。 13、 使用库函数前,尤其是数学函数忘了加#include<?.h>。
x>=0&&x<=9)。 3、 if-else 嵌套时不配对。最好在写每个条件时要用两个{}分别将两个分支先括起来,再
添加其中的语句,以保证其配对不易错。 4、 switch()语句中的格式不正确。()中的表达式结果一定是一些明确的值,不能是区间;
表达式的所有可能结果要列在 case 后边,case 与常量之间有一空格,不要丢掉必要的 break; 5、 随意修改循环控制变量 i 的值,导致循环次数的改变,尤其是当循环有嵌套时。在循环 体中,不要将循环控制变量进行另外的改变。 6、 分不清什么情况下用双重循环,什么情况下用两个控制变量写成一重循环。当 I 不变, j 又循环一遍的时候用双重循环。当 I,j 同时变化的时候用一重循环,此时,循环控制变 量有两个,但条件只写一个就可以,因为另一个总是进行相应的变化的。 7、 忽略循环体与循环控制变量的关系。其实,很多情况下,循环控制变量都在循环体中起 到非常重要的作用。应该利用上这种关系。
先写成一对,然后再在中间加内容。 3、 忘记在语句的末尾加分号,或在预处理命令后多加分号。记住:每一个语句的后边都要
加分号,而预处理命令并不是语句,所以不加分号,他们必须每行一条,不能把多个命
令写在一行。 4、 混淆/和\;注释对应的符号是/* */,而转义字符是以\开头,除号是/。 5、 printf()和 scanf()的参数设置有误,主要表现在以下几方面: 类型不匹配的问题。(例如:有 float a=3.5,但输出的时候 printf(“a=%d”,a);则屏幕上会
编译错误(Compile errors)又称为编译时错误(Compiling-time errors): 是由于 错误的编码产生的。例如关键字拼写错误、将中文标点符号当成英文符号使用、遗漏了某些 必要的标点符号或者使用了一个没有定义的标识符。
编译错误一般都是语法错误,当编译器对程序进行语法检查时,都能发现这些错误,并 能够指出产生错误的位置(标出行号)。我们可以根据编译出错信息指出的行号找到对应的 源代码行改正错误,重新编译源程序。只有当所有的编译错误被改正后,才能通过编译检查, 产生目标代码文件。
C 语言常见错误及解决方法
(注:红色粗体是常见的错误,请大家检查自己的程序,并注意尽量不要犯这些常见的错误。 其余它体是避免错误的方法和正确的写法) 一、基础知识和数据类型、表达式 1、 拼写错误,尤其是 include,main,void,float 等词。C 语言的 32 个关键字与基本含义如下: double :声明双精度变量或函数 int: 声明整型变量或函数 char :声明字符型变量或函数 float:声明浮点型变量或函数 void :声明函数无返回值或无参数,声明无类型指针(基本上就这三个作用) auto :声明自动变量 一般不使用 struct:声明结构体变量或函数 break:跳出当前循环 else :条件语句否定分支(与 if 连用) long :声明长整型变量或函数 switch :用于开关语句 case:开关语句分支 enum :声明枚举类型 register:声明积存器变量 typedef:用以给数据类型取别名(当然还有其他作用) extern:声明变量是在其他文件正声明(也可以看做是引用变量) return :子程序返回语句(可以带参数,也看不带参数) union:声明联合数据类型 const :声明只读变量 short :声明短整型变量或函数 unsigned:声明无符号类型变量或函数 continue:结束当前循环,开始下一轮循环 for:一种循环语句(可意会不可言传) signed:生命有符号类型变量或函数 default:开关语句中的“其他”分支 goto:无条件跳转语句 sizeof:计算数据类型长度 volatile:说明变量在程序执行中可被隐含地改变 do :循环语句的循环体 while :循环语句的循环条件 static :声明静态变量 if:条件语句 2、 {},[],(),‘’,“”不配对。解决这个问题最好的方法就是每当写这些符号的时候就
逻辑错误(Logic errors):当程序没有按照程序员的意图执行时,就表明程序中
存在逻辑错误。一个应用程序可能既没有语法错误,运行时也没有执行任何无效的操作,但 是有可能产生错误的结果,这种错误结果一般都是程序内部的逻辑错误造成的。只有通过测 试应用程序并分析它产生的结果,我们才能核实应用程序是否正确地执行了。
二、流程控制 1、 丢掉语句结束标记“;”,尤其是 for 语句中表达式后或 do-while 语句后的分号,或在预
处理命令后边、while()后、for()后加“;”; 2、 If 语句或循环语句中逻辑表达式或关系表达式书写错误。一定要注意 C 语言的条件与数
学 表 达 式 的 区 别 ( 例 如 我 们 数 学 中 经 常 写 到 的 0 ≤ x ≤ 9, 在 C 语 言 中 应 该 写 成
六、文件 1、 使用之前没有打开文件,使用之后没有关闭文件。 2、 相关函数的调用格式有误。请一定注意实参的类型、顺序、个数上与函数原型(或函数
声明)的一致。
Visual C++6.0 中的调试工具使用入门
一、程序开发过程中出现的错误类型
我们在进行程序设计时,不可避免地会犯错误。程序中的错误可以分为三类:编译错误、 运行时错误和逻辑错误。
改正编译错误的关键是要能正确理解编译器给出的编译错误信息。VC++环境中的编译、 链接错误信息是用英文表示的。对于英文基础薄弱的读者,可以参考本实验指导书后面的 “VC++编译、链接常见错误和警告信息中英文对照”。
通常情况下,一个语法错误可能产生多条编译错误信息,这是由于株连错误造成的,建 议读者在处理编译错误时,找到第一个出现错误的位置改正后重新编译。这样能够避免被株 连错误迷惑。值得指出的是,现在大部分编译器对错误的定位不精确,如果在编译器指出的 行没有发现错误,应该向前查找错误。例如,当提示第 10 行发生错误时,如果在第 10 行没 有发现错误,请从第 10 行开始往前查找错误并修改之。
struct STU {….
Struct data {int year,month,day; }birthday
}; struct STU a; struct STU 是类型名称,而且不分配空间,且不能直接引用。只有定义了结 构体类型 struct STU 的变量 a 以后,才为 a 分配相应的内存空间,引用时也要是 a.??? 3、 结构体变量的成员引用不正确,尤其是当结构体类型中有嵌套定义的时候。一定要一级 一级的引用。例如:上边的例子:如果引用其中的年的话,一定是 a.birthday.year. 不 能直接 a.year. 4、 对结构体变量进行输入输出的时候,整体输入或整体输出。除作为函数参数外,不能对 结构体变量整体操作,只能一个成员一个成员地输入、输出。 5、 不理解共用体的“共占内存”。对共用体中的成员变量,一定要靠一个标记区别它们, 并分别按不同类型引用它们。切记:共用体变量不能做函数形参。
三、数组与指针 1、 字符串的输入有错误:主要表现在使用 scanf()或 gets()时加了&,或输入字符串时用循
环,(这样的话,字符个数无论多长,都不会为自动加\0,将来引用的时候也就不能以 字符串的形式引用。) 2、 对字符串的处理中,循环条件仍然写成 I<N。由于字符串是不定长的,所以循环条件一 般为 str[I]!=’\0’ 或 I<strlen(str) 3、 而输入所对应的变量是指针时(常见的有:输入的变量是字符数组名或指向字符串的指 针)不能加&。 4、 指针定义后未赋值就引用。如果在定义时不知道赋什么值,可以用 p=NULL 赋初值,以 避免引起的灾难性错误。 5、 分不清 p 和*p。前者是指针,即地址,后者表示指针所间接引用的数据,但如果是二 级指针或多级指针,取*以后得到的仍然可能是地址。
四、函数 1、 函数定义的时候,函数头部加分号,而函数声明的地方忘了加分号 2、 函数实参格式不对,主要表现在:给出实参时,多给出数组类型,或者,形参是数组 int
a[];的时候,给出的 a[]或 a[I]. 3、 递归时忘了设置边界条件,这样易造成死循环调用。 4、使用函数之前未声明(包括 C 库函数的声明)。建议大家,将所定义的一切函数都在程 序开始的预处理命令后加上函数原型的声明,这样做不仅可以避免错误,而且整个程序的结 构看起来更清楚。 五、结构体共用体 1、 结构体类型定义有误,主要表现在:结构体类型里还有嵌套的时候,忘记了成员名称。
运行时错误(Run-time errors)是在程序的运行阶段出现的,当运行环境检测到程序 的某些操作无法执行,例如除数为零时,就会出现运行时错误。当运行环境检测到程序的某 些操作是被禁止的,也会产生运行时错误。例如,访问数组时超越数组的边界,空指针引用 (NULL pointer assignment,空指针赋值,即有指针未赋具Baidu Nhomakorabea地址就使用了)等等。
显示出 a=0.00000 或者提示其它运行错误)。基本原则是:float 对应%f, int 对应%d, char 对应%c。 个数不匹配。无论是哪个函数,都可以有 n 个参数,第一个永远是“”括起来的内容, 表示输出格式。剩下的 n-1 个是输出的变量或者输入的变量的地址。需要注意的是,如 果后边有 n-1 个参数,那么前边一定对应 n-1 个%f 一类的格式说明符。 scanf()中变量前忘了加&。记住:scanf()中变量前要有&(但后边学到的字符数组名和指 针前不用加) 6、 定义标识符的时候经常出现使用非法字符的情况,例如:标识符中不能用空格,也就是 说不能有这样的定义:int radium of circle;一般情况下可用下划线将三个单词连接在一 起。 7、 在使用变量前未定义,或未初始化。例如:若下边的 sum 未定义,则在编译时会提示相 应的错误信息,而若未初始化为 0,则求和的结果一定是错误的。 void main() { int I,a[10], sum=0; /*只要下边要用,这个定义就必须要有,一般情况下也要有初始值*/ for(I=0;I<10;I++) sum+=a[I]; printf(“%d”,sum); } 8、 符号常量定义错误。例如:#define PI=3.14159,这里的=应该换成空格。 9、 计算错误。主要注意:++,――和其它运算符一起运算时,除根据优先级进行计算时, 还要考虑先后位置的特殊含义;数据类型不一致时发生的自动转换也会导致计算的误 差;还要注意求模结果的符号与被除数相同;某些特殊情况下 使用懒惰求值法。 10、 不能除以 0,要做合法性检查; 11、类型溢出。记住每种数据类型的取值范围,确保数据在所定义类型范围之内; 12、 数学表达式的格式有误。常见的有:(1)数学与 C 语言运算表达式的混淆(例如: =表示赋值,而= =才表示我们数学中的相等关系)。(2)、忽略了运算的优先级。解决 这个问题的最好方法就是写数学表达式时不要从左到右,而是按优先级的顺序写,写完 优先级高的一个表达式后加上()再写下一级的表达式,例如:计算梯形的面积时,要 s=((a+b)*h)/2,不要 1/2*a+b*h. (3)忽略了计算和赋值时的自动转换。例如:float half=1/2; 这样,因为=右边是整数相除的结果为整数 0,不会得到 0.5 存入 half,进而会影响下边 的计算结果。要想不在这儿绊跟头,当计算不同类型的数据时,一定注意会不会出现引 起错误的自动转换,建议最好加上强制转换。(4)赋值号左边不是变量,例如:若有#define PI 3.14,程序中又出现 PI=3.14159。又例如:f(n)=f(n-1)*n(这是典型的数学语言,在 C 语言中右边的乘积不能正确存储,而左边又是一个函数调用)。 13、 使用库函数前,尤其是数学函数忘了加#include<?.h>。
x>=0&&x<=9)。 3、 if-else 嵌套时不配对。最好在写每个条件时要用两个{}分别将两个分支先括起来,再
添加其中的语句,以保证其配对不易错。 4、 switch()语句中的格式不正确。()中的表达式结果一定是一些明确的值,不能是区间;
表达式的所有可能结果要列在 case 后边,case 与常量之间有一空格,不要丢掉必要的 break; 5、 随意修改循环控制变量 i 的值,导致循环次数的改变,尤其是当循环有嵌套时。在循环 体中,不要将循环控制变量进行另外的改变。 6、 分不清什么情况下用双重循环,什么情况下用两个控制变量写成一重循环。当 I 不变, j 又循环一遍的时候用双重循环。当 I,j 同时变化的时候用一重循环,此时,循环控制变 量有两个,但条件只写一个就可以,因为另一个总是进行相应的变化的。 7、 忽略循环体与循环控制变量的关系。其实,很多情况下,循环控制变量都在循环体中起 到非常重要的作用。应该利用上这种关系。
先写成一对,然后再在中间加内容。 3、 忘记在语句的末尾加分号,或在预处理命令后多加分号。记住:每一个语句的后边都要
加分号,而预处理命令并不是语句,所以不加分号,他们必须每行一条,不能把多个命
令写在一行。 4、 混淆/和\;注释对应的符号是/* */,而转义字符是以\开头,除号是/。 5、 printf()和 scanf()的参数设置有误,主要表现在以下几方面: 类型不匹配的问题。(例如:有 float a=3.5,但输出的时候 printf(“a=%d”,a);则屏幕上会
编译错误(Compile errors)又称为编译时错误(Compiling-time errors): 是由于 错误的编码产生的。例如关键字拼写错误、将中文标点符号当成英文符号使用、遗漏了某些 必要的标点符号或者使用了一个没有定义的标识符。
编译错误一般都是语法错误,当编译器对程序进行语法检查时,都能发现这些错误,并 能够指出产生错误的位置(标出行号)。我们可以根据编译出错信息指出的行号找到对应的 源代码行改正错误,重新编译源程序。只有当所有的编译错误被改正后,才能通过编译检查, 产生目标代码文件。
C 语言常见错误及解决方法
(注:红色粗体是常见的错误,请大家检查自己的程序,并注意尽量不要犯这些常见的错误。 其余它体是避免错误的方法和正确的写法) 一、基础知识和数据类型、表达式 1、 拼写错误,尤其是 include,main,void,float 等词。C 语言的 32 个关键字与基本含义如下: double :声明双精度变量或函数 int: 声明整型变量或函数 char :声明字符型变量或函数 float:声明浮点型变量或函数 void :声明函数无返回值或无参数,声明无类型指针(基本上就这三个作用) auto :声明自动变量 一般不使用 struct:声明结构体变量或函数 break:跳出当前循环 else :条件语句否定分支(与 if 连用) long :声明长整型变量或函数 switch :用于开关语句 case:开关语句分支 enum :声明枚举类型 register:声明积存器变量 typedef:用以给数据类型取别名(当然还有其他作用) extern:声明变量是在其他文件正声明(也可以看做是引用变量) return :子程序返回语句(可以带参数,也看不带参数) union:声明联合数据类型 const :声明只读变量 short :声明短整型变量或函数 unsigned:声明无符号类型变量或函数 continue:结束当前循环,开始下一轮循环 for:一种循环语句(可意会不可言传) signed:生命有符号类型变量或函数 default:开关语句中的“其他”分支 goto:无条件跳转语句 sizeof:计算数据类型长度 volatile:说明变量在程序执行中可被隐含地改变 do :循环语句的循环体 while :循环语句的循环条件 static :声明静态变量 if:条件语句 2、 {},[],(),‘’,“”不配对。解决这个问题最好的方法就是每当写这些符号的时候就
逻辑错误(Logic errors):当程序没有按照程序员的意图执行时,就表明程序中
存在逻辑错误。一个应用程序可能既没有语法错误,运行时也没有执行任何无效的操作,但 是有可能产生错误的结果,这种错误结果一般都是程序内部的逻辑错误造成的。只有通过测 试应用程序并分析它产生的结果,我们才能核实应用程序是否正确地执行了。
二、流程控制 1、 丢掉语句结束标记“;”,尤其是 for 语句中表达式后或 do-while 语句后的分号,或在预
处理命令后边、while()后、for()后加“;”; 2、 If 语句或循环语句中逻辑表达式或关系表达式书写错误。一定要注意 C 语言的条件与数
学 表 达 式 的 区 别 ( 例 如 我 们 数 学 中 经 常 写 到 的 0 ≤ x ≤ 9, 在 C 语 言 中 应 该 写 成
六、文件 1、 使用之前没有打开文件,使用之后没有关闭文件。 2、 相关函数的调用格式有误。请一定注意实参的类型、顺序、个数上与函数原型(或函数
声明)的一致。
Visual C++6.0 中的调试工具使用入门
一、程序开发过程中出现的错误类型
我们在进行程序设计时,不可避免地会犯错误。程序中的错误可以分为三类:编译错误、 运行时错误和逻辑错误。
改正编译错误的关键是要能正确理解编译器给出的编译错误信息。VC++环境中的编译、 链接错误信息是用英文表示的。对于英文基础薄弱的读者,可以参考本实验指导书后面的 “VC++编译、链接常见错误和警告信息中英文对照”。
通常情况下,一个语法错误可能产生多条编译错误信息,这是由于株连错误造成的,建 议读者在处理编译错误时,找到第一个出现错误的位置改正后重新编译。这样能够避免被株 连错误迷惑。值得指出的是,现在大部分编译器对错误的定位不精确,如果在编译器指出的 行没有发现错误,应该向前查找错误。例如,当提示第 10 行发生错误时,如果在第 10 行没 有发现错误,请从第 10 行开始往前查找错误并修改之。