Das vorgestellte Programm ist völlig inkorrekt. Ein variabler Länge Array nicht statisch Lagerdauer aufweisen kann/Gemäß dem C Standard (6.7.6.2 Array Deklaratoren)
2 Wenn eine Kennung, wie mit einem variabel modifizierten Typ deklariert wird, ist es wird eine gewöhnliche Kennung sein (wie in 6.2.3 definiert), haben keine Verknüpfung, und haben entweder Block Scope oder Funktion Prototyp Umfang. Wenn ein Identifier als Objekt mit statischer oder Thread-Speicher-Dauer deklariert ist, darf er keinen Array-Typ variabler Länge haben.
Darüber hinaus sind die Zeigertypen double **
double (*)[cols]
und (auf dem die Anordnung vorgesehen, dass es richtig umgewandelt wird in Ausdrücken deklariert wurde) nicht kompatibel sind. Also ist die Funktion falsch.
double** example(int rows, int cols){
static double tr[rows][cols];
for(int i = 0; i < rows; i++)
for(int j = 0; j < cols; j++)
tr[j][i] = 0;
return tr;
}
Hier ist ein Demonstrationsprogramm, das zeigt, wie man mit Arrays variabler Länge umgeht.
#include <stdio.h>
void init(size_t rows, size_t cols, double a[rows][cols])
// or
// void init(size_t rows, size_t cols, double a[][cols])
// or
// void init(size_t rows, size_t cols, double (*a)[cols])
{
for (size_t i = 0; i < rows; i++)
{
for (size_t j = 0; j < cols; j++) a[i][j] = 0.0;
}
}
void display(size_t rows, size_t cols, double a[rows][cols])
// or
// void display(size_t rows, size_t cols, double a[][cols])
// or
// void display(size_t rows, size_t cols, double (*a)[cols])
{
for (size_t i = 0; i < rows; i++)
{
for (size_t j = 0; j < cols; j++) printf("%lf", a[i][j]);
putchar('\n');
}
}
int main(void)
{
while (1)
{
size_t m, n;
printf("Enter numbers of rows and columns (0 - exit): ");
if (scanf("%zu%zu", &m, &n) != 2 || m == 0 || n == 0) break;
double a[m][n];
putchar('\n');
init(m, n, a);
display(m, n, a);
putchar('\n');
}
return 0;
}
Sein Ausgang könnte wie folgt aussehen
Enter numbers of rows and columns (0 - exit): 2 3
0.0000000.0000000.000000
0.0000000.0000000.000000
Enter numbers of rows and columns (0 - exit): 3 4
0.0000000.0000000.0000000.000000
0.0000000.0000000.0000000.000000
0.0000000.0000000.0000000.000000
Enter numbers of rows and columns (0 - exit): 0 0
Innerhalb der beiden Funktionen der dritte Parameter auf den Zeigertyp eingestellt double (*a)[cols]
. Es ist nicht dasselbe wie double **a
.
Wenn Sie zum Beispiel schreiben, wird das folgende Programm
#include <stdio.h>
#define M 2
#define N 3
int main(void)
{
int a[M][N] =
{
{ 1, 2, 3 },
{ 4, 5, 6 }
};
int **p = (int **)a;
p[0][0] = 10;
return 0;
}
dann wird es nicht definiertes Verhalten, weil p[0]
den Wert in dem Element gespeichert hält a[0][0]
(oder den kombinierten Wert in Elementen gespeichert a[0][0]
und a[0][1]
auf die je Größe des Zeigers), das ist der Wert 1 als Zeigerwert und versuchen, auf den Speicher an Adresse 1 im Ausdruck p[0][0]
zuzugreifen.
'example' ein Doppel zurück Zeiger auf das erste Element. Sie können auf seine Elemente auf die gleiche Weise wie in der Funktion zugreifen, d. H. 'Tr [0] [1]' <- Zeile 0, Spalte 1. – Geoff
Werfen Sie dieses Buch weg, es lehrt Sie * Müll *. Siehe Vlads Antwort unten. 'double **' ist * nicht * der richtige Typ für ein 2D-Array. –