2010-01-10 8 views
31

Dans les règles suivantes pour le cas où tableau désintègre à pointeur:chaîne littérales initialiseur pour un tableau de caractères

lvalue [voir la question 2.5] de type tableau-de-T qui apparaît dans une expression désintègre (avec trois exceptions) dans un pointeur vers son premier élément; le type du pointeur résultant est pointeur-à-T.

(Les exceptions sont lorsque le tableau est l'opérande d'un opérateur sizeof ou &, ou est un initialiseur de chaîne littérale pour un tableau de caractères.)

Comment comprendre le cas lorsque le tableau est « littéral initialiseur de chaîne pour un tableau de caractères "? Un exemple s'il vous plaît.

Merci!

+1

En relation: [Exception au tableau ne se décompose pas en pointeur?] (Http://stackoverflow.com/questions/17752978/exception-to-array-not-decaying-into-a-pointer) – legends2k

Répondre

39

Les trois exceptions où un tableau ne se dégrade pas en un pointeur sont les suivantes:

Exception 1. - Lorsque le tableau est l'opérande de sizeof.

int main() 
{ 
    int a[10]; 
    printf("%zu", sizeof(a)); /* prints 10 * sizeof(int) */ 

    int* p = a; 
    printf("%zu", sizeof(p)); /* prints sizeof(int*) */ 
} 

Exception 2. - Lorsque le tableau est l'opérande de l'opérateur &.

int main() 
{ 
    int a[10]; 
    printf("%p", (void*)(&a)); /* prints the array's address */ 

    int* p = a; 
    printf("%p", (void*)(&p)); /*prints the pointer's address */ 
} 

Exception 3. - Lorsque le tableau est initialisé avec une chaîne littérale.

int main() 
{ 
    char a[] = "Hello world"; /* the literal string is copied into a local array which is destroyed after that array goes out of scope */ 

    char* p = "Hello world"; /* the literal string is copied in the read-only section of memory (any attempt to modify it is an undefined behavior) */ 
} 
+1

J'ai beaucoup aimé votre réponse avant toutes les modifications. Concis et a répondu à la question. Maintenant, il répond à beaucoup de questions qui ne sont même pas posées. :-) –

+0

Merci Prasson. Une question: (1) dans l'Exception 3, alors ici lvalue "Hello world" est l'initialiseur littéral de chaine du tableau char "a", et donc "Hello world" ne se désintègre pas en pointeur? (2) dans l'Exception 2, "& a" est-il identique à l'adresse du premier élément du tableau "a"? – Tim

+0

La réponse est (1) oui, (2) non. Pour (2), sur la plupart des ordinateurs, si vous imprimez les valeurs, ils imprimeront la même chose (je ne sais pas où ils ne le seront pas). Mais '& a' pointe sur tout le tableau alors que' & a [0] 'pointe sur le premier élément de' a'. Donc, si vous imprimez '& a + 1' et' & a [0] + 1', ils seront différents même si '& a' et' & a [0] 'affichent la même valeur. –

5

Ceci est un initialiseur de chaîne de caractères pour un groupe de caractères:

char arr[] = "literal string initializer"; 

peut aussi être:

char* str = "literal string initializer"; 

Définition K & R2:

Une chaîne littérale, également appelé une chaîne constante, est une séquence de caractères sur arrondi par des guillemets doubles comme dans "...". Une chaîne a le type `` tableau de caractères '' et la classe de stockage est statique (voir le paragraphe A.3 ci-dessous) et est initialisée avec les caractères indiqués. Si littéraux de chaîne identiques sont distincts est défini par l'implémentation et le comportement d'un programme qui tente de modifier un littéral de chaîne est indéfini.

+3

Comme le mentionne Prasoon, ce ne sont pas la même chose –

+0

Merci, Eli. Donc, dans ces exemples, quelle est la chaîne littérale iniitalizer de quoi? Et qu'est-ce qu'une "lvalue de type array-of-T" qui ne se décompose pas en pointeur? – Tim

+0

a répondu à une question erronée. – cdosborn

2

Il semble que vous avez tiré cette citation de la FAQ comp.lang.c (peut-être une ancienne version ou peut-être la version imprimée, il ne correspond pas tout à fait avec l'état actuel de celui en ligne):

http://c-faq.com/aryptr/aryptrequiv.html

les liens de la section correspondant à d'autres sections de la FAQ d'élaborer sur ces exceptions.Dans votre cas, vous devriez regarder:

http://c-faq.com/decl/strlitinit.html

7

On suppose les déclarations

char foo[] = "This is a test"; 
char *bar = "This is a test"; 

Dans les deux cas, le type de chaîne « This is a test » est « tableau 15 éléments de char » . Dans la plupart des cas, les expressions de tableau sont implicitement converties du type "tableau d'éléments N de T" en "pointeur vers T", et l'expression évalue l'adresse du premier élément du tableau. Dans la déclaration pour bar, c'est exactement ce qui se passe.

Dans la déclaration pour foo, cependant, l'expression est utilisée pour initialiser le contenu d'un autre tableau et est donc non converti en un type de pointeur; à la place, le contenu du littéral chaîne est copié à foo.

+0

+1 pour la réponse claire et concise; peut-être le seul ici pour montrer que l'exception concerne la chaîne littérale _ et non le tableau char auquel elle est assignée (étant donné que les deux sont des tableaux de caractères). – legends2k

+0

'" Ceci est un test "' car un initialiseur de chaîne ** est ** un tableau. En tant qu'expression, elle ne se décompose pas en pointeur mais reste un tableau. Excellent. – cdosborn

Questions connexes