2010-03-27 6 views
3

J'ai cette fonction:Question sur la valeur NULL vs zéro

void ToUpper(char * S) 
{ 
    while (*S!=0) 
    { 
     *S=(*S >= 'a' && *S <= 'z')?(*S-'a'+'A'):*S; 
     S++; 
    } 
} 

Qu'est-ce que cela signifie pour * S = 0, doit-il être nul à la place!

+1

Y at-il une raison particulière pour laquelle vous n'indentez pas vos codes correctement? Le code correctement indenté est * grandement * meilleur à lire. –

+2

Mon éditeur a foiré le retrait pendant le copier-coller. Je l'ai réparé maintenant. Merci. –

Répondre

9

Cela vérifie la fin de la chaîne qui est un caractère qui a la valeur zéro. Il n'est en aucun cas connecté aux pointeurs NULL.

+2

C'est la bonne réponse, mais en l'occurrence 0 est la même chose qu'une valeur NULL. –

+6

Aussi, je pense qu'il est plus clair d'utiliser ''\ 0'' quand vous voulez dire un marqueur de fin de chaîne et' NULL' quand vous voulez dire un pointeur non-pointant. Oui, ils sont tous zéro dans un sens mais il vaut mieux garder les * concepts * séparés. –

+0

NULL est spécifique à l'implémentation Je ne pense pas que la spécification exige que NULL soit égal à 0 –

4

Je l'écrirais *S != '\0' car je pense que c'est plus idiomatique, mais c'est vraiment une préférence de style personnel. Vous vérifiez le caractère nul (ASCII NUL).

Vous pouvez également vérifier S != 0 avant tout ce code que le pointeur lui-même peut être nul, et vous ne voulez pas déréférencer un pointeur NULL.

-1

J'aime mieux que les algorithmes boucles:

#include <algorithm> 
#include <cstring> 
#include <cctype> 

void ToUpper(char* p) 
{ 
    std::transform(p, p + strlen(p), p, toupper); 
} 

Cette solution fonctionne également pour les encodages de caractères où z ne sont pas séquentiels.

Juste pour le plaisir, voici une expérience qui ne fait qu'une seule itération avec des algorithmes:

#include <algorithm> 
#include <cassert> 
#include <cstring> 
#include <cctype> 
#include <iostream> 
#include <iterator> 

struct cstring_iterator : std::iterator<std::random_access_iterator_tag, char> 
{ 
    char* p; 

    cstring_iterator(char* p = 0) : p(p) {} 

    char& operator*() 
    { 
     return *p; 
    } 

    cstring_iterator& operator++() 
    { 
     ++p; 
     return *this; 
    } 

    bool operator!=(cstring_iterator that) const 
    { 
     assert(p); 
     assert(!that.p); 
     return *p != '\0'; 
    } 
}; 

void ToUpper(char* p) 
{ 
    std::transform(cstring_iterator(p), cstring_iterator(), 
        cstring_iterator(p), toupper); 
} 

int main() 
{ 
    char test[] = "aloha"; 
    ToUpper(test); 
    std::cout << test << std::endl; 
} 
+0

J'aime mieux les algorithmes aussi, en général. Mais ici vous êtes en train de boucler deux fois la longueur de la corde. –

+0

Cette question est marquée C++, alors pourquoi Mike utilise-t-il 'char *' en premier lieu? 'std :: string' à la rescousse! Quoi qu'il en soit, boucler deux fois un tableau est toujours une complexité linéaire;) – fredoverflow

+0

Désolé, mais la mise en œuvre de votre itérateur est incorrecte; il manque de nombreuses opérations random_iterator, et l'opérateur d'inégalité est vraiment endommagé par le cerveau. – jpalecek

-1

NULL est un pointeur en * S est la valeur stockée au niveau du pointeur. Thankes à Dennis Ritchie, le chiffre 0 est acceotable comme les deux.

0

NULL est défini différemment dans C et C++

dans C

#define NULL 0 

dans C++

#define NULL (void*) 0