Frage

Das kam von diese Antwort auf eine frühere Frage von mir.Ist die Behandlung durch den Compiler garantiert? array[4][4] das Gleiche wie array[16]?

Zum Beispiel würde einer der folgenden Aufrufe an api_func() sicher sein?

void api_func(const double matrix[4][4]);

// ...

{
  typedef double Matrix[4][4];

  double* array1 = new double[16];
  double array2[16];

  // ...

  api_func(reinterpret_cast<Matrix&>(array1));
  api_func(reinterpret_cast<Matrix&>(array2));
}
War es hilfreich?

Lösung

Aus der C ++ Standard, bezogen auf den sizeof Operator:

  

Wenn auf eine Anordnung angewendet wird, ist das Ergebnis die Gesamtzahl der Bytes in dem Array. Dies bedeutet, dass die Größe eines Arrays von n Elementen ist n mal die Größe eines Elements.

Von diesem, würde ich sagen, dass double[4][4] und double[16] würden die gleiche zugrunde liegende Darstellung haben müssen.

d., Da

sizeof(double[4]) = 4*sizeof(double)

und

sizeof(double[4][4]) = 4*sizeof(double[4])

dann haben wir

sizeof(double[4][4]) = 4*4*sizeof(double) = 16*sizeof(double) = sizeof(double[16])

Ich denke, ein standardkonforme Compiler dieser gleich implementieren würde, und ich glaube, das ist nicht etwas, das ein Compiler versehentlich brechen. Der üblicher Weg multidimensionalen Arrays der Implementierung wie erwartet funktioniert. den Standard brechen würde erfordern zusätzliche Arbeit, für wahrscheinlich keinen Nutzen.

Der C ++ Standard auch fest, dass eine Reihe von aneinander angrenzend zugewiesenen Elementen besteht, was die Möglichkeit beseitigt etwas seltsam mit Zeigern und Polsterung zu tun.

Andere Tipps

Ich glaube nicht, dass es ein Problem mit der Polsterung gibt, die dadurch entsteht mehrdimensional Array.

Jedes Element in einem Array muss die von der Architektur vorgegebenen Füllanforderungen erfüllen.Ein Array [N][M] wird immer die gleiche Speicherdarstellung haben wie eines von [M*N].

Jedes Array-Element sollte in sequentiell Speichern vom Compiler angelegt. Die beiden Erklärungen während verschiedenen Typen sind die gleiche zugrunde liegende Speicherstruktur.

@Konrad Rudolph:

Ich verwechsele diese beiden (Reihen-Dur/Spalten-Dur) selbst, aber ich weiß Folgendes:Es ist klar definiert.

int x[3][5] ist beispielsweise ein Array der Größe 3, dessen Elemente int-Arrays der Größe 5 sind.(§6.5.2.1) Hinzufügen aller Regeln aus dem Standard zu Arrays, Adressierung usw.Sie erhalten, dass der zweite Index auf aufeinanderfolgende Ganzzahlen verweist, während der erste Index auf aufeinanderfolgende 5-Int-Objekte verweist.(Also ist 3 die größere Zahl;dazwischen liegen 5 Ints x[1][0] und x[2][0].)

Ich wäre besorgt über Polsterung für Dinge wie Matrix hinzugefügt werden [5] [5] jede Zeile Wort ausgerichtet zu machen, aber das könnte einfach mein eigener Aberglaube sein.

Eine größere Frage ist: Sie brauchen wirklich eine solche Guss ausführen

?

Auch wenn Sie könnte der Lage sein, mit ihm wegzukommen, wäre es noch besser lesbar und wartbar sein ganz zu vermeiden. Zum Beispiel könnten Sie konsequent Doppel [m * n] als die tatsächliche Art verwenden, und dann mit einer Klasse arbeiten, die diese Art Wraps, und vielleicht überlädt den Operator [] für einfache Bedienung. In diesem Fall könnten Sie benötigen auch eine Zwischenklasse eine einzelne Zeile zu kapseln -. So, dass Code wie my_matrix [3] [5] noch funktioniert wie erwartet

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