7 Stimmen

Übergabe von Zeigern auf Arrays in C

Ich habe also einen Code, der wie folgt aussieht:

int a[10];
a = arrayGen(a,9);

und die arrayGen-Funktion sieht wie folgt aus:

int* arrayGen(int arrAddr[], int maxNum)
{
    int counter=0;
    while(arrAddr[counter] != '\0') {
        arrAddr[counter] = gen(maxNum);
        counter++;
    }
    return arrAddr;
}

Im Moment sagt mir der Compiler "warning: passing argument 1 of 'arrayGen' makes integer from pointer without a cast".

Mein Denken ist, dass ich 'a', einen Zeiger auf a[0] übergeben, dann, da das Array bereits erstellt wird, kann ich nur in Werte für a[n] füllen, bis ich a[n] == ' \0 '. Ich denke, mein Fehler ist, dass arrayGen geschrieben wurde, um ein Array aufzunehmen, nicht einen Zeiger auf eines. Wenn das wahr ist, bin ich nicht sicher, wie ich vorgehen soll, schreibe ich Werte an Adressen, bis der Inhalt einer Adresse ' \0 '?

17voto

Charlie Martin Punkte 106684

Die grundlegende Magie hier ist diese Identität in C:

*(a+i) == a[i]

Okay, jetzt werde ich es in lesbares Englisch umwandeln.

Hier ist das Problem: Ein Array-Name ist kein L-Wert; ihm kann nicht zugewiesen werden. Also ist die Zeile, die Sie mit

a = arrayGen(...)

ist das Problem. Siehe dieses Beispiel:

int main() {
    int a[10];

    a = arrayGen(a,9);

    return 0;
}

was den Kompilierungsfehler verursacht:

gcc -o foo foo.c
foo.c: In function 'main':
foo.c:21: error: incompatible types in assignment

Compilation exited abnormally with code 1 at Sun Feb  1 20:05:37

Sie müssen einen Zeiger haben, der ist einen l-Wert, dem die Ergebnisse zugewiesen werden sollen.

Dieser Code, zum Beispiel:

int main() {
    int a[10];
    int * ip;

    /* a = arrayGen(a,9);  */
    ip = a ; /* or &a[0] */
    ip = arrayGen(ip,9);

    return 0;
}

kompiliert gut:

gcc -o foo foo.c

Compilation finished at Sun Feb  1 20:09:28

Beachten Sie, dass Sie wegen der Identität oben ip als Array behandeln können, wenn Sie möchten, wie in diesem Code:

int main() {
    int a[10];
    int * ip;
    int ix ;

    /* a = arrayGen(a,9);  */
    ip = a ; /* or &a[0] */
    ip = arrayGen(ip,9);

    for(ix=0; ix < 9; ix++)
        ip[ix] = 42 ;

    return 0;
}

Vollständiger Beispielcode

Nur der Vollständigkeit halber hier mein vollständiges Beispiel:

int gen(int max){
    return 42;
}

int* arrayGen(int arrAddr[], int maxNum)
{
    int counter=0;
    while(arrAddr[counter] != '\0') {
        arrAddr[counter] = gen(maxNum);
        counter++;
    }
    return arrAddr;
}

int main() {
    int a[10];
    int * ip;
    int ix ;

    /* a = arrayGen(a,9);  */
    ip = a ; /* or &a[0] */
    ip = arrayGen(ip,9);

    for(ix=0; ix < 9; ix++)
        ip[ix] = 42 ;

    return 0;
}

4voto

Phaedrus Punkte 8273

Warum überhaupt arrAddr zurückgeben? Ihre Übergabe a[10] durch Referenz, so dass der Inhalt des Arrays geändert werden. Es sei denn, Sie benötigen eine andere Verweis auf das Array, dann ist Charlies Vorschlag richtig.

2voto

Tim D Punkte 31

Hmm, ich weiß, dass Ihre Frage bereits beantwortet wurde, aber etwas anderes am Code stört mich. Warum verwenden Sie den Test gegen ' \0 ', um das Ende des Arrays zu bestimmen? Ich bin mir ziemlich sicher, dass das nur mit C-Strings funktioniert. Der Code kompiliert in der Tat nach der vorgeschlagenen Korrektur, aber wenn Sie Schleife durch Ihr Array, ich bin neugierig zu sehen, ob Sie die richtigen Werte erhalten.

2voto

D.Shawley Punkte 56313

Ich bin nicht sicher, was Sie versuchen zu tun, aber die Zuweisung eines Zeigerwerts zu einem Array ist das, was den Compiler stört, wie erwähnt von Charlie . Ich bin neugierig auf die Prüfung gegen die NUL-Zeichen-Konstante '\0' . Ihr Beispielarray ist nicht initialisierter Speicher, so dass der Vergleich in arrayGen wird nicht das tun, was Sie wollen.

Die Parameterliste, die Sie verwenden, ist letztendlich identisch mit:

int* arrayGen(int *arrAddr, int maxNum)

für die meisten Zwecke. Die eigentliche Aussage in der Norm lautet:

Eine Deklaration eines Parameters als "Array of tipo "wird geändert in "qualifizierter Zeiger auf tipo ", wobei die Typqualifizierer (falls vorhanden) diejenigen sind, die innerhalb der [ und ] der Array-Typableitung angegeben sind. Wenn das Schlüsselwort static auch innerhalb der [ und ] der Array-Typ-Ableitung vorkommt, dann muss der Wert des entsprechenden tatsächlichen Arguments bei jedem Funktionsaufruf den Zugriff auf das erste Element eines Arrays mit mindestens so vielen Elementen ermöglichen, wie durch den Größenausdruck angegeben sind.

Wenn Sie den Aufrufer wirklich zwingen wollen, ein Array zu verwenden, dann verwenden Sie die folgende Syntax:

void accepts_pointer_to_array (int (*ary)[10]) {
    int i;
    for (i=0; i<10; ++i) {
        (*ary)[i] = 0; /* note the funky syntax is necessary */
    }
}

void some_caller (void) {
    int ary1[10];
    int ary2[20];
    int *ptr = &ary1[0];
    accepts_pointer_to_array(&ary1); /* passing address is necessary */
    accepts_pointer_to_array(&ary2); /* fails */
    accepts_pointer_to_array(ptr);   /* also fails */
}

Ihr Compiler sollte sich beschweren, wenn Sie es mit irgendetwas aufrufen, das nicht ein Zeiger auf ein Array von 10 Ganzzahlen ist. Ich kann aber ehrlich sagen, dass ich diese Funktion noch nie irgendwo außerhalb verschiedener Bücher gesehen habe ( Das C-Buch , Experte für C-Programmierung ) ... zumindest nicht in der C-Programmierung. In C++ habe ich jedoch in genau einem Fall Grund gehabt, diese Syntax zu verwenden:

template <typename T, std::size_t N>
std::size_t array_size (T (&ary)[N]) {
    return N;
}

Aber das kann sich ändern. Wenn Sie sich wirklich mit solchen Dingen befassen wollen, kann ich nicht empfehlen Experte für C-Programmierung hoch genug. Sie können auch finden Das C-Buch online unter gbdirect .

0voto

Ray Hidayat Punkte 15627

Versuchen Sie, Ihren Parameter int* arrAddr , nicht int arrAddr[] . Obwohl, wenn ich darüber nachdenke, die Parameter für die main Methode sind ähnlich, aber es funktioniert. Also nicht sicher über die Erklärung Teil.

Edit: Hm, alle Quellen, die ich im Internet finden kann, sagen, dass es funktionieren sollte. Ich bin mir nicht sicher, ich habe immer Arrays als Zeiger selbst übergeben, so hatte nie dieses Problem vor, so ich bin sehr interessiert an der Lösung.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X