Если вы хотите, чтобы исследовать различные авеню, вы могли бы использовать VARIADIC функцию:
#include <stdarg.h>
void displayNum(int n, ...)
{
va_list ap;
va_start(ap, n);
for (int i = 0; i < n; i++)
{
int value = va_arg(ap, int);
printf("%20s: %d\n", label(i+1), value);
}
va_end(ap);
printf("\n");
}
где label
функция который распечатает соответствующую метку на основе значения i
.
Таким образом, вам не нужно передавать фиксированное количество параметров; если вы хотите, чтобы отобразить одно значение, вы бы назвали это как
displayNum(1, first);
Если вы хотите отобразить 3 значения, вы бы назвали это как
displayNum(3, first, second, third);
Первый аргумент n
является фиксированной и всегда должны присутствовать. Остальные аргументы считываются на основе значения первого аргумента. Если вы пройдете 1, displayNum
будет читать и отображать первый дополнительный аргумент. Если вы пройдете 3, displayNum
будет ожидать, что не менее три дополнительных целочисленных аргумента в стеке.
Предостережения: переменные функции не являются безопасными по типу, и компилятор не предупредит вас, когда вы передаете аргументы неправильного типа, и не будет предупреждать вас, если вы передаете слишком мало или слишком много дополнительных аргументов. Если вы называете это displayNum(1, "this is a test");
, вы либо потерпите крах, либо получите искаженный результат.
Полный пример: выход
#include <stdio.h>
#include <math.h>
#include <stdarg.h>
#include <stdlib.h>
#include <string.h>
const char *label(int n)
{
const char *units[] = { "zeroth", "first", "second", "third",
"fourth", "fifth", "sixth", "seventh",
"eighth", "ninth" };
const char *teens[] = { "tenth", "eleventh", "twelfth", "thirteenth",
"fourteenth", "fifteenth", "sixteenth",
"seventeenth", "eighteenth", "ninteenth" };
const char *decades[] = { "", "", "twenty", "thirty", "forty", "fifty",
"sixty", "seventy", "eighty", "ninety" };
static char buf[256] = {0};
if (n < 10)
return units[n];
else if (n < 20)
return teens[n-10];
else
{
int t = n/10;
int u = n % 10;
sprintf(buf, "%s", decades[t]);
if (u > 0)
{
strcat(buf, "-");
strcat(buf, units[u]);
}
else
{
buf[ strlen(buf) - 1 ] = 0;
strcat(buf, "ieth");
}
return buf;
}
return "";
}
void displayNum(int n, ...)
{
va_list ap;
va_start(ap, n);
for (int i = 0; i < n; i++)
{
int value = va_arg(ap, int);
printf("%20s: %d\n", label(i+1), value);
}
printf("\n");
va_end(ap);
}
int main(void)
{
displayNum(1, 1);
displayNum(2, 1, 2);
displayNum(3, 1, 2, 3);
displayNum(10, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
displayNum(25, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
11, 12, 13, 14, 15, 16, 17, 18, 19, 20,
21, 22, 23, 24, 25);
return 0;
}
Примера:
[[email protected]]~/prototypes/stdarg: ./mystdarg
first: 1
first: 1
second: 2
first: 1
second: 2
third: 3
first: 1
second: 2
third: 3
fourth: 4
fifth: 5
sixth: 6
seventh: 7
eighth: 8
ninth: 9
tenth: 10
first: 1
second: 2
third: 3
fourth: 4
fifth: 5
sixth: 6
seventh: 7
eighth: 8
ninth: 9
tenth: 10
eleventh: 11
twelfth: 12
thirteenth: 13
fourteenth: 14
fifteenth: 15
sixteenth: 16
seventeenth: 17
eighteenth: 18
ninteenth: 19
twentieth: 20
twenty-first: 21
twenty-second: 22
twenty-third: 23
twenty-fourth: 24
twenty-fifth: 25
Как написано, функция label
будет обрабатывать только входы до 99, после чего вы получите какой-нибудь веселый выход. Стандарт языка C гарантирует не менее 127 аргументов в одном вызове функции, но вы действительно не хотите этого делать.
EDIT
Или вы могли бы избежать весь этот бред и передать свои значения в массиве, который является лучшим подходом, если все значения одного и того же типа:
void displayNum(int n, const int *values)
{
for (int i = 0; i < n; i++)
printf("%20s: %d\n", label(i + 1), values[i]);
}
Спасибо за ваш быстрый ответ. Но как вы можете передать значение1 в displayNum? – UserFriendly
Вы можете вызвать функцию с помощью displayNum (значение1, firstValue, secondValue, thirdValue, 4thValue, пятое значение); 'inside' main() '. – Cantfindname
Что делать, если пользователь хочет 3 ?. Я не думаю, что это все еще работает, если я так делаю: 'displayNum (value1, firstValue, secondValue, thirdvalue);' – UserFriendly