一区二区三区在线-一区二区三区亚洲视频-一区二区三区亚洲-一区二区三区午夜-一区二区三区四区在线视频-一区二区三区四区在线免费观看

服務器之家:專注于服務器技術及軟件下載分享
分類導航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術|正則表達式|C/C++|IOS|C#|Swift|Android|VB|R語言|JavaScript|易語言|vb.net|

服務器之家 - 編程語言 - C/C++ - 關于C/C++中可變參數的詳細介紹(va_list,va_start,va_arg,va_end)

關于C/C++中可變參數的詳細介紹(va_list,va_start,va_arg,va_end)

2021-01-04 16:33C語言教程網 C/C++

可變參數的函數原理其實很簡單,而va系列是以宏定義來定義的,實現跟堆棧相關.我們寫一個可變函數的C函數時,有利也有弊,所以在不必要的場合,我們無需用到可變參數。如果在C++里,我們應該利用C++的多態性來實現可變參數的功能

由于在C語言中沒有函數重載,解決不定數目函數參數問題變得比較麻煩,即使采用C++,如果參數個數不能確定,也很難采用函數重載。對這種情況,提出了指針參數來解決問題。

如printf()函數,其原型為:
int   printf(   const   char*   format,   ...);

它除了有一個參數format固定以外,后面跟的參數的個數和類型是可變的,例如我們可以有以下不同的調用方法:  
printf( "%d ",i);  
printf( "%s ",s);  
printf( "the   number   is   %d   ,string   is:%s ",   i,   s);  

如何實現其功能?

我們需要以下幾個宏定義:

(1)va_list
定義了一個指針arg_ptr, 用于指示可選的參數.

(2)va_start(arg_ptr, argN)
使參數列表指針arg_ptr指向函數參數列表中的第一個可選參數,argN是位于第一個可選參數之前的固定參數, 或者說最后一個固定參數.如有一va函數的聲明是void va_test(char a, char b, char c, ...), 則它的固定參數依次是a,b,c, 最后一個固定參數argN為c, 因此就是va_start(arg_ptr, c).

(3)va_arg(arg_ptr, type)
返回參數列表中指針arg_ptr所指的參數, 返回類型為type. 并使指針arg_ptr指向參數列表中下一個參數.返回的是可選參數, 不包括固定參數.

(4)va_end(arg_ptr)
清空參數列表, 并置參數指針arg_ptr無效.

(注:va在這里是variable-argument(可變參數)的意思.   這些宏定義在stdarg.h中,所以用到可變參數的程序應該包含這個頭文件)

也需你現在還是不能理解,別著急,現在從一個實例著手.定義這么一個函數,函數的第一個參數是固定的,其余參數是可變的。定義為:
void   simple_va_fun(int i,...); 其代碼為:

復制代碼 代碼如下:


#include <iostream>
#include <stdarg.h>
using namespace std;
void simple_va_fun(int i,...);

 

int main(int argc,char *argv[])
{
    simple_va_fun(100);  
    simple_va_fun(100,200);
    simple_va_fun(100,200,'a');
    return 0;
}

void simple_va_fun(int i,...)  
{  
    va_list   arg_ptr;   //定義可變參數指針
    va_start(arg_ptr,i);   // i為最后一個固定參數
    int j=va_arg(arg_ptr,int);   //返回第一個可變參數,類型為int
    char c=va_arg(arg_ptr,char);   //返回第二個可變參數,類型為char
    va_end(arg_ptr);        //  清空參數指針
    printf( "%d %d %c\n",i,j,c);  
    return;  
}


代碼運行解釋:  
(1)首先在函數里定義一個va_list型的變量,這里是arg_ptr,這個變量是指向參數的指針.

 

(2)然后用va_start宏初始化變量arg_ptr,這個宏的第二個參數是第一個可變參數的前一個參數,是一個固定的參數.

(3)然后用va_arg返回第一個可變的參數,并賦值給整數j。va_arg的第二個參數是你要返回的參數的類型,這里是int型.  返回第一個可變參數后arg_ptr指向第二個可變參數,用同樣的方法返回并賦值給c,類型為char類型。

(4)最后用va_end宏結束可變參數的獲取。

小結:
可變參數的函數原理其實很簡單,而va系列是以宏定義來定義的,實現跟堆棧相關.我們寫一個可變函數的C函數時,有利也有弊,所以在不必要的場合,我們無需用到可變參數.如果在C++里,我們應該利用C++的多態性來實現可變參數的功能,盡量避免用C語言的方式來實現。

附加:

參數在堆棧中分布:
在進程中,堆棧地址是從高到低分配的.當執行一個函數的時候,將參數列表入棧,壓入堆棧的高地址部分,然后入棧函數的返回地址,接著入棧函數的執行代碼,這個入棧過程,堆棧地址不斷遞減,一些黑客就是在堆棧中修改函數返回地址,執行自己的代碼來達到執行自己插入的代碼段的目的. 總之,函數在堆棧中的分布情況是:地址從高到低,依次是:函數參數列表,函數返回地址,函數執行代碼段. 堆棧中,各個函數的分布情況是倒序的.即最后一個參數在列表中地址最高部分,第一個參數在列表地址的最低部分.參數在堆棧中的分布情況如下:

最后一個參數
倒數第二個參數
...
第一個參數
函數返回地址
函數代碼段

延伸 · 閱讀

精彩推薦
  • C/C++C++之重載 重定義與重寫用法詳解

    C++之重載 重定義與重寫用法詳解

    這篇文章主要介紹了C++之重載 重定義與重寫用法詳解,本篇文章通過簡要的案例,講解了該項技術的了解與使用,以下就是詳細內容,需要的朋友可以參考下...

    青山的青6062022-01-04
  • C/C++學習C++編程的必備軟件

    學習C++編程的必備軟件

    本文給大家分享的是作者在學習使用C++進行編程的時候所用到的一些常用的軟件,這里推薦給大家...

    謝恩銘10102021-05-08
  • C/C++C語言實現電腦關機程序

    C語言實現電腦關機程序

    這篇文章主要為大家詳細介紹了C語言實現電腦關機程序,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下...

    xiaocaidayong8482021-08-20
  • C/C++c++ 單線程實現同時監聽多個端口

    c++ 單線程實現同時監聽多個端口

    這篇文章主要介紹了c++ 單線程實現同時監聽多個端口的方法,幫助大家更好的理解和學習使用c++,感興趣的朋友可以了解下...

    源之緣11542021-10-27
  • C/C++C語言中炫酷的文件操作實例詳解

    C語言中炫酷的文件操作實例詳解

    內存中的數據都是暫時的,當程序結束時,它們都將丟失,為了永久性的保存大量的數據,C語言提供了對文件的操作,這篇文章主要給大家介紹了關于C語言中文件...

    針眼_6702022-01-24
  • C/C++詳解c語言中的 strcpy和strncpy字符串函數使用

    詳解c語言中的 strcpy和strncpy字符串函數使用

    strcpy 和strcnpy函數是字符串復制函數。接下來通過本文給大家介紹c語言中的strcpy和strncpy字符串函數使用,感興趣的朋友跟隨小編要求看看吧...

    spring-go5642021-07-02
  • C/C++深入理解goto語句的替代實現方式分析

    深入理解goto語句的替代實現方式分析

    本篇文章是對goto語句的替代實現方式進行了詳細的分析介紹,需要的朋友參考下...

    C語言教程網7342020-12-03
  • C/C++C/C++經典實例之模擬計算器示例代碼

    C/C++經典實例之模擬計算器示例代碼

    最近在看到的一個需求,本以為比較簡單,但花了不少時間,所以下面這篇文章主要給大家介紹了關于C/C++經典實例之模擬計算器的相關資料,文中通過示...

    jia150610152021-06-07
主站蜘蛛池模板: 国产va免费精品高清在线观看 | 青青草原手机在线视频 | 精品视频在线免费 | 亚洲va在线va天堂va偷拍 | 91视在线国内在线播放酒店 | av排名 | 久久免费看少妇级毛片蜜臀 | 俄罗斯烧性春三级k8播放 | 日本视频在线免费观看 | 久久久久久久国产精品视频 | 免费xxxxx大片在线观看影视 | 国产一卡二卡3卡4卡四卡在线 | 青青久久久国产线免观 | 2021久久| 我们日本在线观看免费动漫下载 | 韩国丽卡三级作品 | 久久足恋网 | 99久久www免费 | 粉嫩国产14xxxxx0000 | 国产在线视频福利 | 私人家庭影院5577 | 日本剧情片在线播放中文版 | 女人把扒开给男人爽的 | 成人伊人青草久久综合网破解版 | 国产欧美一区视频在线观看 | a韩剧 | 8插8插| 91日本在线观看亚洲精品 | 国产在线精品99一卡2卡 | 国产成人综合网 | 午夜一区二区福利视频在线 | 国产成人精选免费视频 | 国产成人性色视频 | 免费一级欧美片在线观看 | 国产91 最新 在线 | 99久久精品免费看国产 | 涩涩国产精品福利在线观看 | 欧美亚洲桃花综合 | 好姑娘完整版在线观看中文 | 99视频久久精品久久 | 无限在线观看免费入口 |