2009-11-27 9 views
17

Grundfrage.Unterschied zwischen der Verwendung von Zeichenzeigern und Zeichenfeldern

char new_str[]=""; 

char * newstr; 

Wenn ich einige Daten in sie verketten oder String-Funktionen verwenden, wie strcat/substr/strcpy, was ist der Unterschied zwischen den beiden?

Ich verstehe, ich muss Speicher zuweisen, um den char * -Ansatz (Zeile # 2). Ich bin mir nicht so sicher.

Und const char * und String-Literale sind die gleichen?

Ich muss mehr dazu wissen. Kann jemand auf einen schönen erschöpfenden Inhalt/Material hinweisen?

+1

Werfen Sie einen Blick auf diesen erstaunlichen Tutorial http://pw2.netcom.com/~tjensen/ptr/cpoint.htm – jyz

Antwort

7

Bitte gehen Sie durch this article unter:

wie bei Array von char Siehe auch in Ihrem Fall char new_str [] dann die new_str wird immer Punkt auf der Basis des Arrays. Der Zeiger an sich kann nicht inkrementiert werden. Ja, Sie können Indizes verwenden, um auf das nächste Zeichen im Array zuzugreifen, zB: new_str[3];

Aber im Falle von Zeiger auf char, kann der Zeiger new_str++ inkrementiert werden, um Sie das nächste Zeichen im Array abzurufen.

Auch würde ich empfehlen this article für mehr Klarheit.

2

Der Unterschied ist, dass man ein Zeiger ist, der andere ist ein Array. Sie können zum Beispiel sizeof() -Array. Sie könnten daran interessiert sein zu spähen here

1

Der Typ des ersten ist char [1], der zweite ist char *. Verschiedene Typen.

Speicher für Letzteres mit malloc in C oder new in C++ zuordnen.

char foo[] = "Bar"; // Allocates 4 bytes and fills them with 
        // 'B', 'a', 'r', '\0'. 

Die hier angegebene Größe bezieht sich auf die Initialisierungszeichenfolge.

Der Inhalt von foo ist veränderbar. Sie können zum Beispiel foo[i] ändern, wobei i = 0..3.

OTOH wenn Sie das tun:

char *foo = "Bar"; 

Der Compiler jetzt eine statische Zeichenfolge "Bar" in Nur-Lese-Speicher reserviert und kann nicht geändert werden.

foo[i] = 'X'; // is now undefined. 
+0

Hmm. Nein. foo ist nicht veränderbar. Du kannst foo nicht ändern. Sie können die Elemente von foo ändern, ja, aber Sie können foo nicht in bar ändern, wenn z. B. auch bar ein char-Array ist. –

+0

Gut genug, Herr Nitpicker. –

-2

Wenn Sie in C++ sind, warum verwenden nicht std::string für alle Ihre Bedürfnisse String? Vor allem etwas, was mit Verkettungen zu tun hat. Dies wird Sie vor vielen Problemen bewahren.

1

Wenn Sie C++ verwenden, wie Ihre Tags angeben, sollten Sie wirklich die C++ - Zeichenfolgen verwenden, nicht die C char-Arrays.

Der Typ string macht die Manipulation von Strings viel einfacher.

Wenn Sie mit char Arrays aus irgendeinem Grund stecken, die Zeile:

char new_str[] = ""; 

ordnet 1 Byte von Raum und setzt einen Nullabschluss Charakter hinein. Es unterscheidet sich subtil von:

char *new_str = ""; 

da dies Ihnen einen Verweis auf nicht beschreibbaren Speicher geben kann. Die Aussage:

char *new_str; 

allein gibt Ihnen einen Zeiger aber nichts, auf das er zeigt. Es kann auch einen zufälligen Wert haben, wenn es lokal für eine Funktion ist.

Was die Menschen neigen zu tun (in C statt C++) ist wie etwas zu tun:

char *new_str = malloc (100); // (remember that this has to be freed) or 
char new_str[100]; 

genügend Platz zu bekommen.

Wenn Sie die str... Funktionen verwenden, sind Sie im Grunde dafür verantwortlich, dass Sie genügend Platz im char Array haben, damit Sie alle Arten von seltsamen und wunderbaren Praxis bekommen Code debuggen. Wenn Sie echte C++ - Zeichenfolgen verwenden, wird eine Menge Grunz-Arbeit für Sie erledigt.

5

Dies ist ein Zeichen-Array:

char buf [1000]; 

So zum Beispiel macht dies keinen Sinn:

buf = &some_other_buf; 

Dies, weil buf ist, obwohl es Eigenschaften vom Typ Zeiger hat, ist es bereits auf den einzigen Ort zeigen, der Sinn macht.

char *ptr; 

Auf der anderen Seite, ptr ist nur ein Zeiger und kann irgendwo hin. Meistens ist es so etwas wie das ist:

ptr = buf;    // #1: point to the beginning of buf, same as &buf[0] 

oder vielleicht dies:

ptr = malloc (1000); // #2: allocate heap and point to it 

oder:

ptr = "abcdefghijklmn"; // #3: string constant 

Für alle diese können * ptr to-mit Ausnahme des dritten geschrieben werden Fall, in dem einige kompilierende Umgebungen String-Konstanten als nicht schreibbar definieren. Peter Van der Linden, Expert C Programming, Tiefe C Geheimnisse

*ptr++ = 'h';   // writes into #1: buf[0], #2: first byte of heap, or 
         //    #3 overwrites "a" 
strcpy (ptr, "ello"); // finishes writing hello and adds a NUL 
8

Die ausgezeichnete Quelle ist die Verwirrung zu klären - dass Arrays und Zeiger sind nicht das gleiche ist, wie sie im Speicher adressiert werden.

Mit einem Array,

char new_str[];
, hat der Compiler der neuen_str eine Speicheradresse gegeben, die sowohl bei der Kompilierung als auch bei der Laufzeit bekannt ist, z. 0x1234, daher ist die Indizierung von new_str einfach, indem [] verwendet wird. Beispielsweise new_str[4], zur Laufzeit wählt der Code die Adresse aus, in der sich new_str befindet, z. 0x1234 (das ist die Adresse im physischen Speicher).Durch Hinzufügen des Indexspezifizierers , 0x1234 + 0x4, kann der Wert dann abgerufen werden. Der Zeiger gibt mit einem Zeiger dem Symbol
char *newstr
eine Adresse an, z. B.

. 0x9876, aber zur Laufzeit ist diese Adresse ein indirektes Adressierungsschema. Unter der Annahme, dass Newstr malloc'd

newstr = malloc(10);
ist, passiert, dass jedes Mal eine Referenz im Code verwendet wird, um newstr zu verwenden, da die Adresse von newstr durch den Compiler bekannt ist, d. H. 0x9876, worauf aber newstr zeigt, ist variabel. Zur Laufzeit holt der Code Daten aus dem physischen Speicher 0x9876 (dh newstr), aber an dieser Adresse ist eine andere Speicheradresse (da wir sie mallocten), zB 0x8765 ist es hier, der Code holt die Daten von dieser Speicheradresse malloc zugewiesen zu newstr, dh 0x8765.

Die char new_str[] und char *newstr werden austauschbar verwendet, da ein nullte Element Index des Arrays in einen Zeiger zerfällt und das erklärt, warum Sie könnten newstr[5] oder *(newstr + 5) Beachten Sie, wie der Zeiger Ausdruck verwendet wird, obwohl wir char *newstr erklärt haben, damit

*(new_str + 1) = *newstr;
ODER
*(new_str + 1) = newstr[1];

Zusammengefasst, der wahre Unterschied zwischen den beiden ist, wie sie im Speicher zugegriffen werden.

Holen Sie sich das Buch und lesen Sie es und leben Sie es und atmen Sie es. Es ist ein brillantes Buch! :)

+2

Als eine Randnotiz: C ist bekannt, um kommutative Ausdrücke zu haben, zum Beispiel 4 + 3 ist gleich wie 3 + 4. Dies gilt auch in Zeigern, * (new_str + 1) ist das gleiche wie * (1 + new_str) übrigens ist 1 [new_str]. Das war ein Witz und wird an anderer Stelle im Netz referenziert, wahrscheinlich um jemanden zu vertreiben. IT wird selten in der Produktion verwendet, muss es noch irgendwo sehen! – t0mm13b

0
char new_str[]="abcd"; 

Dies gibt eine Reihe von Zeichen (eine Zeichenkette) der Größe 5 Bytes (ein Byte für jedes Zeichen plus eins für den Null-Terminator). So speichert es die Zeichenfolge 'abcd' im Speicher und wir können auf diese Zeichenfolge mit der Variablen new_str zugreifen.

char *new_str="abcd"; 

Dies gibt eine Zeichenfolge ‚ABCD‘ wird irgendwo in dem Speicher und der Zeiger new_str zeigt auf das erste Zeichen dieser Zeichenkette gespeichert.

0

Um sich in der Speicherzuordnung Seite zu unterscheiden:

// With char array, "hello" is allocated on stack 
char s[] = "hello"; 

// With char pointer, "hello" is stored in the read-only data segment in C++'s memory layout. 
char *s = "hello"; 

// To allocate a string on heap, malloc 6 bytes, due to a NUL byte in the end 
char *s = malloc(6); 
s = "hello"; 
Verwandte Themen