C'de dizinin pointer gibi davranmasını engellemek

Merhabalar bu koddaki bubbleSort fonksiyonundaki dizi parametresi bir pointer gibi davrandığı için main’deki diziyide etkiliyor merakımdan soruyorum bunu önlemenin bir yolu varmıdır (main’nin icinde dizinin bir kopyasını oluşturup fonksiyona onu vermek hariç)

void bubbleSort(int dizi[],int len){
    int temp;
    for (int i = 0;i < len;i++){
        for (int j = 0;j < len-i-1;j++){
            if (dizi[j] > dizi[j + 1]){
                temp = dizi[j];
                dizi[j] = dizi[j + 1];
                dizi[j + 1] = temp;
            }

        }


    }

}


int main(){

    int dizi1[5] = {4,5,2,7,2};
    bubbleSort(dizi1,5);
    for (int i = 0;i < 5;i++){
        printf("%d,",dizi1[i]);
    }

    return 0;
}

Hayir, cunku dizi kolayca kopyalanan bir sey degil.

int, int * gibi degiskenler normal kod akisi sirasinda dogal olarak kopyalaniyor—herhangi bir assembly koduna bakarsaniz, register’lar arasinda gidip gelen her verinin hemen her adimda kopyalandigini gorursunuz. Kopyalanmayacaklari kod daha uzun, daha komplike ve daha yavas.

Buna karsit, dizileri kopyalamak bir is. Belki de asla bitmeyecek, haliyle butun programi etkileyecek bir is. (Dizinin boyu sonsuzsa mesela.) Bu ise ozel fonksiyonlar, hatta yardimci instruction’lar var ama asla bir int degeri gibi dogal/kazara olacak is degil.

Kopyayi otomatik yapmanin bir yolu yok. Belki boyutu bilinen ufak bir dizi optimizasyon olarak stack’te veya register’larda kopyalanabilir, ama dilin semantigi degisikliklerin main tarafindan gorulmesi gerektigini soyluyor—yani boyle bir durumda bile kopya kaynaga geri atanmak zorunda.

C’nin otomatik yaptigi en karmasik islem struct kopyalamak herhalde. Deger olarak paslayip dondurdugunuzde her field’i kopyalayacak kod uretiliyor. Peki array’den ne farki var? Boyutu biliniyor. Ayrica dil de struct’larin boyle davranmasi gerektigini soyluyor.


Bu arada:

Yukaridaki fonksiyonda dizinin kopyasi alinmazsa fonksiyon hic bir ise yaramaz.

main’in icinde kopya olusturmaya alternatif bubbleSort’un icinde kopya olusturup dondurmek.

4 Beğeni

Bir fonksiyona bir bir dizi geçerseniz, C size referansla erişim sağlar. Referansla erişirseniz de asıl veriyi değiştirmiş olursunuz.

Yani asıl veriye erişim sağlayıp sıraladığınızda olması gereken olur ve ilk veriniz değişir.

Referansla erişimi önlemenin bir yolu eriştiğiniz referans yerine başka bir dizi kullanmaktır. Ki biz buna zaten diziyi kopyalamak diyoruz.

Local bir değişken ile bir dizi aynı mantıkla çalışmaz.

Local bir dizi tanımlamak da mümkün ama burada sizin sorunuz net değil.

Sıralma algoritmanız lokal bir dizi yerine ilk dizi üzerinde işlem yapıyor. Kodunuzu fonksiyon içine ikincil bir dizi tanımlayıp bu diziye iik dizidekiv verinizi kopyalabilirsiniz.

Bu durumda yazdırmanız gereken dizi kinci dizi olur ve local tanımladığınız diziyi fonksiyonu sonlandırırken serbest bırakacağınız için ikinci diziniz de yok olur.

Bir dizinin bir yerlerde oluşturulması gerkir değil mi? Sonuçta ilk veri dizinize dokunmayacak ama sıralanmanız gereken ikinci bir listenizin bir yerlerde oluşturulması gerekir. Ve buna main içinde erişmeniz gerekir ki yazdırabilirsiniz.

Sırf can sıkıntısında chatgpt ile biraz sohbet ettim.

Dönüş parametresi olarak bir dizi referansı verelim. Onu yazdırsın fantazi olur dedim.

Sohbetin kodu:

#include <stdio.h>
#include <stdlib.h>

// Bubble sort algoritması ve sıralanmış diziyi döndüren fonksiyon
int* bubbleSort(int* dizi, int len) {
    // Dinamik bellek tahsisi yaparak yeni bir dizi oluştur
    int* sortedDizi = (int*)malloc(len * sizeof(int));
    if (sortedDizi == NULL) {
        printf("Memory allocation failed!\n");
        return NULL;
    }

    // Orijinal diziyi kopyala
    for (int i = 0; i < len; i++) {
        sortedDizi[i] = dizi[i];
    }

    int temp;
    for (int i = 0; i < len; i++) {
        for (int j = 0; j < len - i - 1; j++) {
            if (sortedDizi[j] > sortedDizi[j + 1]) {
                // Değerleri yer değiştir
                temp = sortedDizi[j];
                sortedDizi[j] = sortedDizi[j + 1];
                sortedDizi[j + 1] = temp;
            }
        }
    }

    return sortedDizi; // Sıralanmış dizinin başlangıç adresini döndür
}

int main() {
    int dizi1[5] = {4, 5, 2, 7, 2};
    int size = 5;

    // Bubble sort fonksiyonunu çağır ve sıralanmış diziyi al
    int* sortedDizi = bubbleSort(dizi1, size);
    if (sortedDizi == NULL) {
        return 1; // Bellek tahsisi başarısız olduysa programı sonlandır
    }

    // Sıralanmış diziyi yazdır
    printf("Sorted Array: ");
    for (int i = 0; i < size; i++) {
        printf("%d, ", sortedDizi[i]);
    }
    printf("\n");

    // Dinamik olarak ayrılan belleği serbest bırak
    free(sortedDizi);

    return 0;
}

Kodu çalıştırmadım. Ama yazırmak için sıralanmış bir dizi gerekiyorsa bir bakmakta fayda var.

Kodu derlemedim. Ama denemeye değer.