ProgramlamaC geliştirici

C dilinde fonksiyonlara argüman geçiş mekanizması nasıl çalışır? Farklı türdeki değişkenlerin, yapıların ve dizilerin geçişinde tür hatalarından nasıl kaçınılır?

Hintsage yapay zeka asistanı ile mülakatları geçin

Cevap.

C dilinde fonksiyonlara argümanlar her zaman değeriyle geçirilir. Bu, fonksiyonun argümanın bir kopyasını aldığı anlamına gelir. Basit türler için (int, float) bu açıktır: fonksiyon içindeki değişiklikler orijinal değişkeni etkilemez. Diziler ve yapılar için bazı nüanslar vardır:

  • Bir diziyi bir fonksiyona geçirirken aslında ilk elemanına işaretçi geçirilir, tüm dizi değil. Ancak, işaretçi hala değeriyle geçilir.
  • Yapılar için kopyayı açıkça geçirmek mümkündür (değerle), ancak bu kopyayı geçiş yapmak için işaretçi kullanmak daha avantajlıdır — böylece fonksiyon orijinal yapıyı değiştirebilir.

Örnek: dizi ve yapının işlenmesi

#include <stdio.h> typedef struct { int a; int b; } Pair; void modifyArray(int arr[], int size) { arr[0] = 42; // orijinal diziyi değiştirdi } void modifyStruct(Pair s) { s.a = 100; // sadece yerel kopyayı değiştirir } void modifyStructPtr(Pair *s) { s->a = 200; // işaretçi üzerinden orijinali değiştirir } 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; }

Kandırmaca Sorusu.

Soru: Eğer fonksiyon void func(int arr[10]) olarak tanımlandıysa, bu dizinin içinde her zaman 10 eleman olacağını mı garanti eder?

Cevap: Hayır. int arr[10] ifadesi fonksiyon parametrelerinde aslında int *arr ile eşdeğerdir — dizi boyutu geçiş sırasında kaybolur. Fonksiyon, dizinin gerçek uzunluğunu bilmez, bu yüzden her zaman uzunluğuyla birlikte ek bir parametre almalısınız. Aksi takdirde, dizi sınırlarının dışına çıkma ve Tanımsız Davranış (UB) olasılığı vardır.

Örnek:

void foo(int arr[10]) { printf("%d ", arr[9]); // arr mutlaka 10 eleman içermiyor! }

Tarih

Sinyal işleme projesinde, diziyi fonksiyona geçirdiklerinde, boyutunun her zaman aynı olduğunu tahmin ediyorlardı, ancak bir durumda daha küçük bir dizi geçtiler. Sonuç — bellek sınırlarının dışına çıkma, uygulamanın çökmesi ve denetleyicide öngörülemeyen davranışın ortaya çıkması.


Tarih

Banka yazılımında, yapıyı değerle geçirmeye çalıştılar, işaretçiyle değil. Değişiklikler kaydedilmediği için, işlem modülü hesapların durumunu güncelleyemedi ve hesaplamalarda hatalara neden oldu.


Tarih

Telemetri sisteminde bir öğrenci, dizi temizleme fonksiyonu ekledi, ancak boyutu geçirmeyi unuttu ve diziler farklı boyuttaydı. Hata, büyük miktarda hatalı veri toplandıktan ve hata ayıklama süreci uzun sürdükten sonra ortaya çıktı.