Existe uma maneira de especificar argumentos padrão para uma função em C?
c
arguments
default-parameters
Nathaniel Flath
fonte
fonte
Respostas:
Na verdade não. A única maneira seria escrever uma função varargs e preencher manualmente os valores padrão para argumentos que o chamador não passa.
fonte
open(2)
chamada do sistema usa isso para um argumento opcional que pode estar presente, dependendo dos argumentos necessários, eprintf(3)
lê uma sequência de formato que especifica quantos argumentos haverá. Ambos usam varargs com bastante segurança e eficácia, e embora você possa estragar tudo,printf()
especialmente parece ser bastante popular.Uau, todo mundo é tão pessimista por aqui. A resposta é sim.
Não é trivial: no final, teremos a função principal, uma estrutura de suporte, uma função de wrapper e uma macro em torno da função de wrapper. No meu trabalho, tenho um conjunto de macros para automatizar tudo isso; depois de entender o fluxo, será fácil fazer o mesmo.
Eu escrevi isso em outro lugar, então aqui está um link externo detalhado para complementar o resumo aqui: http://modelingwithdata.org/arch/00000022.htm
Gostaríamos de transformar
em uma função que assume padrões (i = 8, x = 3,14). Defina uma estrutura complementar:
Renomeie sua função
f_base
e defina uma função de wrapper que defina os padrões e chame a base:Agora adicione uma macro, usando as macros variadas de C. Dessa forma, os usuários não precisam saber que estão preenchendo uma
f_args
estrutura e acham que estão fazendo o habitual:OK, agora tudo o que se segue funcionaria:
Verifique as regras sobre como os inicializadores compostos definem os padrões para as regras exatas.
Uma coisa que não funcionará:
f(0)
porque não podemos distinguir entre um valor ausente e zero. Na minha experiência, isso é algo a ser observado, mas pode ser resolvido conforme a necessidade - metade do tempo em que seu padrão é realmente zero.Eu tive o trabalho de escrever isso porque acho que os argumentos e padrões nomeados realmente tornam a codificação em C mais fácil e ainda mais divertida. E C é incrível por ser tão simples e ainda ter o suficiente para tornar tudo isso possível.
fonte
{}
(inicializador vazio) é um erro C99.#define vrange(...) CALL(range,(param){.from=1, .to=100, .step=1, __VA_ARGS__})
Sim. :-) Mas não da maneira que você esperaria.
Infelizmente, C não permite que você sobrecarregue métodos, então você terminaria com duas funções diferentes. Ainda assim, ao chamar f2, você realmente chamaria f1 com um valor padrão. Esta é uma solução "Não se repita", que ajuda a evitar copiar / colar o código existente.
fonte
Podemos criar funções que usam parâmetros nomeados (apenas) para valores padrão. Esta é uma continuação da resposta de bk.
O padrão C99 define que nomes posteriores na inicialização substituam os itens anteriores. Também podemos ter alguns parâmetros posicionais padrão, basta alterar a macro e a assinatura da função de acordo. Os parâmetros de valor padrão podem ser usados apenas no estilo de parâmetro nomeado.
Saída do programa:
fonte
O OpenCV usa algo como:
Se o usuário não souber o que deve escrever, esse truque pode ser útil:
fonte
Não.
Nem mesmo o mais recente padrão C99 suporta isso.
fonte
Não, esse é um recurso da linguagem C ++.
fonte
Resposta curta: Não.
Resposta um pouco mais longa: Há uma solução antiga e antiga em que você passa uma sequência que analisa para argumentos opcionais:
onde opt pode incluir o par "nome = valor" ou algo assim, e que você chamaria como
Obviamente, isso só é útil ocasionalmente. Geralmente quando você deseja uma única interface para uma família de funcionalidades.
Você ainda encontra essa abordagem em códigos de física de partículas escritos por programas profissionais em c ++ (como por exemplo, ROOT ). Sua principal vantagem é que ele pode ser estendido quase indefinidamente, mantendo a compatibilidade com versões anteriores.
fonte
struct
e faria com que o chamador fizesse um, preencha os campos para opções diferentes e depois o passe pelo endereço ouNULL
pelas opções padrão.Provavelmente, a melhor maneira de fazer isso (que pode ou não ser possível no seu caso, dependendo da sua situação) é mudar para C ++ e usá-lo como 'um C melhor'. Você pode usar C ++ sem usar classes, modelos, sobrecarga de operador ou outros recursos avançados.
Isso fornecerá uma variante de C com sobrecarga de função e parâmetros padrão (e quaisquer outros recursos que você escolher usar). Você só precisa ser um pouco disciplinado se quiser realmente usar apenas um subconjunto restrito de C ++.
Muitas pessoas dirão que é uma péssima idéia usar C ++ dessa maneira, e elas podem ter razão. Mas é apenas uma opinião; Eu acho que é válido usar recursos do C ++ com os quais você se sinta confortável sem precisar comprar tudo. Eu acho que uma parte significativa da razão do sucesso do C ++ é que ele foi usado por muitos programadores nos primeiros dias exatamente dessa maneira.
fonte
Ainda outra opção usa
struct
s:fonte
Não.
fonte
20202020
em hexadecimal, mas como digito?Outro truque usando macros:
Se apenas um argumento for passado,
b
recebe o valor padrão (neste caso 15)fonte
Não, mas você pode considerar usar um conjunto de funções (ou macros) para aproximar usando argumentos padrão:
fonte
Sim, com os recursos do C99, você pode fazer isso. Isso funciona sem definir novas estruturas de dados ou mais e sem que a função precise decidir em tempo de execução como foi chamada e sem nenhuma sobrecarga computacional.
Para uma explicação detalhada, veja meu post em
http://gustedt.wordpress.com/2010/06/03/default-arguments-for-c99/
Jens
fonte
Geralmente não, mas em gcc Você pode tornar o último parâmetro de funcA () opcional com uma macro.
Em funcB () eu uso um valor especial (-1) para sinalizar que eu preciso do valor padrão para o parâmetro 'b'.
fonte
Melhorei a resposta de Jens Gustedt para que:
variadic.h:
Cenário de uso simplificado:
E com _Generic:
E com a seleção variável de nome de função, que não pode ser combinada com _Generic:
fonte
SIM
Através de macros
3 parâmetros:
Se você quiser o 4º argumento, será necessário adicionar um my_func3 extra. Observe as alterações em VAR_FUNC, my_func2 e my_func
4 parâmetros:
Única exceção, que variáveis flutuantes não podem receber valores padrão (a menos que seja o último argumento, como no caso dos 3 parâmetros ), porque precisam do ponto ('.'), Que não é aceito nos argumentos da macro. Mas pode descobrir uma solução alternativa, como pode ser visto na macro my_func2 ( de 4 parâmetros )
Programa
Resultado:
fonte
Sim, você pode fazer alguma simulação, aqui você precisa conhecer as diferentes listas de argumentos que pode obter, mas tem a mesma função para lidar com todas.
fonte
Por que não podemos fazer isso?
Atribua um valor padrão ao argumento opcional. Dessa forma, o chamador da função não precisa necessariamente passar o valor do argumento. O argumento assume o valor padrão. E facilmente esse argumento se torna opcional para o cliente.
Por exemplo
void foo (int a, int b = 0);
Aqui b é um argumento opcional.
fonte