2010-02-25 14 views
7

ich the following text from Stanford's Programming Paradigms class lese, und ich bemerkte, dass, wenn der Autor die String-Klasse verwendet, der Konstruktor einen Funktionsaufruf funktioniert das wie folgt aussieht:Elementary C++ Typ Verwirrung

string::string(const char* str) { 
    initializeFrom(str, str + strlen(str)); 
} 

Wenn die InitializeFrom Funktion nimmt zwei char * Argumente, wie kann das zweite Argument eine (char * + int) an ein char * übergeben und es richtig arbeiten lassen? Wie interpretiert das Typsystem diese Aussage?

Vielen Dank im Voraus.

+0

'strlen()' gibt tatsächlich ein 'size_t' zurück, nicht ein' int'. Einer der wichtigen Unterschiede besteht darin, dass "size_t" ein vorzeichenloser Typ ist, d. H. Er kann nur positive Zahlen enthalten. Dies ist sinnvoll - Zeichenkettenlängen können 0, 1 oder 30000 Zeichen sein, aber niemals -7. – MSalters

Antwort

11

Das heißt Zeigerarithmetik. Ein char * + int führt zu einem Zeichen *, dessen Zeichen im Speicher höher sind.

+1

+1 für die korrekte Benennung. :) –

+0

Wenn der 'Int' ist -ve könnte es auch im Speicher niedriger sein; es sollte also ein 'unsigned int' sein, damit das Ergebnis * immer * höher im Speicher ist. [Sorry, wenn das ein Nickerchen ist;] – legends2k

+0

@ legends2k Das ist wahr, obwohl strlen() niemals einen negativen Wert zurückgeben sollte, so dass der bestimmte Code, der hier analysiert wird, dazu führt, dass das zweite Argument immer größer oder gleich dem ersten ist. – ChrisH

0

Das erste Argument zeigt auf den Anfang des char-Array und den zweiten Punkt der NULL-Zeichen am Ende des char-Array.

const char *str = "abc"; 
char *start = str; // start now points to the first char. 
char *end = str + strlen(str); // end now points to the null char at the end. 

Sie können dies durch Drucken bestätigen:

printf("%c %d",*start,*end); // will output: a 0 
0

wie das zweite Argument kommen können (char * + int) übergeben

Es ist immer noch vorbei ein char * Zeige zu strlen(str) hinter dem anfänglich angegebenen Ort.

2

Denken Sie daran, dass ein Zeiger nur eine Variable ist, die eine Speicheradresse enthält. Sie können also Werte zu einer Speicheradresse hinzufügen. Eine Speicheradresse ist eine Nummer.

Wenn Sie 1 auf einen Zeiger eines bestimmten Typs hinzufügen, wird es tatsächlich fügen 1 * sizeof (Typ). Wenn Sie einen beliebigen Wert N hinzufügen, wird tatsächlich N * sizeof (type) hinzugefügt.

betrachte das folgende Beispiel:

int x[5] = {0,1,2,3,4}; 
int *p = &(x[0]);//point to the first element 
p = p + 1;//p now points to the second element. 
4

Binäre additiven Operatoren + und - können verwendet werden, wenn ein Argument einen Zeiger auf jede vollständige Typ ist (sagen wir, T* p) und das andere Argument eine ganze Zahl ist (sagen wir, i). Sie implementieren so genannte Zeigerarithmetik.

Der Compiler wird davon ausgegangen, dass der Zeiger auf ein Element irgendeiner Anordnung zeigt (sagen wir, T array[N]). Die Operation erzeugt einen Zeiger auf ein anderes Element des Arrays, das i Elemente vom ursprünglichen Element entfernt ist. Es ist möglich, den Zeiger in jede Richtung zu "bewegen", d. H. Zum Anfang des Arrays oder zum Ende des Arrays hin. Wenn beispielsweise auf array[3] zeigt, wird p + 4 auf array[7] zeigen.

Der Betrieb ist nur gültig, wenn das Ergebnis zeigt auf ein vorhandenes Element des Arrays oder einem hinter dem letzten Elemente der Anordnung, dh die Anordnung gegebene T array[N] ist es möglich, Verweise auf Elemente aus array[0] zum imaginären Elemente zu schaffen, array[N]. Alle Versuche, diese Grenzen unter Verwendung der Zeigerarithmetik zu überschreiten, führen zu undefiniertem Verhalten.

Der Typ T hat vollständig sein, dass die Zeigerarithmetik verwendet werden kann, nicht mit void * Zeiger bedeutet, für ein Beispiel, auch wenn einige Compiler dies als Erweiterung ermöglichen (void * Zeiger als äquivalent zu char * Zeiger Behandlung).

Neben den binären Additionsoperatoren, Zeigerarithmetik enthält auch Präfix und Postfix unären ++ und -- Operatoren (auf Zeiger angewendet) sowie Verbindung Zuweisungsoperatoren += und -= (mit Zeigern auf ihrer linken Seite und die ganzen Zahlen auf die rechte Seite).

In Ihrem Fall wird str + strlen(str) Ausdruck einen Zeiger von char * Typ erzeugen, die str in der Zeichenfolge an den Abschluss \0 Charakter zeigt.

0

Ich denke, das kann überbeantwortet werden.

In:

initializeFrom(str, str + strlen(str)); 

str ist ein Zeiger auf den Anfang des Strings.

(str + strlen(str)) ist ein Zeiger auf das Ende der Zeichenfolge.

Beachten Sie, dass str (a Zeichenzeiger) ist nur eine ganze Zahl ((int), (long), (long long) je nach Architektur), die eine Stelle im Speicher identifiziert.

+0

Ein Zeiger ist nicht (immer) eine ganze Zahl. Bei x86-16 zum Beispiel handelt es sich um ein Paar Ganzzahlen. – MSalters