Domanda

#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 *'

    }
È stato utile?

Soluzione

  • pName [0] è il primo elemento in una matrice di caratteri ( uno carattere)
  • pName è un collegamento a & amp; pName [0] (un puntatore al primo elemento dell'array)

Il motivo per cui ricevi l'errore è perché strcpy si aspetta un puntatore a un carattere (carattere *) e non un valore carattere (che è ciò che pName [0] è)

Altri suggerimenti

Quando si tratta di puntatori e matrici in C o C ++ aiuta davvero a riconoscerli come costrutti molto distinti (penso che uno dei migliori libri che spiegano questa distinzione sia un libro chiamato " Deep C Secrets " se ricordo bene). Ciò che confonde le acque è il fatto che esiste una conversione silenziosa a senso unico consentita da nomi di array a puntatori (un'incoerenza nella gestione dei nomi delle variabili da parte del linguaggio) - ma è molto importante non interpretare l'esistenza di questo fenomeno di decadimento come implicito equivalenza.

Per aiutarci a ragionare su questo, introduciamo l'idea di una "cella di memoria". Modelliamo una "cella di memoria" con due attributi:

a) value
b) address

Possiamo quindi modellare una semplice variabile C ++ come avente due attributi (non abbiamo bisogno di tipi con questo basso livello di astrazione):

c) name  
d) memory cell

Come la maggior parte dei modelli, presenta alcune carenze (non si occupa di un array con più di un elemento, ma è sufficiente per i nostri scopi).

Quindi, per esempio:

// 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...

Ora ecco la differenza principale tra una variabile array e una variabile C ++ non puntatore (puntatore):

  

Quando viene valutato un nome di variabile in C ++, viene sempre valutato il valore della sua cella di memoria con un'eccezione: se la variabile nomina una variabile di matrice.
    Se la variabile è il nome di un array, viene valutato indirizzo della cella di memoria.
    Vale la pena leggere di nuovo le due righe precedenti.

Ecco alcuni esempi per chiarire le implicazioni (fare riferimento alle variabili sopra):

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

Questo non dovrebbe in alcun modo implicare che una variabile di matrice sia la stessa di una variabile puntatore.
Hanno tipi intrinsecamente diversi e qualsiasi tentativo di trattarli come stesso (ovvero definire un nome di variabile come un array in un'unità di traduzione e come un puntatore in un'altra) comporterà cose brutte.

Quindi per es. non farlo:

// 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

Spero che questo aiuti. Se ritieni ancora che possano essere utili ulteriori chiarimenti, fai una domanda di follow-up e non esitare a ottenere una copia (libreria?) Di quella & Quot; Deep C Secrets & Quot; libro :)

-
post scriptum i tipi di funzione, i loro nomi e il loro decadimento sono irrilevanti per la maggior parte di questo post
post scriptum Ho anche intenzionalmente escluso che la conversione da array a puntatore non si verifichi quando le matrici sono associate a tipi di riferimento

Tecnicamente, strcpy(pName[0], dummy); non è corretto. Anche se la memoria è stata allocata per esso.

Questo perché pName[0] è di tipo 'char' mentre pName + 0 è di tipo char *. Entrambi fanno riferimento alla stessa memoria, ma in modi diversi.

Il compilatore può quindi trasformare strcpy((char*) pName[0], dummy); in <=> che è un cast implicito pericoloso. Se il tuo compilatore è mezzo decente riceverai un avviso o un errore (Come vedi con il tuo & Quot; errore C2664 & Quot;).

Non c'è differenza. Si bloccheranno entrambi poiché non è stato allocato spazio per pName. :) [EDIT: non più un arresto anomalo - la domanda è stata modificata]

La differenza principale è di tipo stilistico, spesso influenzato dal modo in cui viene scritto il codice circostante, principalmente l'accesso all'array o l'accesso al puntatore.

(EDIT: supponendo che tu intendessi davvero & amp; pName [0] come ha sottolineato Brian Bondy.)

Un array è semplicemente un puntatore assegnato automaticamente (di solito) a un blocco di memoria allocato automaticamente. Prendendo il tuo esempio, puoi dichiarare il manichino equamente come:

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

E puoi quindi usare la sintassi dell'array o la sintassi del puntatore per accedere ai dati:

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

Sia [] che * possono essere usati come riferimenti di riferimento e matrici, quindi i seguenti sono equivalenti:

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

Dato il secondo modulo, (ptr + N) è ancora un puntatore, appena oltre l'array. Questo è il motivo per cui è sintatticamente corretto nel tuo esempio. ptr[N] è un de-riferimento del puntatore ed è un carattere (in questo contesto).

pName è puntatore alla memoria appena allocata. char *pName = new char[10];

dummy è anche un array / puntatore. char dummy[] = "dummy";

pName è puntatore e punta all'indirizzo di base, anche se aggiungi (pName + 0) punta ancora alla stessa posizione di memoria, perché aggiungi solo 0. strcpy(pName + 0,dummy);

strcpy usa la variabile pointer e il valore che passa nel primo argomento, quindi stai ottenendo un errore strcpy(pName[0],dummy)

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top