0
votes

Quand une fonction devrait-elle renvoyer quoi?

Je suis un peu confus sur le type de retour d'une fonction, spécifiquement quand retourner quoi. Si nous avons une fonction arbitraire, disons min (x, y), qui devraient revenir conformément aux déclarations de si, que dois-je revenir en dehors de leur portée, qui est requise par la déclaration de la fonction. J'ai appris qu'il est courant d'utiliser "retour 0" ou "retour 1" mais je ne comprends pas pourquoi c'est-à-dire et pourquoi il ne peut pas simplement retourner l'une des déclarations de retour de l'if. xxx


6 commentaires

Une fonction doit renvoyer la valeur que vous souhaitez revenir à l'appelant. Ce que cette valeur dépend de l'objectif de la fonction. Souvent, 0 et 1 sont utilisés pour indiquer le succès et l'échec, ou l'échec et le succès, ou faux et vrai. Souvent, une fonction renvoie une valeur calculée à partir de ses paramètres. Dans le cas d'une fonction min , min représente probablement "minimum", et il doit renvoyer la valeur minimale de ses deux paramètres. Une fonction min ne renvoie normalement pas 1 dans le cas d'égalité (à moins que les deux chiffres ne soient 1).


Une fonction pour renvoyer la différence absolue de deux valeurs ne doit pas être appelée min . Il pourrait être appelé absolutefenceference ou Absdiff ou quelque chose le long de ces lignes. Dans la forme la plus simple, une telle fonction reviendrait à zéro si les deux chiffres sont égaux. Si vous souhaitez en retourner un pour un chiffre égal, vous pouvez l'appeler clampedabsoluteferfence .


Notez que, dans moderne C, int min (x, y) n'est pas une déclaration appropriée. Vous avez besoin de types pour les paramètres, tels que int min (int x, int y) .


@Ericpostpischil mais pourquoi dois-je le déclarer deux fois? Si je veux qu'il retourne la différence. Pourquoi la fonction ne saute-t-elle pas le retour 1 et ne renvoie que l'un des ifs, s'il est vrai et terminer?


@Mike déclarer à quoi deux fois? Le retour 1; ne sera jamais exécuté car les trois cas possibles sont traités auparavant. Par conséquent, vous pouvez supprimer le retour 1; . Ou mieux Écrivez la fonction comme suggérée par la réponse de Ericpostpischil.


Notez que le calcul est sujet à débordement (comportement non défini) si, par exemple, y == int_min + 3 et x == int_max - 3 .


4 Réponses :


2
votes
  • Si x est plus grand que y , retour x-y (évident)
  • Si y est plus grand que x , retourner y-x (aussi évident)
  • si x et y est égal , que pensez-vous devrait être retourné?
    Si Ils sont égaux, les deux xy et yx sont 0 , donc cela n'a pas vraiment d'importance, n'est-ce pas?

    Votre clause finale pourrait être écrite de: xxx

    car ils sont égaux, ils évalueront tous 0 .

    La partie importante est de s'assurer que le contrat de la fonction est maintenu.
    Selon les commentaires, la fonction affirme qu'il retournera la différence entre les deux valeurs. Donc, il devrait renvoyer la différence dans tous les cas , si la valeur plus grande est X, Y ou sont égales.

    Le nom de votre fonction est extrêmement trompeur. Parce qu'il est nommé min , il l'implique de renvoyer la valeur minimum , pas la différence. Vous devez modifier le nom de la fonction à quelque chose comme diff ou delta pour clarté.


    finalement, le moyen plus simple d'écrire la fonction serait: xxx

    Enfin, certaines versions très courtes que je considérerais mieux. xxx


2 commentaires

Ouais mais si je l'exécute avec Printf, il revient 1. Pourquoi est-ce?


@Mike Lorsque vous l'exécutez avec deux valeurs égales, renvoyez 1 car vous l'avez dit de retourner 1 .



-1
votes

Le type de retour de la fonction est spécifié dans la définition, int dans votre cas. En fait, vous devez spécifier le type d'arguments d'entrée ( x, y ), puis le type de la sortie est généralement dérivé de leur type - comme 2/3 cas dans votre fonction et le dernier est entier. ( 0 ).

remarque: Vous devez également choisir un meilleur nom pour la fonction.


1 commentaires

Le corps de la fonction int min (x, y) {...} est la définition de non-prototype (K & R ou pré-standard) C. Les versions actuelles de la norme le permettent toujours, bien que la notation soit marquée obsolescente (bien que C99 et ultérieure exigerait int min (x, y) int x, y; {... Corps de fonction ...} ).



1
votes

Le compilateur doit vous assurer de retourner quelque chose. Si vous avez des retours à l'intérieur de si vous avez des déclarations, comme vous l'avez, comment le compilateur va-t-il dire si vous avez couvert tous les cas?

Même si vous faites quelque chose comme le code ci-dessous, comment le compilateur va-t-il savoir que vous retournera dans toutes les circonstances? Étant donné que ce code lancera une erreur: xxx

Comment pouvez-vous combattre ceci? Vous pouvez écrire un autre retour à la fin de la fonction, comme vous l'avez. Maintenant, le compilateur sache que vous retournerez une valeur quel que soit ce qui se passe.

Cependant, il existe de meilleurs moyens de vous assurer que vous retournerez toujours une valeur. Par exemple, vous pouvez utiliser une instruction d'autre comme une prise de capture: xxx

car l'autre est garantie de prendre tous les cas, le compilateur en est content et ne sera pas lancer des erreurs.


11 commentaires

La première version de la fonction min ne jette pas une erreur et int min (x, y) est mauvais de toute façon. Et il n'y a pas d'exception dans C.


@Jabberwocky: Quel est le problème avec int min (x, y) ? Ce n'est pas un prototype, accordé, et il n'aurait pas dû être écrit par quiconque dans le millénaire actuel et devrait probablement être int min (x, y) int x, y; {... Corps de la fonction ...} , mais il y a une nuance que je ne vois pas dans votre commentaire.


@Jabberwocky I Obtenez une erreur lancée (le contrôle atteint la fin de la fonction non vide) sur GCC. Quant à la décélération, j'ai copié de la question et j'ai oublié de réparer. Va le faire maintenant.


@hat étrange, je ne reçois pas l'erreur: vérifier ici: goodbolt.org/z/on5fex


Même si le type de retour d'une fonction n'est pas annulé, la norme C ne nécessite pas de renvoyer une valeur, à condition que l'appelant ne tente pas d'utiliser la valeur de retour. (Cela peut être utile pour une fonction qui obtient une valeur ou définit une valeur, en fonction d'un paramètre qui est donné. Le chemin "Définir une valeur" n'a pas besoin de renvoyer une valeur.) Donc, un compilateur peut avertir s'il y a Un chemin de contrôle sans retour , mais, lorsqu'il est en mode compatible standard, il doit traduire avec succès une telle fonction.


@hat je reçois l'avertissement ici: goodbolt.org/z/on5fex quand je supprime sinon retour 1; Quelle version du compilateur avez-vous?


@Jabberwocky: Je n'ai pas vérifié le code dans votre dernier commentaire. Le comportement est le même alors.


@Jabberwocky: GCC 7.3.0 Compilation de C99


@hat très étrange. Peut-être que votre IDE (si vous en avez un) passe d'autres drapeaux au compilateur? Quelle est votre ligne de commande exacte pour le compilateur?


@Jabberwocky: Oh, c'est ce que tu me demandais? Je voulais dire -wall était la seule option d'avertissements, je compile avec -c et construire avec -o sur des fichiers autonomes (Buily de Geany par défaut)


Laissez-nous Continuer cette discussion en chat .



0
votes

Pour une fonction qui calculait la différence entre deux valeurs, vous ne renverriez que 1 si la différence entre ces deux valeurs était de 1, 0 si elles étaient égales.

Il y a une école de programmation qui dit qu'il est préférable d'avoir un seul retour à la fin de la fonction, plutôt que de multiples retours dispersés partout. Au lieu de retourner la différence dans chaque branche, calculez et stockez cette différence, et retournez-la à la fin de la fonction: xxx

Comme la plupart des règles de programmation, il existe des exceptions. Il y a des moments où vous veux quitter immédiatement si une certaine condition n'est pas satisfaite. Savoir quand quelle approche est la meilleure chose est une question d'expérience.


0 commentaires