Quelles sont les règles générales pour comparer différents types de données en C?

Disons que j’ai les scénarios suivants:

int i = 10; short s = 5; if (s == i){ do stuff... } else if (s < i) { do stuff... } 

Quand C la comparaison convertit-elle le type de données le plus petit, dans ce cas short en int ou convertit-elle le type de données de droite en type de données de gauche? Dans ce cas, int court?

Ceci est régi par les conversions arithmétiques habituelles . Dans les cas simples, la règle générale est que le type avec la précision “less” est converti pour correspondre au type avec la précision “more”, mais il devient un peu complexe une fois que vous commencez à mélanger signed et unsigned .

En C99, ceci est décrit par la section 6.3.1.8, que je présente ici pour votre commodité:

  • Premièrement, si le type réel correspondant de l’un ou l’autre opérande est long double , l’autre opérande est converti, sans changement de type domaine, en un type dont le type réel correspondant est long double .

  • Sinon, si le type réel correspondant de l’un ou l’autre opérande est double , l’autre opérande est converti, sans changement de type domaine, en un type dont le type réel correspondant est double .

  • Sinon, si le type réel correspondant de l’un ou l’autre opérande est float , l’autre opérande est converti, sans changement de type domaine, en un type dont le type réel correspondant est float .

  • Sinon, les promotions sur les entiers sont effectuées sur les deux opérandes. Ensuite, les règles suivantes sont appliquées aux opérandes promus:

    • Si les deux opérandes ont le même type, aucune conversion supplémentaire n’est nécessaire.
    • Sinon, si les deux opérandes ont des types entiers signés ou que les deux ont des types entiers non signés, l’opérande ayant le type de rang de conversion de nombre entier inférieur est converti en type de l’opérande avec le rang le plus élevé.
    • Sinon, si l’opérande qui a un type entier non signé a un rang supérieur ou égal au rang du type de l’autre opérande, l’opérande avec le type entier signé est converti au type de l’opérande avec le type entier non signé.
    • Sinon, si le type de l’opérande avec le type entier signé peut représenter toutes les valeurs du type de l’opérande avec le type entier non signé, l’opérande avec le type entier non signé est converti en type de l’opérande avec le type entier signé.
    • Sinon, les deux opérandes sont convertis en un type entier non signé correspondant au type de l’opérande avec un type entier signé.

J’ai mis en évidence la partie qui s’applique à votre exemple particulier.

Le concept de rang de conversion d’entier est défini à la section 6.3.1.1 et décrit en gros ce à quoi vous pouvez vous attendre (les types avec moins de précision ont un rang moins élevé que les types avec plus de précision).

De type conversions :

L’ensemble de conversions implicites de la page 44, bien qu’indiqué de manière informelle, est exactement l’ensemble à retenir pour l’instant. Ils sont faciles à retenir si vous remarquez que, comme le disent les auteurs, the `lower' type is promoted to the `higher' type,'' where the ordre» des types est

 char < short int < int < long int < float < double < long double 

Cette règle est facile à retenir - "plus bas au plus élevé" - mais en ce qui concerne les types entiers signés et non signés, cela n'aide pas beaucoup, ceux-ci sont joliment expliqués dans l'article de Oli. Mais c'est facile à retenir et vous aide dans la plupart des cas.

En règle générale, C ne comparera pas deux valeurs si elles ne sont pas du même type et ne convertira jamais implicitement une variable en un type avec moins de précision. Dans votre exemple de code, le short est promu en int , ce qui équivaut à écrire:

 int i = 10; short s = 5; if ((int)s == i){ do stuff... } else if ((int)s < i) { do stuff... } 

Cela fera exactement ce que vous attendez, mais ce n'est pas le cas de la comparaison signée / non signée.

Les types de données sont une sorte d’abstraction. Pour ce qui est de l’ordinateur, il n’y a ni int ni short . Il y a de la mémoire et des données.

Lorsque vous dites int x , vous dites à un ordinateur “donnez-moi assez d’octets pour stocker un int”, quand vous dites short y , vous dites … vous l’avez deviné.

short , comme vous vous en doutez, prend moins d’octets qu’un int et peut donc contenir (et contient souvent) des données dans les octets adjacents. Lors de la comparaison de données de types différents, le problème est “les bits adjacents vont-ils fausser les résultats ou non?”

Lorsque vous comparez deux types de données différents, vous comparez réellement des bits stockés dans deux emplacements différents. Le nombre maximum de bits individuels stockés pour représenter les données doit être de la même taille pour qu’une comparaison fonctionne

Le casting est utilisé pour aider à cela.