2010-01-10 12 views
10

kann ich erklären:Wann ist Zeiger auf Array nützlich?

int (*ap)[N];

So ap Zeiger Array der Größe N. Warum ist das überhaupt sinnvoll in int ist? Wenn ich es an die Funktion übergebe, welche nützliche Sache kann es damit tun, dass es nicht mit einem normalen Zeiger auf den Inhalt des Arrays tun würde?

C FAQ sagen:

2,12: Wie kann ich einen Zeiger auf ein Array deklarieren?

Normalerweise möchten Sie nicht.

+3

ein Zeiger auf einen Zeiger auf einen int ist aber nützlich. – Toad

+0

Ich glaube nicht, dass ich in den über 25 Jahren, die ich in C programmiert habe, Code mit einem Zeiger auf ein Array schreiben musste (ich habe nur Triple Pointer verwendet - SomeType *** var - ein paar Mal, und änderte den Code, um sie zu vermeiden, sobald ich könnte.) –

+1

@reinier: sicher, aber ich habe nicht gefragt, dass – zaharpopov

Antwort

-3

I denke, die Schlussfolgerung aus dieser ganzen Diskussion ist nie. Niemand hat hier wirklich eine Verwendung für dieses Konstrukt demonstriert, wo etwas anderes nicht verständlicher funktionieren würde.

2

Es ist nicht sinnvoll, wirklich. Manchmal werden Zeiger auf Arrays verwendet, z. in Microsoft Windows API - ich habe viele dieser Sachen dort gesehen.

+0

was für in der Win API verwendet? – zaharpopov

+0

Sie können nach "Zeiger auf Array" inurl: msdn.microsoft.com googlen. Beispiele: http://msdn.microsoft.com/en-us/library/ms221359.aspx, http://msdn.microsoft.com/en-us/library/ms714816%28VS.85%29.aspx usw. –

+0

@ adam.wos: habe mir diese Links angeschaut - diese sehen wirklich wie Zeiger auf Arrays in C aus, nur Zeiger – zaharpopov

6

Wenn Sie den Zeiger inkrementieren, wird er auf den Anfang der nächsten Gruppe von N Elementen zeigen.

Dies ist keine große Sache und es ist Sache des Entwicklers.

+4

Gott, hast du das schon mal gesehen? – bmargulies

+1

Toll zu sehen, dass jemand weiß, dass die beiden nicht gleich sind =) –

+0

@bmargulies: Ich habe es für ein Array von MD5-Prüfsummen verwendet, wo jede Prüfsumme 16 Bytes ist. –

0

Dies wird wahrscheinlich kielholen off in subjektiven/argumentativen, aber ...

Meiner Meinung nach, Zeiger auf Arrays in der Sprache sind, weil sie in die Sprache fielen. Es gibt Zeiger auf jeden anderen deklarierbaren Datentyp, also sind diese auch hier. Ich habe noch nie jemanden gesehen, der wirklich nützliche Arbeit daraus gemacht hat. Sie erlauben hypothetisch einen Prototyp, der ein Array und nicht einen Zeiger auf das Element verlangt, aber ...

+0

... aber sie sind dasselbe (ein Zeiger auf das (erste) Element und ein Zeiger auf ein Array)? :) –

+0

Sie bewerten den gleichen Ort, aber die Typen sind unterschiedlich, und Typen sind wichtig. –

-1

Es scheint mir ziemlich nutzlos, einen Zeiger auf ein Array zu machen. In C ist ein Array bereits ein Zeiger auf einen Block dieses Datentyps.

int (*ap)[N]; 
int **ipp; 

haben beide den gleichen Datentyp (ein Zeiger auf einen Zeiger auf eine Ganzzahl). Der einzige Unterschied besteht darin, dass Platz für N ganze Zahlen für p vorhanden ist.

Es ist nicht notwendig, ein Array mit einem Zeiger auf eine Funktion zu übergeben, um den Inhalt des Arrays innerhalb dieser Funktion zu ändern, da es sich bereits um einen Zeiger handelt. Als allgemeine Regel würde ich sagen, dass es unnötig ist und nur eine zusätzliche Notwendigkeit erzeugt, den Zeiger zu dereferenzieren, um auf die Daten in dem Array zuzugreifen. Aber ich bin sicher, dass es irgendwo ein Programm oder einen Algorithmus gibt, der einen legitimen Nutzen daraus ziehen könnte.

+1

Nein, sie sind nicht derselbe Datentyp. Du sagst also, dass es okay ist, 'ipp = ap;' und 'ap = ipp;' zu machen (vorausgesetzt, dass die Zeiger auf etwas Nützliches zeigen)? –

+1

Sie sind nicht das Gleiche. Probieren Sie '++ ap' und' ++ ipp' aus und sehen Sie, was Sie bekommen. –

+2

Arrays ** sind keine ** Zeiger. Ein Array * Ausdruck * kann in den meisten Kontexten implizit in den Zeigertyp konvertiert werden, aber das ist nicht das Gleiche. In Ihrem Beispiel sind "ap" und "ipp" nicht kompatible Typen; Sie könnten den Wert von "ap" nicht zu "ipp" oder umgekehrt zuweisen (zumindest nicht ohne eine explizite Umwandlung). –

2

Es gibt Situationen, in denen Sie den Speicherort über Programme hinweg übergeben möchten. Zum Beispiel könnte eine Windows-API erwarten, dass Sie einen Zeiger auf eine Datenstruktur oder ein Array übergeben, wo Sie, wie Sie in einer anderen Sprache programmieren, sagen C#. Windows-API ist es egal, wie die Zielsprache die Arrays behandelt, für die Windows-API ist es nur ein Byte-Stream im Speicher, der sie füllt und an Sie zurücksendet. Um zu vermeiden, dass verschiedene Sprachen verwendet werden, missmatch wir in einigen Fällen Zeiger auf Array statt impliziten Array-Namen als Zeiger. Darüber hinaus ist nicht garantiert, dass der implizite Array-Name ein langer Zeiger ist, einige Compiler optimieren ihn möglicherweise als relativen Wert mit Segment. Ein Zeiger auf ein Array garantiert, dass es in der Reihenfolge der Maschinenregistergröße ist und Sie auf eine Position irgendwo im verfügbaren RAM verweisen können.

+0

können Sie Code Beispiel von diesem verwendet zeigen? – zaharpopov

13

Ein Zeiger auf ein Array kann verwendet werden, um ein mehrdimensionales Array N dynamisch zuzuweisen, wobei N-1-Dimensionen bekannt sind. Im Folgenden wird ein Nx3-Array erstellt.

int (*ap)[3]; 
ap = malloc(N * sizeof(*ap)); 
/* can now access ap[0][0] - ap[N-1][2] */ 

@Adam E/Cruachan, Dies ist nicht dasselbe wie ein Zeiger auf einen Zeiger. ap ist ein einzelner Zeiger auf einen Speicherblock, der drei aufeinanderfolgende ganze Zahlen enthält. ap ++ wird die Zeigeradresse auf den nächsten Block von drei ganzen Zahlen vorrücken. für int **pp; verweist pp auf einen Integer-Zeiger, von denen jeder auf eine ganze Zahl irgendwo im Speicher zeigen kann.

  +-----+    +------+ +-----+ 
ap ---> | int | vs. pp ---> | int* | -> | int | 
     | int |    +------+ +-----+ 
     | int |  pp+1 -> | int* | -\ 
     +-----+    +------+ \ +-----+ 
ap+1 -> | int |     : :  -> | int | 
     | int |        +-----+ 
     | int | 
     +-----+ 
      : : 
+0

aber wohl ap ist nur ein 2d-Array. – Pod

+2

Ja, aber es ist nicht dasselbe wie "int ap [4] [3];". Es ermöglicht die dynamische Zuweisung der 2. Dimension. –

+0

Ah ich sehe, in diesem Fall gebe ich meinen Fehler zu und ziehe meine Antwort zurück. – Cruachan

2

Im Allgemeinen ist die einzige Zeit, die Sie einen Zeiger auf ein Array sehen werden (T (*a)[N]) ist als Funktionsparameter, wo a gemeint ist ein 2D-Array sein:

void foo(int (*a)[N], size_t count) 
{ 
    size_t i; 
    for (i = 0; i < count; i++) 
     a[i][j] = ...; 
    ... 
} 

void bar(void) 
{ 
    int arr[M][N]; 
    foo(arr, M); 
} 

Beachten Sie, dass für ein Funktionsparameter Erklärung ist int a[][N] zu int (*a)[N] äquivalent, aber dies ist nur für Funktionsparameter Deklarationen true:

void foo (int a[][N], size_t count) {...} 

Zeiger auf Arrays sind im Allgemeinen nicht so nützlich wie Zeiger auf den Basistyp, da Sie die Array-Größe kennen müssen, um einen Zeiger darauf korrekt deklarieren zu können (ein Zeiger auf ein 10-Elemente-Array von int ist ein anderer Typ als a Zeiger auf ein 20-Elemente-Array von int). Persönlich habe ich nicht viel Gebrauch für sie in 20-einigen-ungeraden Jahren der Programmierung gefunden. Beachten Sie, dass in den meisten Kontexten ein Array-Ausdruck (z. B. arr oben) seinen Typ implizit von "N-Element-Array von T" in "Zeiger auf T" konvertiert (außer wenn der Array-Ausdruck ein Operand von ist) sizeof oder &, oder das Array ist ein String-Literal, das als Initialisierer in einer Deklaration verwendet wird). In diesem Fall wird der Typ von arr im Aufruf von foo implizit von "M-Element-Array von N-Element-Array von Int" in "Zeiger auf N-Element-Array von Int" konvertiert.

die Erklärung T a[M][N] Gegeben, alle folgenden Ausdrücke werden, an den gleichen Ort (in dem Array die Adresse des ersten Elements) bewerten, aber die Typen unterschiedlich sein werden, wie unten gezeigt:

 
Expression   Type    Implicitly converted to 
----------   ----    ----------------------- 
     a   T [M][N]   T (*)[N] 
     a[0]   T [N]    T * 
     &a   T (*)[M][N]   
    &a[0]   T (*)[N] 
    &a[0][0]   T * 
-1

Code folgt ein Teil meines Artikels: Pointers und Arrays in C C++

Sie können es heraus @http://pointersandarrays.blogspot.com/

Pointers und 2D-Arrays

Code-Schnipsel folgend zeigt wie man ein 2D-Array deklariert und darauf zugreift. Unter dem 2D-Array befindet sich ein eindimensionales Array. Sie werden sicher sein, nachdem Sie mit dem folgenden Code gespielt haben.

Code Snippet # 4


#include<iostream&rt; 
    using namespace std; 

    int main() 
    { 
    cout<< "Understanding Pointers and 2 D Arrays"<<endl; 
    cout<< "----------------------\n"<<endl; 

    //Declaration of a 2D Array. 
    int tab[3][5]; 
    //Total space required : 3*5 * sizeof(int) = 15 * sizeof(int) 
    //Funda : Since the amount of required space is known by compiler, contiguous 15 memory cells are allocated here.  
    //Hence the case is similar to a 1 D Array of size 15. Lets try this out! 

    //Array initialization using array name 
    for(int i=0; i<3;i++) 
    for(int j=0; j<5;j++) 
     tab[i][j]=i+2*j; 

    //Print array using array name 
    cout << "\nPrint array using array name ..."<<endl;  
    for(int i=0; i<3;i++) 
    { 
     for(int j=0; j<5;j++) 
     printf("%2d ",tab[i][j]); 
     printf("\n"); 
    } 

    //Print array using a pointer. Proof of 1 D array being allocated 
    cout << "\nPrint array using a pointer. Proof of 1 D array being allocated ..." << endl;  
    int *tptr; 
    tptr = &tab[0][0]; // pointer tptr points at first element of the array. 

    for(int i=0; i<15;i++) 
    printf("%d ",*(tptr+i)); 
    tptr = &tab[0][0]; 
    cout << "\nNotice that array is printed row by row in a linear fashion."<<endl; 
    return 0; 
    } 

Ausgabe # 4:

Understanding Pointers and 2D Arrays 

Print array using array name ... 
0 2 4 6 8 
1 3 5 7 9 
2 4 6 8 10 

Print array using a pointer. Proof of 1 D array being allocated ... 
0 2 4 6 8 1 3 5 7 9 2 4 6 8 10 
Notice that array is printed row by row in a linear fashion. 

Verwandte Themen