web-dev-qa-db-fra.com

point d'interrogation dans les expressions

K & R Deuxième édition (page 71) - J'ai dû manquer l'explication:

sign = (s[i] == '-') ? -1 : 1;

Le contexte de ceci est une fonction qui convertit une chaîne en double. Cette partie en particulier intervient après que la fonction a sauté un espace. J'en déduis qu'il est en vérifiant la valeur positive ou négative et en l'enregistrant sous la forme -1 ou +1 pour la conversion de signe à la fin de la fonction ... return sign * val /power;

Je voudrais faire mieux que de déduire ... Je suis particulièrement incertain de ce que le ? et le : 1 font ici (ou ailleurs, d'ailleurs). 

Cela ressemble en quelque sorte à une déclaration abstraite if. Où ? vérifie la vérité et : est else... est-ce vrai? Est-ce limité à if/else?

Je suis un débutant et je n’ai jamais rencontré cette syntaxe d’expression auparavant, alors je me demande s’il existe une raison particulière pour laquelle il semble souvent être remplacé par un if/else-- formel, sinon peut-être par sa lisibilité?

14
d0rmLife

Cela semble un peu comme une déclaration abstraite. 

C'est correct. C'est ce qu'on appelle un "opérateur conditionnel ternaire".

La variable normale if fonctionne sur statement, tandis que l'opérateur conditionnel fonctionne sur expressions.


Je me demande s’il existe une raison particulière de le remplacer par une lisibilité formelle si/d’autre - en plus, peut-être, de lisibilité?

Dans certains cas, la création de branches sur des instructions ne suffit pas et vous devez travailler au niveau de l'expression.

Par exemple, considérons l'initialisation:

const int foo = bar ? 5 : 3;

Cela n'a pas pu être écrit avec une variable if/else normale.


Quoi qu'il en soit, les personnes qui disent que cela équivaut à la variable if/else sont imprécises. Bien que l'assembly généré soit généralement le même, ils ne sont pas équivalents et ne doivent pas être considérés comme une version abrégée de if. Autrement dit, utilisez if chaque fois que cela est possible et n’utilisez l’opérateur conditionnel que lorsque vous devez créer une branche sur des expressions.

13
Pubby

Cela ressemble en quelque sorte à un résumé si, où ? vérifie la vérité et : est autre ... est-ce vrai?

Oui, presque. C'est ce qu'on appelle "l'opérateur conditionnel" (parfois, l'opérateur "l'opérateur ternaire" n'est pas appelé avec précision, car il s'agit du seul opérateur ternaire en C). Ce n'est pas un instruction bien que, c'est un expression, il a une valeur. Il évalue à son deuxième argument si le premier argument est évalué à true et à son troisième argument s'il est faux. Donc

sign = (s[i] == '-') ? -1 : 1;

est équivalent à

if (s[i] == '-') {
    sign = -1;
} else {
    sign = 1;
}
15
user529758

C'est l'opérateur ternaire. (s[i] == '-') ? -1 : 1; renvoie -1 si s[i] == '-' et 1 sinon. Cette valeur est ensuite affectée à sign. En d'autres termes, un moyen plus long d'écrire ceci serait:

int sign;

if(s[i] == '-')
{
  sign = -1;
}
else
{
  sign = 1;
}
3
user554546

?: est l'opérateur conditionnel en C.

Dans votre exemple, cela produirait le même résultat que cette instruction if:

if (s[i] == '-')
{
    sign = -1;
}
else
{
    sign = 1;
}
2
ouah
sign = (s[i] == '-') ? -1 : 1;

est un raccourci pour:

if (s[i] == '-')
{
    sign = -1;
}
else
{
    sign = 1;
}
0
Inisheer