ProgrammierungC Entwickler

Wie funktioniert der Mechanismus zur Übertragung von Argumenten in Funktionen der Programmiersprache C? Wie kann man Typfehler bei der Übertragung von Variablen unterschiedlicher Typen, Strukturen und Arrays vermeiden?

Bestehen Sie Vorstellungsgespräche mit dem Hintsage-KI-Assistenten

Antwort.

In der Programmiersprache C werden Argumente in Funktionen immer per Wert übergeben. Das bedeutet, dass die Funktion eine Kopie des Argumentwerts erhält. Dies ist für einfache Typen (int, float) offensichtlich: Änderungen innerhalb der Funktion beeinflussen nicht die ursprüngliche Variable. Für Arrays und Strukturen gibt es Nuancen:

  • Beim Übergeben eines Arrays an eine Funktion wird tatsächlich ein Zeiger auf das erste Element übergeben, nicht das gesamte Array. Der Zeiger selbst wird jedoch weiterhin per Wert übergeben.
  • Bei Strukturen kann man explizit eine Kopie (per Wert) übergeben, aber es ist vorteilhafter, diese Kopie über einen Zeiger zu machen – so kann die Funktion die ursprüngliche Struktur modifizieren.

Beispiel: Verarbeitung von Array und Struktur

#include <stdio.h> typedef struct { int a; int b; } Pair; void modifyArray(int arr[], int size) { arr[0] = 42; // modifiziert das ursprüngliche Array } void modifyStruct(Pair s) { s.a = 100; // verändert nur die lokale Kopie } void modifyStructPtr(Pair *s) { s->a = 200; // ändert das Original über den Zeiger } int main() { int nums[2] = {1, 2}; Pair p = {10, 20}; modifyArray(nums, 2); modifyStruct(p); modifyStructPtr(&p); printf("nums[0]=%d, p.a=%d ", nums[0], p.a); // nums[0]=42, p.a=200 return 0; }

Fangfrage.

Frage: Wenn eine Funktion als void func(int arr[10]) deklariert ist, hat dieses Array innerhalb der Funktion immer 10 Elemente?

Antwort: Nein. Die Notation int arr[10] in den Argumenten ist tatsächlich gleichbedeutend mit int *arr — die Größe des Arrays geht bei der Übergabe verloren. Die Funktion kennt die tatsächliche Länge des Arrays nicht, daher sollte immer ein zusätzlicher Parameter für seine Länge übergeben werden. Andernfalls sind Überläufe und UB möglich.

Beispiel:

void foo(int arr[10]) { printf("%d ", arr[9]); // arr enthält nicht unbedingt 10 Elemente! }

Geschichte

In einem Projekt zur Verarbeitung von Signalen wurde ein Array über eine Funktion übergeben, in der Annahme, dass seine Länge immer gleich ist, aber in einem Fall wurde ein kleineres Array übergeben. Das Ergebnis — Zugriff außerhalb des Speichers, Absturz der Anwendung und unvorhersehbares Verhalten im Controller.


Geschichte

In Bankensoftware versuchte man, eine Struktur zu modifizieren, indem man sie per Wert und nicht per Zeiger übergab. Die Änderungen wurden nicht gespeichert, was dazu führte, dass das Verarbeitungssystem den Kontostand nicht aktualisierte, was zu Fehlern in den Berechnungen führte.


Geschichte

In einem Telemetriesystem fügte ein Student eine Funktion zur Bereinigung des Arrays hinzu, vergaß jedoch, die Länge zu übergeben, und die Arrays hatten unterschiedliche Größen. Der Fehler wurde erst nach der Erfassung einer großen Menge inkorrekter Daten und einer langen Fehlersuche entdeckt.