2013-04-04 6 views
1

В C мы можем иметь VARIADIC функции, такие как:Возможно передать аргументы, введенные во время выполнения?

void abc(int x, ..) 
{ 
} 

, и мы можем назвать их с переменным числом аргументов, как:

abc(1,2,3) or abc(1,2,3,4,5)

Но в обоих приведенных выше вызовов функций, мы назвали вариационную функцию abc с уже известными нами параметрами; «1, 2, 3» в первом случае и «1, 2, 3, 4, 5» во втором случае.

Мой вопрос:

Есть ли способ вызвать VARIADIC функцию с переменным числом аргументов, введенных пользователем во время выполнения?

Например, в main() я попросить пользователя ввести определенное количество входов, а затем передать эти входы в VARIADIC функции с помощью параметров p1, p2, p3 и так далее ...

+2

Это звучит как очередной поиск ненужного сложного решения, чтобы усложнить ситуацию. Вам даже не нужно использовать va_lists когда-либо в программе на C, они являются излишней особенностью языка. – Lundin

+0

@ Lundin Я нахожу 'printf' довольно изящным. Я могу представить, что есть другие случаи, когда переменные списки аргументов полезны, хотя и не являются строго необходимыми. –

+0

@ KlasLindbäck Хотя функции printf/scanf являются мощными, они также невероятно сложны, медленны, неэффективны и очень небезопасны (нет безопасности типов, возможных переполнений буфера и т. Д.). Кроме того, они синтаксически отклоняются от остальной части языка. Лично я думаю, что они довольно ужасные. Независимо от того, что вы думаете об этих функциях, программисту не нужно создавать собственные функции printf, поэтому va_lists совершенно излишни. – Lundin

ответ

0

Нет, это невозможно.
Компилятор должен сгенерировать соответствующий код и зарезервировать место для идентификаторов во время компиляции. Вы попытались бы изменить статический двоичный файл, что невозможно. Вот почему va_args существует, чтобы иметь возможность передавать неизвестное количество параметров.

+0

Ну, вы можете поместить параметры в стек вручную, но это было бы неразумно, я думаю. – LtWorf

+0

@LtWorf Там могут быть обходные пути, вы правы. Но они будут очень неудобны! И 'va_args' - хороший гаджет, так зачем изобретать колесо? –

1

Вы можете использовать массив, например:

void abc(int size, int *arr) { } 

В главном

int size; 
int A[MAX]; 

size = 3; 
A[0] = 1; A[1] = 2; A[2]=3; 
abc(size,A); 

Пример

int size=0; 
int A[MAX]; 
while(size<MAX && scanf(" %d",&A[size])!=EOF) { 
    size++; 
} 

if(size>0) abc(size, A); 
0

Это действительно выглядит, как вы должны передать указатель на массив вместо.

void yourfunction(int *array, size_t len) { 
    //Do what you want in your function 
} 
0

Вы не можете сделать это легко. Функция переменных аргументов компилируется в соответствии с определенным соглашением о вызове. Таким образом, любая попытка динамически имитировать соглашение о вызове не будет переносимой.

Одним из решений, если вам действительно нужно это сделать, является использование libffi. Существует некоторая поддержка вызова переменной функции.

В противном случае я согласен с другими решениями использования массива с размером в качестве параметра.

1

Практически и теоретически нецелесообразно придумывать такие вещи, хотя обходные пути очень возможны ... Используйте некоторые хорошие структуры данных, такие как linked list, чтобы хранить любое количество элементов и передавать указатель на голову в вызывающей функции.

+1

Почему не массив? – LtWorf

Смежные вопросы