当前位置: 首页 > article >正文

C语言 - 可变参数函数 va_list、va_start、va_arg、va_end

目录

一、_INTSIZEOF宏分析

二、可变参数函数介绍

1、va_list

2、va_start

3、va_arg

4、va_end

三、使用介绍

示例1:

示例2:


一、_INTSIZEOF宏分析


#define _INTSIZEOF(n)   ((sizeof(n)+sizeof(int)-1)&~(sizeof(int) - 1) )

功能:获取n按照4字节的整数倍对齐后的字节数

分析:

  • (sizeof(n)+sizeof(int)-1) 相当于 sizeof(n) + 3
  • ~(sizeof(int) - 1) ) 相当于 ~(3),即:二进制 11111100

由此可知, ((sizeof(n)+sizeof(int)-1)&~(sizeof(int) - 1) ) 相当于 (sizeof(n) + 3) / 4 *4,因此 _INTSIZEOF(n) 作用是将n的字节数按照 sizeof(int) 的整数倍进行对齐。

二、可变参数函数介绍


头文件:stdarg.h

1、va_list

va_list ap;    //ap指针

功能:va_list 表示可变参数列表类型,实际上就是一个char指针

2、va_start

#define va_start(ap,v) ( ap = (va_list)&v + _INTSIZEOF(v) )

功能:va_start用于获取函数参数列表中可变参数的首指针(获取函数可变参数列表)

当调用va_start(ap, param1) 后,ap指针指向 param1后的第一个可变参数

3、va_arg

#define va_arg(ap,t) ( *(t *)((ap += _INTSIZEOF(t)) - _INTSIZEOF(t)) )

功能:va_arg用于获取当前ap所指的可变参数,并将ap指针移向下一可变参数

在执行va_start后ap指针指向了第一个可变参数,再调用va_arg返回当前ap指向的可变参数,并将ap指向下一个可变参数

4、va_end

#define va_end(ap) ( ap = (va_list)0 )

功能:清空va_list可变参数列表

三、使用介绍


示例1:

#define BUF_SIZE	16
void my_printf(const char *fmt, ...)
{
    char buf[BUF_SIZE];
    
    va_list ap;				//ap为指针
    va_start(ap, fmt);		//ap指向 fmt 后的第一个可变参数首地址
    vsnprintf(buf, BUF_SIZE, fmt, ap);	//buf存放 fmt格式化的字符串
    char *p = va_arg(ap, char *);	//调用va_arg取第一个可变参数值,并将ap指针指向下一个可变参数地址
    va_end(ap);
}

示例2:

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <stdarg.h> //头文件

/* */
int fun1(int num, ...)
{
    int i = 0;

    va_list ap;            //ap是个指针
    va_start(ap, num);     //ap指针指向a后的第一个可变参数首地址

    /* 打印所有可变参数 */
    for (i = 0; i < num; i++)
    {
        printf("param%d:[%d]\n", i, va_arg(ap, int));
    }
    va_end(ap);      //清理ap

    return num;
}

int main()
{
    fun1(2, 8, 9); // 2个参数,分别是8和9
    return 0;
}



http://www.kler.cn/a/504734.html

相关文章:

  • 基于光偏振与光学调制实现白光干涉相移
  • vue3 uiapp实现一个数字输入组件, 舒服非数字会默认转成最小数
  • HTML拖拽功能(纯html5+JS实现)
  • Springboot 注解缓存使用教程
  • 6.1 MySQL数字函数和条件函数
  • SpringBoot整合Easy-es
  • Linux ffmpeg 基础用法
  • python范围
  • django基于Hadoop的天气预报数据爬取与可视化分析
  • 【Sharding-JDBC学习】读写分离_shardjdbc5 不支持 shardingdatasource
  • DRV8311三相PWM无刷直流电机驱动器
  • 【Linux系统编程】——深入理解 GCC/G++ 编译过程及常用选项详解
  • C++并发编程之多线程环境下使用无锁数据结构的重要准则
  • Cesium中的CustomDataSource 详解
  • 【人工智能】大语言模型的微调:让模型更贴近你的业务需求
  • 【Python】Paho-MQTT:mqtt 信息收发
  • 40,【6】CTFHUB WEB SQL MYSQL数据库
  • rsarsa-给定pqe求私钥对密文解密
  • Day08-后端Web实战——JDBCMybatis
  • PanWeidb-使用BenchmarkSQL对磐维数据库进行压测
  • 比较之舞,优雅演绎排序算法的智美篇章
  • 数仓建模(六)从ODS到DWD、DWS、ADS
  • 过压保护电路
  • 查看linux 当前运行的 python脚本
  • Linux 系统资源监控笔记
  • MySQL表的创建实验