1

これは私のコードです:

#include <stdio.h>

void add(int num, ...);

int main(void)
{
  int a=100, b=200, c=300;

  add(1, a);
  add(2, a, b);
  add(3, a, b, c);
  return 0;
}

void add(int num, ...)
{
  int *p=NULL;
  p=&num+1;
  printf("%x \n", p);
  if(num==1)
    {
      printf("%d \n", p[0]);
      printf("num is: %d \n", num);
    }
  else if (num==2)
    {
      printf("%d \n", p[0]+p[1]);
      printf("num is: %d \n", num);
    }
  else
    {
      printf("%d \n", p[0]+p[1]+p[2]);
      printf("num is: %d \n", num);
    }
}

私の理解では、p最初はを指しaます。これは10です。したがって、それぞれ10、30、60を出力する必要があります。それにもかかわらず、それは印刷します

6786db50 
1736891264 
num is: 1 
6786db50 
1736924031 
num is: 2 
6786db50 
1867401241 
num is: 3 

p間違ったアドレスを指していますか?として渡された引数を正しく読み取るにはどうすればよい...ですか?

4

2 に答える 2

4

va_*これは、可変個引数関数呼び出しの使用方法ではありません。パラメーターを抽出するには、関数呼び出しを使用する必要があります。

http://unixhelp.ed.ac.uk/CGI/man-cgi?stdarg+3またはhttp://en.wikipedia.org/wiki/Variadic_function#Variadic_functions_in_C.2C_Objective-C.2C_C.2B.2B.2C_and_Dを参照してください

于 2012-06-04T08:00:18.883 に答える
2

あなたの特定の例はうまくいくかもしれませんし、うまくいかないかもしれません(私のシステムであなたが期待したように動作します)。p=&num+1;次の要素にアクセスするために行います。これは、スタックが昇順であるという前提の下で有効ですが、アーキテクチャには当てはまらない場合があります。そして、多くのシステムでは、ある制限までの変数は、スタックよりもレジスターに渡されます。だからあなたの仮定は完全に間違っています。また、変数は左から右、またはその逆のいずれかでスタックにプッシュできることに注意してください。規格では規定されていません。

したがって、仮定に取り組むのではなく、この特定の用途向けに設計された関数を使用する必要があります。

于 2012-06-04T08:06:52.100 に答える