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

文章目录

  • 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错误等,会选择终止程序。
  • 对于一些可以预见的错误,会使用返回错误码的方式进行处理,方便程序员根据需要进行错误处理。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

面试经典150题 -- 区间(总结)

总的链接 : 面试经典 150 题 - 学习计划 - 力扣&#xff08;LeetCode&#xff09;全球极客挚爱的技术成长平台最经典 150 题&#xff0c;掌握面试所有知识点https://leetcode.cn/studyplan/top-interview-150/ 228 汇总区间 直接用双指针模拟即可 ; class Solution { public…

数据结构——实验01-线性表的链式存储和操作

一、实验内容 二、算法思想与算法实现 1、解题思想 &#xff08;1&#xff09;逆序创建链表La就是使用头插法创建一个链表&#xff0c;所谓头插法就是在创建链表时始终将新元素插入到头结点之后&#xff0c;而正序创建链表Lb就是使用尾插法创建一个链表&#xff0c;所谓尾插法…

[晓理紫]每日论文分享(有中文摘要,源码或项目地址)--强化学习、模仿学习

专属领域论文订阅 关注{晓理紫|小李子}&#xff0c;每日更新论文&#xff0c;如感兴趣&#xff0c;请转发给有需要的同学&#xff0c;谢谢支持 如果你感觉对你有所帮助&#xff0c;请关注我&#xff0c;每日准时为你推送最新论文。 为了答谢各位网友的支持&#xff0c;从今日起…

Latex学习记录

目录 1.Latex各种箭头符号总结 2.[Latex]公式编辑&#xff0c;编号、对齐 3.Latex公式编号: 多行公式多编号&#xff0c;多行公式单编号 4.LaTex中输入空格以及换行 1.Latex各种箭头符号总结 箭头符号 - ➚ (piliapp.com)https://cn.piliapp.com/symbol/arrow/Latex各种箭头…

【LeetCode: 462. 最小操作次数使数组元素相等 II + 贪心】

&#x1f680; 算法题 &#x1f680; &#x1f332; 算法刷题专栏 | 面试必备算法 | 面试高频算法 &#x1f340; &#x1f332; 越难的东西,越要努力坚持&#xff0c;因为它具有很高的价值&#xff0c;算法就是这样✨ &#x1f332; 作者简介&#xff1a;硕风和炜&#xff0c;…

根据路由动态注册组件失败

动态注册组件 方式1 import 这种跟webpack的版本有关系 import低版本不支持传入动态参数 <template><components :is"componentName" v-show"isShow" :key"componentName"></components> </template>const _import fi…

网络基础【Linux网络编程】

目录 一、网络发展 二、协议和协议分层 OSI七层网络模型 TCP/IP协议栈 三、网络和OS的关系 四、网络传输基本流程 五、数据包封装和分用 六、IP地址和MAC地址 MAC地址 局域网通信原理 IP地址 一、网络发展 详细参考此篇博文&#xff1a;网络发展史 独立模式 计算机…

第三百零三回

文章目录 1. 概念介绍2. 实现方法2.1 文字信息2.2 红色边框 3. 示例代码4. 内容总结 我们在上一章回中介绍了"如何实现密码输入框"相关的内容&#xff0c;本章回中将介绍如何在在输入框中提示错误.闲话休提&#xff0c;让我们一起Talk Flutter吧。 1. 概念介绍 我们…

Qt加载网页崩溃 ASSERT:“m_adapterClient“ in file ...

1、软件启动后加载网页无异常&#xff0c;点击按钮&#xff0c;加载新网页时崩溃 崩溃代码&#xff1a; QWebEngineView *createWindow(QWebEnginePage::WebWindowType type) { Q_UNUSED(type); return this; } 2、原因 Qt只是调用谷歌的浏览器引擎&#xff…

构建用于预警大型语言模型辅助生物威胁创建的系统

深入解析最新的技术突破、实际应用案例和未来的趋势。与全球数同行一同&#xff0c;从行业内部的深度分析和实用指南中受益。不要错过这个机会&#xff0c;成为AI领域的领跑者。点击订阅&#xff0c;与未来同行&#xff01; 订阅&#xff1a;https://rengongzhineng.io/ 。 Op…

vivado jesd204核综合错误

用204核的时候老是报如下错误。 [Opt 31-67] Problem: A LUT2 cell in the design is missing a connection on input pin I0, which is used by the LUT equation. This pin has either been left unconnected in the design or the connection was removed due to the trimm…

ubuntu 上安装和配置Apache2+Subversion

目录 一、安装Apache2和SVN 二、Apache2设置 三、subversion配置 四、创建仓库和设置权限 五、仓库备份和恢复 系统环境 Ubuntu Linux (20.04) apache2 Subversion(1.13.0) 一、安装Apache2和SVN 通过命令在线安装apache2和subversion apt-get install apache2 libap…

Maven高级知识——分模块开发、继承与聚合

目录 一、分模块设计与开发 1.1 不分模块的问题 1.2 分模块设计 二、 继承与聚合 2.1 继承 2.1.1 继承关系 2.1.2 版本锁定 2.1.2.1 场景 2.1.2.2 介绍 2.1.2.3 实现 2.1.2.4 属性配置 2.2 聚合 2.2.1 介绍 2.2.2 实现 2.3 继承与聚合对比 三、Maven打包方式&#xff08;jar、w…

数据结构—动态查找

动态查找介绍 1. 动态查找的引入&#xff1a;当查找表以线性表的形式组织时&#xff0c;若对查找表进行插入、删除或排序操作&#xff0c;就必须移动大量的记录&#xff0c;当记录数很多时&#xff0c;这种移动的代价很大。 2. 动态查找表的设计思想&#xff1a;表结构本身是…

只用一台服务器部署上线(宝塔面板) 前后端+数据库

所需材料 工具&#xff1a;安装宝塔面板服务器至少一台、域名一个 前端&#xff1a;生成dist文件&#xff08;前端运行build命令&#xff09; 后端&#xff1a;生成jar包&#xff08;maven运行package命令&#xff09; 准备&#xff1a; 打开宝塔面板&#xff0c;点击进入软…

element-ui link 组件源码分享

link 组件的 api 涉及的内容不是很多&#xff0c;源码部分的内容也相对较简单&#xff0c;下面从以下这三个方面来讲解&#xff1a; 一、组件结构 1.1 组件结构如下图&#xff1a; 二、组件属性 2.1 组件主要有 type、underline、disabled、href、icon 这些属性&#xff0c;…

OpenCV+ moviepy + tkinter 视频车道线智能识别项目源码

项目完整源代码&#xff0c;使用 OpenCV 的Hough 直线检测算法&#xff0c;提取出道路车道线并绘制出来。通过tkinter 提供GUI界面展示效果。 1、导入相关模块 import matplotlib.pyplot as plt import numpy as np import cv2 import os import matplotlib.image as mpimg …

虚幻UE 特效-Niagara特效实战-魔法阵

回顾Niagara特效基础知识&#xff1a;虚幻UE 特效-Niagara特效初识 其他四篇实战&#xff1a;UE 特效-Niagara特效实战-烟雾、喷泉、 虚幻UE 特效-Niagara特效实战-火焰、烛火、 虚幻UE 特效-Niagara特效实战-雨天、 虚幻UE 特效-Niagara特效实战-眩晕。 本篇笔记记录了使用空模…

Scrum敏捷开发企业培训-敏捷研发管理

课程简介 Scrum是目前运用最为广泛的敏捷开发方法&#xff0c;是一个轻量级的项目管理和产品研发管理框架。 这是一个两天的实训课程&#xff0c;面向研发管理者、项目经理、产品经理、研发团队等&#xff0c;旨在帮助学员全面系统地学习Scrum和敏捷开发, 帮助企业快速启动敏…

【循环结构·js】

变量命名原则 变量名由字母、下划线、$ 或数字组成&#xff0c;并且必须由字母、下划线、$ 开头。 变量名不能命名为系统关键字和保留字。 JS代码在sourse里面调试 document.write(str); /*在页面上输出变量 str 的值*/数据类型的分类 为什么要标识数据类型&#xff1a; 不…