Можете ли вы иметь в C аргументы переменной длины с функциями, когда вы не хотите передавать какую-либо переменную? - PullRequest
0 голосов
/ 12 мая 2019

Я хочу создать функцию в C с аргументами переменной длины, в которой я не хочу передавать какую-либо переменную в какой-то момент. Я такая вещь возможна в C? Я хотел бы некоторые фрагменты кода, если это возможно. Также я должен упомянуть, что функция будет передавать только переменные char *, когда передаются некоторые переменные.

Ответы [ 5 ]

1 голос
/ 12 мая 2019

нет, вы не можете

вам нужен хотя бы один известный аргумент

void foo(int dummy, ...)
{
va_list ap;
1 голос
/ 12 мая 2019

Функция с переменными аргументами должна иметь как минимум один аргумент имен для чтения других.

Для вашего конкретного случая, поскольку вы хотите передать список char * аргументов, вы можете использовать NULL дляобозначим конец списка аргументов.Поэтому в случае, когда нечего передавать, вы просто передаете одиночный аргумент NULL.

1 голос
/ 12 мая 2019

Это не поддерживается стандартом C.

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

Для функции, определенной с идентификаторомlist, количество аргументов в вызове должно соответствовать количеству параметров в определении;переменное количество аргументов не поддерживается.

Если вы будете вызывать функцию с переменным числом char * аргументов, и это число может быть равно нулю, вы можете объявить функцию с фиктивным первым аргументом, который всегдапередано, но никогда не используется, как в случае:

void foo(int dummy,...);

Обратите внимание, что передача аргументов без аргументов является проблематичным проектом.Обычно подпрограммы, которые принимают различное количество аргументов, определяют количество аргументов из одного или нескольких аргументов.Например, первый аргумент может содержать количество оставшихся аргументов или это может быть строка формата (как в случае printf), из которой можно определить количество и типы оставшихся аргументов.Если вы хотите, чтобы функция принимала нулевые аргументы в некоторых ситуациях, у нее должен быть способ узнать, была ли она вызвана с нулевыми аргументами или более.Для этого потребуется информация в каком-то глобальном состоянии, что обычно является плохим дизайном.

0 голосов
/ 12 мая 2019

Можете ли вы иметь в C аргументы переменной длины с функциями, когда вы не хотите передавать какую-либо переменную?

Да.В современном C, Code не может определять ... функцию без аргументов, но вы можете вызвать такую ​​функцию без аргументов, объявив функцию без сигнатуры функции.Таким образом, функцию можно вызывать с нулевыми аргументами.


Функция все еще нуждается в некотором способе понимания количества аргументов.Это часто делается с первым аргументом в виде счетчика (или формат ) или последним аргументом в качестве сторожа.

Учитывая "будет передано только char*" ...

int foo_count(int counter, ...);    
// zero usage example
foo_count(0);    

int foo_sentinel(char *s);    
// zero usage example
foo_sentinel((char*) NULL);    

Чтобы сделать это с передачей аргументов no , счет должен передаваться другим способом, возможно, с помощью глобальной переменной - хотя это не рекомендуется.(Лучше просто передать счет.)

Объявить функцию:

int foo_count;
int foo(); // no prototype

Вызов функция

foo_count = 0; foo()
foo_count = 1; foo("one")
foo_count = 2; foo("one", "two")

Определить функцию

int foo(char *s1, ...) {
  if (foo_count > 0) {
    va_list ap;
    va_start(ap, s1);
    puts(s1);
    for (int i=1; i < foo_count; i++) {
      puts(va_arg(ap, char *));
    }
    va_end(ap);
  }
}
0 голосов
/ 12 мая 2019

C не предоставляет никакого механизма, позволяющего вызываемой функции определять, сколько аргументов было предоставлено. Механизм должен быть частью вызывающего интерфейса.

Например, printf опирается на спецификации формата %, в то время как execv требует, чтобы вызывающая сторона установила нулевой указатель в качестве последнего аргумента.

Функция varargs может быть вызвана без переменных аргументов, но вызывающая сторона не должна пытаться получить доступ к какому-либо переменному аргументу в этом случае. Например, аргумент mode функции Posix open () используется только в случае создания нового файла, поэтому его не нужно указывать, если аргумент flags не содержит флаг O_CREAT (или какой-либо другой флаг расширения, например O_TMPFILE в Linux, который запрашивает создание файла).

Часть прототипа переменной длины должна следовать как минимум за одним фиксированным аргументом. Поэтому невозможно вызвать функцию varargs без аргументов вообще.

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