ProgramlamaSistem Programcısı

C dilinde işlevlere parametrelerin iletim mekanizmalarını ayrıntılı olarak anlatabilir misiniz: değerine göre ve işaretçiye göre? Her bir yaklaşımın ne zaman haklı olduğunu gösteren örnekler verin.

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

Cevap.

C dilinde işlevlere parametreler her zaman değerine göre iletilir — yani çağrılan koddan bir değer kopyası işlevin içine gönderilir. Eğer işlev dışında bir değişkenin değerini değiştirmek gerekiyorsa, işaretçi ile iletim kullanılır.

Değerine göre iletim

Bir skalar (örneğin, int) iletildiğinde işlev kendi kopyasını alır:

void foo(int a) { a = 10; } int main() { int x = 5; foo(x); // x == 5, değişmeyecek! }

İşaretçiye göre iletim

Değişkenin değerini değiştirmek için işaretçi kullanılır:

void foo(int* a) { *a = 10; } int main() { int x = 5; foo(&x); // x == 10, değer değişti! }

Ne zaman işaretçi kullanmalı

  • Birden fazla değer döndürmek gerektiğinde.
  • Büyük yapıları değiştirmek için (zaman ve bellek tasarrufu, kopyalama yok).
  • Dizilerle çalışmak için (her zaman işaretçi olarak iletilirler).

Kandırmaca soru.

Dizi, işlevin bir parametresi olarak referansla mı iletilir?

Birçok kişi "referansla" diye yanıt verir, ancak C dilinde işlev imzasında dizi referansla iletilmez, aslında işaretçiye dönüşür.

Doğru cevap:

Bir dizi bir işleve iletildiğinde, aslında ilk elemanının işaretçisi iletilir. Yani çağrılan işlev, dizinin gerçek boyutunu bilmez ve dizinin elemanlarındaki herhangi bir değişiklik orijinal diziye yansır.

void foo(int arr[]) { arr[0] = 100; } int main() { int a[3] = {1,2,3}; foo(a); // a[0] 100 olacak! }

Tarihçe


Bir projede işlev, int arr[10] olarak tanımlanan bir dizinin değerlerini güncelleyordu, ancak çağrıldığı kodda dizi daha küçük bir boyuttaydı. İşlev gerçek boyutu bilmediğinden, tampon taşması ve bellek bozulması meydana geldi.


Başka bir durumda, yapının değerine göre işleve iletilmesi nedeniyle, büyük bir bellek bloğu birkaç kez kopyalandı ve bu uygulamanın performans düşüşüne yol açtı.


Geliştirici, bir skalar değerinin "referansla" (işaretçi üzerinden) iletilmesinin orijinal değerin değişmezliğini garanti edeceğini umuyordu, ancak yanlışlıkla işaretçi ile bellek alanı dışındaki bir alanı değiştirdi (işaretçi aritmetiği hata), bu da öngörülemeyen sonuçlara yol açtı.