Pregunta

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

    }
¿Fue útil?

Solución

  • pName [0] es el primer elemento en una matriz de caracteres ( un carácter)
  • pName es un acceso directo a & amp; pName [0] (un puntero al primer elemento de su matriz)

La razón por la que obtiene su error es porque strcpy espera un puntero a un carácter (char *), y no un valor de carácter (que es lo que es pName [0])

Otros consejos

Cuando se trata de punteros y matrices en C o C ++, realmente ayuda a reconocerlos como construcciones muy distintas (creo que uno de los mejores libros que explica esta distinción es un libro llamado " Deep C Secrets " si no recuerdo mal). Lo que enturbia las aguas es el hecho de que se permite una conversión silenciosa unidireccional de nombres de matriz a punteros (una inconsistencia en el manejo del lenguaje de nombres de variables), pero es muy importante no interpretar la existencia de este fenómeno de descomposición como algo que implica equivalencia.

Para ayudarnos a razonar sobre esto, introduzcamos la idea de una 'celda de memoria'. Modelamos una 'celda de memoria' que tiene dos atributos:

a) value
b) address

Podemos modelar una variable simple de C ++ con dos atributos (no necesitamos tipos en este bajo nivel de abstracción):

c) name  
d) memory cell

Como la mayoría de los modelos, tiene algunas deficiencias (no trata con una matriz con más de un elemento, pero es suficiente para nuestros propósitos).

Entonces, por ejemplo:

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

Ahora, aquí está la principal diferencia entre una variable de matriz y una variable de C ++ que no es de matriz (puntero):

  

Cuando se evalúa un nombre de variable en C ++, siempre evalúa el valor de su celda de memoria con una excepción: si la variable nombra una variable de matriz.
    Si la variable es el nombre de una matriz, se evalúa como la dirección de la celda de memoria.
    Vale la pena leer las dos líneas anteriores nuevamente.

Aquí hay algunos ejemplos para ayudar a aclarar las implicaciones (consulte las variables anteriores):

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

Esto de ninguna manera debería implicar que una variable de matriz es la misma que una variable de puntero.
Tienen tipos inherentemente diferentes y cualquier intento de tratarlos como el mismo (es decir, definir un nombre de variable como una matriz en una unidad de traducción y como un puntero en otra) dará como resultado cosas malas.

Entonces, por ejemplo no hagas esto:

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

Espero que esto ayude. Si todavía cree que una aclaración adicional podría ayudar, haga una pregunta de seguimiento y no dude en obtener una copia (¿biblioteca?) De ese & Quot; Deep C Secrets & Quot; libro :)

-
PD. los tipos de funciones y sus nombres y su decadencia son irrelevantes para la mayoría de esta publicación
PD. También he omitido intencionalmente que la conversión de matriz a puntero no se produce cuando las matrices están vinculadas a tipos de referencia

Técnicamente, strcpy(pName[0], dummy); no es correcto. Incluso si se le asignó memoria.

Esto se debe a que pName[0] es del tipo 'char' mientras que pName + 0 es del tipo char *. Ambos hacen referencia a la misma memoria, pero de diferentes maneras.

El compilador puede convertir strcpy((char*) pName[0], dummy); en <=> que es un elenco implícito peligroso. Si su compilador es medio decente, recibirá una advertencia o error (como está viendo con su & Quot; error C2664 & Quot;).

No hay diferencia. Ambos se bloquearán ya que no ha asignado ningún espacio para pName. :) [EDITAR: ya no se produce un bloqueo: la pregunta se ha editado]

La principal diferencia es estilística, frecuentemente influenciada por la forma en que se escribe el código circundante, principalmente acceso de matriz o acceso de puntero.

(EDITAR: suponiendo que realmente quisiste decir & amp; pName [0] como señaló Brian Bondy).

Una matriz es simplemente un puntero que se asigna automáticamente (generalmente) a un bloque de memoria asignado automáticamente. Tomando su ejemplo, puede declarar ficticio igualmente como:

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

Y luego puede usar la sintaxis de matriz o la sintaxis de puntero para acceder a los datos:

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

Tanto [] como * se pueden usar para hacer referencia a punteros y matrices, por lo que los siguientes son equivalentes:

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

Dada la segunda forma, (ptr + N) sigue siendo un puntero, un poco más adelante en la matriz. Por eso es sintácticamente correcto en su ejemplo. ptr[N] es una desreferenciación del puntero y es un carácter (en este contexto).

pName es puntero a la memoria recién asignada. char *pName = new char[10];

ficticio también es una matriz / puntero. char dummy[] = "dummy";

pName es puntero y apunta a la dirección base, incluso si agrega (pName + 0) todavía apunta a la misma ubicación de memoria, ya que solo agrega 0. strcpy(pName + 0,dummy);

strcpy usa la variable de puntero y su valor de paso en el primer argumento, por lo tanto, obtiene el error strcpy(pName[0],dummy)

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top