J'ai quelques boucles dont j'ai besoin dans mon programme. Je peux écrire le pseudo code, mais je ne suis pas tout à fait sûr de savoir comment les écrire logiquement.
J'ai besoin -
if (num is a multiple of 10) { do this }
if (num is within 11-20, 31-40, 51-60, 71-80, 91-100) { do this }
else { do this } //this part is for 1-10, 21-30, 41-50, 61-70, 81-90
Ceci est pour un jeu de société serpents et échelles, si cela a plus de sens pour ma question.
J'imagine la première instruction if dont j'ai besoin pour utiliser le module. Serait- if (num == 100%10)
ce correct?
Le second, je n'ai aucune idée. Je peux l'écrire comme if (num > 10 && num is < 21 || etc.)
, mais il doit y avoir quelque chose de plus intelligent que ça.
c++
comparison
conditional-statements
integer-arithmetic
utilisateur3419168
la source
la source
Réponses:
Pour le premier, pour vérifier si un nombre est un multiple d'utilisation:
Pour le second:
Mais c'est plutôt dense, et vous feriez peut-être mieux de simplement énumérer les options explicitement.
Maintenant que vous avez donné une meilleure idée de ce que vous faites, j'écrirais le deuxième comme suit:
C'est la même logique, mais en utilisant la fonction, nous avons une idée plus claire de ce que cela signifie.
la source
if((num - 1) / 10) % 2 == 1 && num < 100)
- Je pleurerais si je voyais ça.num >= 11
comme (1) que la limite inférieure est proscrite, et (2)%
sur un nombre négatif renvoie également un nombre négatif. (Je dois admettre qu'utiliser& 1
ici est "plus sûr" mais suppose également des connaissances supplémentaires.)getRow(num) % 2 == 0
dans une fonction ainsi pour indiquer clairement quelle est l'intention.bool inEvenRow(int num){ return getRow(num) % 2 ==0;}
L'astuce ici est de rechercher une sorte de points communs entre les gammes. Bien entendu, vous pouvez toujours utiliser la méthode "force brute":
Mais vous remarquerez peut-être que si vous soustrayez
1
denum
, vous aurez les plages:En d'autres termes, tous les nombres à deux chiffres dont le premier chiffre est impair. Ensuite, vous devez trouver une formule qui exprime cela. Vous pouvez obtenir le premier chiffre en divisant par 10, et vous pouvez tester que c'est étrange en vérifiant le reste de 1 lorsque vous divisez par 2. Rassemblez tout cela:
Étant donné le compromis entre un code plus long mais maintenable et un code "intelligent" plus court, je choisirais plus long et plus clair à chaque fois. À tout le moins, si vous essayez d'être intelligent, veuillez inclure un commentaire qui explique exactement ce que vous essayez d'accomplir.
Cela permet de supposer que le prochain développeur qui travaillera sur le code est armé et sait où vous habitez. :-)
la source
&& isTensDigitOdd(num)
, peut-être avec un commentaire avant la définition de la fonction expliquant ce qu'elle fait. Si un tel modèle existe, un commentaire expliquant le raisonnement du modèle est éclairant pour la maintenabilité imo.Si vous utilisez GCC ou tout autre compilateur prenant en charge les plages de cas, vous pouvez le faire, mais votre code ne sera pas portable .
la source
Ceci est pour les futurs visiteurs plus qu'un débutant. Pour une solution plus générale, semblable à un algorithme, vous pouvez prendre une liste de valeurs de début et de fin et vérifier si une valeur passée se trouve dans l'une d'elles:
Par souci de simplicité, j'ai utilisé un lambda polymorphe (C ++ 14) au lieu d'un
pair
argument explicite . Cela devrait aussi probablement s'en tenir à l'utilisation<
et==
être cohérent avec les algorithmes standard, mais cela fonctionne comme ça tant que celaElem
a été<=
défini pour cela. Quoi qu'il en soit, il peut être utilisé comme ceci:Il y a un exemple en direct ici .
la source
Le premier est facile. Il vous suffit d'appliquer l'opérateur modulo à votre valeur num:
Puisque C ++ évalue chaque nombre qui n'est pas 0 comme vrai, vous pouvez également écrire:
Pour le second, je pense que c'est plus simple à comprendre:
Le motif se répète tous les 20, vous pouvez donc calculer le modulo 20. Tous les éléments que vous voulez seront dans une rangée sauf ceux qui sont divisibles par 20.
Pour les obtenir également, utilisez simplement num-1 ou mieux num + 19 pour éviter de traiter des nombres négatifs.
Cela suppose que le modèle se répète pour toujours, donc pour 111-120, il s'appliquerait à nouveau, et ainsi de suite. Sinon, vous devez limiter les nombres à 100:
la source
Avec quelques bons commentaires dans le code, il peut être écrit de manière assez concise et lisible.
la source
num % 10 == 0
c'est la même chosenum
qu'un multiple de 10.if (num % 10 == 0)
signifie la même chose que// Check if it's a multiple of 10
ne devrait pas maintenir votre code. Il s'agit d'un anti-pattern bien connu.%
est un anti-pattern; ce n'est évidemment pas le cas. Vraiment, en supposant que beaucoup de lecteurs de cet article seront des débutants, leur enseigner ce style d'écriture des commentaires apporte une contribution négative à leur développement en tant que programmeurs.Vous avez essentiellement expliqué la réponse vous-même, mais voici le code au cas où.
la source
x < 41 x > 50
et mettez des parenthèses.operator&&
a une priorité plus élevée queoperator||
, donc ça va, mais je suis à peu près sûr que GCC l'avertit quand même.10 < x < 21
comme10 < x && x < 21
plutôt quex > 10 && x < 21
. Il est plus facile de lire l'inégalité quand elle est dans le même ordre que vous l'écririez mathématiquement.Vous y réfléchissez peut-être trop.
La première ligne
if (x % 10)
fonctionne car (a) une valeur qui est un multiple de 10 se calcule comme '0', les autres nombres donnent leur reste, (b) une valeur de 0 dans anif
est considéréefalse
, toute autre valeur esttrue
.Éditer:
Pour basculer dans la vingtaine, utilisez la même astuce. Cette fois, le numéro pivot est
10
:x/10
renvoie n'importe quel nombre de 0 à 9 comme0
, 10 à 19 comme1
et ainsi de suite. Tester sur pair ou impair - le& 1
- vous indique si c'est pair ou impair. Puisque vos plages sont en fait de "11 à 20", soustrayez 1 avant de tester.la source
Un plaidoyer pour la lisibilité
Bien que vous ayez déjà de bonnes réponses, je voudrais vous recommander une technique de programmation qui rendra votre code plus lisible pour certains futurs lecteurs - cela peut être vous dans six mois, un collègue a demandé d'effectuer une révision de code, votre successeur, .. .
C'est pour envelopper toutes les instructions "intelligentes" dans une fonction qui montre exactement (avec son nom) ce qu'elle fait. Bien qu'il y ait un impact minime sur les performances (de la "surcharge d'appel de fonction"), c'est vraiment négligeable dans une situation de jeu comme celle-ci.
En cours de route, vous pouvez nettoyer vos entrées - par exemple, tester les valeurs «illégales». Ainsi, vous pourriez vous retrouver avec un code comme celui-ci - voyez à quel point il est plus lisible? Les "fonctions d'assistance" peuvent être cachées quelque part (elles n'ont pas besoin d'être dans le module principal: leur nom indique clairement ce qu'elles font):
la source
YES
etNO
?TRUE
,True
outrue
? Et quels fichiers d'en-tête devrais-je inclure, le cas échéant, dans le C ordinaire? Alors j'ai roulé le mien. Je me demande si c'est ce qui a obtenu un vote négatif ...Pour le premier:
s'appliquera à:
Pour le second:
demandera:
Nous faisons d'abord
x-1
pour obtenir:Ensuite, nous les divisons par
10
pour obtenir:Nous vérifions donc si ce résultat est étrange.
la source
Vous pouvez essayer ce qui suit:
la source
Je sais que cette question a tellement de réponses, mais je vais quand même jeter la mienne ici ...
Tiré du code complet de Steve McConnell , 2nd Edition: "Stair-Step Access Tables:
Un autre type d'accès à la table est la méthode en escalier. Cette méthode d'accès n'est pas aussi directe qu'une structure d'index, mais elle ne gaspille pas autant d'espace de données. L'idée générale des structures en escalier, illustrée à la figure 18-5, est que les entrées dans un tableau sont valides pour des plages de données plutôt que pour des points de données distincts.
Figure 18-5 L'approche en escalier catégorise chaque entrée en déterminant le niveau auquel elle atteint un «escalier». Le «pas» qu'il atteint détermine sa catégorie.
Par exemple, si vous écrivez un programme de notation, la plage d'entrée «B» peut être comprise entre 75% et 90%. Voici une gamme de notes que vous pourriez avoir à programmer un jour:
Pour utiliser la méthode de l'escalier, vous placez l'extrémité supérieure de chaque plage dans une table, puis écrivez une boucle pour vérifier un score par rapport à l'extrémité supérieure de chaque plage. Lorsque vous trouvez le point auquel le score dépasse pour la première fois le haut d'une fourchette, vous savez quelle est la note. Avec la technique de l'escalier, vous devez faire attention à gérer correctement les extrémités des plages. Voici le code en Visual Basic qui attribue des notes à un groupe d'étudiants en fonction de cet exemple:
Bien qu'il s'agisse d'un exemple simple, vous pouvez facilement le généraliser pour gérer plusieurs étudiants, plusieurs systèmes de notation (par exemple, différentes notes pour différents niveaux de points sur différents devoirs) et des changements dans le système de notation. "
Code complet , 2e édition, pages 426 à 428 (chapitre 18).
la source
Comme d'autres l'ont souligné, rendre les conditions plus concises n'accélérera pas la compilation ou l'exécution, et cela n'aide pas nécessairement non plus la lisibilité.
Cela peut aider à rendre votre programme plus flexible, au cas où vous décideriez plus tard que vous voulez une version du jeu pour tout-petit sur un plateau 6 x 6, ou une version avancée (à laquelle vous pouvez jouer toute la nuit) sur un plateau 40 x 50 .
Je le coderais donc comme suit:
Oui, c'est verbeux, mais cela montre exactement ce qui se passe sur le plateau de jeu.
Si je développais ce jeu pour l'afficher sur un téléphone ou une tablette, je créerais des variables ROWS et COLUMNS au lieu de constantes, afin qu'elles puissent être définies dynamiquement (au début d'un jeu) pour correspondre à la taille et à l'orientation de l'écran.
J'autoriserais également l'orientation de l'écran à changer à tout moment, en milieu de partie - tout ce que vous avez à faire est de changer les valeurs de ROWS et COLUMNS, tout en laissant tout le reste (le numéro de carré actuel sur lequel chaque joueur est, et le carrés de début / fin de tous les serpents et échelles) inchangés. Ensuite, il vous suffit de bien dessiner le tableau et d'écrire du code pour vos animations (je suppose que c'était le but de vos
if
déclarations) ...la source
#define
#define
instructions de type fonction , pour mettre des parenthèses autour des arguments, là où ils apparaissent dans le développement. Alors au lieu de#define finished(num) (num == lastSquare)
vous devriez écrire#define finished(num) ((num) == lastSquare)
. La raison en est que si vous utilisez une telle instruction avec une expression contenant un opérateur avec une priorité suffisamment faible, vous n'obtiendrez pas la réponse que vous attendez. Dans ce cas, si vous n'utilisez pas les parenthèses supplémentaires, alors sefinished(a & b)
développe dans(a & b == lastSquare)
ce qui n'est certainement pas ce que vous voulez.