日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

函数中的可变参数

發(fā)布時(shí)間:2025/4/5 编程问答 20 豆豆
生活随笔 收集整理的這篇文章主要介紹了 函数中的可变参数 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

文章目錄

    • 1 可變參數(shù)的使用
      • 1.1 可變參數(shù)的要點(diǎn)
      • 1.2 可變參數(shù)的應(yīng)用
    • 2 可變參數(shù)原理分析
      • 2.1 可變參數(shù)中設(shè)計(jì)的各個(gè)宏
    • 3 宏中如何傳遞可變參
    • 4 可變參的應(yīng)用:簡(jiǎn)易log實(shí)現(xiàn)

1 可變參數(shù)的使用

1.1 可變參數(shù)的要點(diǎn)

C語(yǔ)言中可以定義參數(shù)可變的函數(shù)。
參數(shù)可變函數(shù)的實(shí)現(xiàn)依賴于stdarg.h頭文件:

  • va_list:參數(shù)集合
  • va_arg:取具體參數(shù)值
  • va_start:標(biāo)識(shí)參數(shù)訪問的開始
  • va_end:標(biāo)識(shí)參數(shù)訪問的結(jié)束

可變參數(shù)的限制:

  • 可變參數(shù)必須從頭到尾按照順序逐個(gè)訪問,無法直接訪問中間的參數(shù)值。
  • 參數(shù)列表中至少要存在一個(gè)確定的命名參數(shù)。
  • 可變參數(shù)函數(shù)無法確定實(shí)際存在的參數(shù)的數(shù)量。
  • 可變參數(shù)函數(shù)無法確定參數(shù)的實(shí)際類型。

注意:va_arg中如果指定了錯(cuò)誤的類型,那么結(jié)果是不可預(yù)測(cè)的。

1.2 可變參數(shù)的應(yīng)用

編寫函數(shù)計(jì)算平均值:

#include <stdio.h> #include <stdarg.h>float average(int n, ...) {va_list args;int i = 0;float sum = 0;va_start(args, n);for(i=0; i<n; i++){sum += va_arg(args, int);}va_end(args);return sum / n; }int main() {printf("%f\n", average(5, 1, 2, 3, 4, 5));printf("%f\n", average(4, 1, 2, 3, 4));return 0; }

2 可變參數(shù)原理分析

2.1 可變參數(shù)中設(shè)計(jì)的各個(gè)宏

知道了參數(shù)是如傳遞的及入棧順序,分析如下代碼就很簡(jiǎn)單了。原理性的實(shí)現(xiàn)代碼如下:

typedef char * va_list; #define _INTSIZEOF(n) ( (sizeof(n) + sizeof(int) - 1) & ~(sizeof(int) - 1) ) // 這里是進(jìn)行內(nèi)存對(duì)齊,32位的實(shí)現(xiàn),如果是64位則不是這種實(shí)現(xiàn)#define va_start(ap,v) ( ap = (va_list)&v + _INTSIZEOF(v) ) //#define va_arg(ap,t) ( *(t *)((ap += _INTSIZEOF(t)) - _INTSIZEOF(t)) ) #define va_arg(ap,t) ( *(t *)( ap=ap + _INTSIZEOF(t), ap- _INTSIZEOF(t)) ) #define va_end(ap) ( ap = (va_list)0 )

3 宏中如何傳遞可變參

在c99語(yǔ)法中支持可變參,如下:

void EM_LOG(int level, const char* function, int line, const char* fmt, ...);#define EMLOG(level, fmt...) EM_LOG(level, __FUNCTION__, __LINE__, fmt)

4 可變參的應(yīng)用:簡(jiǎn)易log實(shí)現(xiàn)

實(shí)現(xiàn)較簡(jiǎn)單,不多說,直接看代碼:

log.h:

#ifndef _LOG_H #define _LOG_H#include <stdio.h> #include <stdarg.h> #include <string.h> #include <stdlib.h>typedef enum {LOG_DEBUG = 1,LOG_INFO,LOG_WARNING,LOG_ERROR }LOG_LEVEL_E;#define OPEN_LOG 1 #define LOG_LEVEL LOG_DEBUGvoid EM_LOG(int level, const char* function, int line, const char* fmt, ...);#define EMLOG(level, fmt...) EM_LOG(level, __FUNCTION__, __LINE__, fmt)#endif

log.cpp:

#include "log.h"const char* EM_LOGLevelGet(int level) {if (level == LOG_DEBUG){return "DEBUG";}else if (level == LOG_INFO){return "INFO";}else if (level == LOG_WARNING){return "WARNING";}else if (level == LOG_ERROR){return "ERROR";}return "UNKOWN"; }void EM_LOG(int level, const char* function, int line, const char* fmt, ...) {va_list arg;int len = 0;va_start(arg, fmt);len = vsnprintf(NULL, 0, fmt, arg) + 1;char* buf = (char*)malloc(len);memset(buf, 0, len);vsnprintf(buf, len, fmt, arg);#ifdef OPEN_LOGprintf("[%s] [%s : %d] %s\n", EM_LOGLevelGet(level), function, line, buf); #endifva_end(arg); }

main.c:

#include "log.h"int main(void) {EMLOG(LOG_DEBUG, "debug...");EMLOG(LOG_INFO, "info...");EMLOG(LOG_WARNING, "warning...");EMLOG(LOG_ERROR, "error...");return 0; }

總結(jié)

以上是生活随笔為你收集整理的函数中的可变参数的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。