首页 > 解决方案 > ANSI C (C89)使用 va_list 从数组中获取值

问题描述

我正在尝试在数组中打印一个值,但无法正常打印该值。尝试仅使用 C89 学习宏。这是代码:

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

int getValues(int, ...);
int *myArr;

int getValues(int num_args, ...) {
   int val[num_args];
   va_list ap;
   int i;
   va_start(ap, num_args);
   for(i = 0; i < num_args; i++) {
      val[i] = va_arg(ap, int);
   }
   myArr = val;
   va_end(ap);
   return *val;
}

int main(void) {
  getValues(1,2,3,4);
  for(int i = 0; i < sizeof(myArr); ++i){
    printf("%d\n", myArr[i]);
  }
  printf("Values are %d\n", myArr[0]); // Want this to print 1
   return 0;
}

标签: arrayscmacrosc89

解决方案


发布的代码有几个问题,下面内联注释。

int getValues(int num_args, ...) {
   int val[num_args];          // <--- variable-length arrays did not exist in C89, not until C99
   /*...*/
   myArr = val;                // <--- saves address of local array 'val' into global `myArr`
   /*...*/
}                              // <--- but `val` ceases to exist once the function returns

int main(void) {
  getValues(1,2,3,4);          // <--- missing first argument, presumably '4' for 'num_args'
  for(int i = 0;
      i < sizeof(myArr);       // <--- sizeof(myArr) == sizeof(int*) is not the array count
      ++i){
    printf("%d\n", myArr[i]);  // <--- `myArr` points to an array which no longer exists
  }
  /*...*/
}

以下是可能的重写,只需进行最小的修改即可使代码正常工作。

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

int *getValues(int, ...);

int *getValues(int num_args, ...) {
   int *val = malloc(num_args * sizeof(int));
   if(val == NULL) return NULL;
   va_list ap;
   va_start(ap, num_args);
   int i;
   for(i = 0; i < num_args; i++) {
      val[i] = va_arg(ap, int);
   }
   va_end(ap);
   return val;
}

int main(void) {
  int *myArr = getValues(5, 1,2,3,4,5);
  if(myArr == NULL) { abort(); } // error
  for(int i = 0; i < 5; ++i){
    printf("%d\n", myArr[i]);
  }
  free(myArr);
  return 0;
}

推荐阅读