2017-09-20 9 views
2

Existe-t-il un ordre de recherche dans les espaces de noms, à savoir, espace de noms de balise et espace de noms ordinaires? Considérez le code suivant:Ordre de recherche d'espace de noms dans C

#include <stdio.h> 

int main (void){ 

    typedef struct{ //This belongs to ordinary name space 
    int min; 
    } st; 
    st myst; 
    myst.min=6; 
    struct myst{ // This belongs to tag name space 
    int min; 
    }; 
    myst.min=7; 
    printf("%d\n%d\n",myst.min,myst.min); 
    return 0; 
} 

Sortie

7

7

Le compilateur recherche la variable à imprimer dans l'espace de noms de balise d'abord, je suppose. Je ne sais pas si la recherche est même faite pour le même identifiant dans l'espace de nom ordinaire et si c'est fait, je ne sais pas pourquoi il ne l'imprime pas.

+0

* "Le compilateur recherche d'abord la variable à imprimer dans l'espace de nom de balise" * - Non, ce n'est pas le cas. Vous n'avez pas spécifié de mot-clé d'étiquette. – StoryTeller

+0

Pas clair. Un nom n'est recherché que dans l'espace de nom que vous spécifiez. BTW: Il n'y a pas d'espace de nom de tag. – Olaf

+0

Mot clé @StoryTeller? Je ne t'ai pas eu. 'struct' est le nom du tag. – 0decimal0

Répondre

7

Il n'y a pas d'ordre de recherche d'espace de noms dans C. Un seul espace de noms est jamais considéré pour un identifiant particulier; il est déterminé par quel type d'identifiant est recherché. Les balises de structure sont d'un type, avec leur propre espace de noms; Les noms de variables appartiennent à la catégorie plus large des "identificateurs ordinaires", qui ont un espace de noms distinct. Il y a aussi d'autres espaces de noms, mais le compilateur peut toujours dire à partir du contexte quel est le contexte d'un identifiant donné. Ainsi, dans votre programme, les deux utilisations de myst.min se réfèrent à la variable déclarée st myst; et il n'y a pas de deuxième variable dans l'espace de noms "tag" (comme vous semblez l'avoir pensé).

Vous pouvez voir par vous-même en commentant tout ce qui main ci-dessus myst.min = 7:

#include <stdio.h> 

int main (void){ 
#if 0 
    typedef struct{ //This belongs to ordinary name space 
    int min; 
    } st; 
    st myst; 
    myst.min=6; 
#endif 
    struct myst{ // This belongs to tag name space 
    int min; 
    }; 
    myst.min=7; 
    printf("%d\n%d\n",myst.min,myst.min); 
    return 0; 
} 

Toute tentative de compiler cela produira une erreur matérielle:

test.c: In function ‘main’: 
test.c:14:3: error: ‘myst’ undeclared (first use in this function) 

Qu'est-ce que la déclaration struct myst fait est déclarer un autre tapez, que vous pouvez ensuite utiliser pour déclarer des variables. Mais ce n'est pas utilisé pour n'importe quoi, sauf si vous faites cela. Par exemple

#include <stdio.h> 

typedef struct { int min; } st; 
struct myst { int min }; 
int main(void) 
{ 
    // uses the typedef name 'st', in the ordinary namespace, 
    // to declare the variable 'myst', also in the ordinary namespace 
    st myst = { 6 }; 

    // uses the struct name 'myst', in the tag namespace, 
    // to declare the variable 'myst2', in the ordinary namespace 
    struct myst myst2 = { 7 }; 

    printf("%d %d\n", myst.min, myst2.min); 
    return 0; 
} 

va imprimer 6 7. Ce programme illustre également comment myst, la variable, et myst, la balise struct, sont en effet dans deux espaces de noms différents et peuvent être référencés indépendamment.


(Merci à John Bollinger pour le nouveau premier alinéa. -ed)

+0

Eh bien, définir réellement le même nom entraînera un conflit. Toujours confus au sujet de l'ordre de recherche. – 0decimal0

+2

@ 0decimal0, il n'y a pas d'ordre de recherche. Un seul espace de noms est jamais considéré pour un identifiant particulier; il est déterminé par quel type d'identifiant est recherché. Les balises de structure sont d'un type, avec leur propre espace de noms; Les noms de variables appartiennent à la catégorie plus large des "identificateurs ordinaires", qui ont un espace de noms distinct. Il y a aussi d'autres espaces de noms, mais le compilateur peut toujours dire à partir du contexte quel est le contexte d'un identifiant donné. –

+0

Merci @JohnBollinger, je comprends maintenant. – 0decimal0

3

C namespaces sont complètement disjoints. Chaque identifiant est recherché dans un seul espace de noms. Par exemple:

  • Identifiers qui suivent struct et union mots clés sont recherchés dans l'espace de noms de tags
  • Identifiers qui suivent le mot-clé goto sont recherchées dans l'espace de noms d'étiquettes
  • Identifiers qui suivent . ou -> symboles sont recherchés dans leur structure ou l'espace de noms des membres de l'union (chaque structure et union a son propre espace de noms, le type de l'expression précédente détermine celui à rechercher)
  • D'autres identifiants sont recherchés dans les noms ordinaires rythme.

Il n'y a pas d'ordre de recherche. L'espace de noms (unique) à rechercher est entièrement déterminé par le contexte.

+0

Vous répondez est précis et succinct, merci. upvoted :) – 0decimal0