Frage

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

    }
War es hilfreich?

Lösung

  • Pname [0] ist das erste Element in einem Zeichenarray (eines Charakter)
  • PNAME ist eine Abkürzung zu & Pname [0] (ein Zeiger auf das erste Element Ihres Arrays)

Der Grund, warum Sie Ihren Fehler erhalten, ist, dass Strcpy einen Zeiger auf ein Zeichen (char*) erwartet und nicht einen Zeichenwert (was PNAME [0] ist)

Andere Tipps

Wenn Sie sich mit Zeigern und Arrays in C oder C ++ befassen, hilft es wirklich, sie als sehr unterschiedliche Konstrukte zu erkennen (ich denke, eines der besten Bücher, das diese Unterscheidung erklärt, ist ein Buch namens "Deep C Secrets", wenn ich mich richtig erinnere). Was das Wasser verwechselt ist, ist die Tatsache, dass es eine einweise stille Konvertierung von Array -Names zu Zeigern (eine Inkonsistenz in der Sprachabwicklung von variablen Namen) erlaubt ist - aber es ist sehr wichtig, die Existenz dieses Zerfallsphänomens nicht so zu interpretieren, wie es impliziert wird Gleichwertigkeit.

Lassen Sie uns die Idee einer „Gedächtniszelle“ vorstellen, um uns dazu zu behaupten. Wir modellieren eine "Speicherzelle" als zwei Attribute:

a) value
b) address

Wir können dann eine einfache C ++ - Variable mit zwei Attributen modellieren (wir benötigen keine Typen auf dieser niedrigen Abstraktionsstufe):

c) name  
d) memory cell

Wie die meisten Modelle hat es einige Mängel (befasst sich nicht mit einem Array mit mehr als einem Element, aber es reicht für unsere Zwecke aus).

Also zum Beispiel:

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

Hier ist der Hauptunterschied zwischen einer Array-Variablen und einer Nicht-Array (-Zeiger) C ++-Variable:

Wenn ein Variablenname in C ++ bewertet wird, bewertet er immer den Wert seiner Speicherzelle mit einer Ausnahme: Wenn die Variable eine Array -Variable nennt.
Wenn die Variable der Name eines Arrays ist, bewertet sie die Variable die Anschrift der Speicherzelle.
Die oben genannten zwei Zeilen sind wieder lesen.

Hier sind einige Beispiele, um die Auswirkungen zu klären (siehe obige Variablen):

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

Dies sollte in keiner Weise bedeuten, dass eine Array -Variable die ist gleich als Zeigervariable.
Sie haben von Natur aus unterschiedliche Typen und jeden Versuch, sie als die zu behandeln gleich (IE Definieren Sie einen Variablennamen als Array in einer Übersetzungseinheit und als Zeiger in einer anderen) wird zu schlechten Dingen führen.

Also für z. B. tun Sie dies nicht:

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

Ich hoffe das hilft. Wenn Sie immer noch der Meinung sind, dass eine weitere Klärung helfen könnte, stellen Sie bitte eine Folgefrage und zögern Sie nicht, eine Kopie (Bibliothek?) Dieses Buches "Deep C Secrets" zu erhalten :)

--
PS -Funktionstypen und ihre Namen und ihr Verfall sind für den größten Teil dieses Beitrags irrelevant
PS Ich habe auch absichtlich ausgelassen, dass die Umwandlung von Array zu Zeiger nicht auftritt, wenn Arrays an Referenztypen gebunden sind

Technisch, strcpy(pName[0], dummy); Ist nicht richtig. Auch wenn das Gedächtnis dafür zugewiesen wurde.

Das ist weil pName[0] ist vom Typ 'char' während pName + 0 ist vom Typ char*. Beide verweisen auf dieselbe Erinnerung, aber auf unterschiedliche Weise.

Der Compiler kann sich dann drehen strcpy(pName[0], dummy); hinein strcpy((char*) pName[0], dummy); Das ist eine gefährliche implizite Besetzung. Wenn Ihr Compiler halb anständig ist, erhalten Sie eine Warnung oder einen Fehler (wie Sie mit Ihrem "Fehler C2664" sehen).

Es gibt keinen Unterschied. Sie werden beide abstürzen, da Sie keinen Platz für PNAME zugeteilt haben. :) [Bearbeiten: Kein Absturz mehr - Frage wurde bearbeitet

Der Hauptunterschied ist ein stilistisches, der häufig von der Art und Weise beeinflusst wird, wie der umgebende Code geschrieben wird - hauptsächlich Array -Zugriff oder meist Zeigerzugriff.

(Bearbeiten: Angenommen, Sie haben wirklich gemeint & pname [0], wie Brian Bondy betonte.)

Ein Array ist einfach ein Zeiger (normalerweise), der einem automatisch zugewiesenen Speicherblock zugewiesen ist. Wenn Sie Ihr Beispiel nutzen, können Sie Dummy gleichermaßen deklarieren wie:

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

Und Sie können dann entweder die Array -Syntax oder die Zeigersyntax verwenden, um auf die Daten zuzugreifen:

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

Beide [] und * Kann de Recreference-Zeiger und -Arrays verwendet werden, sodass das Folgende entspricht:

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

Angesichts der zweiten Form, (ptr + N) ist immer noch ein Zeiger, nur weiter entlang des Arrays. Aus diesem Grund ist es in Ihrem Beispiel syntaktisch korrekt. ptr[N] ist eine Entfernung des Zeigers und ist ein Zeichen (in diesem Zusammenhang).

PNAME ist Zeiger auf den neu zugewiesenen Speicher. char *pName = new char[10];

Dummy ist auch ein Array/Zeiger. char dummy[] = "dummy";

PNAME ist Zeiger und zeigt auf die Basisadresse, selbst Sie fügen (pName + 0) immer noch auf denselben Speicherort hinzu, weil Sie nur 0 hinzufügen. strcpy(pName + 0,dummy);

STRCPY Verwenden Sie die Zeigervariable und Ihr Bestehenswert im ersten Argument. Daher erhalten Sie Fehler strcpy(pName[0],dummy)

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top