web-dev-qa-db-fra.com

tableau char * et tableau char []

si j'écris ceci

 char *array = "One good thing about music";

Je crée réellement un tableau? Je veux dire, c'est la même chose comme ça?

char array[] = {"One", "good", "thing", "about", "music"};
11
yaylitzis

La déclaration et l'initialisation

char *array = "One good thing about music";

déclare un pointeur array et le fait pointer vers un tableau constant de 31 caractères.

La déclaration et l'initialisation

char array[] = "One, good, thing, about, music";

déclare un tableau de caractères, contenant 31 caractères.

Et oui, la taille des tableaux est de 31, car elle inclut le caractère de fin '\0'.


Mis en mémoire, ce sera quelque chose comme ça pour la première:

 + ------- + + ------------------------------ + 
 | tableau | -> | "Une bonne chose à propos de la musique" | 
 + ------- + + --------------------------- --- + 

Et comme ça pour la seconde:

 + ------------------------------ + 
 | "Une bonne chose à propos de la musique" | 
 + ------------------------------ + 

Les tableaux se désintègrent en pointeurs vers le premier élément d'un tableau. Si vous avez un tableau comme

char array[] = "One, good, thing, about, music";

puis en utilisant plain array lorsqu'un pointeur est attendu, c'est la même chose que &array[0].

Cela signifie que lorsque vous, par exemple, passez un tableau en tant qu'argument à une fonction, il sera transmis en tant que pointeur.

Les pointeurs et les tableaux sont presque interchangeables. Vous ne pouvez pas, par exemple, utiliser sizeof(pointer) car cela renvoie la taille du pointeur réel et non pas vers quoi il pointe. Aussi quand vous le faites par exemple &pointer Vous obtenez l'adresse du pointeur, mais &array Renvoie un pointeur sur le tableau. Il convient de noter que &array Est très différent de array (ou son équivalent &array[0]) . Alors que &array Et &array[0] Pointent vers le même emplacement, les types sont différents. En utilisant l'arrat ci-dessus, &array Est de type char (*)[31], tandis que &array[0] Est de type char *.


Pour plus de plaisir: comme beaucoup le savent, il est possible d'utiliser l'indexation de tableaux lors de l'accès à un pointeur. Mais comme les tableaux se désintègrent en pointeurs, il est possible d'utiliser de l'arithmétique de pointeurs avec des tableaux.

Par exemple:

char array[] = "Foobar";  /* Declare an array of 7 characters */

Avec ce qui précède, vous pouvez accéder au quatrième élément (le caractère 'b ') En utilisant soit

array[3]

ou

*(array + 3)

Et comme l'addition est commutative , la dernière peut également être exprimée comme

*(3 + array)

ce qui conduit à la syntaxe amusante

3[array]
36

Non, vous créez un tableau, mais il y a une grande différence:

char *string = "Some CONSTANT string";
printf("%c\n", string[1]);//prints o
string[1] = 'v';//INVALID!!

Le tableau est créé dans une partie en lecture seule de la mémoire, vous ne pouvez donc pas modifier la valeur via le pointeur, alors que:

char string[] = "Some string";

crée la même chaîne constante en lecture seule et la copie dans le tableau de pile. C'est pourquoi:

string[1] = 'v';

Est valable dans ce dernier cas.
Si vous écrivez:

char string[] = {"some", " string"};

le compilateur devrait se plaindre, car vous construisez un tableau de tableaux de caractères (ou pointeurs de caractères) et l'assignez à un tableau de caractères. Ces types ne correspondent pas. Soit écrivez:

char string[] = {'s','o','m', 'e', ' ', 's', 't','r','i','n','g', '\o'};
//this is a bit silly, because it's the same as char string[] = "some string";
//or
char *string[] = {"some", " string"};//array of pointers to CONSTANT strings
//or
char string[][10] = {"some", " string"};

Où la dernière version vous donne un tableau de chaînes (tableaux de caractères) que vous pouvez réellement modifier ...

8
Elias Van Ootegem

Non. En fait, c'est le "même" que

char array[] = {'O', 'n', 'e', ..... 'i','c','\0');

Chaque caractère est un élément distinct, avec un \0 caractère comme terminateur de chaîne.

J'ai cité "pareil", car il existe des différences entre char * array et char array[]. Si vous voulez en savoir plus, jetez un œil à C: différences entre le pointeur char et le tablea

2
Piotr Zierhoffer

C'est très similaire à

char array[] = {'O', 'n', 'e', ' ', /*etc*/ ' ', 'm', 'u', 's', 'i', 'c', '\0'};

mais vous donne une mémoire en lecture seule.

Pour une discussion sur la différence entre un char[] et un char *, voir comp.lang.c FAQ 1,32 .

2
tom