第9章 函数再探

文章目录

函数指针

// 指定返回值和参数
int (*p)(int i);
p(1);
// 可以使用函数名赋值
p = fun;
// 函数指针 数组
int (*p[10])(int i);
// 初始化 多个函数名
int (*p[10])(int i)={a, b, c};
// 省略维度的初始化
int (*p[])(int i)={a, b, c};

函数指针作为参数

函数中的变量

自动变量

自动创建和销毁

静态变量

static
退出函数后 变量不销毁 仅初始化一次
默认初始化为0
仅在声明的语句块可见

全局变量

默认初始化为0
在函数外声明 所有函数均可使用

静态变量 自动变量会隐藏全局变量

递归

参数可变函数

stdarg.h

函数原型

int test(int i, int j, ...);

至少有一个固定参数

获取参数 宏

va_list
va_start()
va_arg()
va_end()
va_copy() 复制剩余的参数
不要在一个备份释放之前 使用它去复制另一个list
在最后传入 0或NULL 确保正确结束循环

可变参数函数要求

  1. 至少一个固定变元
  2. 添加哨兵值 保证循环正常结束
  3. va_arg()可以获取指针值
  4. 必须va_end()

main()函数参数

// argc 参数个数+1 包含程序名
// argv 字符串形式的参数
// 含空格的参数 要使用双引号引起来
int main(int argc, char * argv[])

结束程序

stdlib.h

abort()

不正常结束 没有参数 没有返回值
清空输出缓冲区 关闭打开的流

exit(int)

正常结束
清空输出缓冲区 关闭打开的流
0 EXIT_SUCCESS 结束成功
EXIT_FAILURE 结束失败

atexit()

注册exit()调用的函数 成功返回0
最多32个函数
逆序调用 FILO

_Exit()

同exit() 不调用注册函数

quick_exit(int)

正常结束
调用_Exit(int)

at_quick_exit()

注册quick_exit()调用的函数
逆序调用 FILO

exit()和quick_exit()之间相互独立注册的函数互不影响

提高性能

inline

给编译器的提示 不保证效果
短函数调用编译方式
内联声明函数

inline int add(int i, int j){
	return i + j;
}

restrict

给编译器的提示 不保证效果
指针无别名 编译器改变计算顺序 优化代码

char * strcpy_s(char * restrict str1, char * restrict str2);

_Noreturn

永远不返回
编译器省略吧控制前返回调用点需要的代码和存储空间
stdnoreturn.h noreturn宏 _Noreturn

_Noreturn void finish(){
	exit(EXIT_SUCCESS);
}
上一篇:VirtualAPP技术应用及安全分析报告


下一篇:C Programming Test And Answer 02