ProgramlamaGömülü C geliştirici

C dilinde çok boyutlu dizilerin nasıl ilan edileceğini ve kullanılacağını tanımlayın. Fonksiyonlara geçirirken ve başlatırken hangi tuzaklar var?

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

Cevap

Sorunun Tarihi

C dilindeki çok boyutlu diziler başlangıçta tablolar ve matrislerle çalışmayı basit hale getirmek için tasarlanmıştır. Klasik iki boyutlu dizi - dizi dizileri, tabular verilerin elemanlarıyla basit bir sözdizimi ile çalışabilme imkanı sunar. Zamanla yaklaşım evrimleşti, özellikle değişken uzunluktaki dizilerle çalışırken.

Problemler

Yanlış ilan etme ve başlatma çok boyutlu dizilerin derleme hatalarına veya mantıksal arızalara yol açar. Çok boyutlu bir diziyi bir fonksiyona geçirirken pek çok geliştirici spesifikasyon gereksinimlerinden dolayı kafası karışır - ilk boyut hariç tüm boyutların boyutlarını açıkça belirtmek gerekir.

Çözüm

İki boyutlu dizinin ilanı:

int matrix[3][4];

Tam başlatma:

int matrix[2][3] = { {1, 2, 3}, {4, 5, 6} };

Fonksiyona geçirme - ilk boyut hariç tüm boyutları açıkça belirtmek gerekir:

void printMatrix(int m[][3], int rows) { for (int i = 0; i < rows; ++i) { for (int j = 0; j < 3; ++j) printf("%d ", m[i][j]); printf(" "); } }

C99 standardının getirilmesiyle değişken uzunluktaki dizileri alan fonksiyonlar ilan edilebilir:

void foo(int rows, int cols, int a[rows][cols]);

Önemli Faktörler:

  • Fonksiyonlara geçerken, ilk boyut hariç tüm boyutları açıkça belirtmek zorunludur.
  • C'deki çok boyutlu dizi - dizi dizileridir; elemanlar bellek içinde satırlara göre yerleştirilir (row-major order).
  • Kısmi başlatma, belirtilmemiş elemanları sıfırlarla başlatır.

Kandırmaca Soruları.

1. İki boyutlu bir diziyi ikinci boyutunu belirtmeden alabilen bir fonksiyon ilan edebilir miyiz?

Hayır, C derleme aşamasında, ilk boyut hariç tüm boyutların bilinmesini istemektedir. Bu, elemanlara erişim sırasında işaretçi aritmetiği ile ilgilidir.

Hata örneği:

// Hata: void process(int arr[][], int rows); // Olmaz

2. Çok boyutlu bir dizinin tüm elemanlarını başlatmazsak ne olur?

Geriye kalan elemanlar, eğer dizi statik veya global ise otomatik olarak sıfırlarla doldurulur. Kısmi başlatma ile yerel bir dizide de belirtilmemiş elemanlar sıfır olacak şekilde başlatılır.

int a[2][3] = {{1}, {4}}; // a[0][1] ve a[0][2], a[1][1] ve a[1][2] 0 olur

3. İşaretçi dizisi ile iki boyutlu dizi arasındaki fark nedir?

İki boyutlu dizi tek bir bellek bloğudur. İşaretçi dizisi, ayrı (belki de ayrı olarak tahsis edilmiş) bir boyutlu dizilere işaret eden işaretçiler dizisidir. Bu, „yırtık“ dizilere bellek tahsis etme gibi durumlarda önemlidir.

Tipik Hatalar ve Anti-patentler

  • Çok boyutlu dizilerle bir fonksiyon tasarlarken yapılan hatalar (iç ölçümlerin boyutu belirtilmemiş).
  • Row-major düzenle çalışırken satır ve sütunların karıştırılması.
  • İşaretçi dizisi gerçek çok boyutlu dizi ile değiştirilmektedir ve tam tersi.

Gerçek Hayat Örneği

Negatif Durum

İki boyutlu bir diziyi ikinci boyutunu belirtmeden tanımlama ve geçirme girişimi, derleme hatasına yol açar. Yüzeysel bir düzeltmeyle işaretçi ile değiştirmek, sonraki hesaplamalarda belirsiz veya yanlış davranışa yol açar.

Artılar:

  • Fonksiyonun ilan edilmesi kolay (ilk bakışta).

Eksiler:

  • Derleme hataları, yanlış indeks aritmetiği, veri hasarı.

Pozitif Durum

Geliştirici, tüm boyutların boyutlarını açıkça belirtir, bellek içindeki elemanların saklanma düzenine açıklık getirecek şekilde belgeler, böylece sonraki bakım sırasında hata sayısını azaltır.

Artılar:

  • Güvenli, doğru ve taşınabilir kod.

Eksiler:

  • Dizinin boyutu veya “genişliği” derleme aşamasında bilinmelidir ya da C99 standardı ve değişken uzunluktaki diziler gereklidir.