Как я могу написать этот код, используя stdarg На языке C - PullRequest
0 голосов
/ 24 марта 2020

Мне нужно изменить этот код на другой, используя библиотеку stdarg. Код:

int value(int n, int x_1, ...)
{
      int result = 0;
      int* ptr = &x_1;
      for (int i = 0; i < n / 2; i++)
      {
         result += ((*ptr) / (*(ptr + 1)));
         ptr += 2;
      }
      return result;
 }  

1 Ответ

2 голосов
/ 24 марта 2020

Сведения о том, как аргументы передаются в функцию, являются «соглашением о вызовах». В зависимости от платформы, языка и компилятора правила могут быть сложными. Поэтому небезопасно предполагать, что x_1 находится в стеке, а *(ptr + 1) является первым аргументом после x_1. Цель stdarg.h - предоставить переносимый способ перебора аргументов переменной.

Чтобы использовать stdarg.h, функции нужны три вещи:

  1. Как минимум одно исправленное аргумент
  2. Способ определения количества переменных аргументов
  3. Способ определения типа каждой переменной arugment

Функции типа printf имеют строку формата это и фиксированный аргумент, и он кодирует число и тип каждого аргумента переменной.

Для value первый аргумент n является фиксированным аргументом и дает число переменных аргументов. Не существует четкого способа определить тип каждого аргумента переменной для value. Один из вариантов - сделать выбор, например, «int», и документировать функцию. Поскольку операция внутри for-l oop является делением, возможно, имеет смысл использовать float или double.

Использование stdarg.h в этом случае прямолинейно. Используйте va_start для инициализации va_list, а затем используйте va_arg для получения значения каждого аргумента переменной.

/* value inputs n variable arguments, call them x_i, of type int
 * and returns the value
 * 
 * (x_0 / x_1) + (x_2 / x_3) + ...
 *
 * n must be even
 * the division is integer division
 */
int value(int n, ...)
{
  int result = 0;
  va_list ap;

  va_start(ap, n);

  for (int i = 0; i < n/2; ++i) {
    int a = va_arg(ap, int);
    int b = va_arg(ap, int);
    result += a/b;
  }

  va_end(ap);

  return result;
}

Пример вызовов

В этом примере вычисляется (6/3) + (21/7):

int r = value(4, 6, 3, 21, 7);
printf("%d\n", r);

и приводит к

5

Во втором примере показано, что value можно вызвать, распаковав массив

  int a[] = {49, 7, 64, 8, 121, 11};
  int r = value(6, a[0], a[1], a[2], a[3], a[4], a[5]);

  printf("%d\n", r);

, что приводит к

26
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...