上章回顾

数组和指针相同与不同

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

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

函数指针的申明和调用

函数数组和数组函数

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

附录二 C语言标准库的更多相关文章

  1. (十二)boost库之多线程高级特性

    (十二)boost库之多线程高级特性 很多时候,线程不仅仅是执行一些耗时操作,可能我们还需要得到线程的返回值,一般的处理方法就是定义一个全局状态变量,不断轮训状态,就如我目前维护的一个项目,全局变量定 ...

  2. (二)boost库之字符串格式化

    (二)boost库之字符串格式化 程序中经常需要用到字符串格式化,就个人而言还是比较倾向于C格式的输出,如果只是打印日志,printf就够了,如果到生成字符串,获取你可以选择sprintf,但这些都是 ...

  3. Go语言标准库_输入/输出

    Go语言标准库_输入/输出 转载节选自<Go语言标准库> Reader 接口 type Reader interface { Read(p []byte) (n int, err erro ...

  4. GO语言标准库—命令行参数解析FLAG

    flag包是Go语言标准库提供用来解析命令行参数的包,使得开发命令行工具更为简单 常用方法 1.flag.Usage 输出使用方法,如linux下ls -h的帮助输出 2.flag.Type(参数名, ...

  5. Go语言标准库之JSON编解码

    Go语言标准库之JSON编解码 基本的类型 Go语言中的数据类型和JSON的数据类型的关系 bool -> JSON boolean float64 -> JSON numbers str ...

  6. Go语言标准库之time

    Go语言标准库之time 时间的格式化和解析 格式化 Format Go语言和其他语言的时间格式化的方式不同,Go语言格式化的方式更直观,其他的语言一般是yyyy-mm-dd package main ...

  7. (C/C++学习笔记) 二十二. 标准模板库

    二十二. 标准模板库 ● STL基本介绍 标准模板库(STL, standard template library): C++提供的大量的函数模板(通用算法)和类模板. ※ 为什么我们一般不需要自己写 ...

  8. C语言标准库之setjmp

    协程的介绍 协程(coroutine),意思就是“协作的例程”(co-operative routines),最早由Melvin Conway在1963年提出并实现.跟主流程序语言中的线程不一样,线程 ...

  9. C语言标准库 qsort bsearch 源码实现

    C语言是简洁的强大的,当然也有很多坑.C语言也是有点业界良心的,至少它实现了2个最最常用的算法:快速排序和二分查找. 我们知道,对于C语言标准库 qsort和 bsearch: a. 它是“泛型”的, ...

随机推荐

  1. java.net.SocketException: Too many open files

    1.ps -ef|grep java 2.lsof -p 32636 3.lsof -p 20812|wc –l   这个也可以看一个进程打开的文件数 4.ulimit –a c3p0官方提供了两个参 ...

  2. OpenCV坐标体系的初步认识

    实验基础 本次实验通过一个简短的例子,主要来说明下面4个问题: 1. 坐标体系中的零点坐标为图片的左上角,X轴为图像矩形的上面那条水平线:Y轴为图像矩形左边的那条垂直线.该坐标体系在诸如结构体Mat, ...

  3. Ajax get方法 IE 下乱码

    每个浏览器处理编码的格式不同. ajax使用utf-8来编码发送数据,ie在发送时并没加上charset=utf-8,从而导致乱码(IE默认使用iso-8859-1编码) JavaScript代码: ...

  4. HTML5实战教程———开发一个简单漂亮的登录页面

    最近看过几个基于HTML5开发的移动应用,比如臭名昭著的12036移动客户端就是主要使用HTML5来实现的,虽然还是有点反应迟钝,但已经比较流畅了,相信随着智能手机的配置越来越高性能越来越好,会越来越 ...

  5. Core Text概述

    本文是我翻译的苹果官方文档<Core Text Overview> Core Text框架是高级的底层文字布局和处理字体的技术.它在Mac OS X v10.5 and iOS 3.2开始 ...

  6. String创建对象的个数--西北狼

    public class StringDemo { /** * @param args */ public static void main(String[] args) { // TODO Auto ...

  7. mysql 批量创建表,利用存储过程

    最近根据需求,需要提前创建一批日志表,以日期结尾,每天创建一张,例如XXX20160530,请参考如下: BEGIN    DECLARE `sName` VARCHAR(128);   DECLAR ...

  8. 嵌入式 -- WINKHUB 边信道攻击 (NAND Glitch)

    0x00 前言 随着物联网IOT的飞速发展,各类嵌入式设备, 路由器安全研究也越来越火. 但因为跟以往纯软件安全研究的要求不同, 这类研究往往需要结合相应的硬件知识. 很多朋友困惑如何开始, 甚至卡在 ...

  9. The ShortCuts in the ADT (to be continued)

    1. automatically add all the namespace which need to be include in the class. ctrl+shift+o

  10. 算法导论----VLSI芯片测试; n个手机中过半是好的,找出哪些是好手机

    对于分治(Divide and Conquer)的题目,最重要是 1.如何将原问题分解为若干个子问题, 2.子问题中是所有的都需要求解,还是选择一部分子问题即可. 还有一点其实非常关键,但是往往会被忽 ...