アプリ版:「スタンプのみでお礼する」機能のリリースについて

あるC言語のソースを見ていたら、va_list型の引數を持つ函數がありました。
そのソースは複雜なので、質問するために以下のソースを作りました。
(ですから、このプログラムはじつよう性もないし、無意味なこともしています。)

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

int sum_func1(int sw1, va_list ap1)
{
int sum1 = 0;

va_start(ap1, sw1);
sum1 += va_arg(ap1,int);
sum1 += va_arg(ap1,int);
va_end(ap1);

return(sum1);
}

int sum_func0(int sw0, ...)
{
int sum0;
va_list ap0;
int a0, b0;

va_start(ap0, sw0);
a0=va_arg(ap0, int);
b0=va_arg(ap0, int);
printf("sum_func0です。これから%dと%dを足します。\n", a0, b0);
sum0 = sum_func1(sw0, ap0);
va_end(ap0);

return(sum0);
}

int main(void)
{
printf("1 + 2 = %d\n", sum_func0(0,1,2));
return 0;
}

やっていることは、結局のところ、1と2を足してその結果を表示しているだけです。
このプログラムは動かすことはできますが、表示される足し算の結果がおかしいです。

sum_func0の中で 1(a0)と2(b0)は既にva_argを使って取得しています。
その後、sum_func1の中で、再び この1と2を取得しようとしているのですが、
このようなことは可能でしょうか。
可能ならば、どのように修整すればよいのでしょうか。

これが可能か否かが元のソースの讀み方に影響するのです。

最初に述べたように、va_list型の引數を持つ函數についての質問なので、
va_list型の引數を使わないような修整方法ですと、
期待するものではありません。

A 回答 (3件)

> sum_func0の中で 1(a0)と2(b0)は既にva_argを使って取得しています。


> その後、sum_func1の中で、再び この1と2を取得しようとしているのですが、
> このようなことは可能でしょうか。


va_start ~ va_end で囲めば、何回でも取得できるはずです。
以下に例を示します。


//int sum_func1(int sw1, va_list ap1)
int sum_func1(va_list ap1)
{
int sum1 = 0;

//va_start(ap1, sw1);
sum1 += va_arg(ap1,int);
sum1 += va_arg(ap1,int);
//va_end(ap1);

return(sum1);
}

int sum_func0(int sw0, ...)
{
int sum0;
va_list ap0;
int a0, b0;

va_start(ap0, sw0);
a0=va_arg(ap0, int);
b0=va_arg(ap0, int);
printf("sum_func0です。これから%dと%dを足します。\n", a0, b0);
//sum0 = sum_func1(sw0, ap0);
va_end(ap0);

va_start(ap0, sw0);
sum0 = sum_func1(ap0);
va_end(ap0);

return(sum0);
}
    • good
    • 0
この回答へのお礼

なるほど~、と思いました。
ありがとうございました。

これは單純化して可變數個引數關係のみを拔き出して書くと、
次のように、va_start、va_endの組が、【入れ子にならずに】ならんでいますね。

int sum_func0(int sw0, ...)
{
va_list ap0;

va_start(ap0, sw0);
a0=va_arg(ap0, int);
b0=va_arg(ap0, int);
va_end(ap0);

va_start(ap0, sw0);
a0=va_arg(ap0, int);
b0=va_arg(ap0, int);
va_end(ap0);

}


あとは2番目の「va_start・va_endの組」の内側が、
va_list型ap0を引數とする函數になっているだけですね。

ご回答が私の質問に對して正解であるのは言うまでもないですが、
私の疑問は入れ子にすることはできないのだろうか、
ということでした。

お礼日時:2002/10/18 22:47

>va_start(ap0, sw0);


>a0=va_arg(ap0, int);
>b0=va_arg(ap0, int);

va_argマクロは、ap0の内容を書き換えます。
そのため、sum_func1に正しい引数がわたっていません。

va_list ap0, ap1;

va_start(ap0, sw0);
ap1 = ap0;



sum0 = sum_func1(sw0, ap1);

とすればsum_func1()で問題なく呼び元からの可変引数を利用できます。
    • good
    • 0

あと、sum_func1のなかの、va_start、va_endも不要ですね。

    • good
    • 0
この回答へのお礼

No2、No3

これはおもしろいですね。
もちろん、回答としては正解です。
これも單純化すると、次のような仕組みになっているんですね。

int sum_func0(int sw0, ...)
{

va_list ap0,ap1;

va_start(ap0, sw0);
ap1=ap0;

va_arg(ap0, int);
va_arg(ap0, int);

va_arg(ap1, int);
va_arg(ap1, int);

va_end(ap0);


}

va_list型の變數が2つあるのがポイントですね。
これもap1から引數を取り出す部分を函數にすれば、質問に適しますね。

お礼日時:2002/10/18 23:06

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!