15、【C语言基础】错误处理、递归

C 错误处理

C 语言不提供对错误处理的直接支持,但是作为一种系统编程语言,它以返回值的形式允许您访问底层数据。在发生错误时,大多数的 C 或 UNIX 函数调用返回 1 或 NULL,同时会设置一个错误代码 errno,该错误代码是全局变量,表示在函数调用期间发生了错误。您可以在 errno.h 头文件中找到各种各样的错误代码。

所以,C 程序员可以通过检查返回值,然后根据返回值决定采取哪种适当的动作。开发人员应该在程序初始化时,把 errno 设置为 0,这是一种良好的编程习惯。0 值表示程序中没有错误。

errno、perror() 和 strerror()

C 语言提供了 perror()strerror() 函数来显示与 errno 相关的文本消息。

  • perror() 函数显示您传给它的字符串,后跟一个冒号、一个空格和当前 errno 值的文本表示形式。
  • strerror() 函数,返回一个指针,指针指向当前 errno 值的文本表示形式。

让我们来模拟一种错误情况,尝试打开一个不存在的文件。您可以使用多种方式来输出错误消息,在这里我们使用函数来演示用法。另外有一点需要注意,您应该使用 stderr 文件流来输出所有的错误。

 1 #include <stdio.h>
 2 #include <errno.h>
 3 #include <string.h>
 4
 5 extern int errno ;
 6
 7 int main ()
 8 {
 9    FILE * pf;
10    int errnum;
11    pf = fopen ("unexist.txt", "rb");
12    if (pf == NULL)
13    {
14       errnum = errno;//得到错误号
15       fprintf(stderr, "错误号: %d\n", errno);
16       perror("通过 perror 输出错误");
17       fprintf(stderr, "打开文件错误: %s\n", strerror( errnum ));
18    }
19    else
20    {
21       fclose (pf);
22    }
23    return 0;
24 }

执行结果:

错误号: 2
通过 perror 输出错误: No such file or directory
打开文件错误: No such file or directory

被零除的错误

在进行除法运算时,如果不检查除数是否为零,则会导致一个运行时错误。

为了避免这种情况发生,下面的代码在进行除法运算前会先检查除数是否为零:

 1 #include <stdio.h>
 2 #include <stdlib.h>
 3
 4 main()
 5 {
 6    int dividend = 20;
 7    int divisor = 0;
 8    int quotient;
 9
10    if( divisor == 0){
11       fprintf(stderr, "除数为 0 退出运行...\n");
12       exit(-1);
13    }
14    quotient = dividend / divisor;
15    fprintf(stderr, "quotient 变量的值为 : %d\n", quotient );
16
17    exit(0);
18 }

执行结果:

1 除数为 0 退出运行...

程序退出状态

通常情况下,程序成功执行完一个操作正常退出的时候会带有值 EXIT_SUCCESS。在这里,EXIT_SUCCESS 是宏,它被定义为 0。

如果程序中存在一种错误情况,当您退出程序时,会带有状态值 EXIT_FAILURE,被定义为 -1。所以,上面的程序可以写成:

 1 #include <stdio.h>
 2 #include <stdlib.h>
 3
 4 main()
 5 {
 6    int dividend = 20;
 7    int divisor = 5;
 8    int quotient;
 9
10    if( divisor == 0){
11       fprintf(stderr, "除数为 0 退出运行...\n");
12       exit(EXIT_FAILURE);
13    }
14    quotient = dividend / divisor;
15    fprintf(stderr, "quotient 变量的值为: %d\n", quotient );
16
17    exit(EXIT_SUCCESS);
18 }

执行结果:

quotient 变量的值为 : 4

C 递归

递归指的是在函数的定义中使用函数自身的方法。

语法格式如下:

 1 void recursion()
 2 {
 3    statements;
 4    ... ... ...
 5    recursion(); /* 函数调用自身 */
 6    ... ... ...
 7 }
 8
 9 int main()
10 {
11    recursion();
12 }

流程图:

C 语言支持递归,即一个函数可以调用其自身。但在使用递归时,程序员需要注意定义一个从函数退出的条件,否则会进入死循环。

递归函数在解决许多数学问题上起了至关重要的作用,比如计算一个数的阶乘、生成斐波那契数列,等等。

【示例】数的阶乘

 1 #include <stdio.h>
 2
 3 double factorial(unsigned int i)
 4 {
 5    if(i <= 1)
 6    {
 7       return 1;
 8    }
 9    return i * factorial(i - 1);
10 }
11 int  main()
12 {
13     int i = 15;
14     printf("%d 的阶乘为 %f\n", i, factorial(i));
15     return 0;
16 }

【示例】斐波那契数列

 1 #include <stdio.h>
 2
 3 int fibonaci(int i)
 4 {
 5    if(i == 0)
 6    {
 7       return 0;
 8    }
 9    if(i == 1)
10    {
11       return 1;
12    }
13    return fibonaci(i-1) + fibonaci(i-2);
14 }
15
16 int  main()
17 {
18     int i;
19     for (i = 0; i < 10; i++)
20     {
21        printf("%d\t\n", fibonaci(i));
22     }
23     return 0;
24 }

原文地址:https://www.cnblogs.com/Long-w/p/9674102.html

时间: 2024-08-06 17:10:13

15、【C语言基础】错误处理、递归的相关文章

Go 语言基础——错误处理

学习目标 掌握错误处理 掌握自定义错误处理 掌握defer关键字的使用 错误处理 GO没有异常处理机制 Go语言引入了一个关于错误处理的标准模式,即error接口,该接口的定义如下: type error interface { ? Error() string } 可以通过errors.New快速创建错误实例 errors.New("错误信息") func Foo(param int)(n int, err error) { // ... } //调用时的代码建议按如下方式处理错误情

15、C#基础整理(递归)

带输出参数的函数 输入参数相当于函数而言,相当于已经赋值了的变量,直接可用输出参数相当于定义一个没有值的变量,在函数中进行赋值,然后调用函数的时候将赋值带出函数 例: public void shuchu(int a, out int b) { b = a + 10; //b必须赋值 } 主函数里面的写法: static void Main(string[] args) { int a = 11,b; Program p = new Program(); p.shuchu(a,out b);//

15 Java语言基础数据类型转换之强制转换

public class Add{ public static void main(String[] args) { int x = 3; byte y = 4; y = (byte)(x + y); System.out.println(y); } } 大类型赋值给小类型,需要使用强制类型转换,强制类型转换可能会损失精度 强制类型转换的格式 小类型 小类型标识符 = (大类型) 大类型数值

Java基础知识二次学习-- 第二章 基础语法与递归补充

第二章 基础语法与递归补充   时间:2017年4月24日10:39:18 章节:02章_01节,02章_02节 视频长度:49:21 + 15:45 内容:标识符,关键字与数据类型 心得:由字母,下划线,$,数字组成,应该由字母,下划线$开头,同时应该避开java保留字符 变量是内存中的一小块区域,使用变量名来访问这块区域 执行过程中的内存管理(疑问:这里的内存和Jvm的一样吗?) code segment 存放代码 data segment 静态变量 字符串常量 stack 栈 局部变量 h

C语言基础(转载自大海笔记)

# C语言基础2015年03月26日10:04:411.    语言排行榜C——java——objective-C2.    进制:进制:进位机制.用普通的话讲,应该为人为的定义一种度量来标识一样东西.计算机常用的进制有:十进制.二进制.八进制和十六进制.?    十进制:0-9(十个指头)(进制表示基数:10)?    二进制:0,1(基数为2)?    八进制:0-7(基数为8)?    十六进制:0-9,A-F(基数为16)    可以有很多进制,比如分钟为60进制等等.3.    位权为

Object Pascal 语法之语言基础(四)

1.8 过程与函数 过程与函数是实现一定功能的语句块,是程序中的特定功能单元.可以在程序的其他地方被调用,也可以进行递归调用.过程与函数的区别在于过程没有返回值,而函数有返回值. 1.过程与函数的定义过程与函数的定义包括过程原型或函数原型.过程体或函数体的定义.过程定义的形式如下: procedure ProcedureName(ParameterList); directives; var LocalDeclarations; begin statements end; ProcedureNa

C语言基础学习笔记

--C语言框架-- 数据  字节byte          字符   char         8  半字half word     短整型        short int    16    字word            整型   int(integer)   32               长整型   long int     32                 单精度   float        32   双字(double word) 双精度  double       64 

go语言基础教程

Go 是一个开源的编程语言,它能让构造简单.可靠且高效的软件变得容易. Go是从2007年末由Robert Griesemer, Rob Pike, Ken Thompson主持开发,后来还加入了Ian Lance Taylor, Russ Cox等人,并最终于2009年11月开源,在2012年早些时候发布了Go 1稳定版本.现在Go的开发已经是完全开放的,并且拥有一个活跃的社区. Go 语言环境安装 Go 语言支持以下系统: Linux FreeBSD Mac OS X(也称为 Darwin)

D10——C语言基础学PYTHON

C语言基础学习PYTHON--基础学习D10 20180906内容纲要: 1.协程 (1)yield (2)greenlet (3)gevent (4)gevent实现单线程下socket多并发 2.简单爬虫 3.select 4.IO多路复用 5.小结 6.练习 1 协程 协程又叫微线程,纤程.协程是一种用户态的轻量级线程.协程有自己的寄存器上下文和栈.协程调度切换时,将寄存器上下文.和栈保存到其他地方,在切换回来的时候回复先前保存的寄存器上下文和栈.协程能保存上一次调用时的状态.一个cpu支

第2章 C#语言基础

C#语言基础本章将介绍一些C#语言的基础知识.本章和接下来的两章中的所有程序和代码片段都可以作为交互式示例在LINQPad中运行.阅读本书时使用这些示例可以加快你的学习进度.在LINQPad中编辑执行这些示例可以立即看到结果,无须在Visual Studio中建立项目和解决方案.若要下载这些示例,请点击LINQPad中的Samples选项卡,然后点击“Download more samples”.LINQPad是免费程序,详见http://www.linqpad.net 2.1 第一个C#程序