C++编程常见错误及处理_c++常见错误及解决方法-程序员宅基地

技术标签: 编程实践系列  c++  C、C++学习  开发语言  

C++编程常见错误及处理

在 C++ 程序错误一般分类:

语法错误;运行错误;语义错误(也称逻辑错误)。本文介绍相关错误产生的原因及处理。

语法错误(syntax errors

是指程序中含有不符合语法规定的语句,在编译过程中显现,如:

#include <iostream> 
using namespace std;
main()
{
    int a=5  //语句末尾必须有英文分号
    cout << "a=" << A <<endl;  //忽略了大小写字母的区别
    return 0;
}

1)引号、逗号、分号,运算符是英文的,而不能是中文的,注意切换输入法。

2)变量未定义就用,注意C++ 严格区分大小写,在写关键字、标识符要注意int为关键字,INT则为用户标识符,即可定义int INT;  int Int;

3)变量赋值、运算时显示类型不匹配(如:int a=2;float b=2.001;当使a=b时)

处理:编译阶段报错,根据报错的信息,我们修改代码,再次编译,直到没有语法错误为止。

【特别提示:在编译语言(本文介绍的C++)中,语法错误在编译期时出现,编译器要所有的语法都正确,才能正确编译。解释型语言(如python)的语法错误可能要到运行期才会出现,不容易区分语法错误及语义错误。还有些采用混合方式(如JAVA、C#),先将代码编译为bytecode,在运行时再进行解释。

解释型语言(Interpreted language),是一种编程语言。这种类型的编程语言,逐句解释(将代码一句一句直接)运行,不需要像编译语言(Compiled language)一样,经过编译器先行编译为机器码,之后再运行。】

运行错误(runtime errors

运行过程中,程序可能出现错误。这些错误属于运行错误,不会在编译过程中显现,如:

打开不存在的文件、下标越界,栈溢出等。

C++ 异常(Exception)机制就是为解决运行时错误而引入的。运行时错误如果放任不管,系统就会执行默认的操作,终止程序运行,也就是我们常说的程序崩溃(Crash)。C++ 提供了异常(Exception)机制,让我们能够捕获运行时错误,给程序一次“起死回生”的机会,或者至少告诉用户发生了什么再终止程序。

一个发生运行时错误的程序:

#include <iostream>
#include <string>
using namespace std;
int main(){
    string str = "Hello, world!";
    char ch1 = str[100];  //下标越界,ch1为垃圾值
    cout<<"ch1="<<ch1<<endl;
    char ch2 = str.at(100);  //下标越界,抛出异常
    cout<<"ch2="<<ch2<<endl;
    cout << "呵呵" << endl;  
    return 0;
}

运行之效果如下:

运行代码,在控制台输出 ch1 的值后程序崩溃。下面我们来分析一下原因。

at() 是 string 类的一个成员函数,它会根据下标来返回字符串的一个字符。与[ ]不同,at() 会检查下标是否越界,如果越界就抛出一个异常;而[ ]不做检查,不管下标是多少都会照常访问。at() 函数检测到下标越界会抛出一个异常,这个异常可以由程序员处理,但是我们在代码中并没有处理,所以系统只能执行默认的操作,也即终止程序执行。

我们可以借助 C++ 异常机制来捕获上面的异常,避免程序崩溃。捕获异常的语法为:

try{

    // 可能抛出异常的语句

}catch(exceptionType variable){

    // 处理异常的语句

}

try和catch都是 C++ 中的关键字,后跟语句块,不能省略{ }。try 中包含可能会抛出异常的语句,一旦有异常抛出就会被后面的 catch 捕获。从 try 的意思可以看出,它只是“检测”语句块有没有异常,如果没有发生异常,它就“检测”不到。catch 是“抓住”的意思,用来捕获并处理 try 检测到的异常;如果 try 语句块没有检测到异常(没有异常抛出),那么就不会执行 catch 中的语句。catch 关键字后面的exceptionType variable指明了当前 catch 可以处理的异常类型,以及具体的出错信息。

修改上面的代码,加入捕获异常的语句:

#include <iostream>
#include <string>
#include <exception>
using namespace std;
int main(){
    string str = "Hello, world!";
  
    try{
        char ch1 = str[100]; //下标越界
        cout<<"ch1="<<ch1<<endl;
    }catch(exception e){
        cout<<"[1]out of bound!"<<endl;
    }
    try{
        char ch2 = str.at(100); //下标越界
        cout<<"ch2="<<ch2<<endl;
    }catch(exception &e){  //exception类位于<exception>头文件中
        cout<<"[2]out of bound!"<<endl;
    }
    cout << "呵呵" << endl;  
    return 0;
}

 运行之效果如下:

可以看出,第一个 try 没有捕获到异常,输出了一个没有意义的字符(垃圾值)。因为[ ]不会检查下标越界,不会抛出异常,所以即使有错误,try 也检测不到。换句话说,发生异常时必须将异常明确地抛出,try 才能检测到;如果不抛出来,即使有异常 try 也检测不到。所谓抛出异常,就是明确地告诉程序发生了什么错误。

第二个 try 检测到了异常,并交给 catch 处理,执行 catch 中的语句。需要说明的是,异常一旦抛出,会立刻被 try 检测到,并且不会再执行异常点(异常发生位置)后面的语句。本例中抛出异常的位置是第at() 函数,它后面的 cout 语句就不会再被执行,所以看不到它的输出。执行完 catch 块所包含的代码后,程序会继续执行 catch 块后面的代码,就恢复了正常的执行流,输出了“呵呵”。

C++ 异常处理(try catch)https://blog.csdn.net/qq_26460841/article/details/88352736

C++ 高级教程之异常处理 https://bbs.huaweicloud.com/blogs/281241

语义错误(semantic errors

也称逻辑错误(Logic error),编译没有报错,运行也没有抛出异常,但是输出的结果不正确,可能是语句中公式写错、条件语句的条件写错如if(a==b)误用为if(a=b)、算法错误或选择了错误的算法,变量作用域错误、对问题或需求的理解有误等。如:求一个数的阶乘,代码中的for语句中的i <= n误写为i < n 造成输出的结果不正确:

#include <iostream>
using namespace std;
 
int main()
{
    unsigned int n;
    unsigned long long factorial = 1;
 
    cout << "输入一个整数: ";
    cin >> n;
 
    for(int i = 1; i < n; ++i)  //i < n 应改为 i <= n 
    {
        factorial *= i;
    }
 
    cout << n << " 的阶乘为:"<< " = " << factorial;    
    return 0;
}

运行之效果如下:

处理:细心审读程序代码,分析思考,可以在程序中插入打印语句、显示程序的动态过程,还可借助调试工具(Debugger)。
【关于调试工具一般和开发语言或集成开发环境(IDE)相关。大多数程序设计语言都有专门的调试工具,可以用这些工具来分析程序的动态行为。调试工具可以帮助思考,但不能代替思考】

上例比较简单,细心审读程序代码不难发现出错的原因。下面特意演示插入调试用打印语句的示例:
在上例的factorial *= i;后面加入一句:cout << "i=" << i << endl; //调试用打印语句

运行之效果如下:


 
因此需要将for语句中的误写为i < n改为i <= n

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/cnds123/article/details/125545628

智能推荐

Vue中实现div编辑效果,及contenteditable设置为plaintext-only与true的区别-程序员宅基地

文章浏览阅读9.6k次,点赞5次,收藏20次。有时候我们希望实现点击一段div内文本时就能直接进行编辑,当然使用文本框、富文本等也可以实现,但终究有些麻烦。目录效果预览参数介绍封装与使用使用效果差异plaintext-only 的效果使用contenteditable = "true" 的效果效果预览今天我给大家介绍的这种方式是直接使用div的 contenteditable属性,即可实现div的文本编辑..._plaintext-only

对标大厂标准CSDN能力认证 and 超级实习生-大厂实习直通车_csdn认证-程序员宅基地

文章浏览阅读8.1k次,点赞41次,收藏61次。对标大厂标准CSDN能力认证 and 超级实习生-大厂实习直通车详情介绍!!!_csdn认证

快速找出System.Management.Automation.dll,c#调用powershell-程序员宅基地

文章浏览阅读772次。public static void InvokeSystemPS(string cmd) { List<string> ps = new List<string>(); ps.Add("Set-ExecutionPolicy RemoteSigned"); ps..._system.management.automation

MacBook键盘符号_苹果电脑箭头符号是哪个键-程序员宅基地

文章浏览阅读1.1k次。图标介绍⌘Command⇧Shift⇪Caps Lock⌥Option = Alt⌃ControlEnter⌫Delete⌦Fn + Delete↑上箭头↓下箭头←左箭头→右箭头⇞Fn + ↑ = Page Up⇟Fn + ↓ = Page DownHomeFn + ←EndFn + →⇥Tab = 右制表符⇤Shift + Tab = 左制表符..._苹果电脑箭头符号是哪个键

相机成像模型——建立过程(世界坐标系,相机坐标系,图像坐标系,图像像素坐标系,四者之间的关系)_相机成像模型的建立-程序员宅基地

文章浏览阅读1.8w次,点赞11次,收藏62次。相机在计算机视觉应用中起着重要作用,作为图像数据来源,影响着后续各个处理步骤。成像模型就是用数学公式刻画整个成像过程,即被拍摄物体空间点到照片成像点之间的几何变换关系。总体上,相机成像可以分为四个步骤:刚体变换、透视投影、畸变校正和数字化图像。 一、刚体变换(从世..._相机成像模型的建立

Lottie—json文件解析_lottie json解析-程序员宅基地

文章浏览阅读1.6w次,点赞11次,收藏14次。Lottie主要类图:Lottie对外通过控件LottieAnimationView暴露接口,控制动画。LottieAnimationView继承自ImageView,通过当前时间绘制canvas显示到界面上。这里有两个关键类:LottieComposition 负责解析json描述文件,把json内容转成Java数据对象;LottieDrawable负责绘制,把LottieCompo..._lottie json解析

随便推点

模块-----向数据库里面建表,写入数据,在读取数据_编写模块读取数据库数据-程序员宅基地

文章浏览阅读886次。1首先建立模块等一系列的文件,文件2etc/config.xml文件:1.10standardRichardMason_编写模块读取数据库数据

通过本机端口映射VMware中虚拟机应用(例如同一局域网别人想远程连接你虚拟机中的数据库)-程序员宅基地

文章浏览阅读489次,点赞3次,收藏7次。虚拟机中安装一下达梦数据库,并且以后大家都连接你虚拟机中达梦数据库进行开发。。。。。。在不改动自己虚拟机配置,以及本地网卡任何配置的情况下如何解决?本虚拟机网络一直使用的NAT模式。

python字符串的大小写转换_python将一个字符串小写字母转化成大写字母-程序员宅基地

文章浏览阅读5.3k次。字符串的大小写转换操作:upper():把字符串中所有字符都转换成大写字母,转换的结果是新的字符串对象(即id不同)lower():把字符串中所有字符都转换成小写字母,转换的结果是新的字符串对象(即id不同)swapcase():把字符串中所有小写字母都转换成大写字母,把字符串中所有大写字母都转换成小写字母,转换的结果是新的字符串对象(即id不同)capitalize():把第一个字符转换为大写,把其余字符转换为小写,转换的结果是新的字符串对象(即id不同)title():把每个单词的第一个字符_python将一个字符串小写字母转化成大写字母

计算机网络硬件脆弱性,计算机网络的脆弱性包括哪些-程序员宅基地

文章浏览阅读936次。计算机的脆弱性主要包含在那几个方面呢?佰佰安全网是如何对这个问题进行解答的吧。当我们了解了计算机网络的脆弱性我们就能很好的回答计算机网络安全的问题了哦。计算机的脆弱性主要表现在:存储数据的密度极高。在一块磁盘、光盘或磁带中,可以存储大且数据信息,而这些存储介质很容易被带出办公室,也很容易受意外损坏。数据泄露。计算机工作时辐射出电磁波,任何人都可借助并不复杂的设备在一定的范围内收到它,从而造成信息泄..._电脑用户的脆弱账号是什么意思

vue-grid-layout使用方法以及参数介绍_vuegridlayout自定义高度-程序员宅基地

文章浏览阅读2.5k次。vue-grid-layout 一个可拖拽的编辑器,_vuegridlayout自定义高度

element 的el-tabs默认选中项改变背景颜色问题_使用elementui的tabs标签,如何修改它点击时背景颜色为蓝色-程序员宅基地

文章浏览阅读1.1w次,点赞11次,收藏14次。element 的el-tabs默认选中项改变背景颜色问题在前端页面中,经常style部分会添加一个scoped属性,表示此处的style只在此页面生效,如下所示。<style scoped></style>但是对于element组件如el-tabs,想改变选中项颜色必须把样式写在其外边,单独写一个style标签即可,如下。<style>.el-tabs__item:hover { color: orange; background-color: or_使用elementui的tabs标签,如何修改它点击时背景颜色为蓝色

推荐文章

热门文章

相关标签