Question

#include <cstring>
int main()
    {
    char *pName = new char[10];
    char dummy[] = "dummy";
    strcpy(pName + 0,dummy);//how this is different from -->this works
    strcpy(pName[0],dummy);//this one...--> error C2664: 'strcpy' : 
                           //cannot convert parameter 1 
                           //from 'char' to 'char *'

    }
Était-ce utile?

La solution

  • pName [0] est le premier élément d'un tableau de caractères ( un caractère)
  • pName est un raccourci vers & amp; pName [0] (un pointeur sur le premier élément de votre tableau)

La raison pour laquelle vous obtenez votre erreur est parce que strcpy attend un pointeur sur un caractère (char *), et non une valeur de caractère (qui correspond à ce que pName [0] est]

Autres conseils

Lors de l'utilisation de pointeurs et de tableaux en C ou C ++, il est vraiment utile de les reconnaître comme des constructions très distinctes (je pense que l'un des meilleurs livres expliquant cette distinction est un livre intitulé & "Deep C Secrets & "si je me souviens bien". Ce qui trouble les choses, c’est le fait qu’il existe une conversion unidirectionnelle permise des noms de tableaux en pointeurs (une incohérence dans le traitement par la langue des noms de variables) - mais il est très important de ne pas interpréter l’existence de ce phénomène de dégradation comme impliquant équivalence.

Pour nous aider à raisonner à ce sujet, introduisons l’idée de "cellule mémoire". Nous modélisons une "cellule de mémoire" comme ayant deux attributs:

a) value
b) address

Nous pouvons ensuite modéliser une variable C ++ simple avec deux attributs (nous n'avons pas besoin de types à ce niveau d'abstraction peu élevé):

c) name  
d) memory cell

Comme la plupart des modèles, il présente certaines lacunes (ne traite pas un tableau contenant plus d’un élément, mais cela suffit pour nos besoins).

Ainsi, par exemple:

// non-array variable: name 'i', and memory cell: value=3, address=0x0A
int i = 3;

// non-array variable: name 'p', and memory cell: value=0x0A, address=0x0B
int *p = &i;

// array variable: name 'a', and memory cell: vale=4, address=0x0C     
int a[1] = { 4 };

// non-array variable: name 'b', and memory cell: value=0x0C, address = 0x0D
int (*b)[1] = &a;

// non-array variable: name 's', and memory cell: value=0x0C, address = 0x0E
int *s = &a[0];


// non-array variable: name 't', and memory cell: value=0x0C, address = 0x0F
int *t = a; // Here is the key difference! read on...

Maintenant, voici la différence principale entre une variable de tableau et une variable C ++ non-tableau (pointeur):

  

Lorsqu'un nom de variable en C ++ est évalué, il correspond toujours à la valeur de sa cellule de mémoire, à une exception près: si la variable nomme une variable de type tableau.
    Si la variable est le nom d'un tableau, elle correspond à l'adresse de la cellule de mémoire.
    Les deux lignes ci-dessus méritent d'être relues.

Voici quelques exemples pour clarifier les implications (reportez-vous aux variables ci-dessus):

int k = i;  // the 'i' name evaluates to the value of its cell, so 'k' is set to 3

int *q = p; // 'p' evaluates to the value of its cell, so 'q' is set to 0x0A

int *r = a; // 'a' evaluates to the *address* of its cell, so 'r' is set to 0x0C

int (*c)[1] = b; // 'c' is set to 0x0D

Cela ne doit en aucun cas impliquer qu'une variable de tableau est identique à une variable de pointeur.
Ils ont intrinsèquement différents types et toute tentative de les traiter comme identiques (c.-à-d. Définir un nom de variable comme un tableau dans une unité de traduction et comme un pointeur dans une autre) entraînera de mauvaises choses. / p>

Donc pour par exemple ne faites pas ceci:

// myproj_file1.cpp
int array[100] = { 0 }; // here 'array' evaluates to the *address* of the first memory cell

// myproj_file2.cpp
extern int* array; // here 'array' evaluates to the *value* of the first memory cell 
            // Assuming the linker links the two
            // what it does if you read the assembly, is something like this: 
            // extern int* array = (int*) array[0];
            // but it doesn't have to, it can do anything, since the behavior is undefined

J'espère que cela aide. Si vous pensez toujours qu'une clarification supplémentaire pourrait aider, posez une question complémentaire et n'hésitez pas à vous procurer une copie (bibliothèque?) De ce & "Deep C Secrets &"; livre:)

-
p.s. les types de fonctions, leurs noms et leur déclin ne sont pas pertinents pour la plupart de cet article
p.s. J'ai aussi volontairement laissé de côté que la conversion de tableau en pointeur ne se produit pas lorsque les tableaux sont liés à des types de référence

Techniquement, strcpy(pName[0], dummy); n’est pas correct. Même si de la mémoire était allouée pour cela.

Cela est dû au fait que pName[0] est du type 'char' alors que pName + 0 est du type char *. Ils font tous deux référence à la même mémoire, mais de manière différente.

Le compilateur peut ensuite transformer strcpy((char*) pName[0], dummy); en <=> qui est une distribution implicite dangereuse. Si votre compilateur est à moitié correct, vous recevrez un avertissement ou une erreur (Comme vous le voyez avec votre & Erreur C2664 & ";).

Il n'y a pas de différence. Ils vont tous les deux planter car vous n’avez pas alloué d’espace pour pName. :) [EDIT: Plus de crash - la question a été modifiée]

La principale différence est une différence stylistique, souvent influencée par la manière dont le code environnant est écrit: accès principalement à un tableau ou principalement à un pointeur.

(EDIT: supposons que vous vouliez vraiment dire & amp; pName [0] comme l'a souligné Brian Bondy.)

Un tableau est simplement un pointeur automatiquement (généralement) attribué à un bloc de mémoire alloué automatiquement. En prenant votre exemple, vous pouvez déclarer le mannequin de la même manière:

char    dummy[] = "dummy";
char    *dummy = "dummy";

Et vous pouvez ensuite utiliser la syntaxe du tableau ou la syntaxe du pointeur pour accéder aux données:

char    ch = dummy[0];   // get the first element of the array
char    ch = *dummy;     // get the data pointed to by dummy

[] et * peuvent tous deux être utilisés pour renvoyer des pointeurs et des tableaux, les éléments suivants sont équivalents:

array[N];
*(ptr + N);

Étant donné le deuxième formulaire, (ptr + N) est toujours un pointeur, juste plus loin dans le tableau. C'est pourquoi c'est syntaxiquement correct dans votre exemple. ptr[N] est un dé-référencement du pointeur et est un caractère (dans ce contexte).

pName est un pointeur sur la mémoire récemment allouée. char *pName = new char[10];

dummy est aussi un tableau / pointeur. char dummy[] = "dummy";

pName est un pointeur et pointe vers l'adresse de base, même si vous ajoutez (pName + 0) pointe toujours vers le même emplacement mémoire, car votre seul ajout de 0. strcpy(pName + 0,dummy);

strcpy utilise la variable de pointeur, et votre valeur de passage en premier argument, donc vous obtenez une erreur strcpy(pName[0],dummy)

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top