【C语言】异常处理 | assert函数 | errno错误码

news2024/12/23 17:55:19

文章目录

  • C语言传统的处理错误的方式
      • 1. 终止程序(例如使用 `assert`)
      • 2. 返回/设置错误码
          • 手动实现
          • C语言库函数内置的错误码
          • Linux系统调用内置的错误码

C语言传统的处理错误的方式

C语言传统的处理错误的方式主要包括assert终止程序返回或设置错误码两种方式。

1. 终止程序(例如使用 assert

#include <stdio.h>
#include <assert.h>

void divide(int a, int b) 
{
    assert(b != 0);  // 防止除0错误:如果b为0,则终止程序
    int result = a / b;
    printf("Result: %d\n", result);
}

int main() 
{
    divide(10, 2);    // 正常情况
    divide(5, 0);     // 会终止程序,因为除数为0
    return 0;
}

请添加图片描述

上述代码中,divide 函数使用 assert 来确保除数不为0,如果除数为0,则终止程序。这种方式的缺陷在于终止程序对用户来说不够友好,且难以接受。

2. 返回/设置错误码

手动实现
#include <stdio.h>
#include <stdlib.h>

int divide(int a, int b, int* result) 
{
    if (b == 0) 
    {
        return -1;  // 返回错误码表示除数为0
    }
    *result = a / b;
    return 0;       // 返回0表示成功
}

int main() 
{
    int result;
    int status;

    status = divide(10, 2, &result);
    if (status == 0) 
    {
        printf("Result: %d\n", result);
    }
    else 
    {
        printf("Error: Division by zero\n");
    }

    status = divide(5, 0, &result);
    if (status == 0) 
    {
        printf("Result: %d\n", result);
    }
    else 
    {
        printf("Error: Division by zero\n");
    }

    return 0;
}

上述代码中,divide 函数返回一个整数作为状态码,如果除数为0,则返回-1表示错误,否则返回0表示成功。在 main 函数中,根据返回的状态码来判断是否出现错误,并进行相应的处理。这种方式的缺陷在于程序员需要手动检查错误码,并进行处理,不够直观。


当然,如Linux系统的很多库的接口函数、C语言的标准库都是通过把错误码放到errno中,表示错误。
而且,Linux系统调用和C标准库中的errno使用的是几乎同一套错误码
请添加图片描述

C语言库函数内置的错误码

使用C语言的标准库的库函数时,这些函数通常会将发生的错误码存储在全局变量errno中。errno是一个整数,在<errno.h>头文件中定义了一系列常量,每个常量代表一个可能的错误码。

程序员可以使用strerror函数获取与特定错误码相对应的错误字符串,然后将其打印出来。下面是一个简单的示例:

#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>

int main() 
{
    FILE *file = fopen("nonexistent_file.txt", "r");
    
    if (file == NULL) 
    {
        perror("打开文件时发生错误");
        printf("错误码:%d,错误信息:%s\n", errno, strerror(errno));
    } else 
    {
        // 文件打开成功,进行相应的操作
        fclose(file);
    }

    return 0;
}

请添加图片描述

在这个例子中,如果fopen打开文件失败,perror函数将打印与当前errno值相对应的错误信息(中文提示),而strerror函数用于获取错误字符串,然后将其打印出来。这有助于程序员更容易理解和处理发生的错误。

Linux系统调用内置的错误码

当在Linux(例如CentOS 7)下使用系统调用或库函数时,errno的使用方式是相似的。以下是一个使用系统调用open的例子,演示如何检查错误并打印相关信息:

#include <stdio.h>
#include <fcntl.h>
#include <errno.h>
#include <string.h>
#include <unistd.h>

int main() {
    int fd = open("nonexistent_file.txt", O_RDONLY);

    if (fd == -1) {
        perror("打开文件时发生错误");
        printf("错误码:%d,错误信息:%s\n", errno, strerror(errno));
    } else {
        // 文件打开成功,进行相应的操作
        close(fd);
    }

    return 0;
}

请添加图片描述

在这个例子中,open系统调用尝试打开一个不存在的文件。如果调用失败,perror函数将打印中文错误信息,strerror函数将打印与errno值相对应的英文错误字符串。程序员可以根据错误信息更好地了解发生的问题,并根据需要采取适当的处理措施。

总结一下:
实际中,C语言通常结合使用 assert断言设置错误码 这两种方式:

  • 对于非常严重的错误,例如内存错误,除0错误等,会选择终止程序。
  • 对于一些可以预见的错误,会使用返回错误码的方式进行处理,方便程序员根据需要进行错误处理。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1428975.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Linux系统安全:安全技术 和 防火墙

一、安全技术 入侵检测系统&#xff08;Intrusion Detection Systems&#xff09;&#xff1a;特点是不阻断任何网络访问&#xff0c;量化、定位来自内外网络的威胁情况&#xff0c;主要以提供报警和事后监督为主&#xff0c;提供有针对性的指导措施和安全决策依据,类 似于监控…

flinkjar开发 自定义函数

编写自定义加密函数&#xff0c;继承ScalarFunction类&#xff0c;实现eval方法&#xff0c;参数个数类型和返回值根据业务来自定义。 import org.apache.flink.table.functions.ScalarFunction; import javax.crypto.Cipher; import javax.crypto.KeyGenerator; import javax…

Axure 动态面板初使用 - 实现简单的Banner图轮播效果

使用工具版本 Axure 9 实现的效果 步骤过程 1、打开Axure工具&#xff0c;从元件库拖个动态面板到空白页&#xff1b; 2、给面板设置一个常用的banner尺寸&#xff0c;举个栗子&#xff1a;343151(移动端我常用的banner尺寸)&#xff0c;顺便给它起个名字&#xff0c;就叫…

探讨深浅拷贝在js加密中的运用

深浅拷贝是JavaScript中常用的概念&#xff0c;用于复制对象或数组。它们在处理数据时有不同的用途&#xff0c;适用于不同的场景。在本文中&#xff0c;我们将详细介绍深浅拷贝的概念&#xff0c;提供案例代码&#xff0c;并探讨它们在JavaScript中的应用场景&#xff0c;以及…

演讲回顾:如何为大规模研发团队加速CI构建,实现高效流水线

近日&#xff0c;龙智联合Atlassian举办的DevSecOps研讨会年终专场”趋势展望与实战探讨&#xff1a;如何打好DevOps基础、赋能创新”在上海圆满落幕。龙智Atlassian技术与顾问咨询团队&#xff0c;以及清晖、JamaSoftware、CloudBees等生态伙伴的嘉宾发表了主题演讲&#xff0…

Mysql的BufferPool

Mysql的BufferPool Mysql是一个存储数据到磁盘的进程&#xff0c;但是磁盘的速度难以与CPU相比&#xff0c;所以InnoDB存储引擎在处理客户端的请求时&#xff0c;当需要访问某个页的数据时&#xff0c;就会把完整的页的数据全部加载到内存中。将整个页加载到内存中后就可以进行…

C++初阶之类与对象(上)详细解析

个人主页&#xff1a;点我进入主页 专栏分类&#xff1a;C语言初阶 C语言进阶 数据结构初阶 Linux C初阶 欢迎大家点赞&#xff0c;评论&#xff0c;收藏。 一起努力&#xff0c;一起奔赴大厂 目录 一.前言 二.类的定义和使用 2.1类的引入 2.2类的定义和访问限定…

进程中线程使用率偏高问题排查

1. top命令查看CPU使用率高的进程 2. top -H -p 15931 查看进程下的线程 3. printf "%x\n" 17503 线程PID 10进制转16进制 0x445f 4. jstack -l 15931 导出java进程栈信息&#xff0c;里面包含线程nid0x445f和所在的类 第二种&#xff1a; Arthas方式快捷明了 结合代…

069:vue中EventBus的使用方法(图文示例)

第069个 查看专栏目录: VUE ------ element UI 本文章目录 示例背景示例效果图示例源代码父组件&#xff1a;子组件A&#xff1a;子组件B&#xff1a;eventbus/index.js&#xff1a; EventBus的基本使用方法&#xff1a; 示例背景 在Vue中&#xff0c;使用EventBus可以实现组件…

布隆过滤器的概述和使用

1 布隆过滤器概述 1.1 概述 布隆过滤器&#xff08;Bloom Filter&#xff09;是1970年由布隆提出的。它实际上是由一个很长的二进制向量&#xff08;数组&#xff09;和一系列随机映射函数&#xff08;hash函数&#xff09;组成&#xff0c;它不存放数据的明细内容&#xff0…

C语言中的指针详解

大家好&#xff0c;今天给大家介绍C语言中的指针详解&#xff0c;文章末尾附有分享大家一个资料包&#xff0c;差不多150多G。里面学习内容、面经、项目都比较新也比较全&#xff01;可进群免费领取。 **指针是C语言中的一个重要概念&#xff0c;它提供了一种直接访问内存地址…

【学员分享-考试心得】国产数据库潜力无限,云贝教育OBCP认证培训帮您解难题

近年来&#xff0c;随着国产化转型的推进&#xff0c;国外数据库的岗位需求逐渐减少&#xff0c;让许多IT从业者倍感压力。在这种情况下&#xff0c;了解国产数据库成为了求职市场上的竞争力。云贝老师们将聚焦于OceanBase、PostgreSQL、TDSQL等IT培训&#xff0c;探讨其对国产…

LED点阵屏(基于51单片机)

师从江科大 LED点阵屏 LED点阵屏由若干个独立的LED组成&#xff0c;LED以矩阵的形式排列&#xff0c;以灯珠亮灭来显示文字、图片、视频等。 LED点阵屏分类 按颜色&#xff1a;单色、双色、全彩 按像素&#xff1a;8*8、16*16等&#xff08;大规模的LED点阵通常由很多个…

SpringBoot实战2

目录 1.如何返回两个类型的数据&#xff1f;User和Booth 2.如何使用MyBatis遍历一个数组进行查询&#xff1f; 3.前端要的数据太多太杂&#xff0c;我们拼接多个List&#xff0c;前端找数据困难&#xff0c;浪费时间。因此我们进行三表联表查询。 1.首先创建一个vo包&#x…

【数据结构】双向链表 超详细 (含:何时用一级指针或二级指针;指针域的指针是否要释放)

目录 一、简介 二. 双链表的实现 1.准备工作及其注意事项 1.1 先创建三个文件 1.2 注意事项&#xff1a;帮助高效记忆 1.3 关于什么时候 用 一级指针接收&#xff0c;什么时候用 二级指针接收&#xff1f; 1.4 释放节点时&#xff0c;要将节点地址 置为NULL&#xff0…

FANUC机器人开机时无法进入系统,示教器黑屏故障处理总结

FANUC机器人开机时无法进入系统&#xff0c;示教器黑屏故障处理总结 故障描述&#xff1a; FANUC机器人开机时&#xff0c;示教器在初始化时显示&#xff1a;EMAC initial call failed&#xff08;示教器上电时会进入boot画面&#xff0c;左上角会出现一些白色的英文提示&#…

项目安全-----加密算法实现

目录 对称加密算法 AES &#xff08;ECB模式&#xff09; AES(CBC 模式)。 非对称加密 对称加密算法 对称加密算法&#xff0c;是使用相同的密钥进行加密和解密。使用对称加密算法来加密双方的通信的话&#xff0c;双方需要先约定一个密钥&#xff0c;加密方才能加密&#…

openGauss学习笔记-212 openGauss 数据库运维-日志参考

文章目录 openGauss学习笔记-212 openGauss 数据库运维-日志参考212.1 日志类型简介212.2 系统日志212.3 操作日志212.4 审计日志212.5 WAL日志212.6 性能日志 openGauss学习笔记-212 openGauss 数据库运维-日志参考 212.1 日志类型简介 在数据库运行过程中&#xff0c;会出现…

Java面试——计网篇

一、基础篇 1、 TCP/IP 网络模型 对于同一台设备上的进程间通信&#xff0c;有很多种方式&#xff0c;比如有管道、消息队列、共享内存、信号等方式&#xff0c;而对于不同设备上的进程间通信&#xff0c;就需要网络通信&#xff0c;而设备是多样性的&#xff0c;所以要兼容多…