第五夜:C语言标准库、错误处理和调试、输入输出

C语言标准库

C语言是一种通用的、面向过程式的计算机程序设计语言。1972 年,为了移植与开发 UNIX 操作系统,丹尼斯·里奇在贝尔电话实验室设计开发了 C 语言。
C标准库是一组 C 内置函数、常量和头文件,比如 stdio.hstdlib.hmath.h 等等。这个标准库可以作为 C 程序员的参考手册。
C语言标准库有各种不同的实现,比如glibc, 用于嵌入式Linux的uClibc,还有ARM公司的C语言标准库及精简版的MicroLib等。不同标准库的实现并不相同,而且提供的函数也不完全相同,不过有一个它们都支持的最小子集,这也就是最典型的C语言标准库。
典型的C语言标准库(GNU C 标准库)官网:The GNU C Library

glibc和libc有什么区别呢?
libc是Linux下的ANSI C的函数库;
glibc是Linux下的GUN C函数库;
ANSI C和GNU C有什么区别呢?
ANSI C是基本的C语言函数库,包含了C语言最基本的库函数。这个库可以根据 头文件划分为 15 个部分,其中包括:字符类型 (<ctype.h>)、错误码 (<errno.h>)、 浮点常数 (<float.h>)、数学常数 (<math.h>)、标准定义 (<stddef.h>)、 标准 I/O (<stdio.h>)、工具函数 (<stdlib.h>)、字符串操作 (<string.h>)、 时间和日期 (<time.h>)、可变参数表 (<stdarg.h>)、信号 (<signal.h>)、 非局部跳转 (<setjmp.h>)、本地信息 (<local.h>)、程序断言 (<assert.h>) 等等。这在其他的C语言的IDE中都是有的。
而GNU C函数库是一种类似于第三方插件的东西,由于Linux是用C语言写的,所以Linux的一些操作是用C语言实现的,所以GNU组织开发了一个C语言的库 用于我们更好的利用C语言开发基于Linux操作系统的程序。其实我们可以把它理解为类似于Qt是一个C++的第三方函数库一样。

标准库 内容
<stdio.h> 输入和输出
<stdlib.h> 最常用的一些系统函数
<string.h> 字符串处理
<math.h> 定义了一系列数学函数
<ctype.h> 包含了一系列字符类测试函数
<time.h> 时间和日期
<stdarg.h> 可变参数列表
<signal.h> 信号
<assert.h> 声明断言
<setjmp.h> 非局部跳转
<errno.h> 定义错误代码和处理错误的函数
<stddef.h> 一些常数、类型和变量
<locale.h> 定义了特定地域的设置,比如日期格式和货币符号
<float.h> 包含了一组与浮点值相关的常量和运算
<limits.h> 定义整数数据类型的取值范围

C语言错误处理和调试

C 语言不提供对错误处理的直接支持,但是作为一种系统编程语言,它以返回值的形式提供底层数据。在发生错误时,大多数的 C 或 UNIX 函数调用返回 1 或 NULL,同时会设置一个错误代码 errno,该错误代码是全局变量,表示在函数调用期间发生了错误。可以在 errno.h 头文件中找到各种各样的错误代码。
所以,C 程序员可以通过检查返回值,然后根据返回值决定采取哪种适当的动作。开发人员应该在程序初始化时,把 errno 设置为 0,这是一种良好的编程习惯。0 值表示程序中没有错误。

C语言错误处理一例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#include <stdio.h>
#include <errno.h>
#include <string.h>

extern int errno ;

int main (){
FILE * pf;
int errnum;
pf = fopen ("unexist.txt", "rb");
if (pf == NULL){
errnum = errno;
fprintf(stderr, "错误号: %d\n", errno);
perror("通过 perror 输出错误");
fprintf(stderr, "打开文件错误: %s\n", strerror( errnum ));
}else{
fclose (pf);
}
return 0;
}

C语言调试

Linux下的C语言程序调试,可以使用GDB。这篇文章记录了GDB调试器基本使用,更多的调试技术,后续再研究。

C语言输入输出

getchar() & putchar()

一次只能输入输出一个字符。
Example:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#include <stdio.h>

int main(){
int c;

printf( "Enter a value :");
c = getchar( );
printf( "\nYou entered: ");
putchar( c );
printf( "\n");

char *s = "abc";
int i =0;
for ( i=0;i<sizeof(s);i++){
putchar(s[i]);
putchar('\n');
}

return 0;
}

gets() & puts()
char *gets(char *s) 函数从 stdin 读取一行到 s 所指向的缓冲区,直到一个终止符或 EOF。
int puts(const char *s) 函数把字符串 s 和一个尾随的换行符写入到 stdout。

Example:

1
2
3
4
5
6
7
8
9
10
#include <stdio.h>

int main(){
char str[100];
printf( "Enter a value :");
gets( str );
printf( "\nYou entered: ");
puts( str );
return 0;
}

scanf() 和 printf()
int scanf(const char *format, …) 函数从标准输入流 stdin 读取输入,并根据提供的 format 来浏览输入。

int printf(const char *format, …) 函数把输出写入到标准输出流 stdout ,并根据提供的格式产生输出。

format 可以是一个简单的常量字符串,但是您可以分别指定 %s、%d、%c、%f 等来输出或读取字符串、整数、字符或浮点数。还有许多其他可用的格式选项,可以根据需要使用。

Example:

1
2
3
4
5
6
7
8
9
10
11
12
13
#include <stdio.h>
int main() {

char str[100];
int i;

printf( "Enter a value :");
scanf("%s %d", str, &i);

printf( "\nYou entered: %s %d ", str, i);
printf("\n");
return 0;
}
第六夜:内存管理、读写文件、管道 第四夜:存储类型、结构体、链表
Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×