Frage

Dieses Beispiel funktioniert:

static char *daytab[] = {
    "hello",
    "world"
};

Dies gilt nicht:

static char *daytab[] = {
    {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31},
    {0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}
};

So wie ich es zu sehen ist, dass das erste Beispiel ein Array erzeugt, die mit Zeigern zu den beiden Stringliterale gefüllt ist (die selbst Arrays). Das zweite Beispiel, IMO, sollte identisch sein -. Ein Array erstellen und mit Zeigern auf den zwei char-Arrays füllen

Könnte mir jemand erklären, warum das zweite Beispiel ist falsch?

P. S. Sie könnten wahrscheinlich es so schreiben (habe es nicht getestet):

static char a[] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
static char b[] = {0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
static char *daytab[] = {
    a,
    b
};

Aber das sieht aus wie zu viel Arbeit.)

War es hilfreich?

Lösung

Dieses:

{0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}

Ist nur ein Feldinitialisierung. Es ist nicht selbst ein Array erstellen. Das erste Beispiel, wenn Sie einen Stringliteral zu einem Zeiger zugewiesen, DID diese Zeichenfolgen in statischen Speicher erstellen (für Sie versteckt) und dann nur die Zeiger auf ihnen zugewiesen.

Also im Grunde gibt es keine Möglichkeit, char * mit dem Feldinitialisierung zu initialisieren. Sie benötigen eine aktuelle Array zu erstellen, und diese Zahlen zuweisen. Sie würde so etwas zu tun haben:

char a[][] = { {32, 30, 0}, {34, 32, 33, 0} }; // illegal

Aber das ist illegal.

Sie müssen die Array separat und ordnen sie in ein Array wie Ihr letztes Beispiel bauen.

Andere Tipps

Versuchen:

static char daytab[][13] = {
    {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31},
    {0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}
};

Das ist nicht char * s. Sie sind entweder nicht verkohlen. Sie wollen wahrscheinlich:

static int daytab[][13] ...

Nun, ist dieser Thread schon ein bisschen alt, aber ich war mit dem gleichen Problem zu tun und fand einen Weg, um ein Array von Zeigern auf Arrays zu initialisieren, wie folgt aus:

#include <iostream>
using namespace std;

int *a[] = {
  (int[]) { 0 } ,
  (int[]) { 1 , 2 } ,
  (int[]) { 3 , 4 , 5 } ,
  (int[]) { 6 , 7 , 8 , 9 }
};

main()
{
  cout
  << a[0][0] << endl
  << a[1][0] << " " << a[1][1] << endl
  << a[2][0] << " " << a[2][1] << " " << a[2][2] << endl
  << a[3][0] << " " << a[3][1] << " " << a[3][2] << " " << a[3][3] << endl;
}

Und ich bekomme die Ausgabe, Kompilieren mit Gnu g ++

0
1 2
3 4 5
6 7 8 9

und Kompilieren mit Intel icpc

0
1 1
40896 32767 -961756724
0 32767 4198878 0

So scheint die Syntax grundsätzlich richtig, nur, dass die Intel-Compiler correcly es nicht unterstützt, wahrscheinlich aufgrund eines fehlenden gemeinsamen Nutzung dieses Stils.


--- edit ---

Hier ist auch eine C-Version (wie gefordert):

#include <stdio.h>

int *a[] = { 
  (int[]) { 0 } , 
  (int[]) { 1 , 2 } , 
  (int[]) { 3 , 4 , 5 } , 
  (int[]) { 6 , 7 , 8 , 9 } 
};

int main()
{
  printf( "%d\n" , a[0][0] );
  printf( "%d %d\n" , a[1][0] , a[1][1] );
  printf( "%d %d %d\n" , a[2][0] , a[2][1] , a[2][2] );
  printf( "%d %d %d %d\n" , a[3][0] , a[3][1] , a[3][2] , a[3][3] );
}

Ich habe es getestet mit gcc und Klirren und druckt es das richtige Ergebnis. Btw. die falsche Ausgabe des Intel-Compiler war ein Compiler-Fehler.

static char **daytab;
daytab=(char**)malloc(2*sizeof(char*));
daytab[0]=(char*)(char[]){0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
daytab[1]=(char*)(char[]){0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};

Die Syntax Ihres zweites Beispiel ist die Syntax für eine mehrdimensionale Arrayliteral.

Ein mehrdimensionales Array kein Array von Zeigern auf Arrays.

Es wäre überraschend, wenn die Syntax für eine Sache, auch die Syntax für eine andere Sache ist, je nach Typ es deklariert ist zu sein.

Im ersten Beispiel, weil ein Stringliteral auf einen Zeiger ausgewertet wird eher als ein Array-Wert, wird der Wert als ein Array von Zeigern ausgewertet. Da literal ein Array als Array Wert ausgewertet wird, anstatt einen Zeiger, ist das zweite Beispiel ein mehrdimensionales Array - ein Array, dessen Elemente Arraywerte, kein Array, dessen Elemente sind Zeiger auf Array-Werte.

Der folgende Code zeigt die Kombinationen von mehrdimensionalen Arrays, Zeiger auf Arrays, Arrays von Zeigern, und Zeiger auf Zeiger. Von diesen drei sind nur Arrays von Zeigern und Zeiger auf Zeiger miteinander kompatibel:

void multi_array (int x[][4], size_t len) // multidimensional array
{
    for (size_t i = 0; i < len; ++i)
        for (size_t j = 0; j < 4; ++j)
            putchar( 'a' + x[i][j] );
    putchar('\n');
}

void ptr_array (int (*x)[4], size_t len) // pointer to an array
{ ... as multi_array  }

void array_ptr (int *x[], size_t len) // array of pointers
{ ... as multi_array  }

void ptr_ptr (int **x, size_t len) // pointer to pointer
{ ... as multi_array  }

int main() {
    int a[][4] = { { 1,2,3,4 } };
    int b[] = { 1,2,3,4 };
    int* c[] = { b };

    multi_array( a, 1 );
    multi_array( (int[][4]) { { 1,2,3,4} }, 1 ); // literal syntax as value
    ptr_array( &b, 1 );
    array_ptr( c, 1 );
    ptr_ptr( c, 1 ); // only last two are the same

    return 0;
}

Beachten Sie, dass Ihr erstes Beispiel nicht, entweder nicht funktioniert. Es muss sein:

static const char *daytab[] = {
    "hello",
    "world"
};

Beachten Sie die const .

Edit:. Und mit „funktioniert nicht“, ich meine schlechte Praxis und fehleranfällig, was wohl schlimmer ist

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top