【C语言天天练(四)】可变参数函数

2024-04-20 12:38

本文主要是介绍【C语言天天练(四)】可变参数函数,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

引言:


        可变参数函数指可以接受可变数量参数的函数。比如printf函数就是一个可变参数函数。


编写:

         要完成可变参数函数的编写,需要用到定义于stdarg.h头文件中的一个类型va_list和三个宏va_start、va_arg、va_end。

         注意:

         1、可变参数必须从头到尾按照顺序逐个访问。如果在访问几个可变参数后想半途中止,这是可以的。但是,如果想一开始就访问列表中的参数,那是不行的。

         2、由于参数列表中的可变参数部分并没有原型,所以,所有作为可变参数传递给函数的值都将执行缺省参数类型提升。

         3、参数列表中的省略号,它提示此处可能传递数量和类型未确定的参数。省略号只能出现参数表的尾部。


        变长参数函数的关键在于如何处理一个甚至连名字都没有的参数表。标准头文件<starg.h>中包含一组宏定义,它们对如何遍历参数表进行了定义。

        va_list类型用于声明一个变量,该变量将依次引用各参数。

        va_start宏将va_list声明的变量初始化为指向第一个无名参数的指针。在使用变量之前,该宏必须被调用一次。参数表必须至少包括一个有名参数,va_start将最后一个有名参数作为起点。

        va_arg宏,调用该宏,该函数都将返回一个参数,并将声明的变量指向下一个参数。va_arg使用一个类型名来决定返回的对象类型、指针移动的步长。

        va_end宏,该宏必须在函数返回之前调用,以完成一些必要的清理工作。


程序示例:

#include <stdarg.h>
#include <stdio.h>/**计算平均值*/float
average(int n_values, ...)
{va_list	var_arg;int		count;float	sum = 0;va_start(var_arg, n_values);	/*准备访问可变参数׼       */for(count = 0; count < n_values; count+=1){sum += va_arg(var_arg, int);/*添加取自可变参数列表的值         ֵ*/	}va_end(var_arg);				/*完成处理可变参数       */return sum/n_values;
}void
main(int argc,  char **argv)
{printf("the average of 3 and 8 is %f\n", average(2, 3, 8));printf("the average of 3 and 8 and 11 is %f\n", average(3, 3, 8, 11));return;}

注意:


       C语言中的可变参数函数没有长度检查和类型检查,可能会被利用为攻击目标。设计函数时应先考虑替补方案。

这篇关于【C语言天天练(四)】可变参数函数的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/920279

相关文章

C语言中联合体union的使用

本文编辑整理自: http://bbs.chinaunix.net/forum.php?mod=viewthread&tid=179471 一、前言 “联合体”(union)与“结构体”(struct)有一些相似之处。但两者有本质上的不同。在结构体中,各成员有各自的内存空间, 一个结构变量的总长度是各成员长度之和。而在“联合”中,各成员共享一段内存空间, 一个联合变量

大语言模型(LLMs)能够进行推理和规划吗?

大语言模型(LLMs),基本上是经过强化训练的 n-gram 模型,它们在网络规模的语言语料库(实际上,可以说是我们文明的知识库)上进行了训练,展现出了一种超乎预期的语言行为,引发了我们的广泛关注。从训练和操作的角度来看,LLMs 可以被认为是一种巨大的、非真实的记忆库,相当于为我们所有人提供了一个外部的系统 1(见图 1)。然而,它们表面上的多功能性让许多研究者好奇,这些模型是否也能在通常需要系

【操作系统】信号Signal超详解|捕捉函数

🔥博客主页: 我要成为C++领域大神🎥系列专栏:【C++核心编程】 【计算机网络】 【Linux编程】 【操作系统】 ❤️感谢大家点赞👍收藏⭐评论✍️ 本博客致力于知识分享,与更多的人进行学习交流 ​ 如何触发信号 信号是Linux下的经典技术,一般操作系统利用信号杀死违规进程,典型进程干预手段,信号除了杀死进程外也可以挂起进程 kill -l 查看系统支持的信号

ABAP怎么把传入的参数刷新到内表里面呢?

1.在执行相关的功能操作之前,优先执行这一段代码,把输入的数据更新入内表里面 DATA: lo_guid TYPE REF TO cl_gui_alv_grid.CALL FUNCTION 'GET_GLOBALS_FROM_SLVC_FULLSCR'IMPORTINGe_grid = lo_guid.CALL METHOD lo_guid->check_changed_data.CALL M

java中查看函数运行时间和cpu运行时间

android开发调查性能问题中有一个现象,函数的运行时间远低于cpu执行时间,因为函数运行期间线程可能包含等待操作。native层可以查看实际的cpu执行时间和函数执行时间。在java中如何实现? 借助AI得到了答案 import java.lang.management.ManagementFactory;import java.lang.management.Threa

人工和AI大语言模型成本对比 ai语音模型

这里既有AI,又有生活大道理,无数渺小的思考填满了一生。 上一专题搭建了一套GMM-HMM系统,来识别连续0123456789的英文语音。 但若不是仅针对数字,而是所有普通词汇,可能达到十几万个词,解码过程将非常复杂,识别结果组合太多,识别结果不会理想。因此只有声学模型是完全不够的,需要引入语言模型来约束识别结果。让“今天天气很好”的概率高于“今天天汽很好”的概率,得到声学模型概率高,又符合表达

SQL Server中,isnull()函数以及null的用法

SQL Serve中的isnull()函数:          isnull(value1,value2)         1、value1与value2的数据类型必须一致。         2、如果value1的值不为null,结果返回value1。         3、如果value1为null,结果返回vaule2的值。vaule2是你设定的值。        如

Windows 可变刷新率是什么?如何开启?

在现代计算设备中,显示屏的刷新率对用户体验起着至关重要的作用。随着显示技术的不断进步,固定刷新率显示器逐渐被支持可变刷新率(Variable Refresh Rate, VRR)技术的显示器所取代。 可变刷新率定义 可变刷新率是什么?可变刷新率(VRR)是一种显示技术,它允许显示器的刷新率动态调整,以匹配显卡输出的帧率。传统的显示器通常具有固定的刷新率(如60Hz、75Hz等),这意味着显示器

C语言 将“China”译成密码

将“China”译成密码,密码规律是:用原来的字母后面的第4个字母代替原来的字母。例如,字母“A”后面的第4个字母是“E”,用“E”代替“A”。因此,“China”应译为“Glmre”。编译程序用付赋初值的方法使c1,c2,c3,c4,c5这五个变量的值分别为“C”,“h”,“i”,“n”,“a”,经过运算,使c1,c2,c3,c4,c5分别变成“G”,“l”,“m”,“r”,“e”。分别用put

tf.split()函数解析

API原型(TensorFlow 1.8.0): tf.split(     value,     num_or_size_splits,     axis=0,     num=None,     name='split' ) 这个函数是用来切割张量的。输入切割的张量和参数,返回切割的结果。  value传入的就是需要切割的张量。  这个函数有两种切割的方式: 以三个维度的张量为例,比如说一