函數的參數不確定的編寫方式

通過《C程序設計語言》第二版第7章的介紹,我們知道標題準確翻譯或許是“變長變元表”,這個無可厚非,我們只要知道我們要編寫一個函數參數個數不確定的函數,如何編寫?

形式:

int printf(char *fmt, ...);

從形式上出發,我們需要處理的部分是”…”。

這部分的處理,我們可以這樣設計:
首先“…”表示的是一個變元表,這個表我們可以理解成是一個鏈表,對於鏈表的處理,我們往往需要一個指針指向當前元素。變元表的遍歷可以採用鏈表的遍歷思路。
1.獲得變元表的開始位置
2.獲得當前位置的元素值,並且位置+1處理
3.循環執行步驟2,直到變元表結束

這裏有個問題,我們並不知道,變元表的結束位置。也就是說,我們必須知道我們的變元表的元素個數,這樣上面的設計思路才能實施,假設我們知道變元表中的元素個數,這也是編寫變長變元表的前提。

我們現在使用文件 stdarg.h 文件中函數,實現變元表的處理:
va_list: 用於定義變元變量指針
va_start:初始化變元變量指針
va_end:釋放處理過程中的資源
va_arg:獲得當前變元變量指針對應的值(依賴數據類型),並且+1變元變量的指針值

從這個設計我們可以看出,對於表的處理,基本上就是“定界遍歷”這樣的方式。這些都是基本的遍歷思想。我們從這裏也明白,對於計算機的理解要建立在最基礎的理解方式上面,因爲,這樣的理解是深刻的,沒有特殊的元素在這裏面,都是些基本的設計理念。

一個簡單的例子:

/*************************************************************************
    > File Name: main.c
    > Author: mhsheng
    > Mail:[email protected] 
    > Created Time: Mon 14 Nov 2016 03:14:04 PM CST
 ************************************************************************/

#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>

void 
minprintf(char *fmt, ...)
{
    va_list     ap;
    char        *p;
    int         iVal;
    double      dVal;

    va_start(ap, fmt);

    for (p=fmt; *p!='\0'; ++p) {
        if (*p != '%') {
            putchar(*p);
            continue;
        }

        ++p;
        switch (*p) {
        case 'd':
            iVal = va_arg(ap, int);
            printf("%d", iVal);
            break;

        case 'f':
            dVal = va_arg(ap, double);
            printf("%f", dVal);
            break;

        default:
            break;
        }
    }

    va_end(ap);
}

int
main(int argc, char **argv) 
{
    minprintf("%d, %f\n", 13, 0.12);

    exit(0);
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章