Pergunta

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

    }
Foi útil?

Solução

  • pname [0] é o primeiro elemento em uma matriz de caracteres (1 personagem)
  • Pname é um atalho para & pname [0] (um ponteiro para o primeiro elemento da sua matriz)

A razão pela qual você está recebendo seu erro é porque o strcpy espera um ponteiro para um char (char*), e não um valor de char (que é o que é o pname [0])

Outras dicas

Ao lidar com ponteiros e matrizes em C ou C++ que realmente ajuda a reconhecê-los como muito distinto construções (eu acho que um dos melhores livros que explica esta distinção é um livro chamado "Deep C Segredos" se eu me lembro corretamente).O que confunde as águas é o fato de que existe uma maneira silenciosa de conversão permitida a partir da matriz de nomes para ponteiros (uma inconsistência na linguagem de manipulação de nomes de variáveis), mas é muito importante não interpretar a existência de decadência como um fenómeno que implica equivalência.

Para nos ajudar a raciocinar sobre isso, vamos apresentar a ideia de uma "célula de memória'.Temos o modelo de uma "célula de memória' como tendo dois atributos:

a) value
b) address

Podemos, então, um modelo simples em C++ variável como tendo dois atributos (nós não precisamos de tipos em que este baixo nível de abstração):

c) name  
d) memory cell

Como a maioria dos modelos, tem algumas deficiências (não lidar com uma matriz com mais de um elemento, mas é suficiente para os nossos propósitos).

Assim, por exemplo:

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

Agora aqui está a principal diferença entre uma variável de array e um não array (ponteiro) variável C++:

Quando um nome de variável em C++ é avaliado, ele sempre avalia o valor da célula de memória com uma exceção:se os nomes de variáveis uma variável de matriz.
Se a variável é o nome de uma matriz avalia a endereço da célula de memória.
As duas linhas acima vale a pena ler de novo.

Aqui estão alguns exemplos para ajudar a esclarecer as implicações (consulte as variáveis acima):

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

Isto não deve implicar que uma variável de matriz é o mesmo como uma variável de ponteiro.
Eles têm inerentemente diferentes tipos e qualquer tentativa de tratá-los como a mesmo (i.é.definir um nome de variável como uma matriz em uma unidade de tradução, e como um ponteiro em outro), vai resultar em coisas ruins acontecendo.

Assim, por exemplo:não faça isso:

// 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 isso ajude.Se você ainda sentir que de mais esclarecimentos podem ajudar, por favor, pergunte a um acompanhamento questão, e não hesite em obter uma cópia (biblioteca?) de que "Profundo C Segredos", o livro :)

--
p.s.função de tipos e os seus nomes e a sua decadência são irrelevantes para a maioria este post
p.s.Eu também intencionalmente deixada de fora que a matriz-para-ponteiro de conversão não ocorre quando as matrizes são vinculados a tipos de referência

Tecnicamente, strcpy(pName[0], dummy); não está correto. Mesmo que a memória fosse alocada para isso.

Isto é porque pName[0] é do tipo 'char' enquanto pName + 0 é do tipo char*. Ambos fazem referência à mesma memória, mas de maneiras diferentes.

O compilador pode então virar strcpy(pName[0], dummy); em strcpy((char*) pName[0], dummy); que é um elenco implícito perigoso. Se o seu compilador for meio decente, você receberá um aviso ou erro (como está vendo com o seu "Erro C2664").

Não há diferença. Ambos vão travar, pois você não alocou nenhum espaço para o PNAME. :) [Editar: Não é mais um acidente - a pergunta foi editada

A principal diferença é estilística, freqüentemente influenciada pela qual se encaixa na maneira como o código circundante é escrito - principalmente acesso à matriz ou acesso principalmente ao ponteiro.

(Editar: assumindo que você realmente quis dizer e Pname [0] como Brian Bondy apontou.)

Uma matriz é simplesmente um ponteiro automaticamente (geralmente) atribuído a um bloco de memória alocado automaticamente. Levando seu exemplo, você pode declarar dummy igualmente como:

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

E você pode usar a sintaxe da matriz ou a sintaxe do ponteiro para acessar os dados:

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

Ambos [] e * Pode ser usado de referência e matrizes de referência, portanto, os seguintes são equivalentes:

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

Dada a segunda forma, (ptr + N) ainda é um ponteiro, apenas mais longe ao longo da matriz. É por isso que está sintaticamente correto em seu exemplo. ptr[N] é uma des-referência do ponteiro e é um char (neste contexto).

O PNAME é um ponteiro para a memória recém -alocada. char *pName = new char[10];

Dummy também é uma matriz/ponteiro. char dummy[] = "dummy";

O PNAME é ponteiro e aponta para o endereço base, até você adiciona (Pname + 0) ainda está apontando para o mesmo local de memória, porque você adiciona apenas 0. strcpy(pName + 0,dummy);

StrCpy Use a variável de ponteiro e seu valor de aprovação no primeiro argumento, portanto, você está recebendo erro strcpy(pName[0],dummy)

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top