C dilinde bir işaretçi veya dizi işlevine geçirildiğinde aslında işaretçinin değerinin (yani bellek adresinin) bir kopyası geçirilir, dizi veya bellek içeriği değil. Tarihsel olarak diziler C dilinde değer ile geçilmez - bunun yerine işleve dizinin ilk elemanına işaret eden bir işaretçi gider. Bu mekanizma bellek tasarrufu sağlar, ancak yanlış kullanımda istenmeyen yan etkilere neden olabilir.
Sorun - işaretçiler ve diziler arasındaki kafa karışıklığı: geliştiriciler sık sık işlev içinde diziyi değiştiremeyeceklerini veya işlevin otomatik olarak geçirilen dizinin boyutunu bildiğini düşünürler. Pratikte işlev dizinin orijinal boyutunu kaybeder ve kolayca sınırlarının dışına çıkabilir.
Çözüm - her zaman dizinin boyutunu ayrı bir argüman olarak açıkça geçirmek, işaretçi kopyası ve nesne kopyası arasındaki farkı net bir şekilde anlamak, işaretçi üzerinden yapılan herhangi bir değişikliğin orijinal verilere yansıyacağını unutmamak.
Dizinin doğru bir şekilde geçirilmesine örnek:
void print_array(const int* arr, size_t size) { for (size_t i = 0; i < size; ++i) printf("%d ", arr[i]); } int main() { int nums[] = {1,2,3,4,5}; print_array(nums, sizeof(nums)/sizeof(nums[0])); return 0; }
Anahtar özellikler:
Bir işlev, int arr[10] olarak bildirildiğinde geçirilen dizinin uzunluğunu öğrenebilir mi?
Cevap: Hayır, işlev içinde sizeof(arr) ifadesi işaretçinin boyutunu döndürecektir, tüm dizinin boyutunu değil. Boyutu ayrı olarak geçirmek gerekir.
Diziyi int arr[] ve int arr olarak işlevlerde geçirmek aynı şey midir?*
Cevap: Evet, işlevin imzasında eşdeğerdir - her iki durumda da int için bir işaretçi geçirilir. Sadece sözdiziminde farklılıklar vardır.
İşlev içinde dizinin elemanlarını değiştirerek, orijinal dizi değişir mi?
Cevap: Evet, çünkü işaretçi geçirilmiş, işlev işaretçinin işaret ettiği belleği değiştirir.
Proje dizileri başlatmak için bir işlev tanımlayarak boyutu işlev içinde sizeof(arr) / sizeof(arr[0]) ile belirledi. Test aşamasında işlev çalışıyordu, ancak diğer diziler işlenirken - başka bir bellek alanını yazıyor veya hatalı çalışıyordu.
Artılar:
Eksiler:
İşlev her zaman dizinin boyutunu ayrı bir parametre olarak alıyordu, uzunluk çağıran taraf tarafından hesaplanıyordu. İşlev içinde yalnızca geçirilen parametrelerle çalışılıyordu.
Artılar:
Eksiler: