2010-09-05 15 views
1

Je viens de commencer à lire The C Programming Language et j'ai de la difficulté à comprendre une partie. Voici un extrait de la page 24:Valeur numérique des caractères numériques dans C

#include<stdio.h> 

/*countdigits,whitespace,others*/ 

main() 
{ 
    intc,i,nwhite,nother; 
    intndigit[10]; 

    nwhite=nother=0; 
    for(i=0;i<10;++i) 
     ndigit[i]=0; 

    while((c=getchar())!=EOF) 
     if(c>='0'&&c<='9') 
      ++ndigit[c-'0']; //THIS IS THE LINE I AM WONDERING ABOUT 
     else if(c==''||c=='\n'||c=='\t') 
      ++nwhite; 
     else 
      ++nother; 

    printf("digits="); 
    for(i=0;i<10;++i) 
     printf("%d",ndigit[i]); 
    printf(",whitespace=%d,other=%d\n", 
     nwhite,nother); 
} 

La sortie de cette exécution du programme sur lui-même est

digits=9300000001,whitespace=123,other=345 

La déclaration

intndigit[10]; 

déclare ndigit être un tableau de 10 entiers. Un tableau des indices commencent toujours à zéro en C, de sorte que les éléments sont

ndigit[0], ndigit[ 1], ..., ndigit[9] 

Ceci se reflète dans la boucle pour initialiser et qui impriment la matrice. Un indice peut être n'importe quelle expression entière, qui inclut des variables entières comme i et des constantes entières. Ce programme particulier repose sur les propriétés de la représentation de caractères des chiffres. Par exemple, le test

if(c>='0'&&c<='9') 

détermine si le caractère de c est un chiffre. Le cas échéant, la valeur numérique de ce chiffre est

c-'0'` 

Cela ne fonctionne que si « 0 », « 1 », ..., « 9 » ont des valeurs décroissantes consécutives. Heureusement, cela est vrai pour tous les jeux de caractères. Par définition, les caractères ne sont que de petits entiers, donc les variables char et les constantes sont identiques aux entiers dans les expressions arithmétiques. C'est naturel et pratique; par exemple

c-'0' 

est une expression de nombre entier ayant une valeur comprise entre 0 et 9 correspondant au caractère « 0 » à « 9 » stocké dans c, et donc un indice valable pour le ndigit de réseau.

La partie que j'ai du mal à comprendre pourquoi la partie -'0' est nécessaire dans l'expression c-'0'. Si un caractère est un petit nombre entier comme le dit l'auteur, et que les caractères numériques correspondent à leurs valeurs numériques, alors que fait -'0'?

Répondre

7

Les caractères numériques ne correspondent pas à leurs valeurs numériques. Ils correspondent à leurs valeurs d'encodage (dans ce cas, ASCII). IIRC, ascii '0' est la valeur 48. Et, heureusement pour cet exemple et la plupart des jeux de caractères, les valeurs de '0' à '9' sont stockées dans l'ordre dans le jeu de caractères.Donc, en soustrayant la valeur ASCII pour '0' de n'importe quel chiffre ASCII renvoie sa valeur "vrai" de 0-9.

+0

Merci, l'auteur dit essentiellement la même chose, mais ce n'était pas en train de sombrer dans Tout est logique maintenant.. – ubiquibacon

+1

Si vous saviez que '0' était 48, vous pouvez simplement utiliser 48. L'utilisation de '0' est au moins en partie pour faciliter la portabilité vers d'autres jeux de caractères (non ASCII) où les chiffres ont des valeurs de caractères différentes. –

+2

La norme C garantit que «0» à «9» sont contigus, quel que soit le codage. –

0

Il convertit du code ASCII de la touche '0' de votre clavier à la valeur zéro.

si vous avez fait int x = '0' + '0' le résultat ne serait pas zéro.

3

La valeur numérique d'un caractère est (sur la plupart des systèmes) sa valeur ASCII. La valeur ASCII de '0' est 48, '1' est 49, etc.

En soustrayant 48 de la valeur du caractère '0' devient 0, '1' devient 1, etc. En l'écrivant c - '0' vous n'avez pas réellement besoin de savoir quelle est la valeur ASCII de '0' (ou que le système utilise ASCII - il pourrait utiliser EBCDIC). La seule chose qui compte est que les valeurs sont des entiers croissants consécutifs.

0

Dans la plupart des codages de caractères, tous les chiffres sont placés consécutivement dans le jeu de caractères. En ASCII par exemple, ils commencent par '0' à 0x30 ('1' est 0x31, '2' est 0x32, etc.). Si vous voulez la valeur numérique d'un chiffre donné, vous pouvez simplement en soustraire '0' et obtenir la bonne valeur. L'avantage d'utiliser '0' au lieu de la valeur spécifique est que votre code peut être transporté vers d'autres jeux de caractères avec beaucoup moins d'effort.

+1

C'est une exigence de la norme C que le codage utilisé a des valeurs numériques dans des emplacements contigus. –

0

Si vous accédez à une chaîne de caractères par ses caractères, vous obtiendrez les valeurs ASCII, même si les caractères sont des nombres.

Heureusement, les personnes qui ont conçu cette table de caractères ont fait en sorte que les caractères de 0 à 9 soient séquentiels. Vous pouvez donc simplement convertir ASCII en nombre en soustrayant la valeur ASCII de '0'.

C'est ce que fait le code. Je dois admettre que c'est déroutant quand on le voit la première fois, mais ce n'est pas sorcier.

La valeur du caractère ASCII de '0' est 48, '1' est 49, '2' est 50 et ainsi de suite.

Pour référence est ici un beau-chart ASCII:

http://www.sciencelobby.com/ascii-table/images/ascii-table1.gif