2. 程序中的顺序点
(1) 顺序点简介
顺序点介绍 :
1.顺序点位置 : 顺序点存在于程序之中;
2.顺序点定义 : 顺序点是 代码 执行过程中, 修改变量值 的 最晚时刻 ;
3.顺序点操作 : 程序运行到顺序点时, 之前的代码操作 都要反映到后续访问中 ;
顺序点列举 :
1.表达式结束 : 每个表达式结束都是顺序点, 以分号 “;” 结尾, 每个分号的位置都是顺序点;
2.某些表达式的运算对象计算 : &&, || (逻辑运算), ? :(三目运算符), 逗号 表达式 中每个 运算对象计算后 是顺序点;
3.函数运行前 : 函数调用并且在执行函数体之前, 所有实际参数求值完之后是一个顺序点, 如参数是表达式, 需要将表达式计算出结果;
顺序点代码示例 :
#include <stdio.h> int fun(int i, int j) { printf("%d, %d\n", i, j); } //注意 : 这个知识点可能过时, k = k++ + k++; 在 Ubuntu 中执行结果是 5 int main() { //顺序点 : 在 k = 2; 表达式以分号结束, 这是一个顺序点 int k = 2; int a = 1; /* 顺序点 : 分号结尾处是顺序点, 该顺序点 第 1 个 k++, 计算时 k 先是 2, 自增操作到顺序点时执行; 第 2 个 k++, 计算时 k 还是 2, 自增操作到顺序点时执行; 加法计算完毕后 k 变成 4, 两次自增后变为 6 */ k = k++ + k++; printf("k = %d\n", k); /* a-- && a 进行逻辑运算, 其中 && 是顺序点, a-- 在 && 时执行 自减操作, 然后 a-- 结果变成了 0, a 的值也变成了 0, 进行逻辑与操作结果为 0 */ printf("a--&&a = %d\n",a--&&a); return 0; } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
3. C 语言 函数 的 缺省认定
(n) 标题3
函数缺省认定简介 :
1.描述 : C 语言中 默认 没有类型的 参数 和 返回值 为 int 类型;
2.举例 :
fun(i) { return i } 1 2 3 4 等价于 int fun(int i) { return i; } 1 2 3 4
3.代码示例 :
#include <stdio.h> //函数缺省认定 : 没有类型的 参数 和 返回值 为 int 类型 fun(i, j) { return i + j; } int main() { printf("fun(i, j) = %d\n",fun(3, 3)); return 0; } 1 2 3 4 5 6 7 8 9 10 11 12 13 14
4.可变参数 的 定义 和 使用
(1) 简介
可变参数简介 :
1.描述 : 函数可以接收的参数个数是不定的, 根据调用的需求决定有几个参数;
2.依赖头文件 : 如果要使用可变参数, 需要导入 stdarg.h 头文件;
3.核心用法 : va_list, va_start, va_end, va_arg 配合使用, 访问可变参数值;
可变参数示例 :
1.函数名相同, 参数个数不同 : open 函数, 有两种用法, 一个有 2 个参数 int open(const char *pathname, int flags) , 一个有三个参数 int open(const char *pathname, int flags, mode_t mode) , C 语言中明显没有重载, 这里是用可变参数来实现的 ; 使用 man 2 open 命令查看 open 函数的文档;
可变参数的注意点 :
1.取值必须顺序进行 : 读取可变参数的值时, 必须从头到尾按照前后顺序读取, 不能跳过任何一个参数;
2.必须确定1个参数 : 参数列表中必须有一个命名确定的参数;
3.可变参数数量无法确定 : 使用 va_arg 获取 va_list 中的值时, 无法判断实际有多少个参数;
4.可变参数类型无法确定 : 使用 va_arg 获取 va_list 中的值时, 无法判断某个参数是什么类型的;
依次读取可变参数时, 注意 可变参数 的 数量 和 类型, 每个位置的参数 是 什么类型, 一定不要读取错误, 否则会产生不可预测的后果;
(2) 代码示例 ( 定义 使用 可变参数 )
代码示例 :
1.代码 :
#include <stdio.h> #include <stdarg.h> /* 定义可变参数 : ① 列出第一个参数 int a ② 使用 ... 表明后面有 个数不定 并且 类型不定 的 参数 */ double avg(int arg_count, ...) { va_list args; int i = 0; //循环控制变量 double sum = 0; //统计参数之和 //初始化列表, 让列表准备取值 va_start(args, arg_count); for(i = 0; i < arg_count; i ++) { //从可变参数列表中获取数据, 数据类型是 int 类型 sum = sum + va_arg(args, int); } //结束使用可变参数列表 va_end(args); return sum / arg_count; } int main() { //使用定义了可变参数的函数, 传入 11 个参数 printf("%f\n", avg(10, 1, 2, 3, 4, 5 , 6, 7, 8, 9, 10)); //使用定义了可变参数的函数, 传入 4 个参数 printf("%f\n", avg(3, 444, 555, 666)); return 0; } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39
2.编译运行结果 :