从零开始学C++之异常(一):C语言错误处理方法、C++异常处理方法(throw, try, catch)简介

一、C语言错误处理方法

1、返回值(if … else语句判断错误) 2、errno(linux 系统调用) 3、goto语句(函数内局部跳转) 4、setjmp、longjmp(Do not use setjmp and longjmp in C++ programs; these functions do not support C++ object semantics. ) #define _JBLEN  16

typedef _JBTYPE  jmp_buf[_JBLEN];

Saves the current state of the program.

int setjmp(
   jmp_buf env 
);

 Parameters

env

Variable in which environment is stored.

 Return Value

Returns 0 after saving the stack environment. If setjmp returns as a result of a longjmp call, it returns the value argument of longjmp, or if the value argument of longjmp is 0,setjmp returns 1. There is no error return.

Restores stack environment and execution locale.

void longjmp( 
   jmp_buf env, 
   int value  
);

 Parameters

env

Variable in which environment is stored.

value

Value to be returned to setjmp call.

#include <stdio.h>
#include <setjmp.h>

jmp_buf buf;

double Divide(double a, double b)
{
    if (b == 0.0)
    {
        longjmp(buf, 1);        // throw
    }
    else
        return a / b;
}

int main(void)
{
    int ret;
    ret = setjmp(buf);
    if (ret == 0)           // try
    {
        printf("division ...\n");
        printf("%f\n", Divide(5.0, 0.0));
    }
    else if (ret == 1)      // catch
    {
        printf("divisiong by zero\n");
    }
    return 0;
}

分析一下,首先setjump设置成功返回0,执行Divide函数,除数为0,longjump跳回到setjump处,返回参数1,故继续输出

divisiong by zero, setjump和longjump 已经是c++异常的雏形,即使Divide函数本身没有调用longjump,而是调用了某个函数,在这个函数内longjump,也可以跳转到setjump 处,这样就不用通过一层层的函数返回值来判断错误。

C语言的出错处理被认为是紧耦合的,函数的使用者必须在非常靠近函数调用的地方编写错误处理代码,这会使得其变得笨拙以及难以使用。

二、C++异常处理方法(throw, try, catch)

错误处理代码的编写不再冗长乏味,并且不再与“正常”代码混在一起。程序员可以将注意力集中于正常流程,然后在某个区域里编写异常处理代码。如果多次调用同一个函数,只需在一个地方编写一次错误处理代码。 错误不能被忽略。

#include <iostream>
using namespace std;

double Divide(double a, double b)
{
    if (b == 0.0)
    {
        throw 1;        // throw
    }
    else
        return a / b;
}

int main(void)
{
    try         // try
    {
        cout << "division ..." << endl;
        cout << Divide(3.0, 1.0) << endl;
        cout << Divide(5.0, 0.0) << endl;

    }
    catch (int)     // catch
    {
        cout << "divisiong by zero" << endl;
    }
    return 0;
}

即无论在多远throw,都可以被catch到,但需要注意的是类型需要匹配,下面的文章将讨论抛出自定义类型的异常。

参考:

C++ primer 第四版 Effective C++ 3rd C++编程规范

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏瓜大三哥

UVM模型(五)之factory机制

UVM模型(五)之factory机制 ? factory其实就是一个宏,当设计set_override等操作时,才有必要去理解factory机制的原理。...

2419
来自专栏我是业余自学C/C++的

redis_3.0.7_sds.h_sdslen()

1333
来自专栏大闲人柴毛毛

Java并发编程的艺术(二)——重排序

当我们写一个单线程程序时,总以为计算机会一行行地运行代码,然而事实并非如此。 什么是重排序? 重排序指的是编译器、处理器在不改变程序执行结果的前提下,重新排列指...

35910
来自专栏大闲人柴毛毛

三分钟理解“工厂模式”——设计模式轻松掌握

举个例子 假设需要我们写一个简单的计算器,能实现加减乘除运算,仅要求输入两个数,选择运算符,计算出结果就行了。 使用简单工厂模式的设计如下: ? 工厂类提供了一...

2827
来自专栏虚拟化云计算

OpenStack数据库远程对象模型

在OpenStack的各个服务之间有些数据库对象是远程操作的,远程对象所实现的效果是:一个 A 服务中的远程对象实例,可以由消息队列传送到B 服务,B 服务能够...

712
来自专栏各种机器学习基础算法

php链式操作的实现

一、什么是链式操作? 直接说链式操作,也许大家不清楚是什么,但是在平时使用框架的过程中,大家肯定见到过这样子的使用: $db->where()->limit()...

3277
来自专栏张善友的专栏

读《代码不朽:编写可维护软件的10大要则》C# 版

这本书特别针对没有接受过计算机科学或软件工程专业学习的软件开发人员,这类人员除了熟悉所用语言语法和语义之外,很少接受其他专业培训,对软件工程中的一些概念理解欠缺...

5840
来自专栏王亚昌的专栏

分享一个调用耗时统计类

    项目中经常需要统计调用一个外部接口的耗时,在做性能测试时也常需要分析N次调用所需时间,这类统计有一个共性点,即关注调用或执行的相对时间,而不关心绝对时间...

722
来自专栏程序员互动联盟

【编程基础】C++异常处理简介

遗憾的是,在实践中人们通常会忽略出错情况,就好像程序处在一个无错误的状态下进行工作的。毫无疑问,导致上述问题的一个原因就是,检测错误是一个乏味的工作并且导致代码...

2605
来自专栏PHP技术

PHP 代码规范简洁之道

原文出处: Scholer 1. 统一的编码规范 编码规范往简单说其实就是三个方面: 换行 空格 变量命名 放在 PHP 里面,还有一些附加的地方,比如关键字...

3576

扫码关注云+社区