Danke für deinen Ratschlag und deine Ausführungen Nytro.
Ich hätte jetzt schon gesagt, dass ich die Arrays grundsätzlich soweit ganz gut verstanden habe. Auch die Unterschiede zu Pointern. Was natürlich nicht heisst, dass ich mir einbilde, alles darüber zu wissen! :-)
Aber wenn ich mir die so "üblichen" Kapitelbeiträge in verschiedenen Büchern und Online-Tutorials dazu anschaue, bekomme ich jedenfalls nicht den Eindruck, dass ich elementar etwas noch nicht verstanden hätte.
VLAs waren mir halt neu - finde das einfach interessant.
Deine Übungen sehen spannend aus - werde sie auch sehr gerne versuchen zu beantworten - wenn ichs denn kann! Danke dafür! :-)
Grundsätzlich
Der Parameter a der Funktion f ist kein "echtes" array. Beim Aufruf der Funktion wird die Adresse (Anfangsadresse) des Arrays in einen Pointer vom Typ int konvertiert (int Pointer). sizeof(a) liefert dir also nur die Grösse eines Pointers. Bei einem 64 Bit OS ist diese 8 Byte. Auf einem 32 Bit OS wäre sie allerdings nur 4 Byte.
b ist ein array (kein Pointer) und zwar lokal (Lebensdauer: auto) auf dem Stack mit der Grösse 16 Byte (int entspricht hier 4 Byte: also 4 * 4 = 16).
c ist ein "echtes" 2D Array (also nicht blos ein Array aus Pointern). Es hat 4 Zeilen mit je 4 Spalten (erst die Zeilen, dann die Spalten, wie bei einer Matrix). Das Array liegt auf dem Stack (lückenlos) und weist 16 Elemente auf, von denen jedes 4Byte beansprucht. Also 4^3 = 64 (Byte).
zu 1.
Tatsächlich gäbe es keinen Unterschied. Auch hier ist dieses Array nur ein Pointer. Laut K&R (S. 100) wäre die Syntax int* a zu bevorzugen, da somit sofort klar wäre, dass es sich hierbei nur um einen Pointer und nicht um ein Array handelt (sizeof a liefert auch hier nur die Grösse des Pointers)
zu 2.
Selbe Geschichte wie bei 1.
Die Angabe static 4 ist vielmehr ein versprechen (Hinweis) an den Compiler, dass das array _mindestens_ 4 Elemente aufweist, was ihm (dem Compiler) allenfalls gestattet gewisse Optimierungen vorzunehmen.
NytroX hat geschrieben: ↑04.12.2022, 21:50
z.B. int (*array)[n][m] = malloc(sizeof *array); ist ja nichts mit VLAs, wenn das schon zu kompliziert ist brauchst du mit VLAs und dessen Besonderheiten gar nicht anfangen. :-P
Hier waage ich mal zu widersprechen :-)
Schon klar: mit malloc reserviere ich dynamisch Speicher auf dem Heap. Doch für den Syntax array[n][m] sind VLAs nötig, da n und m keine Konstanten, sondern Variablen sind. Unter C89 wäre das nicht gegangen. Da ginge nur eine Zahlenkonstante, eine Konstante mittels enum oder eine mittels DEFINE.
Ich lasse mich gerne eines Besseren belehren, falls etwas an meinen Antworten so nicht korrekt ist. :-)
LG, starcow
Jonathan hat geschrieben: ↑04.12.2022, 23:03
Aber um Dozenten zu überzeugen: Das klingt so ein bisschen wie ein Erstsemestlerding :D Je länger man in der Uni ist desto mehr versteht man, dass Dozenten auch nicht unbedingt Experten sind. Bzw. dass das, was man so landläufig als Experte bezeichnet auch einfach nicht immer Ahnung oder Recht hat. Und das ist vollkommen ok so.
Ich hätte bis gestern auch behauptet, dass es UB ist, aber wenn mir dann jemand sagt "aaaaactually gibt es auch Variable length Arrays" dann hätte ich halt gesagt "aha, interessant schick mal Link". Irgendwelche Punkte oder Noten beeinflusst sowas in der Regel nicht, es zählt halt der Gesamteindruck und wenn du dich schon mit deinem Dozenten "anlegst" ist der hoffentlich ohnehin positiv (oder du blamierst dich gerade ziemlich :D).
Wenn dein Dozent so ein Ego-Problem hat, dass er dir nicht glauben will, dann vergiss es einfach. Du kannst bei so Diskussionen nicht viel gewinnen, und derartige Menschen würden dir am Ende eher noch einen reinwürgen wenn du zu lange darauf rumreitest.
Weise Worte! :-)