附录二 C语言标准库

上章回顾

数组和指针相同与不同

通过指针访问数组和通过数组访问指针

指针在什么时候可以加减运算

函数指针的申明和调用

函数数组和数组函数

git@github.com:Kevin-Dfg/Data-Structures-and-Algorithm-Analysis-in-C.gitgit@github.com:Kevin-Dfg/Data-Structures-and-Algorithm-Analysis-in-C.git

附录二

附录二

C语言标准库

C语言标准库

git@github.com:Kevin-Dfg/Data-Structures-and-Algorithm-Analysis-in-C.gitgit@github.com:Kevin-Dfg/Data-Structures-and-Algorithm-Analysis-in-C.git

预习检查

NULL和NUL有什么差别 字符串操作有哪几个常用函数

memcpy和strcpy有什么差别

git@github.com:Kevin-Dfg/Data-Structures-and-Algorithm-Analysis-in-C.gitgit@github.com:Kevin-Dfg/Data-Structures-and-Algorithm-Analysis-in-C.git

课程目标

本章概述

重点

难点

对标准C语言的补充,以及一些常用的特性。

本章目标

了解一些C语言特殊的宏定义 掌握函数可变参数的应用

理解NULL, offsetof, errno宏或函数

掌握函数可变参数列表难点 C语言库的日期函数操作

函数的可变参数列表 标准C的异常处理机制

git@github.com:Kevin-Dfg/Data-Structures-and-Algorithm-Analysis-in-C.gitgit@github.com:Kevin-Dfg/Data-Structures-and-Algorithm-Analysis-in-C.git

本章结构

C标准语言库概要和应用 C标准语言库概要和应用

git@github.com:Kevin-Dfg/Data-Structures-and-Algorithm-Analysis-in-C.gitgit@github.com:Kevin-Dfg/Data-Structures-and-Algorithm-Analysis-in-C.git

标准语言库概述

标准语言库概述

标准C语言函数 标准C语言函数

主要库文件 主要库文件

标准库应用总结

标准库应用总结

                  2.1 标准语言概述 函数库简介

C语言标准库的历史 标准库函数优势 独立环境和宿主环境

git@github.com:Kevin-Dfg/Data-Structures-and-Algorithm-Analysis-in-C.gitgit@github.com:Kevin-Dfg/Data-Structures-and-Algorithm-Analysis-in-C.git

                  2.1.1 函数库简介 标准c语言包括语言标准和一组标准库

支持字符和字符串、输入与输出、数学函数、期与时

间转换、动态存储分配和其他特性

预处理器命令#include,引用这个库的头文件

例:

下列程序段中头文件math.h使程序能够访问余弦函数cos。 #include <math.h>

double x,y;

x = cos(y);

git@github.com:Kevin-Dfg/Data-Structures-and-Algorithm-Analysis-in-C.gitgit@github.com:Kevin-Dfg/Data-Structures-and-Algorithm-Analysis-in-C.git

             2.1.1 函数库简介 对定义为函数的库功能,标准C语言允许实现提供除真

正函数以外的同名函数式宏

例:

假设担心math.h中已有名为cos的宏,则可以用下面两种

方法引用基础函数。两者都利用宏名后面不能紧跟一个开 括号的特点,避免扩展同名函数或宏cos。

#include<math.h>

double a,b,(*p)(double);

...

p = &cos;

a= (*p)(b); /* calIs function cos,always */ a= (cos)(b); /* calls function cos,always */

也可以取消所有涉及到的宏的定义: #include<math.h>

#undef cos

...

嵌入式家园 www.embedclub.com

a = cos(b); /* calls function cos,always */

git@github.com:Kevin-Dfg/Data-Structures-and-Algorithm-Analysis-in-C.git

                                 2.1.2 C语言标准库的历史 C语言提供的标准函数库,函数库通过#include进行引用

在C89标准中:

<assert.h> <ctype.h> <errno.h> <float.h> <limits.h> <locale.h> <math.h> <setjmp.h> <signal.h> <stdarg.h> <stddef.h> <stdio.h> <stdlib.h> <string.h> <time.h>

在95年的修正版中

<iso646.h> <wchar.h> <wctype.h>

在C99中增加了六个函数库

<complex.h> <fenv.h> <inttypes.h> <stdbool.h> <stdint.h>

<tgmath.h>

git@github.com:Kevin-Dfg/Data-Structures-and-Algorithm-Analysis-in-C.gitgit@github.com:Kevin-Dfg/Data-Structures-and-Algorithm-Analysis-in-C.git

                2.1.3 标准库函数优势

准确性 高效性 可移植性

git@github.com:Kevin-Dfg/Data-Structures-and-Algorithm-Analysis-in-C.gitgit@github.com:Kevin-Dfg/Data-Structures-and-Algorithm-Analysis-in-C.git

                            2.1.4 独立环境和宿主环境

“独立(free—standing)”系统 嵌入式系统可以不要任何类型的文件系统,也可以基本上不

要操作系统

不要求它们提供除语言本身以外的任何东西

宿主(hosted)”环境 程序运行在RC机、大型机或者介于两者之间的计算机上

git@github.com:Kevin-Dfg/Data-Structures-and-Algorithm-Analysis-in-C.gitgit@github.com:Kevin-Dfg/Data-Structures-and-Algorithm-Analysis-in-C.git

               2.2 标准C语言函数 标准C语言函数

C++兼容性

git@github.com:Kevin-Dfg/Data-Structures-and-Algorithm-Analysis-in-C.gitgit@github.com:Kevin-Dfg/Data-Structures-and-Algorithm-Analysis-in-C.git

                                      2.2.1标准C语言函数 如何从标准c语言定义得到传统c语言库函数定义

消除任何使用标准c语言类型的函数,如long long与_Complex,或 消除标准c语言中新增的函数(C89或C99).

删除限定符const、restrict与volatile 删除数组声明符括号内使用的static. 将类型void * 换成char * ,将size_t换成int。

git@github.com:Kevin-Dfg/Data-Structures-and-Algorithm-Analysis-in-C.gitgit@github.com:Kevin-Dfg/Data-Structures-and-Algorithm-Analysis-in-C.git

                            2.2.1标准C语言函数 库函数注意事项

库名原则上是保留字。编程人员不能定义与标准库名称同名的外部

对象。

库头文件或文件名可以内置在实现中,但仍然要被包括之后才能访

问其名称

编程人员可以多次按任意顺序包括库头文件

例 下面的方法可以保证库头文件不被包括多次: /* I Header Btddef.H */

#ifndef _STDDEF /* Don.t try to redeclare */ #define _STDDEF l

typedef int ptrdiff_t; .../* 0ther definitions */

git@github.com:Kevin-Dfg/Data-Structures-and-Algorithm-Analysis-in-C.git#endif

git@github.com:Kevin-Dfg/Data-Structures-and-Algorithm-Analysis-in-C.git

                           2.2.2 C++兼容性 C++语言包括标准C语言运行库,但增加了几个C++

特定库 不能从c语言程序中调用c++函数,但c++提供了从

C++中调用c语言函数的方法 在C++中,声明c语言函数时有两个要求

函数声明要使用标准c语言原型,因为c++要求原型。 外部c语言要显式地标为具有c语言连接,即在c++的存储类extern后面加

上字符串“C”。

git@github.com:Kevin-Dfg/Data-Structures-and-Algorithm-Analysis-in-C.gitgit@github.com:Kevin-Dfg/Data-Structures-and-Algorithm-Analysis-in-C.git

                                2.2.2 C++兼容性 c语言函数中调用另一C语言函数

extern int f(void); c++中调用C语言函数

extern“C“int f(void); c++中要声明一组c语言函数,则可以对所有c语言函

数采用连接规范:

extern“C“{

double sqrt(double x);

int f(void);

......

}

git@github.com:Kevin-Dfg/Data-Structures-and-Algorithm-Analysis-in-C.gitgit@github.com:Kevin-Dfg/Data-Structures-and-Algorithm-Analysis-in-C.git

                    2.2.2 C++兼容性 从C语言或c++调用头文件library.h

在头文件中包括extern “C”声明(条件预编译__cplusplus宏),表 示这是个c++程序。

/* File library.h */ #ifdef __cplusplus

extern“c” { #endif

/* C declarations */ #ifdef __cplusplus

}

用正常c语言声#endif编写头文件,要求c++用户用# include命令包装连接声明

extern “C“ { #include”library.h“

git@github.com:Kevin-Dfg/Data-Structures-and-Algorithm-Analysis-in-C.git}

git@github.com:Kevin-Dfg/Data-Structures-and-Algorithm-Analysis-in-C.git

                            2.3 主要的库文件

stddef.h math.h ctype.h erron.h stdbool.h iso645.h assert.h

stdio.h stdlib.h string.h stdarg.h time.h setjmp.h signal.h

git@github.com:Kevin-Dfg/Data-Structures-and-Algorithm-Analysis-in-C.gitgit@github.com:Kevin-Dfg/Data-Structures-and-Algorithm-Analysis-in-C.git

            2.3.1 Stddef.h

语法概要之定义

#include<stddef.h> #define NULL ......

typedef ...

ptrdiff_t; size_tj wchar_t;

typedef ...

typedef ...

#define offsetof(type,member-designator)

git@github.com:Kevin-Dfg/Data-Structures-and-Algorithm-Analysis-in-C.gitgit@github.com:Kevin-Dfg/Data-Structures-and-Algorithm-Analysis-in-C.git

                                                           2.3.1 Stddef.h

NULL

size_t

null指针常量

0 转换为类型void的0

ptrdiff_t

实现定义的带符号整型

是两个指针相减所得到的类型

sizeof运算符得到的无符号整型

offsetof

扩展一个整型常量表达式

#define offsetof(type,memb)((size_t)&((type*)0)->memb)

git@github.com:Kevin-Dfg/Data-Structures-and-Algorithm-Analysis-in-C.gitgit@github.com:Kevin-Dfg/Data-Structures-and-Algorithm-Analysis-in-C.git

                             2.3.1 Stddef.h

例:对于sizeof(int)为4的字节寻址计算机

#include<Stddef.h>

struct s{int a; int b;}x;

程序运行结果是:

diff的值为1 size的值为4

offset的值为4

size_t size,offset; ptrdiff_t diff;

Diff = &x.b-&x.a;

Size = sizeof(x.a); offset=offsetof(struct s,b);

git@github.com:Kevin-Dfg/Data-Structures-and-Algorithm-Analysis-in-C.gitgit@github.com:Kevin-Dfg/Data-Structures-and-Algorithm-Analysis-in-C.git

                                    2.3.2 math.h

双精度浮点数的精度进行操作

参数传递和错误处理

如果传递过来的参数不在其定义域内,函数会返回一些不确定的值 ,并将变量errno置为EDOM。

如果返回值太大,无法用一个double类型表示(造成上溢),这些函数 会返回HUGEVAL,并将errno置为ERANGE。

如果函数结果太小,无法表示,则函数返回0,errno是否设置为 ERANGE由实现确定

EDOM,ERANGE和HUGEVAL都在math.h中定义。

git@github.com:Kevin-Dfg/Data-Structures-and-Algorithm-Analysis-in-C.gitgit@github.com:Kevin-Dfg/Data-Structures-and-Algorithm-Analysis-in-C.git

                                2.3.3 ctype.h

字符处理有两类函数:分类与转换

分类函数的名称以is开头 转换函数的名称以to开头

宽字符进行运算的分类与转换函数

分类函数----isw 转换函数----tow

git@github.com:Kevin-Dfg/Data-Structures-and-Algorithm-Analysis-in-C.gitgit@github.com:Kevin-Dfg/Data-Structures-and-Algorithm-Analysis-in-C.git

                                         2.3.3 ctype.h

字符处理有两类函数:分类与转换

分类函数的名称以is开头 转换函数的名称以to开头

宽字符进行运算的分类与转换函数

分类函数----isw 转换函数----tow

通用函数

分类函数wcstrans与iswctrans 转换函数 wctrans与towctrans

git@github.com:Kevin-Dfg/Data-Structures-and-Algorithm-Analysis-in-C.gitgit@github.com:Kevin-Dfg/Data-Structures-and-Algorithm-Analysis-in-C.git

            2.3.3 ctype.h

例:

#inelude<ctype.h> #define TRUE 1 #define FALSE 0

int is_id(const char *s) {

}

char ch;

if ((ch= *s++) ==‘\0’) return FALSE; /*empty string*/ if(!(isalpha(ch)||ch ==‘_’)) return FALSE;

while ((ch = *s++)!=‘\0’)

{

if(!(isalnum(ch) || ch==‘_’)) return FALSE; }

return TRUE;

git@github.com:Kevin-Dfg/Data-Structures-and-Algorithm-Analysis-in-C.gitgit@github.com:Kevin-Dfg/Data-Structures-and-Algorithm-Analysis-in-C.git

            2.3.4 erron.h

语法概要

#include<errno.h>

extern int errno; or # define errno ... #define EDOM ...

#define ERANGE #define ETLSEQ

... ...

#include<stdio.h>

void perror(const char *s)

#include<string.h>

char *strerror(int errnum)

git@github.com:Kevin-Dfg/Data-Structures-and-Algorithm-Analysis-in-C.gitgit@github.com:Kevin-Dfg/Data-Structures-and-Algorithm-Analysis-in-C.git

                              2.3.4 erron.h

errno

保存库程序中实现定义的错误码,通常被定义为errno.h 中以E开头的宏 在标准c语言中,errno不能是变量,但可以扩展成int类型的任何可修改的

lvalue的宏。 errno用法

例 errno的常见用法是在调用库函数之前先清零,随后再进行检查:

errno=0; x = sqrt(y); if(errno)

{

printf(”?sqrt falled,code%d\n”,errno);

x=0; }

git@github.com:Kevin-Dfg/Data-Structures-and-Algorithm-Analysis-in-C.gitgit@github.com:Kevin-Dfg/Data-Structures-and-Algorithm-Analysis-in-C.git

                                              2.3.4 erron.h

c语言实现通常定义一组标准错误码:

EDOM 参数不在数学函数能接受的域中。例如log函数的参数不能为负数参数

ERANGE 数学函数的结果超出范围

EILSEQ 翻译多字节字符序列时遇到的编码错误。这个错误最终会由mbrtowc或

wcrtomb发现,它们又被其他宽字符函数调用(c89增补l) 函数strerror返回一个错误消息字符串的指针,其内容是由实现定义的,字符串不

能修、但可以在后续调用strerror函数时覆盖 函数perror在标准错误输出流中打印下面的序列:参数字符串s、冒号、空格、包

errno中当前错误码的错误短消息和新行符

git@github.com:Kevin-Dfg/Data-Structures-and-Algorithm-Analysis-in-C.gitgit@github.com:Kevin-Dfg/Data-Structures-and-Algorithm-Analysis-in-C.git

                             2.3.4 erron.h

perror 使用例子: perror 函数代替printf函数

#include<math.h> #include<errno.h>

}

...... errno=0;

x = sqrt(y); if(errno){

perror(“sqrt failed”); x=0;

如果调用sqrt失败,则输出如下: sqrt failed:domain error

git@github.com:Kevin-Dfg/Data-Structures-and-Algorithm-Analysis-in-C.gitgit@github.com:Kevin-Dfg/Data-Structures-and-Algorithm-Analysis-in-C.git

            2.3.5 boolfalsetrue 语法概要

#include <stdbool.h>

#define bool _Bool /*无符号整数类型,只能保存数值01 */ #define false 0

#define true 1

#define __bool_true_false_are_define 1

git@github.com:Kevin-Dfg/Data-Structures-and-Algorithm-Analysis-in-C.gitgit@github.com:Kevin-Dfg/Data-Structures-and-Algorithm-Analysis-in-C.git

                    2.3.6 iso646.h

语法概要

#include <iso646.h> #define and && #define and_eq &= #define bitand & #define bitor | #define compl ~ #define not ! #define not_eq != #define or || #define or_eq |= #define xor ^ #define xor_eq ^=

如果调用sqrt失败,则输出如下: sqrt failed:domain error

git@github.com:Kevin-Dfg/Data-Structures-and-Algorithm-Analysis-in-C.gitgit@github.com:Kevin-Dfg/Data-Structures-and-Algorithm-Analysis-in-C.git

                         2.3.7 assert.h

Assert.h函数提供标准控制流扩展

语法概要

作用

#include<assert.h> #ifndef NDGBUG

void assert(int expression); #else

#define assert(x) ((void)0) #endif

标准输出流中打印一个诊断消息(参数文本、文件名(_FILE_)和号(_LINE_) ) 调用abort函数或exit函数终止程序

git@github.com:Kevin-Dfg/Data-Structures-and-Algorithm-Analysis-in-C.gitgit@github.com:Kevin-Dfg/Data-Structures-and-Algorithm-Analysis-in-C.git

            2.3.7 assert.h

例:测试一个条件并可能使程序终止

#include <assert.h> #include <stdio.h> #include <stdlib.h> struct ITEM

{

int key;

int value; };

void additem(struct ITEM *itemptr) {

assert(itemptr != NULL); }

int main(void) {

additem(NULL); return 0;

git@github.com:Kevin-Dfg/Data-Structures-and-Algorithm-Analysis-in-C.gitgit@github.com:Kevin-Dfg/Data-Structures-and-Algorithm-Analysis-in-C.git

}

                                                           2.3.8 string.h

C 常用字符串处理函数及使用示例 char *strncat(char *s1, const char *s2, size_t n)

将字符串s2中最多n个字符添加到字符串s1的后面。s2的第一个字符重定义s1 的null终止符。返回s1的值

int strcmp(const char *s1, const char *s2)

比较字符串s1和字符串s2。函数在s1等于、小于或大于s2时分别返回0、小于0 或大于0的值

int strncmp(const char *s1, const char *s2, size_t n)

比较字符串s1中的n个字符和字符串s2。函数在s1等于、小于或大于s2时分别 返回0、小于0或大于0的值

git@github.com:Kevin-Dfg/Data-Structures-and-Algorithm-Analysis-in-C.gitgit@github.com:Kevin-Dfg/Data-Structures-and-Algorithm-Analysis-in-C.git

                                                           2.3.8 string.h

C 常用字符串处理函数及使用示例 char *strcpy(char *s1, const char *s2)

将字符串s2复制到字符串数组s1中,返回s1的值 char *strncpy(char *s1, const char *s2, size_t n)

将字符串s2中最多n个字符复制到字符串数组s1中,返回s1的值 char *strcat(char *s1, const char *s2)

将字符串s2添加到字符串s1的后面。s2的第一个字符重定义s1的null终止符。 返回s1的值

git@github.com:Kevin-Dfg/Data-Structures-and-Algorithm-Analysis-in-C.gitgit@github.com:Kevin-Dfg/Data-Structures-and-Algorithm-Analysis-in-C.git

                                                              2.3.8 string.h

C 常用内存处理函数

void *memccpy(void *destin,void *source, char ch,unsigned n)

若复制了ch,则返回直接跟随ch的在destin中的字节的一个指针 Void * memcpy(void *destin,void *source,unsigned ,unsigned n)

从source复制一个n字节的块到destin.如果源块和目标块重迭,则选择复制方向 void *memchr(void *s,char ch,unsigned n)

返回在s中首先出现ch的一个指针;如果在s数组中不出现ch,就返回NULL.. void *memcmp(void *s1,void *s2,unsigned n)

比较正好是n字节长的两个字符串s1和s2.些函数按无符号字符比较字节

git@github.com:Kevin-Dfg/Data-Structures-and-Algorithm-Analysis-in-C.gitgit@github.com:Kevin-Dfg/Data-Structures-and-Algorithm-Analysis-in-C.git

                                                       2.3.8 string.h

C 常用内存处理函数

int memicmp(void *s1,void *s2,unsigned n)

比较s1和s2的前n个字节,不管字符大写或小写.

void *memmove(void *destin,void *source,unsigned n)

从source复制字节到destin

void *memcpy(void *destin,void *source,unsigned n)

从source复制字节到destin

void *memset(void *s,char ch,unsigned n)

将s的所有字节置于字节ch中.s数组的长度由n给出.

git@github.com:Kevin-Dfg/Data-Structures-and-Algorithm-Analysis-in-C.gitgit@github.com:Kevin-Dfg/Data-Structures-and-Algorithm-Analysis-in-C.git

             2.3.9 stdarg.h

Stdarg.h头文件提供了访问可变参数表 语法概要

#define #define

typedef ... va_list;

va_start(va_list ap,type LastFixedParm) ... va_arg(va_list ap,type)...

void void

va_end(va_list ap); va_copy(va_list dest,va_list src);

#include<stdarg.h>

git@github.com:Kevin-Dfg/Data-Structures-and-Algorithm-Analysis-in-C.gitgit@github.com:Kevin-Dfg/Data-Structures-and-Algorithm-Analysis-in-C.git

                                                 2.3.9 stdarg.h

stdarg.h中定义的宏、函数和类型的含义 Va_list 这种类型声明局部状态变量,用于遍历参数。

Va_start 这个宏初始化状态变量ap,要先调用之后才能调用.将ap中的 内部指针设置成指向传入函数的第一个可变参数。

Va_arg 这个宏返回参数表中下一个参数的值,将内部参数指针(在ap中 )移到下一个参数(如有)。

Va_end 这个函数或宏在用va_arg读取所有参数之后调用。

Va_copy (C99)这个宏在dest中复制src的当前状态,在参数表中生成第

二个指针。然后可以独立对src与dest采用va_arg。

git@github.com:Kevin-Dfg/Data-Structures-and-Algorithm-Analysis-in-C.gitgit@github.com:Kevin-Dfg/Data-Structures-and-Algorithm-Analysis-in-C.git

           2.3.9 stdarg.h

编写可变个数参数的函数

#include “printargs.h”

int arg_types[] =(INTARG,DBLARG,INTARG,DBLARG,0); int main()

{

printargs(&ar9_types[0],l,2.0,3,4.0);

return 0; }

printargs的声明和整数类型指定符的值放在文件printargs.h中。

/* file printargs.h;Standard C*/ #include<stdarg.h>

#define INTARG 1 /* codes used in argtypep[]*/ #define DBLARG 2

......

void printargs(int *argtypep,...);

git@github.com:Kevin-Dfg/Data-Structures-and-Algorithm-Analysis-in-C.gitgit@github.com:Kevin-Dfg/Data-Structures-and-Algorithm-Analysis-in-C.git

           2.3.9 stdarg.h

标准C语言中printargs的相应定义如下: #include<stdio.h>

#include “printargs.h”

void printargs( int*argtypep,...) /* Standard C */ {

va_list ap;

int argtype; va_start(ap,argtypep);

while (( argtype = *argtypep++) != 0) {

} }/*while*/

switch(argtype) {

case TNTARG: printf(”int:%d\n”,va_arg(ap,int)); break;

case DBLARG: printf(“double:%f\n“,va_arg(ap,double)); break;

va_end(ap);

嵌入式家园 www.embedclub.com

}git@github.com:Kevin-Dfg/Data-Structures-and-Algorithm-Analysis-in-C.git

                             2.3.10 setjmp.h

语法概要

#include<setjmp.h>

typedef ...... jmp_buf;

int setjmp(Jmp_buf env);

void longJmp(jmp_buf env,int status)

setjmp与longjmp函数实现

非本地跳转

处理异常

例外情形

git@github.com:Kevin-Dfg/Data-Structures-and-Algorithm-Analysis-in-C.gitgit@github.com:Kevin-Dfg/Data-Structures-and-Algorithm-Analysis-in-C.git

                                          2.3.10 setjmp.h

jmp_buf

数组类型

Setjmp

env是个由实现定义的数组 返回0

Longjmp

env是个由实现定义的数组 返回status

git@github.com:Kevin-Dfg/Data-Structures-and-Algorithm-Analysis-in-C.gitgit@github.com:Kevin-Dfg/Data-Structures-and-Algorithm-Analysis-in-C.git

            2.3.10 setjmp.h

#include<setjmp.h> Imp_buf ErrorEnv; int guard(void)

/* Return 0 if successfult else longjmp code.*/ {

}

int status = setjmp(ErrorEnv); if(status!=0) return status; /*error*/ process();

return 0;

int process(void) {...

if(error_happened)longjmp(ErrorEnv,error_code); }

git@github.com:Kevin-Dfg/Data-Structures-and-Algorithm-Analysis-in-C.gitgit@github.com:Kevin-Dfg/Data-Structures-and-Algorithm-Analysis-in-C.git

            2.3.11 signal.h

语法概要

#include <signal.h>

#define SIG_IGN #define SIG_DFL #define SIG_ERR #define SIGxxxx......

void(*signal(int sig,void(*func)(int)))(int); int raise(int sig);

typedef ... sig_atomic_t;

/* Non—Standard extensionst */

int kill(int pid,intsig);

int (*ssignal(int softsig,int(*func)(int)))(int);

int gsignal(int softsig);

git@github.com:Kevin-Dfg/Data-Structures-and-Algorithm-Analysis-in-C.gitvoid peignal(int sig,char* prefix);

git@github.com:Kevin-Dfg/Data-Structures-and-Algorithm-Analysis-in-C.git

                                            2.3.11 signal.h

运用特点

信号是(潜在的)异步事件 信号的触发可以通过计算机的错误探测机制、用户程序中的kill或raise函数以及程

序外部的操作

用法:

信号处理器是个用户函数

void my_handler(int the_signal){...} SIG_IGN -signal(sig,SIG_IGN) SIG_DFL -signal(sig, SIG_DFL)

raise或gsignal函数在当前进程中发出指定的信号(或软件 信号)

kill函数使特定进程中发出指定的信号 嵌入式家园 www.embedclub.com

git@github.com:Kevin-Dfg/Data-Structures-and-Algorithm-Analysis-in-C.git

            2.3.11 signal.h

运用实例

void new_handler(int sig){...} void(*old_handler)();

/*Set new handler,saving old handler*/ old_handler = signal(sig, &new_handler); if(old_handler == SIG_ERR)

fprintf(”stderr,”?Could.t establish new handler.\n”);

/* store old handler*/ if(signal(sig,old_handler)==SIG_ERR)

fprintf(“stderr,”?Couldt put back old handler.\n”);

git@github.com:Kevin-Dfg/Data-Structures-and-Algorithm-Analysis-in-C.gitgit@github.com:Kevin-Dfg/Data-Structures-and-Algorithm-Analysis-in-C.git

                              2.3.11 signal.h

信号处理注意事项

如果信号是由raise或gsignal发出的,则这些函数返回其调用者。 如果信号是由abort发出的,则标准c语言程序终止。其他实现可能返回abort

的调用者。

如果处理的信号是SIGFPE或另一实现定义的计算信号,则返回时的行为是未 定义的。

git@github.com:Kevin-Dfg/Data-Structures-and-Algorithm-Analysis-in-C.gitgit@github.com:Kevin-Dfg/Data-Structures-and-Algorithm-Analysis-in-C.git

                      2.4 标准库应用总结

编写参数数目可变的函数 判断字符 标准C的异常处理机制 对内存进行操作的标准库函数

C语言日期操作 malloc()、calloc()、realloc() NULL和NUL的区别 非格式化输入输出函数

git@github.com:Kevin-Dfg/Data-Structures-and-Algorithm-Analysis-in-C.gitgit@github.com:Kevin-Dfg/Data-Structures-and-Algorithm-Analysis-in-C.git

                                         2.4.1编写参数数目可变的函数 利用stdarg.h

例:

printf(" Hello, world! \n" ); /* no more arguments */

printf("%s\n" , "Hello, world!"); /* one more string argument */ printf("%s, %s\n" , "Hello" , "world!"); /* two more string arguments */ printf("%s, %d\n", "Hello", 42); /* one string, one int */

git@github.com:Kevin-Dfg/Data-Structures-and-Algorithm-Analysis-in-C.gitgit@github.com:Kevin-Dfg/Data-Structures-and-Algorithm-Analysis-in-C.git

                   2.4.2 标准C的异常处理机制

绝对终止 条件结束 非局部goto 信号(Signals) 公共变量

git@github.com:Kevin-Dfg/Data-Structures-and-Algorithm-Analysis-in-C.gitgit@github.com:Kevin-Dfg/Data-Structures-and-Algorithm-Analysis-in-C.git

                                    2.4.2.1 绝对终止

调用stdlib.h

abort: 粗鲁地结束程序 exit: 文明地结束程

两者区别

abort立即结束程序 ,不保存数据 exit保存数据,执行客户用atexit注册的清除代码

git@github.com:Kevin-Dfg/Data-Structures-and-Algorithm-Analysis-in-C.gitgit@github.com:Kevin-Dfg/Data-Structures-and-Algorithm-Analysis-in-C.git

                2.4.2.1 绝对终止 例

#include <stdio.h>

#include <stdlib.h>

static void atexit_handler_1(void)

{

printf("within 'atexit_handler_1'\n");

结果

}

static void atexit_handler_2(void)

within 'atexit_handler_2' within 'atexit_handler_1' 并返回退出码给调用环境.

{

printf("within 'atexit_handler_2'\n");

}

int main(void) {

atexit(atexit_handler_1);

atexit(atexit_handler_2);

exit(EXIT_SUCCESS);

printf("this line should never appear\n");

git@github.com:Kevin-Dfg/Data-Structures-and-Algorithm-Analysis-in-C.gitgit@github.com:Kevin-Dfg/Data-Structures-and-Algorithm-Analysis-in-C.git

return 0; }

                             2.4.2.2 条件结束 <assert.h> 中的assert

#define assert(condition) _assert((condition), #condition, __FILE__, __LINE__)

printf函数 调用abort终止程序

自定义assert函数 例:

void _assert(int test, char const *test_image, char const *file, int line) {

} }

if (!test) {

printf("Assertion failed: %s, file %s, line %d\n", test_image, file, line); abort();

git@github.com:Kevin-Dfg/Data-Structures-and-Algorithm-Analysis-in-C.gitgit@github.com:Kevin-Dfg/Data-Structures-and-Algorithm-Analysis-in-C.git

                                                     2.4.2.3 非局部goto

<setjmp.h > 中的setjmp与longjmp

特点

可以goto到任何地方 在程序的任意地方控制它

操作特点

jmp_buf内容:程序位置指针、堆栈与框架指针,寄存器与内存值 setjmp(j)设置goto指针

setjmp可以标记相应的异常处理过程

longjmp来引发终止异常

longjmp(j, r)来goto到对象j指定的地方

git@github.com:Kevin-Dfg/Data-Structures-and-Algorithm-Analysis-in-C.gitgit@github.com:Kevin-Dfg/Data-Structures-and-Algorithm-Analysis-in-C.git

               2.4.2.3 非局部goto 操作实例

#include <setjmp.h> #include <stdio.h> jmp_buf j;

void raise_exception(void) {

int main(void) {

printf("exception raised\n");

printf("'setjmp' is initializing 'j'\n"); raise_exception();//恢复上下文 printf("this line should never appear\n");

longjmp(j, 1);

} else {

/* jump到异常处理过程 */

printf("this line should never appear\n"); }

printf("'setjmp' was just jumped into\n");

运行结果

/* 异常处理过程 */ }

运行结果

return 0; }

'setjmp' is initializing 'j'

'setjmp' is initializing 'j'

exception raised

exception raised

setjmp' was just jumped into

setjmp' was just jumped into

git@github.com:Kevin-Dfg/Data-Structures-and-Algorithm-Analysis-in-C.gitgit@github.com:Kevin-Dfg/Data-Structures-and-Algorithm-Analysis-in-C.git

if (setjmp(j) == 0) {

                                  2.4.2.4 信号(Signals)

<signal.h > 中的raise与signal

实例

raise来引发信号,并进入到相应的处理过程

signal两种安装指定处理方法:

* signal(SIGxxx, SIG_DFL),//使用系统默认的处理方法. * signal(SIGxxx, SIG_IGN), //告诉系统忽略信号。

void handler(int signal_value); void f(void)

{

}

signal(SIGFPE, handler); /* 注册处理过程*/

/* ... */

raise(SIGFPE); /* 通过 'SIGFPE'来调用处理过程 */

git@github.com:Kevin-Dfg/Data-Structures-and-Algorithm-Analysis-in-C.gitgit@github.com:Kevin-Dfg/Data-Structures-and-Algorithm-Analysis-in-C.git

                             2.4.3 对内存进行操作的标准库函数

memmove() 与memcpy() 内存copy

Memmove 考虑到相互覆盖 memcpy 速度比 memmove 快

例: 将buf从"RIGHT"改为“RIGRIGHT”

static char buf[] ={'R','I','G','H','T','\0','-','-','-'}; Int main()

{

int i;

for (i = 0; i<6; ++i) {

buf[i + 3] = buf[i]; }

git@github.com:Kevin-Dfg/Data-Structures-and-Algorithm-Analysis-in-C.gitgit@github.com:Kevin-Dfg/Data-Structures-and-Algorithm-Analysis-in-C.git

}

                        2.4.4 对内存进行操作的标准库函数

memcmp() 与strncmp() memcmp遇到NULL字符时不会结束 memcmp()函数不能用来比较结构的值

例: 结构体比较 struct foo{

short s; long l;

} 分析(32位系统环境)

struct foo byte[0] s的低位字节 struct foo byte[0] s的低位字节

struct foo byte[1] s的高位字节 struct foo byte[1] s的高位字节

struct foo byte[2] 无用信息(使l从一个long类型边界开始) struct foo byte[2] 无用信息(使l从一个long类型边界开始)

struct foo byte[3] 无用信息(使l从一个long类型边界开始) struct foo byte[3] 无用信息(使l从一个long类型边界开始)

struct foo byte[4] l的最低位字节 struct foo byte[4] l的最低位字节

struct foo byte[5] l的次低位字节 struct foo byte[5] l的次低位字节

struct foo byte[6] l的次高位字节 struct foo byte[6] l的次高位字节

git@github.com:Kevin-Dfg/Data-Structures-and-Algorithm-Analysis-in-C.gitstruct foo byte[7] 1的最高位字节

struct foo byte[7] 1的最高位字节 git@github.com:Kevin-Dfg/Data-Structures-and-Algorithm-Analysis-in-C.git

                                    2.4.4 对内存进行操作的标准库函数

strcpy() () 与memcpy () strcpy()函数只能拷贝字符串,遇到NULL字符时结束 memcpy()函数可以拷贝任意类型的数据,指定字节数

使用规则

拷贝字符串时,通常都使用strcpy()函数 在拷贝其它数据时,通常都使用memcpy()函数。

git@github.com:Kevin-Dfg/Data-Structures-and-Algorithm-Analysis-in-C.gitgit@github.com:Kevin-Dfg/Data-Structures-and-Algorithm-Analysis-in-C.git

            2.4.4 对内存进行操作的标准库函数 例

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

typedef struct cust_str {

int id ;

char last_name [20] ; char first_name[l5];

} CUSTREC;

git@github.com:Kevin-Dfg/Data-Structures-and-Algorithm-Analysis-in-C.gitgit@github.com:Kevin-Dfg/Data-Structures-and-Algorithm-Analysis-in-C.git

            2.4.4 对内存进行操作的标准库函数

void main (void) {

}

dest_cust. id, dewstw_cwu.setm. fibrsetd_cnlaumbe.c, odemst_cust. last_name) ; 嵌入式家园 www.embedclub.com

char * src_string = "This is the source string" ; char dest_string[50];

CUSTREC src_cust;

CUSTREC dest_cust;

printf("Hello! I'm going to copy src_string into dest_string!\n"); printf("Done! dest_string is: %s\n" , strcpy(dest_string, src_string)) ; printf("Encore! Let's copy one CUSTREC to another. \n") ;

prinft("I'll copy src_cust into dest_cust. \n");

/ * First, intialize the src_cust data members. * /

src_cust. id = 1 ;

strcpy(src_cust. last_name, "Strahan");

strcpy(src_cust. first_name, "Troy");

memcpy(&dest_cust, &src_cust, sizeof(CUSTREC)); printf("Done! I just copied customer number # %d (%s %s). " ,

git@github.com:Kevin-Dfg/Data-Structures-and-Algorithm-Analysis-in-C.git

                  2.4.4.1 日期概述

Coordinated Universal Time(UTC)世界标准时间

Calendar Time:日历时间 epoch:时间点

clock tick:时钟计时单元

git@github.com:Kevin-Dfg/Data-Structures-and-Algorithm-Analysis-in-C.gitgit@github.com:Kevin-Dfg/Data-Structures-and-Algorithm-Analysis-in-C.git

                         2.4.4.2 计时 C中的计时函数是clock()

lock_t clock( void )

#define CLOCKS_PER_SEC ((clock_t)1000)

git@github.com:Kevin-Dfg/Data-Structures-and-Algorithm-Analysis-in-C.gitgit@github.com:Kevin-Dfg/Data-Structures-and-Algorithm-Analysis-in-C.git

            2.4.4.2 计时 实例:机器运行一个循环或者处理其它事件到底花了多少时间

#i nclude “stdio.h” #i nclude “stdlib.h” #i nclude “time.h” int main( void )

{

long i = 10000000L; clock_t start, finish; double duration;

/* 测量一个事件持续的时间*/

printf( "Time to do %ld empty loops is ", i );

start = clock();

while( i- -);

finish = clock();

duration = (double)(finish - start) / CLOCKS_PER_SEC;

printf( "%f seconds\n", duration );

system("pause");

git@github.com:Kevin-Dfg/Data-Structures-and-Algorithm-Analysis-in-C.gitgit@github.com:Kevin-Dfg/Data-Structures-and-Algorithm-Analysis-in-C.git

}

                        2.4.4.2 计时

实例:获得日历时间 time_t time(time_t * timer); 代码分析

#include "time.h" #include "stdio.h" int main(void)

{

结果:The Calendar Time now is 1122707619 结果:The Calendar Time now is 1122707619

}

struct tm *ptr;

time_t lt;

lt =time(NULL);

printf("The Calendar Time now is %d\n",lt); return 0;

即从197011000秒到此时的秒数。 即从197011000秒到此时的秒数。

git@github.com:Kevin-Dfg/Data-Structures-and-Algorithm-Analysis-in-C.gitgit@github.com:Kevin-Dfg/Data-Structures-and-Algorithm-Analysis-in-C.git

                                    2.4.4.2 计时

实例:获得日期和时间

struct tm * gmtime(const time_t *timer);

}

获得的世界标准时间是2005年7月30日7点18分20秒 struct tm * localtime(const time_t * timer);

获得的本地时间会比时间标准时间晚8个小时 代码分析

#include "time.h" #include "stdio.h" int main(void)

{

结果:

struct tm *local;

time_t t;

t=time(NULL);

local=localtime(&t);

printf("Local hour is: %d\n",local->tm_hour); local=gmtime(&t);

Local hour is: 15

printf("UTC hour is: %d\n",local->tm_hour);

git@github.com:Kevin-Dfg/Data-Structures-and-Algorithm-Analysis-in-C.gitreturn 0;

git@github.com:Kevin-Dfg/Data-Structures-and-Algorithm-Analysis-in-C.git

结果:

Local hour is: 15

UTC hour is: 7

UTC hour is: 7

                                                              2.4.4.2 计时 固定的时间格式

格式:

星期几 月份 日期 时:分:秒 年\n\0 例如:Wed Jan 02 02:03:55 1980\n\0

char * asctime(const struct tm * timeptr); 通过tm结构来生成具有固定格式的保存时间信息的字符串 把tm结构对象中的各个域填到时间字符串的相应位置

char * ctime(const time_t *timer);

通过日历时间来生成时间字符串 先参照本地的时间设置 再把日历时间转化为本地时间 然后再生成格式化后的字符串。

git@github.com:Kevin-Dfg/Data-Structures-and-Algorithm-Analysis-in-C.gitgit@github.com:Kevin-Dfg/Data-Structures-and-Algorithm-Analysis-in-C.git

                                                             2.4.5 malloc()calloc()realloc() malloc()

修改一个原先已经分配的内存块的大小

分配特点

增加

缩小

内存原先的内容依然保留

新增加的内存添加到原先内存块的后面

如果原先的内存块无法改变大小,分配另外一块正确大小的内存,并把原先

那块内存的内容复制到新的块上

内存块尾部的部分内存便被拿掉

剩余部分内存的原先内容依然保留

git@github.com:Kevin-Dfg/Data-Structures-and-Algorithm-Analysis-in-C.gitgit@github.com:Kevin-Dfg/Data-Structures-and-Algorithm-Analysis-in-C.git

                                                                2.4.5 malloc()calloc()realloc()

realloc()

有一个参数,分配的内存空间的大小 语法:void *malloc(size_t size) 不能初始化所分配的内存空间 可能有遗留各种各样的数据 返回一个对象

calloc()

有两个参数,分别为元素的数目和每个元素的大小

语法:void *calloc(size_t numElements,size_t sizeOfElement); 能初始化所分配的内存空间 分配的内存空间中的每一位都初始化为零 返回一个由某种对象组成的数组

git@github.com:Kevin-Dfg/Data-Structures-and-Algorithm-Analysis-in-C.gitgit@github.com:Kevin-Dfg/Data-Structures-and-Algorithm-Analysis-in-C.git

                                    2.4.6 NULL和NUL的区别

NULL

NUL

定义空指针宏 NULL可以被定义为(void *)0

ASCII字符集中第一个字符的名称,对应于一个零值 NUL可以被定义为'\0'

git@github.com:Kevin-Dfg/Data-Structures-and-Algorithm-Analysis-in-C.gitgit@github.com:Kevin-Dfg/Data-Structures-and-Algorithm-Analysis-in-C.git

                      2.5 标准库应用总结

编写参数数目可变的函数 判断字符 标准C的异常处理机制 对内存进行操作的标准库函数

标准C语言运算符宏 串拷贝与内存拷贝 C语言日期操作 非格式化输入输出函数

git@github.com:Kevin-Dfg/Data-Structures-and-Algorithm-Analysis-in-C.gitgit@github.com:Kevin-Dfg/Data-Structures-and-Algorithm-Analysis-in-C.git

阶段小节

如何编写一个可变参数的函数

C语言库中的日期函数的具体实例操作   内存和字符串函数库的实例应用和分析   格式化输入和输出操作

git@github.com:Kevin-Dfg/Data-Structures-and-Algorithm-Analysis-in-C.gitgit@github.com:Kevin-Dfg/Data-Structures-and-Algorithm-Analysis-in-C.git

本章结构

C标准语言库概要和应用 C标准语言库概要和应用

git@github.com:Kevin-Dfg/Data-Structures-and-Algorithm-Analysis-in-C.gitgit@github.com:Kevin-Dfg/Data-Structures-and-Algorithm-Analysis-in-C.git

标准语言库概述

标准语言库概述

标准C语言函数 标准C语言函数

简单讲述了C语言库和C++ 之间的特性

主要库文件 主要库文件

本节着重讲述在C语言编程 中常需用到的标准库函数

标准库应用总结

标准库应用总结

深入讲述标准语言库的具体

应用

本节主要讲述标准语言的

发展历史和特性

实验1 题目

从文件file.txt中读出所有内容,并计算出文件中有多少个字母,有多少数 字,有多少个标点符号。注意在操作过程要用malloc来分配内存空间;

实验目的

考察对文件的读操作;

练习判断字符库中的函数用法;

考察对内存函数的操作和字符串函数的应用

实验分析

计算出文件字符的数量,申请对应大小的空间;

读出文件中的内容,并拷贝写入到内存空间中;

统计分析内存空间的字符情况;

实验结果

熟悉对文件的操作,同时深入理解内存和字符串的操作细节。

git@github.com:Kevin-Dfg/Data-Structures-and-Algorithm-Analysis-in-C.gitgit@github.com:Kevin-Dfg/Data-Structures-and-Algorithm-Analysis-in-C.git

实验2

实验内容

就第一题的所得的结果,添加到文件末尾:格式为 写入时间:格式1970年1月1日0时0分0秒 字母:num 个

数字:num 个

标点:num 个 统计时间:1970年1月1日0时0分0秒 操作用时:NUM ms。

实验目的

考察对文件的写操作; 了解C语言的日期函数操作;

实验分析

通过日期函数得到当前时间;

通过文件写入函数向文件末尾添加内容;

记录数据写入完时的时间;

通过时间差函数得到操作所用的时间;

实验结果

熟悉文件的操作的定位,同时深入体验C语言日期操作函数 。

git@github.com:Kevin-Dfg/Data-Structures-and-Algorithm-Analysis-in-C.gitgit@github.com:Kevin-Dfg/Data-Structures-and-Algorithm-Analysis-in-C.git

上一篇:Nginx+keepalived双机热备(主从模式)


下一篇:Z30云台PC控制问题