C语言如何实现函数单个形参添加默认值

前言

(1)如果有嵌入式企业需要招聘湖南区域日常实习生,任何区域的暑假Linux驱动实习岗位,可C站直接私聊,或者邮件:zhangyixu02@gmail.com,此消息至2025年1月1日前均有效
(2)最近看到一个问题,关于C语言的函数形参是否能够有默认值的探讨。一开始,我个人认为,C语言的函数形参是不能有默认值的,后面不看不知道,一查吓一跳,发现还真的有这种玩法,在此推荐给大家。
(3)需要注意的是,如下方法要求在C99标准以上的编译器中使用。
(4)学习本文之前,建议先去了解一下C语言可变参数,这是本人往期讲解可变参数的博客:
<1>如何编写一个可变参数函数?如何让所有单片机的所有串口实现printf函数?
<2>单片机如何实现日志等级打印(适用于多线程,多串口)

理论讲解

(1)如果学习过C++的朋友都知道,在C++中,函数有一个默认参数。在C语言中,我们能否也实现默认参数呢?

“__ VA_ARGS __”宏介绍

(1)我们都知道,C语言的函数存在可变参数,例如经典的printf()函数。有函数有可变参数,那么宏定义有没有可变参数呢?
(2)显然是有了,本文介绍的__ VA_ARGS __这个宏,就是用来传递可变参数列表的。使用方法如下:

#include <stdio.h>// 简单的可变参数宏,将可变参数打印到控制台
#define PRINT_VARIABLE_ARGS(format, ...)  printf(format, __VA_ARGS__)int main()
{// 使用宏打印不定数量的参数PRINT_VARIABLE_ARGS("Hello, %s! The sum is: %d\n", "John", 10+20);return 0;
}

(3)现在我们知道了__ VA_ARGS __这个宏的作用,那么又有什么实际意义呢?想要更详细了解的,请看单片机如何实现日志等级打印(适用于多线程,多串口)

“##”的用法

(1)对于__ VA_ARGS __这个宏,有一个特点,就是说,如果宏定义的可变列表...中没有传入任何值。__ VA_ARGS __就将会是一个空值。
(2)以上面的代码为例子,假如我们可变参数里面不传入任何值,将会出现如下问题

#include <stdio.h>// 简单的可变参数宏,将可变参数打印到控制台
#define PRINT_VARIABLE_ARGS(format, ...)  printf(format, __VA_ARGS__)int main()
{// 使用宏打印不定数量的参数PRINT_VARIABLE_ARGS("Hello world");return 0;
}
# 只进行预编译
gcc -E -P -o test.i test.c
# 编译
gcc test.c

在这里插入图片描述

(3)为了解决这个问题,我们可以使用##这个特殊的操作。如果可变参数被忽略或为空,##操作将使预处理器(preprocessor)去除掉它前面的那个逗号。例如我们将代码修改成如下,进入编译就能够成功通过。

#include <stdio.h>// 简单的可变参数宏,将可变参数打印到控制台
#define PRINT_VARIABLE_ARGS(format, ...)  printf(format, ##__VA_ARGS__)int main()
{// 使用宏打印不定数量的参数PRINT_VARIABLE_ARGS("Hello world");return 0;
}

在这里插入图片描述

逗号运算符

(1)我们要实现默认参数,还需要使用到逗号运算符。**逗号运算符的运算优先级会把逗号后边的值输出返回。**例如(123,321),最终输出的是321。

实现一个默认参数

(1)有了上面的基础,我们现在就可以实现一个函数默认参数了。
(2)实现多个形参的默认参数目前还没想到处理办法,现在就只能实现一个默认形参的默认参数。如果有大佬知道如何实现多个形参的默认参数,欢迎赐教。

C代码

(1)首先,我们创建一个C文件,里面输入如下内容。

#include <stdio.h>#define fun(...)    _fun((123, ##__VA_ARGS__));void _fun(int val)
{printf("fun input val:%d", val);
}int main()
{fun();printf("\r\n---\r\n");fun(321);
}

(2)执行代码,最终结果如下。

fun input val:123
---
fun input val:321

参考

(1)微信公众号:C语言怎么给函数添加形参的默认值
(2)C站:整理:C/C++可变参数,“## VA_ARGS”宏的介绍和使用
(3)C站:C语言中"#“和”##"的用法
(4)C站:C语言中逗号运算符怎么用?
(5)C站:单片机如何实现日志等级打印(适用于多线程,多串口)
(6)C站:如何编写一个可变参数函数?如何让所有单片机的所有串口实现printf函数?

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

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

相关文章

大话设计模式之简单工厂模式

简单工厂模式&#xff08;Simple Factory Pattern&#xff09;是一种创建型设计模式&#xff0c;属于工厂模式的一种。在简单工厂模式中&#xff0c;有一个工厂类负责根据输入参数的不同来创建不同类的实例。 简单工厂模式包含以下几个要素&#xff1a; 1. **工厂类&#xff0…

牛客的一道题(C)变种水仙花

描述&#xff1a; 变种水仙花数 - Lily Number&#xff1a;把任意的数字&#xff0c;从中间拆分成两个数字&#xff0c;比如1461 可以拆分成 &#xff08;1和461&#xff09;,&#xff08;14和61&#xff09;,&#xff08;146和1),如果所有拆分后的乘积之和等于自身&#xff…

Qlib-Server部署

Qlib-Server部署 介绍 构建Qlib服务器,用户可以选择: 一键部署Qlib服务器逐步部署Qlib服务器一键部署 Qlib服务器支持一键部署,用户可以选择以下两种方法之一进行一键部署: 使用docker-compose部署在Azure中部署使用docker-compose进行一键部署 按照以下步骤使用docker…

day72Html

常用标签&#xff1a; 分类&#xff1a; 块级标签&#xff1a;独立成行 行级标签&#xff1a;不独立成行&#xff0c;同一行可放多个行级标 注意网页显示时&#xff0c;忽略空白字符,(回车符&#xff0c;空格&#xff0c;tab制表符&#xff09; 一&#xff09;块级标签&#xf…

python中的deque详解

deque&#xff08;双端队列&#xff09;是Python标准库collections模块中的一个类&#xff0c;它支持从两端快速添加和删除元素。deque为固定大小或者可变大小的队列提供了线程安全的实现&#xff0c;并且它比使用列表&#xff08;list&#xff09;来实现相同的功能更为高效。 …

.NET core 5.0 及以上的Windows Service开发

首先&#xff0c;一定要和.NET Framework区分开&#xff0c; 详细请看微软的2023年的最新官方文档 Create Windows Service using BackgroundService - .NET | Microsoft Learn Create a Windows Service installer - .NET | Microsoft Learn 同样微软的官方微博给出了开发…

【明道云】如何让用户可以新增但不能修改记录

【背景】 遇到一个需求场景&#xff0c;用户希望新增数据后锁住数据不让更改。 【分析】 在设计表单时直接将字段设置只读是不行的。字段设置只读将会直接让界面上此字段的前端组件不可编辑。包括新增时也无法填入。显然是不符合需求的。 需要既能新增&#xff0c;新增后又不…

【WebJs 爬虫】逆向进阶技术必知必会

前言 在数字化时代&#xff0c;网络爬虫已成为一种强大的数据获取工具&#xff0c;广泛应用于市场分析、竞争对手研究、舆情监测等众多领域。爬虫技术能够帮助我们快速、准确地获取网络上的海量信息&#xff0c;为决策提供有力支持。然而&#xff0c;随着网络环境的日益复杂和…

猫,路由器,WIFI

家庭网络常识 1&#xff1a;猫、路由器、wifi_哔哩哔哩_bilibili 入户光纤插到猫上面&#xff0c;网线连接猫和路由器&#xff0c;网线连接路由器和电脑。路由器可以发射WIFI。 手机通过WIFI连接到路由器。 左边是猫&#xff0c;右边是光猫。 &#xff08;modem&#xff09; …

重学SpringBoot3-SpringBoot可执行JAR的原因

更多SpringBoot3内容请关注我的专栏&#xff1a;《SpringBoot3》 期待您的点赞&#x1f44d;收藏⭐评论✍ 重学SpringBoot3-SpringBoot可执行JAR的原因 Spring Boot可执行JAR的结构打包运行JAR 包内部结构 工作原理优点总结 Spring Boot 的一个核心特性是它的可执行 JAR&#x…

88. 合并两个有序数组(javascript)

给你两个按 非递减顺序 排列的整数数组 nums1 和 nums2&#xff0c;另有两个整数 m 和 n &#xff0c;分别表示 nums1 和 nums2 中的元素数目。 请你 合并 nums2 到 nums1 中&#xff0c;使合并后的数组同样按 非递减顺序 排列。 注意&#xff1a;最终&#xff0c;合并后数组…

QML通过鼠标拖动的位置

当通过鼠标拖动Rectangle 的位置时&#xff0c;可以使用Qt Quick的MouseArea组件来实现 Rectangle {id: rectx:0;y:0width: 200; height: 100color: "lightblue"MouseArea {id: mouseAreaanchors.fill: parentdrag.target: rect//要拖动的项目的IDdrag.axis: Drag.XA…

25G SFP28 AOC线缆最新数据传输解决方案

在当今云计算、大数据、人工智能等领域&#xff0c;对高速数据传输的需求不断增加。传统的1G和10G网络已经无法满足数据中心日益增长的流量&#xff0c;因此迫切需要更高速的解决方案。25G SFP28 AOC有源光缆迎合了这一需求&#xff0c;成为连接数据中心、服务器、存储等25G设备…

游戏客户客户端面经

C#和C的类的区别C# List添加100个Obj和100 int内存是怎么变化的重载和重写的区别&#xff0c;重载是怎么实现的重写是怎么实现的&#xff1f;虚函数表是类的还是对象的用过哪些C的STLVector底层是怎么实现的Vector添加一百次数据内存是怎么变化Map的底层&#xff0c;红黑树的查…

增强现实(AR)和虚拟现实(VR)营销的未来:沉浸式体验和品牌参与

--- 如何将AR和VR技术应用于营销&#xff0c;以提高品牌知名度、客户参与度 增强现实&#xff08;AR&#xff09;和虚拟现实&#xff08;VR&#xff09;不再只是游戏。这些技术为品牌与受众互动提供了创新的方式。营销人员可以创造更好的客户体验&#xff0c;并为身临其境的故…

华为Mate 60 Pro+是双卡双待吗 华为Mate 60 Pro+是4g还是5g手机

华为mate60 pro支持双卡双待&#xff0c;卡片类型为nano-SIM卡为全球首款搭载双星卫星通信的手机&#xff0c;支持天通卫星电话及双向北斗卫星消息。 华为mate60 pro支持5G网络 华为Mate 60 Pro搭载了华为自研的麒麟芯片&#xff0c;拥有强大的计算能力和出色的能效比。无论是…

蓝桥杯23年第十四届省赛真题-填充|DFS,贪心

题目链接&#xff1a; 1.填充 - 蓝桥云课 (lanqiao.cn) 蓝桥杯2023年第十四届省赛真题-填充 - C语言网 (dotcpp.com) 说明&#xff1a; dfs就不再多说了&#xff0c;对于每个?都有0和1两个分支&#xff0c;数据范围是&#xff1a; 那么有m个 ?&#xff0c;时间复杂度就是…

Redis部署中的问题总汇

前言&#xff1a;本文内容为实操记录&#xff0c;仅供参考&#xff01; Redis安装参考这篇文章&#xff1a;http://t.csdnimg.cn/G15Mv 本文是安装及使用过程中遇到的问题总结。 redis在解压完之后&#xff0c;使用make进行编译&#xff08;在安装目录进行编译&#xff09;。如…

2015年认证杯SPSSPRO杯数学建模B题(第二阶段)替换式密码全过程文档及程序

2015年认证杯SPSSPRO杯数学建模 B题 替换式密码 原题再现&#xff1a; 历史上有许多密码的编制方法。较为简单的是替换式密码&#xff0c;也就是将文中出现的字符一对一地替换成其它的符号。对拼音文字而言&#xff0c;最简单的形式是单字母替换加密&#xff0c;也就是以每个…

YOLOv9 实现多目标跟踪

YOLOv9项目结合了YOLOv9的快速目标检测能力和DeepSORT的稳定跟踪能力&#xff0c;实现了对视频流中多个对象的实时、准确检测和跟踪。在具体应用中&#xff0c;该项目能够对视频中的行人、车辆或其他物体进行实时定位、识别和持续跟踪&#xff0c;即使在复杂环境、对象互相遮挡…