C语言的可变参数函数理解与应用

2023-11-13

一、可变参数函数的理解

  1. 官方定义:C语言允许定义参数数量为可变的函数,这称为可变参数函数。它与传统意义上的强制定义固定参数的函数不同。
  2. 可变参数函数应用最广的是格式化输入输出函数。如printf,scanf。可支持任意参数输入输出。
  3. 可变参数函数可有助于我们封装printf函数。例如,可以指定打印到控制台或文件中。

二、可变参数函数的应用

        1、可变参数的常规打印

        直接参考代码,注释写的很清楚了。

        代码的核心也是通过vprintf打印到控制台。

#include <stdlib.h>
#include <stdio.h>
// 可变参数的头文件
#include <stdarg.h>

// 默认为打印到控制台
void script_log_error(char *fmt, ...)
{
    // 定义可变参数列表
    va_list ap;
    // 获取不定参数的首地址,首地址是从fmt开始
    va_start(ap, fmt);
    // 打印可变参数
    printf("数据为:");
    vprintf(fmt, ap);
    // 结束
    va_end(ap);

    printf("\n");
}

int main()
{
    // 使用可变参数的函数打印
	script_log_error("type is_3:%f,%s,%d hunhe5", 362.01, "123654", 50);
    script_log_error("type is_5: no data");
}

        2、可变参数的解析并打印

        解析主要分四步处理:

                1.通过循环遍历的方式,解析每个输入字符

                2.把%d、%f、%s作为关键字解析,并获取对应的数据。

                3.把修饰性字符与实际数据都转换成字符串并存储于二维数组中。

                4.把二维数组中的内容转换到一维数组中,然后打印一维数组。

#include <stdlib.h>
#include <stdio.h>
// 可变参数的头文件
#include <stdarg.h>

void script_dzlog_error(char *fmt, ...)
{
    va_list ap;
    char *p, *sval;
    int ival;
    double dval;
    // 存储修饰性字符
    char data_val[256] = {0};
    // 存储每一段数据
    char data[10][256] = {0};

    int idx_d1 = 0;
    int cnt_v = 0;

    // 获取不定参数的首地址,首地址是从fmt开始
    va_start(ap, fmt);
    for (p = fmt; *p; p++) {
        if(*p != '%') {
            // 获取修饰性字符
            data_val[cnt_v++] = *p;
            continue;
        }
        switch(*++p) {
        case 'd':
        {
            ival = va_arg(ap, int);
            char tmp[128] = {0};

            // 把修饰性字符复制到data中
            memcpy(&data[idx_d1++][0], data_val, sizeof(data_val));
            // 清空data_val
            memset(data_val, 0x00, sizeof(data_val));
            cnt_v = 0;

            // 把数据型字符复制到data中
            my_itoa(ival, tmp);
            memcpy(&data[idx_d1++][0], tmp, sizeof(tmp));

            break;
        }
        case 'f':
        {
            dval = va_arg(ap, double);
            char tmp[128] = {0};

            // 把修饰性字符复制到data中
            memcpy(&data[idx_d1++][0], data_val, sizeof(data_val));
            // 清空data_val
            memset(data_val, 0x00,
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

C语言的可变参数函数理解与应用 的相关文章

  • Skywalking-9.6.0系列之本地源码编译并启动

    Skywalking相信有很多人使用过 通过容器或者下载安装包进行安装的 今天从源代码角度 拉取 构建 启动 官方文档步骤简洁明了 我这边会结合自己遇到的一些问题做出总结 当前构建资源版本 MAC 10 15 7 IDEA 2021 2 n
  • 正版steam gta5如何免登录教程

    gta5中文叫做侠盗猎车手5 是一款围绕犯罪为主题的开放式动作冒险游戏 凭借其全新的雷霆引擎 不一样的战斗方式 乃至今日仍受到众多玩家的喜爱 这么受欢迎的游戏当然需要付费购买啦 这可让许多小伙伴们都望而止步 为了满足玩家们的游戏需求 小编此
  • 常用的加解密技术(2)

    公开密钥体系 公开密钥密码体制是现代密码学的最重要的发明和进展 一般理解密码学 Cryptography 就是保护信息传递的机密性 但这仅仅是当今密码学主题的一个方面 对信息发送与接收人的真实身份的验证 对所发出 接收信息在事后的不可抵赖以

随机推荐

  • python切片的总结

    目录 介绍切片 格式 1 切割单个值 2 切割完整对象 3 start和end全部取正数的情况 4 start和end全部取负数的情况 5 start和end正负混合情况 7 切片中的三个参数为表达式 8 切片可以操作其他的对象 总结 介绍
  • Centos7 防火墙详细操作

    centos7 通过firewall cmd命令添加防火墙白名单 1 查看防护墙状态 firewall cmd state 或 systemctl status firewalld active running gt 表示防火墙已经开启 i
  • iOS进阶_NSURLConnection(被弃用的原因:Connection的缺点)

    NSURLConnection下载 我们在前面的文章中介绍了MAC电脑搭建Apache服务器 在Sites文件夹中放置一个视频文件MVVM mp4 pbb 通过NSURLConnection进行下载 访问http localhost 我们可
  • 局部变量和静态局部变量

    一 局部变量 局部变量也叫auto自动变量 auto可写可不写 一般情况下代码块 内部定义的变量都是自动变量 它有如下特点 1 作用域 a 在一个函数内定义 只在函数范围内 也就是在定义变量的 之内 有效 b 在复合语句中定义 只在复合语句
  • 解决GridView控件的居中问题

    先简单介绍一下GridView控件 它被称为列表视图控件 用于在一个列表中显示数据源的值 其中每列表示一个字段 每行表示一条记录 简单来讲 就是一个列表 可以将数据源绑定到该列表控件上 在浏览器上显示出来就是存放着数据的列表 我在VS201
  • jetbrains IDE 关闭自动提示

    去掉Auto display code completion前面的对勾
  • python基础知识之函数的定义及用法

    目录 前言 一 函数的定义和调用 1 函数的作用 2 函数名的命名规范 3 函数的返回值 return 4 调用函数 二 函数的参数 1 函数形参和实参 2 参数传递的两种形式 3 函数定义的三种形参 三 函数的作用域 1 全局变量 2 局
  • Android 5.0学习之AnimatedVectorDrawable

    http blog csdn net cym492224103 article details 41677825 前言 示例代码地址 animated vector drawable 几句代码 几个配置文件即可实现以上效果 流畅的体验 无缝
  • replaceAll用法 (vue搜索框过滤数据高亮显示)

    举例 vue搜索框过滤数据高亮显示 在计算属性里面写一个方法 先用filter过滤item 然后用indexof方法查找是否包含 item name index0f this txt gt 1 indexof gt 1表示包含 this t
  • 01-不是过去的原因而是现在目的

    01 不是过去的原因而是现在目的 例1 如我们现在不敢或不喜欢与人交往的性格 甚至闭门不出 我们很自然的认识是受小时候在父母虐待下长大或父母关系不和 或在学校 职场收到耻辱 家庭环境等过去因素的影响而留下心灵创伤 也就是我们内心把原因归结为
  • 跨平台C/C++开发软件CLion使用教程:入门指南(二)

    本篇教程主要介绍 CLion 入门指南里关于协助编码的内容 点击获CLion官方正式版 自动完成 Ctrl SpaceCLion 中的基本补全在您键入时工作 并提供所有可用补全的列表 要过滤此列表并仅查看与预期类型匹配的建议 请使用智能完成
  • JAVA 练习题(4)

    数字资产的概念被提出来 用于给数字资产加密的业务变得非常火热 现有一套用于给数字资产加密的系统专门用于产生加密密码 请设计一个方法用于给数字密码进行加密 加密规则如下 根据数字长度的每位数 给每位数 5 再对10求余 最后将所有数字反转 得
  • 使用Electron来给若依系统打包成exe程序,出现登录成功但是不跳转页面(已解决)

    阿丹 之前解决了css找不到文件等问题 那么新问题就来了 问题描述 进入到登录页面发现问题 点击登录一直在转圈 但是不进去 更诡异的是 后台相应的很快 已经显示操作成功了 甚至 redis中都存了token了 并且前台的验证码图片还能正常访
  • STM32串口中断处理中.是否需要清除接受/发送完成/中断 标志位的问题.

    关于是否在串口中断服务程序中 是否加清除标志位操作 手册有说明 正常的读写DR寄存器都能达到清楚标志的效果 所以除了多缓存通信的情况下 没必要增加清除标志位 两个清除函数 USART ClearFlag 清除完成标志位 USART Clea
  • ShardingSphere-JDBC 5.0.0-beta使用:数据源拒绝建立连接,来自服务器的消息:“连接太多”

    问题分析 I wonder if the jar package is missing This is a non Maven project 问题处理 调试发现 问题出在少了蛮多依赖包 由于是非maven项目 有些jar包还可能冲突 版本
  • Java Robot 编写脚本机器人(一)基本用法测试

    Test public void test throws AWTException 获取机器人类 Robot robot new Robot 获取当前屏幕 Point point MouseInfo getPointerInfo getLo
  • 【Python_PySide2学习笔记(一)】PySide2动态加载UI方式,重写关闭窗体事件

    PySide2设置关闭提示窗口 动态加载UI方式 重写关闭窗体事件 前言 转载 https blog csdn net qq 44703282 article details 119830807 在此链接中介绍了两种重写关闭提示窗体事件的方
  • Vue CLI3配置详解-----脚手架的认识以及项目初始化、项目目录结构

    使用Vue CLI3创建项目 脚手架 scaffold 指施工现场为工人操作并解决垂直和水平运输而搭设的各种支架 建筑界的通用术语 写在前面 如果你只是简单的写几个Vue的 Demo 程序 那你不需要Vue CLI 如果你 开发大型项目 那
  • React中函数组件与类组件的区别

    React中函数组件与类组件的区别 一 组件定义 函数组件 import React from react function Index props const value setvalue useState React return di
  • C语言的可变参数函数理解与应用

    一 可变参数函数的理解 官方定义 C语言允许定义参数数量为可变的函数 这称为可变参数函数 它与传统意义上的强制定义固定参数的函数不同 可变参数函数应用最广的是格式化输入输出函数 如printf scanf 可支持任意参数输入输出 可变参数函