9
votes

Tableau de pointeurs sur des tableaux de caractères

Je suis confus sur la ligne de code suivante:

#include <stdio.h>
int main () {
    char* words[] = { "aaa", "bbbb", "ccccc", "dddddd" };
    printf("\n\n(*words)[0] = %s", words[0]);
    printf("\n\n(*words)[0]+1 = %s", words[0]+1);
    return 0;
}

c

1 commentaires

Êtes-vous confondre mots [0] + 1 , (mots + 1) [0] et mots [1] ?


8 Réponses :


3
votes

mots [0] pointe vers le premier "A" dans "AAA".

mots [0] +1 déplace ce pointeur le long d'un personnage, il s'agit donc de pointer à la seconde 'A'.

mots [1] points sur "BBBB"

mots [1] +1 points "BBB", par ex. le deuxième 'B' dans "BBBB".


0 commentaires

0
votes

mots [0] renvoie l'adresse de AAA. Ajout de 1 à cela incrémente l'adresse à pointer vers la seconde a.

Voulez-vous avoir des mots [0 + 1]?

Cela devrait vous donner ce que vous attendez.


0 commentaires

0
votes
char* words[] = { "aaa", "bbbb", "ccccc", "dddddd" };
All the 4 strings have static storage duration and are allocated prior to the program startup.In the initializer, the arrays are converted to pointers to char and the words array is initialized with the pointer values.  

0 commentaires

1
votes

Les chaînes littérales sont stockées dans la mémoire statique. Leur emplacement réel est dépendant de la mise en œuvre mais les chaînes littérales sont stockées quelque part , typiquement dans la partie de données de l'exécutable - il n'est ni dynamique ni attribution de pile. Votre tableau contient alors des pointeurs sur ces emplacements.

mots [0] +1 doit indiquer sur la chaîne BBBB et non au deuxième caractère d'AAA.

Ce n'est tout simplement pas la façon dont l'indexation de tableau fonctionne. Vous indexez le tableau des chaînes avec mots [0] , vous avez maintenant une chaîne et toutes les opérations s'appliquent à cette chaîne. Vous ne pouvez pas faire de l'arithmétique avec des indices de tableau en dehors de l'indice. Pour accéder à la chaîne "bbbb" , vous utiliseriez des mots [1] .


0 commentaires

6
votes

La différence est parce que mots [0] +1 n'est pas identique à celui des mots [0 + 1] . .

Le premier point sur le deuxième caractère dans mots [0] , tandis que ce dernier pointe vers le deuxième mot.


0 commentaires

2
votes

La façon dont je le vois, les mots [0] +1 doivent pointer sur la chaîne BBBB et non au deuxième caractère d'AAA

Non. mots [0] est un pointeur de caractère lui-même - il est parfaitement amende que vous obtenez le deuxième caractère de "AAA" en y ajoutant un. Ce que vous voulez, c'est mots + 1 ou & mots [0] + 1 qui sera correctement "BBBB".

En outre, les chaînes elles-mêmes sont allouées lors du lancement de l'exécutable et sont probablement placées dans la section de données ou de BSS du binaire par la liaison. De plus, lorsque vous déclarez et initialisez mots , il sera attribué sur la pile comme tout autre tableau automatique et ses éléments seront affectés aux pointeurs au début de chaque constante de chaîne.


2 commentaires

Je vois. J'ai effectivement essayé de faire des choses telles que mots [1] [1] = 'u' pour changer bbbb dans bubb , mais bbbb reste la même chose après que je l'ai changé (!). Est-ce alors parce que les cordes sont en lecture seule (je suppose qu'ils sont depuis qu'ils sont des r devalues)?


@Curvature Oui, ils sont. Soyez content que cela ne changeait pas - modifier les constantes de chaîne est UB.



1
votes

L'espace de pile et de tas est alloué de manière dynamique - c'est-à-dire qu'ils sont alloués au moment de l'exécution. Votre code compilé est-il attribué dynamiquement, sur le tas ou la pile? Évidemment ni ni. Le stockage pour les constantes est similaire au stockage pour le code ... ils sont stockés dans l'exécutable sur disque et sont chargés en mémoire en lecture seule. (Note pour les pédants: Voici comment les choses sont faites dans une mise en œuvre typique; il n'est pas mandaté par la norme linguistique.)

mots [0] est l'adresse du premier "A" de "AAAA". L'ajout de 1 à cette adresse devrait sûrement donner l'adresse de la seconde «A» de «AAAA». L'adresse de "BBBB" est la voie à mots [1] .

dans le format de votre printf que vous avez "(* mots) [0]", mais c'est différent. * mots est identique à celui des mots [0] . (* mots) [0] est identique que ** mots , qui est le premier "A" (pas son adresse) de "AAAA". Vous imprimeriez (* mots) [0] avec % c , pas % s . .


0 commentaires

15
votes

Ceci est comme ..

Entrez l'image Description ici P>

Depuis les mots un tableau de caractère des pointeurs afin que chaque index de matrice de mots tiendra la Adresse du littéral à chaîne, c'est-à-dire. Adresse de base des littéraux à chaîne Si vous imprimerez P>

 printf("%s",words[0])// index 0 will print aaa.


0 commentaires