数学函数
“非局部跳转”
在该头文件中定义了一种特别的函数调用和函数返回顺序的方式。这种方式不同于以往的函数调用和返回顺序,
它允许程序流程立即从一个深层嵌套的函数中返回。
中定义了两个宏:
int setjmp(jmp_buf env); /*设置调转点*/
longjmp(jmp_buf jmpb, int retval); /*跳转*/
宏setjmp的功能是将当前程序的状态保存在结构env ,为调用宏longjmp设置一个跳转点。setjmp将当前信息保存在env中供longjmp使用。其中env是jmp_buf结构类型的。
Demo :
#include
#include
static jmp_buf buf;
void second(void) {
printf("second\n");
// 打印
longjmp(buf,1);
// 跳回setjmp的调用处
- 使得setjmp返回值为1
}
void first(void) {
second();
printf("first\n");
// 不可能执行到此行
}
int main() {
if ( ! setjmp(buf) ) {
first();
// 进入此行前,setjmp返回0
} else {
// 当longjmp跳转回,
setjmp返回1,因此进入此行
printf("main\n");
// 打印
}
return 0;
}
直接调用setjmp时,返回值为0,这一般用于初始化(设置跳转点时)。以后再调用longjmp宏时用env变量进行跳转。程序会自动跳转到setjmp宏的返回语句处,此时setjmp的返回值为非0,由longjmp的第二个参数指定。
一般地,宏setjmp和longjmp是成对使用的,这样程序流程可以从一个深层嵌套的函数中返回。
信号
在signal.h头文件中,提供了一些函数用以处理执行过程中所产生的信号。
宏:
SIG_DFL
SIG_ERR
SIG_IGN
SIGABRT
SIGFPE
SIGILL
SIGINT
SIGSEGV
SIGTERM
函数:
signal();
raise();
变量:
typedef sig_atomic_t
sig_atomic_t类型是int类型,用于接收signal函数的返回值。
以SIG_开头的宏用于定义信号处理函数
SIG_DFL 默认信号处理函数。
SIG_ERR表示一个错误信号,当signal函数调用失败时的返回值。
SIG_IGN信号处理函数,表示忽略该信号。
SIG开头的宏是用来在下列情况下,用来表示一个信号代码:
SIGABRT异常终止(abort函数产生)。
SIGFPE浮点错误(0作为除数产生的错误,非法的操作)。
SIGILL非法操作(指令)。
SIGINT交互式操作产生的信号(如CTRL - C)。
SIGSEGV无效访问存储(片段的非法访问,内存非法访问)。
SIGTERM终止请求。
signal函数
void(*signal(int sig,void (*func)(int)))(int);
上面的函数定义中,sig 表示一个信号代码(相当于暗号类别),即是上面所定义的SIG开头的宏。当有信号出现(即当收到暗号)的时候,参数func所定义的函数就会被调用。如果func等于SIG_DFL,则表示调用默认的处理函数。如果等于SIG_IGN,则表示这个信号被忽略(不做处理)。如果func是用户自定义的函数,则会先调用默认的处理函数,再调用用户自己定义的函数。 自定义函数,有一个参数,参数类型为int,用来表示信号代码(暗号类别)。同时,函数必须以return、abort、exit 或 longjump等语句结束。当自定义函数运行结束,程序会继续从被终止的地方继续运行。(除非信号是SIGFPE导致结果未定义,则可能无法继续运行)
如果调用signal函数成功,则会返回一个指针,该指针指向为所指定的信号类别的所预先定义的信号处理器。
如果调用失败,则会返回一个SIG_ERR,同时errno的值也会被相应的改变。
raise 函数
int raise(int sig);
发出一个信号sig。信号参数为SIG开头的宏。
如果调用成功,返回0。否则返回一个非零值。
可变参数
头文件定义了一些宏,当函数参数未知时去获取函数的参数
变量:typedef va_list
宏:
va_start()
va_arg()
va_end()
变量和定义
va_list类型通过stdarg宏定义来访问一个函数的参数表,参数列表的末尾会用省略号省略
声明:void va_start(va_list ap, last_arg);
用va_arg和va_end宏初始化参数ap,last_arg是传给函数的固定参数的最后一个,省略号之前的那个参数 注意va_start必须在使用va_arg和va_end之前调用
声明:type va_arg(va_list ap, type);
用type类型扩展到参数表的下个参数
注意ap必须用va_start初始化,如果没有下一个参数,结果会是undefined
声明:void va_end(va_list ap); 允许一个有参数表(使用va_start宏)的函数返回,如果返回之前没有调用va_end,结果会是undefined。参数变量列表可能不再使用(在没调用va_start的情况下调用va_end)
一些常数,类型和变量
头文件定义了一些标准定义,许多定义也会出现在其他的头文件里
宏命令:NULL 和 offsetof()
变量:
typedef ptrdiff_t
typedef size_t
typedef wchar_t
变量和定义:
ptrdiff_t是两个指针相减的结果
size_t是sizeof一个关键词得到的无符号整数值
wchar_t是一个宽字符常量的大小,是整数类型
NULL是空指针的常量值
offsetof(type, member-designator);这个宏返回一个结构体成员相对于结构体起始地址的偏移量(字节为单位),type是结构体的名字,member-designator是结构体成员的名字。