¿Hay alguna manera de especificar argumentos predeterminados para una función en C?
c
arguments
default-parameters
Nathaniel Flath
fuente
fuente
Respuestas:
Realmente no. La única forma sería escribir una función varargs y completar manualmente los valores predeterminados para los argumentos que la persona que llama no pasa.
fuente
open(2)
llamada al sistema usa esto para un argumento opcional que puede estar presente dependiendo de los argumentos requeridos, yprintf(3)
lee una cadena de formato que especifica cuántos argumentos habrá. Ambos usan varargs de manera bastante segura y efectiva, y aunque ciertamente puedes arruinarlos,printf()
especialmente parece ser bastante popular.Wow, todos son tan pesimistas por aquí. La respuesta es sí.
No es trivial: al final, tendremos la función central, una estructura de soporte, una función de contenedor y una macro alrededor de la función de contenedor. En mi trabajo tengo un conjunto de macros para automatizar todo esto; Una vez que comprenda el flujo, le será fácil hacer lo mismo.
He escrito esto en otro lugar, así que aquí hay un enlace externo detallado para complementar el resumen aquí: http://modelingwithdata.org/arch/00000022.htm
Nos gustaría girar
en una función que toma valores predeterminados (i = 8, x = 3.14). Defina una estructura complementaria:
Cambie el nombre de su función
f_base
y defina una función de contenedor que establezca valores predeterminados y llame a la base:Ahora agregue una macro, usando las macros variadas de C. De esta manera, los usuarios no tienen que saber que en realidad están poblando una
f_args
estructura y piensan que están haciendo lo habitual:Bien, ahora todo lo siguiente funcionaría:
Verifique las reglas sobre cómo los inicializadores compuestos establecen valores predeterminados para las reglas exactas.
Una cosa que no funcionará
f(0)
, porque no podemos distinguir entre un valor perdido y cero. En mi experiencia, esto es algo a tener en cuenta, pero se puede solucionar cuando surja la necesidad, la mitad del tiempo que su valor predeterminado realmente es cero.Tuve la molestia de escribir esto porque creo que los argumentos y valores predeterminados realmente hacen que la codificación en C sea más fácil e incluso más divertida. Y C es increíble por ser tan simple y tener suficiente para hacer todo esto posible.
fuente
{}
(inicializador vacío) es un error C99.#define vrange(...) CALL(range,(param){.from=1, .to=100, .step=1, __VA_ARGS__})
Si. :-) Pero no de la forma que esperarías.
Desafortunadamente, C no le permite sobrecargar los métodos, por lo que terminaría con dos funciones diferentes. Aún así, al llamar a f2, en realidad estarías llamando a f1 con un valor predeterminado. Esta es una solución "No te repitas", que te ayuda a evitar copiar / pegar el código existente.
fuente
Podemos crear funciones que utilizan parámetros con nombre (solo) para los valores predeterminados. Esta es una continuación de la respuesta de bk.
El estándar C99 define que los nombres posteriores en la inicialización anulan los elementos anteriores. También podemos tener algunos parámetros posicionales estándar, simplemente cambie la macro y la firma de la función en consecuencia. Los parámetros de valor predeterminado solo se pueden usar en el estilo de parámetro con nombre.
Salida del programa:
fuente
OpenCV usa algo como:
Si el usuario no sabe lo que debe escribir, este truco puede ser útil:
fuente
No.
Ni siquiera el último estándar C99 lo admite.
fuente
No, esa es una característica del lenguaje C ++.
fuente
Respuesta corta: no.
Respuesta un poco más larga: hay una solución antigua y antigua en la que pasa una cadena que analiza para obtener argumentos opcionales:
donde opt puede incluir el par "nombre = valor" o algo así, y al que llamarías como
Obviamente, esto solo es útil ocasionalmente. En general, cuando desea una interfaz única para una familia de funcionalidades.
Todavía encuentra este enfoque en códigos de física de partículas escritos por programas profesionales en c ++ (como, por ejemplo, ROOT ). Su principal ventaja es que puede extenderse casi indefinidamente mientras se mantiene la compatibilidad.
fuente
struct
y pediría a la persona que llama que haga uno, complete los campos para diferentes opciones y luego lo pase por dirección o paseNULL
por las opciones predeterminadas.Probablemente la mejor manera de hacer esto (que puede o no ser posible en su caso dependiendo de su situación) es pasar a C ++ y usarlo como 'una mejor C'. Puede usar C ++ sin usar clases, plantillas, sobrecarga del operador u otras características avanzadas.
Esto le dará una variante de C con sobrecarga de funciones y parámetros predeterminados (y cualquier otra característica que elija usar). Solo tiene que ser un poco disciplinado si realmente quiere usar solo un subconjunto restringido de C ++.
Mucha gente dirá que es una idea terrible usar C ++ de esta manera, y podrían tener un punto. Pero es solo una opinión; Creo que es válido usar características de C ++ con las que te sientas cómodo sin tener que comprar todo. Creo que una parte importante de la razón del éxito de C ++ es que fue utilizado por una gran cantidad de programadores en sus primeros días exactamente de esta manera.
fuente
Otra opción más usa
struct
s:fuente
No.
fuente
20202020
en hexadecimal, pero ¿cómo lo escribo?Otro truco usando macros:
Si solo se pasa un argumento,
b
recibe el valor predeterminado (en este caso 15)fuente
No, pero puede considerar el uso de un conjunto de funciones (o macros) para aproximarse utilizando argumentos predeterminados:
fuente
Sí, con las características de C99 puede hacer esto. Esto funciona sin definir nuevas estructuras de datos más o menos y sin que la función tenga que decidir en tiempo de ejecución cómo se llamó, y sin ninguna sobrecarga computacional.
Para una explicación detallada, vea mi publicación en
http://gustedt.wordpress.com/2010/06/03/default-arguments-for-c99/
Jens
fuente
Generalmente no, pero en gcc Puede hacer que el último parámetro de funcA () sea opcional con una macro.
En funcB (), uso un valor especial (-1) para indicar que necesito el valor predeterminado para el parámetro 'b'.
fuente
Mejoré la respuesta de Jens Gustedt para que:
variadic.h:
Escenario de uso simplificado:
Y con _Generic:
Y con la selección de nombre de función variable, que no se puede combinar con _Generic:
fuente
SI
A través de macros
3 parámetros:
Si desea el 4to argumento, entonces se necesita agregar my_func3 adicional. Observe los cambios en VAR_FUNC, my_func2 y my_func
4 parámetros:
La única excepción es que las variables flotantes no pueden tener valores predeterminados (a menos que sea el último argumento como en el caso de los 3 parámetros ), porque necesitan un punto ('.'), Que no se acepta dentro de los argumentos macro. Pero puede resolver un problema como se ve en la macro my_func2 ( de 4 parámetros )
Programa
Salida:
fuente
Sí, puede hacer algo similar, aquí debe conocer las diferentes listas de argumentos que puede obtener, pero tiene la misma función que manejar.
fuente
¿Por qué no podemos hacer esto?
Otorgue al argumento opcional un valor predeterminado. De esa manera, el llamador de la función no necesariamente necesita pasar el valor del argumento. El argumento toma el valor predeterminado. Y fácilmente ese argumento se vuelve opcional para el cliente.
Por ej.
nulo foo (int a, int b = 0);
Aquí b es un argumento opcional.
fuente