Chaîne de pointeur et tableau de caractères en c
Je viens de commencer à apprendre le C et le trouvé un peu de confusion sur le pointeur de la chaîne et de la chaîne(tableau de char). Quelqu'un peut-il m'aider à effacer de ma tête, un peu?
//source code
char name[10] = "Apple";
char *name2 = "Orange";
printf("the address of name: %p\n", name);
printf("the address of the first letter of name: %p\n", &(*name));
printf("first letter of name using pointer way: %c\n", *name);
printf("first letter of name using array way: %c\n", name[0]);
printf("---------------------------------------------\n");
printf("the address of name2: %p\n", name2);
printf("the address of the first letter of name2: %p\n", &(*name2));
printf("first letter of name2 using pointer way: %c\n", *name2);
printf("first letter of name2 using array way: %c\n", name2[0]);
//output
the address of name: 0x7fff1ee0ad50
the address of the first letter of name: 0x7fff1ee0ad50
first letter of name using pointer way: A
first letter of name using array way: A
---------------------------------------------
the address of name2: 0x4007b8
the address of the first letter of name2: 0x4007b8
first letter of name2 using pointer way: O
first letter of name2 using array way: O
donc je suppose que le nom et le nom2 point à l'adresse de leur première lettre. alors ma confusion(voir le code ci-dessous)
//code
char *name3; //initialize a char pointer
name3 = "Apple"; //point to the first letter of "Apple", no compile error
char name4[10]; //reserve 10 space in the memory
name4 = "Apple"; //compile errorrrr!!!!!!!!!!
Je crée un pointeur de char appelé nom2 et nom2 pointeur vers la première lettre de "Apple" ce qui est bien, puis-je créer un autre tableau de char et d'allouer 10 de l'espace dans la mémoire. et puis essayez d'utiliser nom4 qui est une adresse de points à la première lettre de "Apple". En conséquence, j'ai une erreur de compilation.
Je suis tellement frustré par ce langage de programmation. parfois, ils fonctionne de la même manière. mais parfois, ils n'en ont pas. Quelqu'un peut-il expliquer la raison et si je veux vraiment créer une chaîne ou un tableau de caractères séparés lignes. comment je peux faire???
Merci beaucoup...
Absolument terrible commentaire. C'est à un niveau inférieur que l'une de ces langues fournir.
Éventuellement pertinentes: stackoverflow.com/questions/579734/...
Cette différence entre les tableaux et les pointeurs est quelque chose qui, en tant qu'assemblée programmeur (où ils sont tous juste d'adresses!) son trébuché moi dans le passé, trop. Mais je vais laisser l'un de la C-les experts de la langue de la réponse (qui sera probablement citer les spec pour vous.)
si parce que "Apple"(char *) n'est pas du même type que nom4(de type tableau) lors de l'affectation, pourquoi ils peuvent travailler de la même façon à obtenir une valeur spécifique?? comme *nom3 = nom3[0], *nom4 = nom4[0]
OriginalL'auteur eded | 2013-06-13
Vous devez vous connecter pour publier un commentaire.
Vous pouvez initialiser un tableau lorsque vous déclarez, comme ceci:
Mais depuis que nous avons généralement de traiter des tableaux de char comme des chaînes de caractères, C) permet à un cas particulier:
Cependant, une fois que vous avez déclaré un tableau, vous ne pouvez pas réaffecter. Pourquoi? Envisager une affectation comme
La première ligne déclare un pointeur de char et "objectifs" à la première lettre en
foo
. Depuisfoo
est une constante de chaîne, il se trouve quelque part dans la mémoire avec toutes les autres constantes. Lorsque vous réaffectez le pointeur, vous êtes d'affecter une nouvelle valeur: l'adresse debar
. Mais la chaîne d'origine,foo
reste inchangé. Vous avez déplacé le pointeur, mais je n'ai pas modifié les données.Lorsque vous déclarez un tableau, toutefois, vous n'êtes pas déclarer un pointeur à tous. Vous êtes à la réservation d'une certaine quantité de mémoire et de lui donner un nom. De sorte que la ligne
commence avec la constante de chaîne
data
, puis alloue 5 nouveaux octets, les appellec
, et des copies de la chaîne. Vous pouvez accès les éléments de la matrice exactement comme si vous aviez déclaré un pointeur vers eux; les tableaux et les pointeurs sont (pour la plupart des besoins) interchangeables.Mais comme les tableaux ne sont pas des pointeurs, vous ne pouvez pas réaffecter.
Vous ne pouvez pas faire
c
"point" n'importe où d'autre, parce que ce n'est pas un pointeur, c'est le nom d'une zone de mémoire.Vous peut modifier la valeur de la chaîne, soit un caractère à la fois, ou par l'appel d'une fonction comme
strcpy()
:L'Efficacité De Pointe
Note, également, que l'initialisation d'un tableau est en général une copie des données: la chaîne d'origine est copié à partir de la constante de la zone de la zone de données, où votre programme peut changer. Bien sûr, cela signifie que vous êtes en utilisant deux fois plus de mémoire que vous pouvez penser. Vous pouvez éviter la copie et généralement économiser de la mémoire par la déclaration d'un pointeur à la place. Que les feuilles de la chaîne dans la constante de la zone et alloue suffisamment de mémoire pour un pointeur, quelle que soit la longueur de la chaîne.
OriginalL'auteur Adam Liss
Bien que le pointeur et tableau semble familier, ils sont différents. le
char *name3
est juste un pointeur verschar
, il ne faut pas plus de mémoire qu'un pointeur. il vient de stocker une adresse à elle, alors vous pouvez affecter une chaîne, puis l'adresse stockée dansname3
changement de l'adresse de"Apple"
.Mais votre
name4
est un tableau dechar[10]
, il conserve la mémoire de 10 caractères, si vous voulez l'affecter, vous devez utiliserstrcpy
ou quelque chose à écrire, c'est de mémoire, mais de ne pas lui attribuer une adresse comme"Apple"
.merci pour votre aide leonhart
OriginalL'auteur leonhart
Vous ne pouvez pas directement attribuer une valeur à un tableau de type (par exemple, votre tableau de dix
char
sname4
). Pour le compilateur,name4
est un "tableau" et vous ne pouvez pas utiliser l'assignation=
opérateur d'écrire sur un tableau avec une chaîne littérale.Pour réellement se déplacer le contenu de la chaîne "Apple" dans les dix tableau d'octets que vous avez alloué pour elle (
name4
), vous devez utiliserstrcpy()
ou quelque chose du genre.Ce que vous faites avec
name3
est assez différente. Il est créé comme unchar *
et initialisé à la poubelle, ou zéro (vous ne savez pas sûr qu'à ce point). Ensuite, vous affectez dans la emplacement de la chaîne statique "Apple". C'est une chaîne qui vit dans la mémoire en lecture seule, et la tentative d'écriture dans la mémoire de l'name3
pointeur de points ne pourra jamais réussir.Sur cette base, vous pouvez supposer que la dernière instruction tente d'affecter l'emplacement de la mémoire d'une chaîne statique pour quelque chose d'ailleurs qui représente une collection de 10
char
s. La langue ne vous fournit pas avec pré-déterminé de la façon d'effectuer cette tâche.C'est ici que réside sa puissance.
Vous pouvez initialiser un tableau en une chaîne de cette façon, mais ne pas les utiliser pour l'affectation par la suite. C'est une très bonne question et facile de se confondre avec. Essentiellement, le
=
opérateur n'est pas en fait la même chose la première fois que vous l'utilisez sur une variable par rapport à la deuxième fois que vous l'utilisez sur une variable. C'est évidemment déroutant pour le débutant, mais la réponse implique la compréhension du langage d'assemblagemerci pour votre aide Steven
OriginalL'auteur Steven Lu
Quand vous dites
vous déclarez
name3
au point de la chaîne statique"Apple"
. Si vous êtes familier avec les langages de niveau supérieur, vous pouvez le considérer comme immuable (je vais l'expliquer dans ce contexte, car il semble que vous avez programmé avant; pour la justification technique, vérifiez le C standard).Quand vous dites
vous obtenez une erreur, car vous d'abord déclarer un tableau de 10 caractères (en d'autres mots, vous êtes à diriger le début de 10 octets de la section de mutable de mémoire), puis de tenter d'affecter le immuable valeur
"Apple"
à ce tableau. Dans ce dernier cas, la répartition de données se produit dans certains en lecture seule segment de mémoire.Cela signifie que les types ne correspondent pas:
Si vous voulez
name4
d'avoir la valeur"Apple"
, utilisezstrcpy
:Si vous voulez
name4
avoir la valeur initiale"Apple"
, vous pouvez le faire ainsi:La raison que cela fonctionne, alors que votre exemple précédent n'est pas, c'est parce que
"Apple"
est un tableau valide pour initialiser unchar[]
. En d'autres termes, vous êtes la création d'un 10-byte char tableau, et la fixation de sa valeur initiale à"Apple"
(avec des 0 dans les autres endroits).Cela pourrait faire plus de sens si vous pensez à un tableau int:
Probablement le plus facile familière explication, je pense qu'un tableau est une collection de seaux pour les choses, alors que la chaîne statique
"Apple"
est une seule chose '".strcpy(name4, "Apple")
fonctionne parce que c'exemplaires de chacun des choses (caractères) dans le"Apple"
enname4
un par un.Cependant, il n'est pas logique de dire: "cette collection de seaux d'eau est égale à la chose". Il n'a de sens que pour "remplir" les seaux avec des valeurs.
J'ai ajouté quelques précisions supplémentaires. J'espère que cela aide.
merci pour votre aide sapi
OriginalL'auteur sapi
Je pense que cela va aider à éclaircir aussi:
De sortie:
Nous voyons donc que
arr == &arr
. Puisque c'est un tableau, le compilateur sait que vous allez toujours vouloir l'adresse du premier octet, indépendamment de la façon dont il est utilisé.arr
est un tableau de 7+1 octets, qui sont sur le pile demain()
. Le compilateur génère des instructions tho réserve de ces octets, puis le remplir avec des "au Revoir". Il n'y a pas de pointeur!ptr
d'autre part, est un pointeur, un entier de 4 octets, également sur la pile. C'est pourquoi&ptr
est très proche de&arr
. Mais ce qu'il points, est un static string ("Bonjour"), c'est-off dans la lecture seule section de l'exécutable (c'est pourquoiptr
's la valeur est très différente de ce numéro).printf("%s\n", &arr)
arrive à travailler pour vous, mais il n'est pas garanti par la norme.&arr
est de typechar(*)[8]
, c'est: "pointeur sur un tableau de 8 caractères". Il n'y a aucune garantie qu'il sera correctement convertirchar*
la façon dont vous vous attendez.Vrai, et yech. Le nom d'un tableau donne l'adresse de son premier élément. C'est pourquoi
*(arr+1)
œuvres. À l'aide de l'extra&
avant le nom est redondant, non-standard, et de la confusion.Merci les gars bon point. Visual Studio n'ai pas à me plaindre, mais je ne l'ai pas essayé dans
gcc -Wall
. Je pense que mes erreurs, et vos commentaires sont très utiles, ensemble, dans la compréhension de ce problème, donc je vais le laisser être.merci pour votre aide Jonathon
OriginalL'auteur Jonathon Reinhart