#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main(void)
{
srand(time(0));
int age = (rand() % 120) + 1;
printf("Si tu as %d an(s) tu es %s.\n", age, (age >= 18) ? "majeur" : "mineur");
}
Il n'y a pas de raison de désigner l'addition par "opérateur binaire", donc pas plus de désigner l'opérateur conditionnel par le terme "opérateur ternaire", même si c'est le seul à avoir trois pattes.
Il n'y a pas de raison non plus de mettre des parenthèses dans son premier opérande, quand les priorités, ou la lisibilité d'une expression composée, ne l'exigent pas.
A savoir : en raison des priorités d'opérateurs, le code
char *statut = age < 5 ? "un bébé"
: age < 10 ? "un enfant"
: age < 18 ? "un ado"
: age < 65 ? "en pleine forme"
: "un peu vieux";
fait exactement ce qu'on en attend, sans avoir à tartiner des parenthèses partout.
----
Je suspecte une confusion avec la forme syntaxique du if (*)
if (condition) instruction;
où les parenthèses sont, là, absolument obligatoires, comme dans for, while et switch.
(*) la fameuse "boucle if" !
---
PS, si on veut gagner en lisibilité sur l'appel
printf("Si tu as %d an(s) tu es %s.\n", age, (age >= 18) ? "majeur" : "mineur");
il est préférable de passer au style "un argument par ligne"
printf("Si tu as %d an(s) tu es %s.\n",
age,
age >= 18 ? "majeur" : "mineur");
qui est particulièrement adapté aux printf, en faisant apparaitre nettement les valeurs à afficher, surtout si elles sont nombreuses et données par des expressions.
- Edité par michelbillaud 15 février 2022 à 11:20:15
Il y a un nom officiel, qui n'est pas pire qu'un autre.
Je ne sais pas d'où sort (historiquement) l'idée d'appeler ce truc "opérateur ternaire". Le fait qu'il soit ternaire est une propriété au niveau syntaxique, pas sa définition sémantique.
Peut être une mauvaise interprétation d'une phrase du kernighan & ritchie (p 51) qui parle d'expression conditionnelle écrite grâce à l'opérateur ternaire ?:
L'index du bouquin ne parle pas de ternary operator ni de binary operator, mais par contre du unary plus / unary minus.
Mais bon << Although many ternary operators are possible, the conditional operator is so common, and other ternary operators so rare, that the conditional operator is commonly referred to as the ternary operator. >>, https://en.wikipedia.org/wiki/%3F:
- Edité par michelbillaud 15 février 2022 à 18:12:57
Il y a un nom officiel, qui n'est pas pire qu'un autre.
Je ne sais pas d'où sort (historiquement) l'idée d'appeler ce truc "opérateur ternaire". Le fait qu'il soit ternaire est une propriété au niveau syntaxique, pas sa définition sémantique.
Peut être une mauvaise interprétation d'une phrase du kernighan & ritchie (p 51) qui parle d'expression conditionnelle écrite grâce à l'opérateur ternaire ?:
L'index du bouquin ne parle pas de ternary operator ni de binary operator, mais par contre du unary plus / unary minus.
Mais bon << Although many ternary operators are possible, the conditional operator is so common, and other ternary operators so rare, that the conditional operator is commonly referred to as the ternary operator. >>, https://en.wikipedia.org/wiki/%3F:
- Edité par michelbillaud il y a environ 3 heures
Je dirais que c'est comme un frigidaire ou du scotch : parfois on appelle un objet par sa marque ... La pareil, quand on pense operateur conditionnel, on pense opérateur ternaire et vice et versa (comme diraient les Tranxen 200)
En fait en relisant, la question portait sur la "formule", pas l'opérateur, dans age = majeur ? 18 : 17;
Si par formule on entend la partie droite de l'affectation, c'est une expressionconditionnelle, du moins dans le vocabulaire commun qu'on utilise pour décrire les langages de programmation. Dans d'autres langages, elle prend différentes formes, genre
let age = 18 if majeur else 17
Ou
let age = if majeur then 18 else 17;
Le standard C semble utiliser "conditional expression" dans un sens différent : toute expression qui a l'air d'être formée à partir des opérateurs && || ?: ! Etc. Et qui donc exprime une condition. Ce qu'on appellerait plutôt expression logique, par contraste avec les expressions arithmétiques, mais bon, dans l'état où il est, on va pas changer le standard C.
- Edité par michelbillaud 16 février 2022 à 7:51:48
Je vous remercie tous de m'avoir répondu. Étant débutant en C, j'aurais un faveur à vous demander, pouuriez svp m'aider à réecrire l'exemple suivant en le remplaçant par l'opérateur tertenaire :
int main ()
{
int age=0;
printf("Quel age avez vous ? : ");
scanf ("%d", &age);
if (age>=18)
{
printf("Vous êtes majeur !");
}
else
{
printf("Vous êtes mineur!");
}
return 0;
}
Tu as eu pas mal de réponses en ce sens qui sont très proche de ce que tu cherches !
Ça ne t'as pas aidé ?
C'est parce qu'il y a des notions que j'ai pas encore étudiées. Pardonnez mon insistance malgré vos explications. Et encore merci à vous Rouloude et à tous les autres de m'avoir répondu. 🙏🙏🙏
la raison d'être d'une expression conditionnelle, c'est quand même de retourner une valeur. Un exemple où on ignore la valeur retournée, c'est pas très représentatif de l'usage qu'on en fait.
Un point intéressant : pour des raisons historiques, ce n'est pas encore trop la mode en C, mais il est bon de marquer "const" les variables si on n'a pas l'intention d'en changer la valeur plus loin. En rust par exemple, les "variables" sont des constantes, et il faut le déclarer explicitement si on veut quelles soient "mutables". Ça peut éviter des accidents.
Ça et ne déclarer une variable que quand on est capable de lui donner une valeur qui a un sens.
Le ternaire rend ça possible
const enum tarif t = age < 10 ? ENFANT
: age < 18 ? MINEUR
: age < 65 ? ADULTE
: : SENIOR;
alors que
const enum tarif t; // NOPE
if (age < 10) t = ENFANT
etc
ça va pas le faire
PS: si on veut écrire en anglais, faut que ça ça soit de l'anglais. En anglais, majeur se dit adult, ou of (legal) age (of majority).
En anglais, major, c'est un adjudant dans l'armée, ou le major d'une promotion (top of one's year). Et comme adjectif, c'est "important".
- Edité par michelbillaud 16 février 2022 à 18:13:55
Un point intéressant : pour des raisons historiques, ce n'est pas encore trop la mode en C, mais il est bon de marquer "const" les variables si on n'a pas l'intention d'en changer la valeur plus loin. En rust par exemple, les "variables" sont des constantes, et il faut le déclarer explicitement si on veut quelles soient "mutables". Ça peut éviter des accidents.
[...] -
Edité par michelbillaud il y a environ 15 heures
Attention à ne pas faire penser aux débutants que le mot clé const en C permet de déclarer des constantes (notion de constante au moment de la compilation). const en C est mal foutu. Il ne fait que marquer l'intention (comme tu le dis bien) de ne pas changer une valeur. C'est plus une promesse qu'autre chose. Le compilo peut vérifier dans quelques cas que c'est bien le cas, mais la plupart du temps il fait confiance à l'utilisateur qui lui fait cette promesse pour optimiser le code qu'il génère. Si l'utilisateur ment (intentionnellement ou pas) c'est se tirer une balle dans le pied. De plus const en C souffre de pas mal de problèmes surtout s'il est utilisé à plusieurs niveaux d'indirections. En conclusion, il vaut mieux que les débutants ne l'utilisent pas ; pour définir une «vraie constante» il vaudra sans doute mieux qu'ils passent par un define bien construit.
La notion d'immuabilité (comme celle proposée par Rust) est une notion très différente de const en C, en fait ce sont deux choses qui n'ont pas de lien direct.
ce qui est const, c'est pas le pointeur, mais les caractères pointés.
et il faut écrire
char * const chaine = "abc";
si on veut empêcher de modifier le pointeur.
Mais bon, const, c'est un modificateur (comme volatile, cui cui) ajouté au langage C de K&R pour le standard ANSI, qui avait pour but de codifier les pratiques existantes dans les divers compilateurs du moment. Quitte à ce que ça tourne au "je dis pas que vous pouvez pas le faire mais undefined behaviour, c'est vous qui voyez lol".
Le gros problème est que const signifie aussi bien «je promets de ne pas changer la valeur» que «ce truc ne peut pas changer de valeur, si il y a une tentative alors il faut crasher».
C'est un ajout tardif qui est mal géré et qui se gère mal.
Autant c'est super utile dans les prototypes de fonction pour indiquer qu'un paramètre de type pointeur sur T ne modifiera pas ce qui est pointé (comme par exemple avec le pointeur de fonction de comparaison dans qsort que tu mentionnes), autant c'est chiant à utiliser parce que cette propriété se propage, la fameuse const correctness.
Et puis on se retrouve face à une fonction de la libc comme strchr qui prend bien un paramètre const char * (la promesse que cette fonction ne modifiera pas la chaîne) et qui renvoie … un char * (du coup on peut modifier le contenu sans passer par des casts). Aucun message d'avertissement …
Par exemple :
#include <stdio.h>
#include <string.h>
int main(void)
{
char const string[] = "ABC";
char *p=strchr(string,'B');
*p='b';
printf("'B' est à l'indice %zu dans la chaine \"%s\"", p-string, string);
return 0;
}
On s'essaiera même à utiliser const corectement, et on peut se dire qu'un fonction qui libère une structure allouée sur le tas ne modifie par la structure et s'imaginer créer quelque chose comme :
et là le compilo nous avertit qu'on donne un pointeur sur quelque chose de constant à une fonction (free) qui s'attend à avoir quelque chose qui ne pointe pas sur quelque chose de constant et c'est parti par des casts qui nuisent à la lisibilité (entre autre).
Et je ne parle même pas du merdier lorsqu'on commence à vouloir manipuler des pointeurs constant sur des char constant …
Le const tel que définit en C n'est pas forcément très utile en dehors des prototypes, enfin àmha.
J'utilise le const aussi bien en C qu'en C++. Il est vrai qu'en C++ il est vital alors qu'en C il est plus gadget. Il permet d'indiquer que la donnée pointée ne sera que lue et c'est un avantage intéressant. C'est vrai de dans certains cas, le const est moins contrôlé en C. Mais pourquoi se priver de ce qu'il nous apporte. Quelques exemples (en comparant avec C++) où parfois il ne nous aide pas assez en C.
// C++ C
char txt = "XY"; // ne compile pas warning possible
const char Txt = "XY"; // compile compile
char str[] = "ABC"; // compile compile
char* p=strchr(Txt,'X'); // ne compile pas compile!!
char* q=strchr(str,'B'); // compile compile
const char* r=strchr(Txt,'X'); // compile compile
// Le C++ a transmis la constness de la chaine à p.
strcpy( txt, "123" ); // - plante!
strcpy( Txt, "123" ); // ne compile pas warning et plante!
// plus tordu:
const int X = 42;
const int* pq = &X; // valide valide
int* pt = NULL; // valide valide
const int** ppt = &pt; // ne compile pas! valide!
*ppt = &pq; // valide valide mais provoque pt=pq
*pt = 43; // valide plante car modifie const X
// Le C++ a bloqué une conversion semblant anodine mais qui peut amener plus tard à un problème.
la raison d'être d'une expression conditionnelle, c'est quand même de retourner une valeur.
On peut aussi dire qu'une opération produit une valeur. En effet, la notion de retour est plutôt propre à l'implémentation des fonctions, où la valeur retournée est le résultat produit par l'appel de fonction.
Le point est que condition ? Expression1 : Expression2 sans rien faire du résultat, ça se fait aussi bien avec if else, qui est déjà connu.
Et donc ça ne motive pas à retenir une autre syntaxe pour faire la même chose, sans bénéfice démontré.
- Edité par michelbillaud 20 février 2022 à 6:33:47
age = (major)? 18 : 17;
× Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
× Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
Le Tout est souvent plus grand que la somme de ses parties.
Recueil de code C et C++ http://fvirtman.free.fr/recueil/index.html
On écrit "j'ai tort", pas "tord" qui est le verbe "tordre" à la 3ème personne de l'indicatif présent
En recherche d'emploi.