深入C语言——实现可变参数函数
文章目录
- 初步示例
- 函数解析
- 最大值函数
初步示例
stdarg.h提供了C语言对可变参数的支持,先举一个简短的例子
//testStdArg.c
#include <stdarg.h>
#include <stdio.h>void printIntList(int N, ...){va_list args; //存放...所代表的参数va_start(args, N); //初始化变量argsfor (int idx = 1; idx <= N; ++idx)printf("param %d: %d, ", idx, va_arg(args, int));printf("-----\n");va_end(args);
}int main(void)
{printIntList(4,1,2,3,4);printIntList(4,1,2,3);printIntList(3,1,2,3,4);
}
编译之后输出结果为
>gcc testStdArg.c
>a.exe
param 1: 1, param 2: 2, param 3: 3, param 4: 4,
-----
param 1: 1, param 2: 2, param 3: 3, param 4: 4,
-----
param 1: 1, param 2: 2, param 3: 3,
-----
函数解析
其中,va_list为stdarg.h中声明的数据类型,用以存放...所代表的参数,在printIntList中,定义了va_list类型的args用于存储变量。
在stdarg.h中声明了三个函数,在上面的案例中都用上了,下面逐一解析
void va_start(va_list ap, last_arg)
- 用于初始化
ap变量,last_arg为最后一个参数的下标 - 对于函数
printIntList(4,1,2,3,4)而言,总共输入了5个参数,故其last_arg应该为4。
type va_arg(va_list ap, type)
- 逐个检索函数参数列表中类型为
type参数 - 在
printIntList中,va_arg被写在一个循环中,会逐个检索int型的参数 - 在
printIntList(4,1,2,3)中,由于N设为4,所以va_arg会检索4次,最后返回的4实际上是一个野指针。
void va_end(va_list ap)
- 在参数调用结束之后,应该调用
va_end来释放ap
最大值函数
有了这个函数,就可以实现多个参数求统计参数的功能,例如求最大值
//testMax
#include <stdarg.h>
#include <stdio.h>double getMax(int N, ...){va_list args;va_start(args, N);double val;double max = va_arg(args, double);for(int idx=2; idx <= N; ++idx){val = va_arg(args, double);max = max > val ? max : val;}va_end(args);return max;
}int main(void)
{double a = getMax(4,1.2,2.3,3.4,2.5);printf("%f", a);
}
测试结果如下
>gcc test.c
>a.exe
3.400000
最后留一个小作业,如何用C语言实现一个参数个数可变的复杂一点的应用,比如求标准差σ=1N∑i=1N(xi−xˉ)2\sigma=\sqrt{\frac1N\sum^N_{i=1}(x_i-\bar x)^2}σ=N1∑i=1N(xi−xˉ)2。
这里面的问题是,va_arg相当于是一个不断向前的迭代器,但并没有索引的功能,所以必须一次性取出,而不能跑多次循环。一个最直接的解决方案就是开一个数组或者链表,来缓存va_arg中的数据。
相关文章:
深入C语言——实现可变参数函数
文章目录初步示例函数解析最大值函数初步示例 stdarg.h提供了C语言对可变参数的支持,先举一个简短的例子 //testStdArg.c #include <stdarg.h> #include <stdio.h>void printIntList(int N, ...){va_list args; //存放...所代表的参数va_start(…...
41-Dockerfile-Dockerfile简介
Dockerfile简介前言Dockerfile 简介基础知识使用Dockerfile 构建镜像步骤Dockerfile 构建过程Dockerfile基本结构Dockerfile示例总结前言 本篇开始来学习下Dockerfile相关的用法 Dockerfile 简介 Dockerfile : 是用来构建 Docker 镜像的文本文件,是有一条条构建镜…...
【408】操作系统 - 刻骨铭心自测题1(上)
文章目录OS练习题第一部分:1:2:3:4:5:6:7:8:9:10:11:12:13:14:15:16:17&am…...
【老卫拆书】009期:Vue+Node肩挑全栈!《Node.js+Express+MongoDB+Vue.js全栈开发实战》开箱
今天刚拿到一本新书,叫做《Node.jsExpressMongoDBVue.js全栈开发实战》,做个开箱。 外观 先从外观上讲,这本是全新的未开封的,膜还在。 这本书介绍从技术原理到整合开发实战,以丰富的项目展现全栈开发的一个技巧。 …...
【LeetCode】动态规划总结
动态规划解决的问题 动态规划和贪心的区别: 动态规划是由前一个状态推导出来的; 贪心是局部直接选最优的。 动态规划解题步骤 状态定义:确定dp数组以及下标的含义状态转移方程:确定递推公式初始条件:dp如何初始化遍历…...
CAS详解.
CAS这个机制就给实现线程安全版本的代码,提供了一个新的思路,之前通过加锁,把多个指令打包成整体,来实现线程安全。现在就可以考虑直接基与CAS来实现一些修改操作,也能保证线程安全(不需要加锁)…...
Mock.js初步使用(浏览器端)
Mock.js:生成随机数据,拦截 Ajax 请求。官方地址:http://mockjs.com/第一个demodemo.html<!DOCTYPE html> <html> <head><meta charset"utf-8"><title>mockjs demo</title> </head> <…...
opencv保存图片
大家好,我是csdn的博主:lqj_本人 这是我的个人博客主页: lqj_本人的博客_CSDN博客-微信小程序,前端,python领域博主lqj_本人擅长微信小程序,前端,python,等方面的知识https://blog.csdn.net/lbcyllqj?spm1011.2415.3001.5343哔哩哔哩欢迎关注…...
【c++】数据类型
文章目录整型实型科学计数法sizeof关键字字符型字符串类型转义字符bool布尔类型c规定在创建一个变量或者常量时,必须要指定出相应的数据类型,否则无法给变量分配内存。 整型 作用:整型变量表示的是整数类型的数据。 实型 float f3.14; //默…...
Elasticsearch的写的底层原理
前面有一篇文章讲解了Elasticsearch的读写搜索过程,有的人感觉不太理解,今天我们再来看看这些过程的原理 写数据底层原理 首先是将数据写入到内存buffer中,在这里的时候,数据是搜索不到。他同时会将数据写入到translog日志文件中…...
【网络编程】Java中的Socket
文章目录前言socket是什么?Java中的SocketJava实现网络上传文件前言 所谓Socket(套接字),就是对网络中不同主机上的应用进程之间进行双向通信的端点的抽象。一个套接字就是网络上进程通信的一端,提供了应用层进程利用…...
有趣的Hack-A-Sat黑掉卫星挑战赛——跟踪卫星
国家太空安全是国家安全在空间领域的表现。随着太空技术在政治、经济、军事、文化等各个领域的应用不断增加,太空已经成为国家赖以生存与发展的命脉之一,凝聚着巨大的国家利益,太空安全的重要性日益凸显[1]。而在信息化时代,太空安…...
Ubuntu安装配置Cuda和Pytorch gpu
前言 在Ubuntu中操作系统中,通过Anconda安装对应的虚拟环境以及软件包,一般都需要适配Cuda、Pytorch版本等 以下安装配置都是在Ubuntu操作系统下 1. 安装Cuda 通过Ubuntu操作系统查看cuda适配的版本:nvidia-smi 截图如下: 查看Ubuntu版本可如下方式 (1)cat /proc/ver…...
三、Java面向对象
1 . 方法 方法(method)是程序中最小的执行单元方法就是一些代码的打包 需要的时候可以直接调用方法之间是平级的关系 不能在方法里面定义方法方法不调用就不执行 方法的定义 // 方法的定义 /* [修饰符] 返回值类型 方法名称([参数 1],[参数 2]){语句A;return 返回值; } *///…...
pygame7 弹球游戏2
上节课我们做到当球静止下来后在第0号球上画一个球杆 本节课我们将会让这个球杆将球打出来 1、鼠标事件 pygame.mouse.get_pressed():返回鼠标左键,中间,右键的情况 2、键盘事件: pygame.key.get_pressed(): 返回所有键盘的情况 3、pyg…...
计算机网络4:计算机网络体系结构
目录计算机网络体系结构1.网络模型2.每一层的代表含义2.1 OSI7层模型2.2 五层协议2.3 TCP/IP 四层协议3.数据在各层之间的传输过程4.为什么要进行分层计算机网络体系结构 1.网络模型 2.每一层的代表含义 2.1 OSI7层模型 (1)物理层:比特流–…...
1630_GNU的二进制分析工具nm简单使用探索
全部学习汇总: GreyZhang/toolbox: 常用的工具使用查询,非教程,仅作为自我参考! (github.com) GNU有一套二进制的分析工具,之前是用过objdump的,但是也没有系统掌握。如果做底层软件的设计,这些…...
【Redis】Redis高可用之Redis Cluster集群模式详解(Redis专栏启动)
📫作者简介:小明java问道之路,2022年度博客之星全国TOP3,专注于后端、中间件、计算机底层、架构设计演进与稳定性建工设优化。文章内容兼具广度深度、大厂技术方案,对待技术喜欢推理加验证,就职于知名金融公…...
1.8 正则表达式
正则表示式是用来匹配与查找字符串的,从网上爬取数据不可避免的会用到正则表达式。 Python 的表达式要先引入 re 模块,正则表达式以 r 引导。Re库主要功能函数函数说明re.search()在一个字符串中搜索匹配正则表达式的第一个位置,返回match对象…...
Postgresql 根据单列或几列分组去重row_number() over() partition by
Postgresql 根据单列或几列分组去重row_number() over() partition by 一般用于单列或者几列需要去重后进行计算值的 count(distinct(eid)) 可以 比如有个例子,需要根据名称,城市去筛选覆盖的道路长度,以月因为建立了唯一索引是ok的&#…...
利用ngx_stream_return_module构建简易 TCP/UDP 响应网关
一、模块概述 ngx_stream_return_module 提供了一个极简的指令: return <value>;在收到客户端连接后,立即将 <value> 写回并关闭连接。<value> 支持内嵌文本和内置变量(如 $time_iso8601、$remote_addr 等)&a…...
树莓派超全系列教程文档--(62)使用rpicam-app通过网络流式传输视频
使用rpicam-app通过网络流式传输视频 使用 rpicam-app 通过网络流式传输视频UDPTCPRTSPlibavGStreamerRTPlibcamerasrc GStreamer 元素 文章来源: http://raspberry.dns8844.cn/documentation 原文网址 使用 rpicam-app 通过网络流式传输视频 本节介绍来自 rpica…...
从WWDC看苹果产品发展的规律
WWDC 是苹果公司一年一度面向全球开发者的盛会,其主题演讲展现了苹果在产品设计、技术路线、用户体验和生态系统构建上的核心理念与演进脉络。我们借助 ChatGPT Deep Research 工具,对过去十年 WWDC 主题演讲内容进行了系统化分析,形成了这份…...
Java 8 Stream API 入门到实践详解
一、告别 for 循环! 传统痛点: Java 8 之前,集合操作离不开冗长的 for 循环和匿名类。例如,过滤列表中的偶数: List<Integer> list Arrays.asList(1, 2, 3, 4, 5); List<Integer> evens new ArrayList…...
P3 QT项目----记事本(3.8)
3.8 记事本项目总结 项目源码 1.main.cpp #include "widget.h" #include <QApplication> int main(int argc, char *argv[]) {QApplication a(argc, argv);Widget w;w.show();return a.exec(); } 2.widget.cpp #include "widget.h" #include &q…...
vue3 定时器-定义全局方法 vue+ts
1.创建ts文件 路径:src/utils/timer.ts 完整代码: import { onUnmounted } from vuetype TimerCallback (...args: any[]) > voidexport function useGlobalTimer() {const timers: Map<number, NodeJS.Timeout> new Map()// 创建定时器con…...
【HTML-16】深入理解HTML中的块元素与行内元素
HTML元素根据其显示特性可以分为两大类:块元素(Block-level Elements)和行内元素(Inline Elements)。理解这两者的区别对于构建良好的网页布局至关重要。本文将全面解析这两种元素的特性、区别以及实际应用场景。 1. 块元素(Block-level Elements) 1.1 基本特性 …...
SpringTask-03.入门案例
一.入门案例 启动类: package com.sky;import lombok.extern.slf4j.Slf4j; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cache.annotation.EnableCach…...
在Mathematica中实现Newton-Raphson迭代的收敛时间算法(一般三次多项式)
考察一般的三次多项式,以r为参数: p[z_, r_] : z^3 (r - 1) z - r; roots[r_] : z /. Solve[p[z, r] 0, z]; 此多项式的根为: 尽管看起来这个多项式是特殊的,其实一般的三次多项式都是可以通过线性变换化为这个形式…...
Web中间件--tomcat学习
Web中间件–tomcat Java虚拟机详解 什么是JAVA虚拟机 Java虚拟机是一个抽象的计算机,它可以执行Java字节码。Java虚拟机是Java平台的一部分,Java平台由Java语言、Java API和Java虚拟机组成。Java虚拟机的主要作用是将Java字节码转换为机器代码&#x…...
