2017-01-21 2 views
0

Stellen Sie sich dieses ziemlich einfache Szenario vor. Ich habe eine Funktion, die einige Manipulationen durchführt und ein Array von Zeichenzeigern zurückgibt. Aus Gründen der Einfachheit, lassen Sie diese Funktion keine Argumente haben:Zurückgeben eines Arrays von Zeichenfolgen (char *) in C

#include <stdio.h> 

char **func(void); 

int main() { 
    printf("%s\n", func()[0]); 
    return 0; 
} 

char **func() { 
    static char arr[3][10] = {"hi", "bye", "cry"}; 
    return arr; 
} 

Ich möchte dieses Array zugreifen können, in meiner main() Funktion. Ich mache das Array statisch, um zu vermeiden, dass die Adresse an eine lokale Variable zurückgegeben wird, die im Bereich func() definiert ist. Dieser Code kompiliert, aber mit einer Warnung:

Warnung: Rückkehr von inkompatiblen Zeigertyp [-Wincompatible-pointer-types]

        Rückkehr arr;

                           ^

Aber was soll ich die Rückkehr Argument machen dann? Ein Zeiger auf ein Char-Array? Ich dachte, dass es in C schlecht ist, ein Array zurückzugeben.

Das Ausführen dieses Programms führt zu einem nicht hilfreichen Segmentierungsfehler.

Also was mache ich falsch? Kann ich keinen Zeiger auf ein Array von Zeichenzeigern zurückgeben? Daher ist ein char **? Füge ich Array/Pointer-Zerfall zusammen? Wie würde ich ein Array von Strings zurückgeben? Gibt es eine Möglichkeit, ein Zeichenfolgenarray ohne das Schlüsselwort static zurückzugeben?

Edit: Sicher können Sie alle mit meiner Verwirrung einfühlen? Es ist nicht so, als ob die Array-Pointer-Zerfallsfunktion von C trivial ist.

+2

Sie haben kein Array von 'char *'. 'char **' und 'char [] []' ist nicht derselbe Datentyp.Warum deklarieren Sie Ihr Array nicht als 'static char * arr [] = {"hi", "tschüss", "weinen"}; 'Dann können Sie' arr' wie im ursprünglichen Code zurückgeben. – DyZ

+1

Was machst du falsch? Sie möchten ein Array von Char-Zeigern zurückgeben, aber Sie haben kein Array von Char-Zeigern *. (Es ist so, als wolle man in eine Welt zurückkehren, in der die globale Erwärmung nicht stattfindet.) –

Antwort

2

In der Anweisung return arr;, arr wird auf ein Array von 10 Zeichen auf Zeiger Zerfall, das heißt vom Typ char (*)[10] während Rückgabetyp Ihrer Funktion char ** ist. Beide Zeigertypen sind nicht kompatibel.
Sie können den Typ arr in der Deklaration vom Array von Arrays zum Array von Zeigern ändern.

static char *arr[3] = {"hi", "bye", "cry"}; 

oder Sie können den Rückgabetyp der Funktion ändern char (*)[10]

char (*func())[10] {...} 
+0

Dieser Code funktioniert nicht ganz so, wie Sie vielleicht erwarten. Die Deklaration erstellt ein Array von 10 Zeigern zu char. Ich vermute eher, dass Sie eine Reihe von Zeigern auf 10 Zeichen haben wollten. Das wäre char (* arr []) [10]. Weitere Informationen zu diesem Thema finden Sie unter: http://cdecl.ridiculousfish.com/ –

+0

@PeterCamilleri; 'char (* arr []) [10]' deklariert 'arr' als ein Array von Zeigern zu einem Array von 10' char's. Ich wollte 'arr' als ein Array von 3 Zeigern zu 'char' deklarieren. Aus Versehen habe ich '10' anstelle von' 3' geschrieben. – haccks

+0

OK, aber in jedem Fall werden sogar die drei nicht benötigt, da der Compiler herausfinden kann, wie viele Elemente die Initialisierungskonstante sind. Indem Sie diese Information nicht wiederholen, ist es nur eine Sache weniger falsch zu machen. In einigen Programmiergemeinschaften heißt das DRY - Do not Repeat Yourself. Nicht üblich in "C", aber immer noch ein nützliches Konzept, wenn möglich. –

2

Das Array:

static char arr[3][10] = {"hi", "bye", "cry"}; 

ist ein Array von Reihen von 10 Zeichen. Dies ist NICHT kompatibel mit Char **.

Versuchen

static char *arr[] = {"hi", "bye", "cry"}; 

statt.

+0

Danke! Könnte ich ein 'char *' Array ohne die Verwendung von 'static' zurückgeben? –

+1

@KennethWorden Nein, kannst du nicht. Wenn Sie einen Zeiger auf eine lokale Variable zurückgeben, haben Sie ein undefiniertes Verhalten. – DyZ