欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

C/C++中不定參數(shù)的使用詳解

 更新時間:2023年12月01日 09:55:06   作者:超人不會飛)  
這篇文章主要為大家詳細(xì)介紹了C/C++中不定參數(shù)的使用的相關(guān)知識,文中的示例代碼講解詳細(xì),具有一定的借鑒價值,感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下

C語言的不定參

C語言的不定參數(shù)最常見的應(yīng)用示例就是printf函數(shù),如下,參數(shù)列表中的...表示不定參數(shù)列表

#include <stdio.h>
int printf(const char *format, ...);

試著模擬實現(xiàn)C語言的printf函數(shù)

void myprintf(const char *fmt, ...)
{
    //TODO
}

C語言中,對于...不定參列表,要用va_*系列宏函數(shù)操作

#include <stdarg.h>

???????void va_start(va_list ap, last);
type va_arg(va_list ap, type);
void va_end(va_list ap);
void va_copy(va_list dest, va_list src);

va_list

va_list可以理解為一個指針類型,開始時,通過調(diào)用va_start,它會指向不定參列表的第一個參數(shù)

va_start

我們知道,C/C++的函數(shù)參數(shù)通過壓棧的方式傳入,不定參列表的多個參數(shù)也需要壓棧。

va_start的作用是使ap指向不定參列表的第一個參數(shù)。通過不定參數(shù)列表前的最后一個函數(shù)參數(shù),找到不定參列表的首元素,并使ap(va_list類型的指針)指向首元素。因此,C函數(shù)使用...不定參數(shù),前面至少包含一個其它參數(shù),由它提供不定參數(shù)的起始位置。

va_arg

va_arg的作用是在不定參數(shù)列表中,從ap指向的參數(shù)開始,逐個返回type類型的數(shù)據(jù),一般需要循環(huán)調(diào)用va_arg,在此過程中ap會不斷往后走

va_end

ap使用結(jié)束后就失效了,為了避免野指針的引用,va_end可以銷毀ap指針

va_copy

拷貝src到dest,使得二者指向同一個不定參數(shù)列表,src不用再次調(diào)用va_start,但要調(diào)用va_end

Test Demo:

void myprintf(size_t num, ...)
{
    va_list ap1;
    va_start(ap1, num);
    va_list ap2;
    va_copy(ap2, ap1);
    for (int i = 0; i < num; i++)
    {
        char ch = va_arg(ap1, int);
        std::cout << ch;
    }
    std::cout << std::endl;
    for (int i = 0; i < num; i++)
    {
        char ch = va_arg(ap2, int);
        std::cout << ch;
    }
    std::cout << std::endl;
    va_end(ap1);
    va_end(ap2);
}

int main()
{
    myprintf(3, 'L', 'O', 'L');
    return 0;
}

輸出結(jié)果

[ckf@VM-8-12-centos 1.before]$ ./vargs 
LOL
LOL

注意:va_arg對于可變參數(shù)的處理是有一些規(guī)則的,特別是對于小整數(shù)類型(如char和float)。這些類型在傳遞給va_arg時會被默認(rèn)轉(zhuǎn)換為int和double,而不是它們的實際類型。因此,在Test Demo中,對于傳入的char類型參數(shù),在調(diào)用va_arg時也應(yīng)該指定type為int,獲得返回值后再轉(zhuǎn)換為實際類型char。

以下函數(shù)可以對不定參數(shù)列表進(jìn)行格式化操作。

#include <stdarg.h>

int vprintf(const char *format, va_list ap);
int vfprintf(FILE *stream, const char *format, va_list ap);
int vsprintf(char *str, const char *format, va_list ap);
int vsnprintf(char *str, size_t size, const char *format, va_list ap);

它們的作用與printf相同,都可以通過參數(shù)format,對不定參數(shù)進(jìn)行格式化。區(qū)別在于:printf使用不定參...作為格式化的數(shù)據(jù),而上面以v開頭printf結(jié)尾的函數(shù),使用ap指向的不定參數(shù)列表作為格式化的數(shù)據(jù)。除此之外,內(nèi)部的區(qū)別就在于輸出的方向了,vprintf將格式化后的字符串輸出到stdout,vfprintf輸出到指定的文件流,vsprintf和vsprintf輸出到指定的內(nèi)存空間str,且后者可以指定輸出的字節(jié)個數(shù)。

Test Demo:

void myprintf(const char *fmt, ...)
{
    va_list ap;
    va_start(ap, fmt);

    char str[64] = {0};
    int len = vsnprintf(str, sizeof(str), fmt, ap);
    str[len] = 0;
    std::cout << str << std::endl;

    va_end(ap);
}
int main()
{
    myprintf("%s %c %d", "你好", '!', 2024);
    return 0;
}

輸出結(jié)果

[ckf@VM-8-12-centos 1.before]$ ./vargs 
你好 ! 2024

C++的不定參

補(bǔ)充:

  • args參數(shù)包作為參數(shù)傳遞給另一個函數(shù)時,記得加...,表示這個args參數(shù)是不定參數(shù)包
  • 函數(shù)接收Args...類型的參數(shù)包時,通??梢詫?shù)設(shè)置為&&萬能引用,減少拷貝的成本
  • C++11標(biāo)準(zhǔn)庫中,很多構(gòu)造方法都使用了以不定參數(shù)包為參數(shù)的條目,方便一些無法缺點參數(shù)個數(shù)的實例的構(gòu)造

例如:

std::make_shared,由于并不確定構(gòu)造智能指針指向的對象類型需要傳入多少參數(shù),C++11使用了Args不定參數(shù)包

?

emplace函數(shù),C++11很多容器都重載了這個函數(shù),emplace支持可變參數(shù)包,并且用參數(shù)包中的參數(shù)作為新插入元素構(gòu)造函數(shù)的參數(shù)。

Test Demo

template <class T>
void myprintfcpp(T val) // 終止函數(shù)
{
    std::cout << val;
}

template <class T, class... Args>
void myprintfcpp(T val, Args &&...args)
{
    std::cout << val;
    myprintfcpp(std::forward<Args>(args)...);
}

int main()
{
    myprintfcpp(3, 'L', 'O', 'L');
    std::cout << std::endl;
    return 0;
}

輸出結(jié)果

[ckf@VM-8-12-centos 1.before]$ ./vargs 
3LOL

到此這篇關(guān)于C/C++中不定參數(shù)的使用詳解的文章就介紹到這了,更多相關(guān)C++不定參數(shù)內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • C語言實現(xiàn)二叉樹遍歷的迭代算法

    C語言實現(xiàn)二叉樹遍歷的迭代算法

    這篇文章主要介紹了C語言實現(xiàn)二叉樹遍歷的迭代算法,包括二叉樹的中序遍歷、先序遍歷及后序遍歷等,是非常經(jīng)典的算法,需要的朋友可以參考下
    2014-09-09
  • C++編寫簡單的打靶游戲

    C++編寫簡單的打靶游戲

    這篇文章主要介紹了使用C++編寫簡單的打靶游戲,本人也是個菜鳥,水平有限,有錯誤遺漏的地方在所難免,大家看看就好。
    2015-03-03
  • 詳解vs2022創(chuàng)建及調(diào)用.lib的方法

    詳解vs2022創(chuàng)建及調(diào)用.lib的方法

    這篇文章主要介紹了vs2022創(chuàng)建及調(diào)用.lib的方法,調(diào)用Lib的原則就是可以讓編譯器找到頭文件和庫文件的目錄,并正確引入,本文給大家詳細(xì)講解需要的朋友可以參考下
    2022-11-11
  • C語言超全面講解函數(shù)的使用方法下

    C語言超全面講解函數(shù)的使用方法下

    函數(shù)是一組一起執(zhí)行一個任務(wù)的語句。每個?C?程序都至少有一個函數(shù),即主函數(shù)?main()?,所有簡單的程序都可以定義其他額外的函數(shù),由于篇幅過大,分為兩篇講解,下面開始下篇
    2022-04-04
  • C++實現(xiàn)五子棋小游戲

    C++實現(xiàn)五子棋小游戲

    這篇文章主要為大家詳細(xì)介紹了C++實現(xiàn)五子棋小游戲,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-05-05
  • C++高精度算法的使用場景詳解

    C++高精度算法的使用場景詳解

    在我們進(jìn)行計算的過程中,經(jīng)常會遇到幾十位,甚至幾百位的數(shù)字的計算問題,也有可能會遇到小數(shù)點后幾十位,幾百位的情況,而我們面對這樣的情況下,long long  和 double 的數(shù)據(jù)范圍顯然是不夠使用的了。因此這時,我們就需要引入一個新的算法,叫做高精度算法
    2022-09-09
  • C++控制臺循環(huán)鏈表實現(xiàn)貪吃蛇

    C++控制臺循環(huán)鏈表實現(xiàn)貪吃蛇

    這篇文章主要為大家詳細(xì)介紹了C++控制臺循環(huán)鏈表實現(xiàn)貪吃蛇,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2020-04-04
  • C/C++實現(xiàn)獲取硬盤序列號的示例代碼

    C/C++實現(xiàn)獲取硬盤序列號的示例代碼

    獲取硬盤的序列號、型號和固件版本號,此類功能通常用于做硬盤綁定或硬件驗證操作,下面我們就來學(xué)習(xí)一下如何使用C/C++實現(xiàn)獲取硬盤序列號吧
    2023-11-11
  • C程序讀取鍵盤碼的方法

    C程序讀取鍵盤碼的方法

    這篇文章主要介紹了C程序讀取鍵盤碼的方法,運行時可通過鍵盤按鍵獲取其對應(yīng)的鍵盤碼,文章最后附帶了鍵盤碼與按鍵的對照表,需要的朋友可以參考下
    2014-09-09
  • C++中的多態(tài)詳談

    C++中的多態(tài)詳談

    多態(tài)通俗來說就是多種形態(tài),本文通過實例代碼給大家介紹C++中的多態(tài)定義及實現(xiàn),通過實例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友參考下吧
    2021-05-05

最新評論