详解C语言可变参数列表(stdarg头文件及其定义的宏)

news2024/7/6 21:09:36

        前言:在一些函数定义时,()内的参数并不是所有的函数参数都是唯一的,如printf函数的定义

这里的省略号就代表printf函数的参数是可以变化的,而对于一些函数其参数是固定的,如strlen

之所以有这样的不同,主要还是因为函数的作用不同,printf函数需要打印多个不同类型的数据,而strlen函数是计算字符串长度,只需要传递字符串地址即可。使用可变参数列表可以很好的解决我们的需求,而可变参数列表的实现是通过头文件<stdarg>实现的,下面就来详细介绍;

2.stdarg头文件的介绍

        基本概念:定义宏,来处理未知类型,未知参数个数的函数

         使用方法:在基本参数之后添加...来代表未知的类型,未知的参数个数

va_list  的介绍

  原型:               typedef char* va_list;

    va_list是一种指向可变参数列表的指针(注意:是指向整个可变参数列表的指针,并没有指向第一个参数,指向第一个参数需要通过va_start来实现)

        va_list arg;定义了一个数据类型为va_list的变量arg,用于进行可变参数列表的操作

va_start 的介绍

        原型:           void va_start(va_list ap, last_arg);

         具体来说:va_start的参数有两个,第一个是va_list数据类型的变量(也就是一个指向可变参数列表的指针),第二个是可变参数列表前的最近的一个参数(也就是...之前的)

        作用:初始化可变参数列表,将指针指向可变参数列表的第一个参数,使程序能够一一访问可变参数列表的每一个参数:

        va_start(arg,num);num是我自己设置的函数参数(...之前的最近的一个参数)

    

va_arg 的介绍

        

        用法:获取可变参数列表的每一个参数,并将其返回,同时将指针指向下一个参数;

        va_arg(arg,double);

va_end的介绍

        

         作用:结束对可变参数列表的访问,并释放资源

2.一个简单的例子(求任意参数的平均数)

#include <stdio.h>
#include <stdarg.h>
/*函数声明部分*/
double average(int num, ...)
{
    /*定义一个可变参数列表*/
    va_list valist;

    /*初始化可变参数列表,使其指向可变参数列表的第一个参数*/
    va_start(valist, num);

    int i = 0;
    double sum = 0.0;//用于存储总和
    for (i = 0; i < num; i++)
    {
        /*访问可变参数列表的每一个值,并将其返回*/
        sum += va_arg(valist, double);
    }

    /*清理valist所占用的内存*/
    va_end(valist);
    return sum / num;
}
int main()
{
    /*存储任意参数*/
    double a = average(10, 12.0, 23.0, 34.0, 45.0, 56.0, 76.0, 32.0, 33.0, 11.0, 90.0);
    double b = average(5, 22.3, 44.2, 14.5, 66.3, 99.5);
    printf("平均值=%.2lf\n", a);
    printf("平均值=%.2lf\n", b);
    return 0;
}

总结: 利用可变参数列表的设计程序的步骤

1.编写相应的函数,在函数参数部分添加固定参数和...来表示可变参数列表;

2.定义一个va_list类型的变量,作为可变参数列表;

3.使用va_start来初始化可变参数列表,使指针指向可变参数列表的第一个参数;

4.使用va_arg不断访问可变参数列表的每一个参数,并获得其参数,同时指向下一个参数;

5.使用va_end来清理可变参数列表的内存,释放资源;

        Tip:使用时一定要注意格式,va_list后面直接跟可变参数列表的名称即可;va_start( , )第一个参数是列表名称,第二个是函数中的固定参数(比如上述代码的num);va_arg( , )第一个参数是列表名称,第二个参数是可变参数的数据类型;va_end()参数是列表名称;

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/532080.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Go-Benchmark入门-进阶篇(下)

接上文&#xff1a;Go-Benchmark入门-基础篇&#xff08;上&#xff09; 引言 本篇是进阶篇&#xff0c;围绕最佳实践&#xff0c;介绍项目中可能会用得上的一些技巧和科普更多的 benchmark 知识&#xff0c;也是对本人半个多月实践的一次总结和备忘。 go版本&#xff1a; …

CBA 总决赛激战正酣,线上观赛体验如何保证?

近日&#xff0c;许多球迷都在关注着 CBA 总决赛的激烈赛况。浙江队在征战 CBA 28 年后首次闯入总决赛&#xff0c;并将决赛主场放在了即将承办杭州亚运会正式比赛的奥体中心场馆&#xff0c;使得这轮系列赛成为了浙江篮球史上浓墨重彩的一笔。也难怪球迷现场观赛热情高涨&…

孙鑫VC++第四章 2.简单绘图-绘制

目录 1. 按键消息 2. 绘制线条 2.1 利用SDK全局函数实现画线功能 2.2 利用MFC的CDC类实现画线功能 2.3 利用MFC的CClientDC类实现画线功能 2.4 利用MFC的CWindowDC类实现画线功能 3. 在桌面窗口中画线 3.1 绘制彩色线条 4. 使用画刷绘图 4.1 简单画刷 4.2 位图画刷 …

vue+elementui+nodejs医院疫情防控管理系统3935y

语言 node.js 框架&#xff1a;Express 前端:Vue.js 数据库&#xff1a;mysql 数据库工具&#xff1a;Navicat 开发软件&#xff1a;VScode 互联网的飞速发展&#xff0c;使人们的生活离不开网络&#xff0c;医院的发展也同样是。现代医院中&#xff0c;不论大小都有各自的管…

想要快速开发东南亚市场?附见效快的方法

外贸人开发东南亚市场的超全指南&#xff0c;觉得有用的话&#xff0c;转发给身边的朋友哦&#xff5e; 一、8大开发东南亚客户的渠道 01 外贸客户开发系统 这个是目前主流的开发客户的渠道&#xff0c;也是效果最好的。可以根据产品关键字、HS编码、SCI编码通过在线数据库…

使用eclipse运行DBeaver源码

一、安装eclipse(rcp) 官网地址&#xff1a;https://www.eclipse.org/ 1、进入官网后点击downloads 2、点击Download Packages 3、选择版本&#xff1a;Eclipse IDE for RCP and RAP Developers 4、选择合适的镜像进行下载 5、找到下载的文件进行解压 6、找到解压后的文件…

Netty实战(一)

Nett的概念及体系结构 第一章 Java网络编程1.1 Java NIO1.2 选择器 第二章 Netty是什么2.1 Netty简介2.2 Netty的特性2.2.1 设计2.2.2 易于使用2.2.3 性能2.2.4 健壮性2.2.5 安全性2.2.6 社区驱动 2.3 Netty的使用者2.4 异步和事件驱动2.4.1 异步2.4.2 异步和伸缩性 第三章 Net…

企业缺少成本票的三个解决方式!

业务是流程&#xff0c;财税是结果&#xff0c;税收问题千千万&#xff0c;关注《税算盘》来帮你找答案。 成本票指的是计入要素费用的票据&#xff0c;主要是指直接或是间接计入生产成本或制造费用等多方面的发票和票据。简单来说成本票&#xff0c;就是企业销售商品后提供服…

MyBatis Plus 插件

一、分页插件 多个插件的情况下分页插件需要放到最后执行 1.1、增加分页插件配置 package com.xx.config;import com.baomidou.mybatisplus.annotation.DbType; import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor; import com.baomidou.mybatisplu…

IT项目管理工具推荐:选择最适合你的优秀工具

国际数据公司的一份报告指出&#xff0c;25%的IT项目彻底失败&#xff0c;这还不包括需要返工的50%的项目&#xff0c;也不包括20-25%未能提供投资回报的项目。众所周知&#xff0c;管理IT项目有很多挑战。以下是最常见的挑战&#xff1a; 1.学习曲线大 挑战&#xff1a; 由于I…

c#与NPOI

简介 操作指南 某些API参考 视频讲解 完整代码 1、简介 NPOI是源于一个用于读取xls,doc,ppt文档的POI 项目&#xff0c;POI是Java项目&#xff0c;后面因为有.Net的市场&#xff0c;于是将POI移植到.Net上。Npoi 可以在没有安装Office 的情况写 对 Word 或 Excel 文档进行读写…

《如何向ChatGPT提问并获得高质量的答案》—Prompt技术的完整指南

本教程收集于:AIGC从入门到精通教程 目录 第1章:提示工程技术简介 第2章:说明提示技术(Instructions Prompt Technique)

OpenPCDet系列 | 5.3 PointPillars算法——BaseBEVBackbone伪图像特征提取模块

文章目录 BaseBEVBackbone模块1. BaseBEVBackbone初始化2. BaseBEVBackbone前向传播 OpenPCDet的整个结构图&#xff1a; BaseBEVBackbone模块 在进行了bev视图的特征转换后&#xff0c;随后进行backbone2d模块进行进一步的特征处理&#xff0c;在PointPillars中选择的是Bas…

AI绘画小程序开发流程

最近市场上出现了很多AI绘画的小程序和APP&#xff0c;这些小程序使用起来非常方便&#xff0c;用户体验也不错&#xff0c;可以解决一部分用户的实际需求。今天和大家分享如何开发一个AI类的绘画小程序以及要注意的问题&#xff0c;希望对大家有所帮助。北京木奇移动技术有限公…

电脑蓝屏怎么U盘重装系统详细图文教学

电脑蓝屏怎么U盘重装系统详细图文教学。很多用户遇到电脑蓝屏的问题之后&#xff0c;不懂怎么去进行问题的解决。蓝屏问题其实自己制作一起启动盘就可以轻松的解决问题了。一起来看看以下的详细处理方法分享吧。 准备工作&#xff1a; 1、U盘一个&#xff08;尽量使用8G以上的U…

如何获取和制作免费的icon图标素材

icon 图标在界面设计中虽然占比不大&#xff0c;但却是不可缺少的设计元素之一。设计师通过 icon 图标&#xff0c;将抽象的概念通俗化&#xff0c;降低用户理解某个操作的难度。而设计师也会通过改变 icon 图标的样式来展现整体界面的视觉效果。icon 图标的风格有很多&#xf…

Linux gdb调试

使用gdb进行调试 我们将使用GNU的调试器gdb调试这个程序。gdb是一个功能很强大的调试器&#xff0c;它是一个自由软件&#xff0c;能够用在许多UNIX平台上。它同时也是Linux系统中的默认调试器。gdb已被移植到许多其他的计算机平台上&#xff0c;并且能够用于调试嵌入式实时系统…

(转载)从0开始学matlab(第6天)—数据文件与运算

1数据文件 有许多的方法用于加载和保存 MATLAB 的数据文件&#xff0c;这些方法后面进行介绍。在这里我们只向大家介绍最简单的 save 和 load 命令。 save 命令用于保存当前 MATLAB 工作区内的数据到一个硬盘文件。这个命令的基本形式如下 save filename var1 var2 var3 …

《拥抱AGI时代,电信日前省级电信公司的一次“非电信”培训》

数字信息基础设施是数字中国的关键底座&#xff0c;打通数字基础设施大动脉&#xff0c;建设数字中国成为推进中国式现代化的重要引擎。作为算力时代的探险家&#xff0c;出海浪潮的逐浪人&#xff0c;中国电信正全面融入数字经济建设大局&#xff0c;展现出新发展新格局下央企…

飞凌嵌入式技术帖——i.MX9352的GPIO怎么用?

之前小编为大家介绍过在飞凌嵌入式i.MX6ULL开发板上操作GPIO的方法。本期&#xff0c;让我们一起走近i.MX9352处理器&#xff0c;深入了解这位i.MX系列新成员的GPIO该如何操作&#xff0c;以及它与前辈i.MX6ULL处理器又有哪些异同。 01 硬件原理分析 以点灯和按键为例&#xf…