Existe-t-il un moyen de spécifier des arguments par défaut à une fonction en C?
c
arguments
default-parameters
Nathaniel Flath
la source
la source
Réponses:
Pas vraiment. La seule façon serait d' écrire une fonction varargs et de remplir manuellement les valeurs par défaut pour les arguments que l'appelant ne transmet pas.
la source
open(2)
appel système l'utilise pour un argument facultatif qui peut être présent en fonction des arguments requis etprintf(3)
lit une chaîne de format qui spécifie le nombre d'arguments. Les deux utilisent des varargs de manière assez sûre et efficace, et bien que vous puissiez certainement les visser, celaprintf()
semble particulièrement populaire.Wow, tout le monde est tellement pessimiste ici. La réponse est oui.
Ce n'est pas anodin: à la fin, nous aurons la fonction principale, une structure de support, une fonction wrapper et une macro autour de la fonction wrapper. Dans mon travail, j'ai un ensemble de macros pour automatiser tout cela; une fois que vous aurez compris le flux, il vous sera facile de faire de même.
J'ai écrit cela ailleurs, alors voici un lien externe détaillé pour compléter le résumé ici: http://modelingwithdata.org/arch/00000022.htm
Nous aimerions tourner
dans une fonction qui prend les valeurs par défaut (i = 8, x = 3,14). Définissez une structure associée:
Renommez votre fonction
f_base
et définissez une fonction wrapper qui définit les valeurs par défaut et appelle la base:Ajoutez maintenant une macro, en utilisant les macros variadiques de C. De cette façon, les utilisateurs n'ont pas à savoir qu'ils remplissent réellement une
f_args
structure et pensent qu'ils font l'habituel:OK, maintenant tout ce qui suit fonctionnerait:
Vérifiez les règles sur la façon dont les initialiseurs composés définissent les valeurs par défaut pour les règles exactes.
Une chose qui ne fonctionnera pas:
f(0)
parce que nous ne pouvons pas distinguer entre une valeur manquante et zéro. D'après mon expérience, c'est quelque chose à surveiller, mais peut être pris en charge lorsque le besoin s'en fait sentir --- la moitié du temps, votre valeur par défaut est vraiment nulle.J'ai eu du mal à écrire ceci parce que je pense que les arguments nommés et les valeurs par défaut rendent le codage en C plus facile et encore plus amusant. Et C est génial pour être si simple et en avoir encore assez pour rendre tout cela possible.
la source
{}
(initialiseur vide) est une erreur C99.#define vrange(...) CALL(range,(param){.from=1, .to=100, .step=1, __VA_ARGS__})
Oui. :-) Mais pas d'une manière que vous attendez.
Malheureusement, C ne vous permet pas de surcharger les méthodes, vous vous retrouveriez donc avec deux fonctions différentes. Pourtant, en appelant f2, vous appelleriez en fait f1 avec une valeur par défaut. Il s'agit d'une solution «Ne vous répétez pas», qui vous aide à éviter de copier / coller du code existant.
la source
Nous pouvons créer des fonctions qui utilisent des paramètres nommés (uniquement) pour les valeurs par défaut. Ceci est une continuation de la réponse de bk.
La norme C99 définit que les noms ultérieurs dans l'initialisation remplacent les éléments précédents. Nous pouvons également avoir certains paramètres de position standard, il suffit de modifier la signature de macro et de fonction en conséquence. Les paramètres de valeur par défaut ne peuvent être utilisés que dans le style de paramètre nommé.
Sortie du programme:
la source
OpenCV utilise quelque chose comme:
Si l'utilisateur ne sait pas ce qu'il doit écrire, cette astuce peut être utile:
la source
Non.
Même la toute dernière norme C99 ne le prend pas en charge.
la source
Non, c'est une fonctionnalité du langage C ++.
la source
Réponse courte: Non.
Réponse légèrement plus longue: il existe une ancienne, ancienne solution de contournement où vous passez une chaîne que vous analysez pour des arguments facultatifs:
où opt peut inclure une paire "nom = valeur" ou quelque chose, et que vous appelleriez comme
De toute évidence, cela n'est utile qu'occasionnellement. Généralement lorsque vous souhaitez une interface unique à une famille de fonctionnalités.
Vous trouvez toujours cette approche dans les codes de physique des particules qui sont écrits par des programmes professionnels en c ++ (comme par exemple ROOT ). Son principal avantage est qu'il peut être étendu presque indéfiniment tout en conservant la rétrocompatibilité.
la source
struct
et je demanderais à l'appelant d'en créer une, de remplir les champs pour différentes options, puis de la transmettre par adresse ou de passerNULL
pour les options par défaut.La meilleure façon de le faire (ce qui peut ou non être possible dans votre cas selon votre situation) est probablement de passer au C ++ et de l'utiliser comme «un meilleur C». Vous pouvez utiliser C ++ sans utiliser de classes, de modèles, de surcharge d'opérateur ou d'autres fonctionnalités avancées.
Cela vous donnera une variante de C avec surcharge de fonction et paramètres par défaut (et quelles que soient les autres fonctionnalités que vous choisissiez d'utiliser). Vous devez juste être un peu discipliné si vous voulez vraiment utiliser uniquement un sous-ensemble restreint de C ++.
Beaucoup de gens diront que c'est une très mauvaise idée d'utiliser C ++ de cette façon, et ils pourraient avoir raison. Mais c'est juste une opinion; Je pense qu'il est valable d'utiliser des fonctionnalités de C ++ avec lesquelles vous êtes à l'aise sans avoir à acheter tout cela. Je pense qu'une partie importante de la raison du succès du C ++ est qu'il a été utilisé par un grand nombre de programmeurs à ses débuts exactement de cette façon.
la source
Encore une autre option utilise
struct
s:la source
Non.
la source
20202020
en hexadécimal, mais comment le taper?Une autre astuce à l'aide de macros:
Si un seul argument est passé,
b
reçoit la valeur par défaut (dans ce cas 15)la source
Non, mais vous pourriez envisager d'utiliser un ensemble de fonctions (ou macros) pour approximer à l'aide d'arguments par défaut:
la source
Oui, avec les fonctionnalités de C99, vous pouvez le faire. Cela fonctionne sans définir de nouvelles structures de données ou ainsi et sans que la fonction doive décider au moment de l'exécution comment elle a été appelée, et sans aucune surcharge de calcul.
Pour une explication détaillée, voir mon article sur
http://gustedt.wordpress.com/2010/06/03/default-arguments-for-c99/
Jens
la source
Généralement non, mais dans gcc Vous pouvez rendre le dernier paramètre de funcA () optionnel avec une macro.
Dans funcB (), j'utilise une valeur spéciale (-1) pour signaler que j'ai besoin de la valeur par défaut pour le paramètre 'b'.
la source
J'ai amélioré la réponse de Jens Gustedt pour que:
variadic.h:
Scénario d'utilisation simplifié:
Et avec _Generic:
Et avec la sélection de nom de fonction variadic, qui ne peut pas être combinée avec _Generic:
la source
OUI
Grâce aux macros
3 paramètres:
Si vous voulez le 4ème argument, alors un my_func3 supplémentaire doit être ajouté. Notez les changements dans VAR_FUNC, my_func2 et my_func
4 paramètres:
Seule exception: les variables flottantes ne peuvent pas recevoir de valeurs par défaut ( sauf si c'est le dernier argument comme dans le cas des 3 paramètres ), car elles ont besoin de point ('.'), Ce qui n'est pas accepté dans les arguments de macro. Mais peut comprendre une solution de contournement comme on le voit dans la macro my_func2 (cas de 4 paramètres )
Programme
Production:
la source
Oui, vous pouvez faire quelque chose de simulair, ici vous devez connaître les différentes listes d'arguments que vous pouvez obtenir, mais vous avez alors la même fonction pour gérer tout.
la source
Pourquoi ne pouvons-nous pas faire cela.
Donnez à l'argument facultatif une valeur par défaut. De cette façon, l'appelant de la fonction n'a pas nécessairement besoin de passer la valeur de l'argument. L'argument prend la valeur par défaut. Et facilement cet argument devient facultatif pour le client.
Par exemple
void foo (int a, int b = 0);
Ici b est un argument facultatif.
la source