fmt与##__VA__ARGS__

2023-12-01 18:44
文章标签 fmt args va ##__

本文主要是介绍fmt与##__VA__ARGS__,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

在宏定义中,fmt是一个占位符,用于表示格式字符串。fmt可以是一个字符串字面量,也可以是一个参数。

而##__VA_ARGS__是一个可变参数宏定义的特殊标记,用于表示可变数量的额外参数。##是连接符,用于将前面的内容和后面的额外参数连接起来。

举例:

#include <stdio.h>#define PRINT_MESSAGE(fmt, ...) printf(fmt, ##__VA_ARGS__)int main() {int num1 = 10;int num2 = 20;float price = 5.99;char name[] = "John";PRINT_MESSAGE("Number1: %d Number2 :%d\n", num1,num2);PRINT_MESSAGE("The price is %.2f\n", price);PRINT_MESSAGE("Name: %s\n", name);return 0;
}

关于格式化字符串:
printf 函数的第一个参数就是格式字符串。例如,上面的Number1: %d Number2 :%d\n

关于…和__VA_ARGS__

  • … 是在函数或宏的参数列表中使用,表示该函数或宏可以接受可变数量的参数。它用于声明函数或宏的参数,并将实际传递的参数列表与之匹配。注意,... 它不能在宏的展开中使用。
  • ##VA_ARGS 是在宏定义中使用的特殊标记,用于表示可变参数的展开。它用于展开可变参数,并将展开后的参数列表与其前面的内容连接起来。## 是连接符,用于在没有额外参数时确保宏定义仍然有效。

在上面的示例中,… 是宏定义中的参数,表示宏可以接受可变数量的参数(例如,fmt 后面的参数)。而 ##VA_ARGS 是宏定义中的展开语法,用于将前面的内容和可变参数展开连接起来。通过使用 ##VA_ARGS,即使没有额外的参数传递给宏,宏定义仍然有效。

利用宏进行log分级的代码展示:

#include <stdio.h>#define ERROR 1
#define INFO 2#define logLevel(Group, fmt, ...) \
do {                             \switch (Group) {              \case ERROR:              \printf("ERROR: ");   \break;               \case INFO:               \printf("INFO: ");    \break;               \default:                 \printf("unknown ");   \}                            \printf(fmt, ##__VA_ARGS__);  \
} while (0)           int main() {logLevel(ERROR, "Something went wrong.\n");logLevel(INFO, "Information message: %s\n", "Details");logLevel(3, "Something went wrong.\n");return 0;
}

打印:

ERROR: Something went wrong.
INFO: Information message: Details
unknown Something went wrong.

这篇关于fmt与##__VA__ARGS__的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



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

相关文章

yolov8代码记录---(tasks.py中的c1、c2和args) / (断点续训)

一、task中的c1、c2和args参数解析 如果你想在yolov8中修改或添加 新的结构块,基本都会修改到task.py中的c1、c2和args参数。 此处以Conv所在的判断分支代码为例: if m in (Classify, Conv, ConvTranspose, ..., C3x, RepC3):c1, c2 = ch[f], args[0]if c2 != nc:c2 = make_

template<typename ... _Args>可变参数模板

template<typename ... _Args> 是一种用于定义可变参数模板(variadic template)的语法。这种模板允许你在编译时处理数量可变的参数列表。这种特性非常有用,尤其是在需要处理不确定数量的参数时。 #include <iostream>// 可变参数模板函数template<typename... Args>void print(Args... args

函数的参数*args和**kwargs

1 问题 本文将分析函数的参数*args和**kwargs。 2 方法 不定长元祖参数*args;不定长元祖参数,就是不确定数量的参数,定义一个参数把传入的参数组合成元祖,来接受函数调用时传递过来的N个参数,在函数体内以元祖形式按顺序读取。代码清单 1 def hanshu(a,*args):    print("formal arg:",a)    for arg in args:

【c语法】##__VA_ARGS__与__VA_ARGS__

欢迎来到 破晓的历程的 博客 ⛺️不负时光,不负己✈️ 文章目录 引言__VA_ARGS__ 引言 在调试过程中,我们经常会自定义打印,比如日志信息的输出,这时就会用VA_ARGS,接下来详细讲解! VA_ARGS __VA_ARGS__是C语言设定的一个预定义宏,用于处理可变参数的参数列表。通常用在宏定义中,以便宏可以接收不定数量的参数,并将他们

vscode 调试python代码时添加参数(args)

https://blog.csdn.net/zk0272/article/details/83105574

初学go语言println() vs fmt.Println

初学Go语言,会不会有如下疑问? // test.gopackage mainimport ("fmt""unsafe")const (Unknown = "abc_const"Female = len(Unknown)Male = unsafe.Sizeof(Female))// const (// a = iota// b// c// )const (a = io

C++11参数包...Args

以list中的包装器做介绍 包装器是由一个类模板接收后存储在统一的...Args中 标准格式 说明:...Args就是参数包的类型 实例:  //参数包void Show(){cout <<"结束" << endl;}template<class T,class ...Args>void Show(T& val ,Args... args2){cout <<

*args和**kwargs这个在python中的意思

1、**kwargs 在Python中,是一个用于解包字典的操作符。当在函数调用时使用时,它会将字典中的键值对解包为关键字参数传递给函数。这样可以方便地将字典中的数据作为关键字参数传递给函数。 例如,如果有一个字典data = {'a': 1, 'b': 2},可以使用**data将字典解包为关键字参数传递给函数: def my_function(a, b):print(a, b)data

JSTL fmt:formatNumber 数字、货币格式化

JSTL fmt:formatNumber 数字、货币格式化 <fmt:formatNumber value="12" type="currency" pattern="$.00"/> -- $12.00 <fmt:formatNumber value="12" type="currency" pattern="$.0#"/> -- $12.0 <fmt:formatNumbe

java中为什么main方法是public static void main(String [] args)

问题 为什么java的main方法是 public static void main(String [] args),为什么要用public 、static、void 修饰 当然也可以这样写 public static void main(String... args)  问题解答 main 方法是Java程序的入口,在java运行时,jvm会寻找类中的public static