Fonksiyona 2 boyutlu dizi aktarmak

Başlatan XX_CİHAN_XX, 25 Haziran 2010, 21:39:33

XX_CİHAN_XX

Arkadaşlar (standart)C de bir fonksiyona 2 boyutlu dizi aktarıp daha sonra bunu fonksiyon içersinde kullanmaya yönelik örnek koda ihtiyacım var.
Yirmi yaşındaki bir insan, dünyayı değiştirmek ister . Yetmiş yaşına gelince , yine dünyayı değiştirmek ister, ama yapamayacağını bilir.

XX_CİHAN_XX

Aradığım örneği buldum...
#include <stdio.h>

#define NUM_STUDENTS 25
#define NUM_TESTS 10

int get_highest(int a[][NUM_TESTS], int row, int col);

int main()
{
   int grades[NUM_STUDENTS][NUM_TESTS] = { {55, 60, 65},
                                           {85, 90, 95} };
   int num_students = 2;
   int num_tests = 3;
   int high_test;
   
   high_test = get_highest( grades, num_students, num_tests);

   printf("The highest score is %d.\n", high_test);
   return 0;
}

int get_highest(int a[][NUM_TESTS], int row, int col)
/* Assumes that there is at least one element */
{
   int i, j;
   int highest = a[0][0];

   for( i = 0; i < row; i++)
      for( j = 0; j < col; j++)
         if ( a[i][j] > highest)
            highest = a[i][j];
   return highest;
}
Yirmi yaşındaki bir insan, dünyayı değiştirmek ister . Yetmiş yaşına gelince , yine dünyayı değiştirmek ister, ama yapamayacağını bilir.

fatihinanc

Hocam GCC derleyicisinde şu kodu derleyebilirsiniz.

Fonksiyon parametresi olarak tanımladığımız
gelen isimli diziye satır değerini verip vermemekte serbestiz.
yani gelen isimli diziyi char gelen[][2] diye de tanımlayabiliyoruz

Kod :
#include <stdlib.h>

void ikiboyut(char gelen[2][2])
{
char i, j;
	for( i = 0; i <2; i++ ) 
	{
    for( j = 0; j < 2; j++ )
    printf( "%d ", gelen[ i ][ j ] );
    printf( "\n" );
	}

}

int main()
{
    char dizi[2][2]={{0,1},
                     {2,3}};
    printf("Hello world!\n");
    ikiboyut(dizi);
    return 0;
}
Kainat dediğimiz kitap, yazıldığı dil ve harfler öğrenilmedikçe anlaşılamaz.  (Galileo Galilei)

XX_CİHAN_XX

Teşekkürler @fatihinanc,
Aynen o şekilde denedim.
Başarılı bir şekilde derledi.
Yirmi yaşındaki bir insan, dünyayı değiştirmek ister . Yetmiş yaşına gelince , yine dünyayı değiştirmek ister, ama yapamayacağını bilir.

fatihinanc

Rica ederim hocam.
Bu sene C# dersinin finalinde sorulan sorunun ufak bir parçasıydı
oradan aklımda kalmış.

Burada sormam doğru mu bilmiyorum ama
Forumda okuduğum kadarıyla galiba daha önce asm kullanıyormuşsunuz hocam.
Şimdi C ile nasıl gidiyor?
asm yi aratıyor mu yoksa ona göre daha mı rahat?
Kainat dediğimiz kitap, yazıldığı dil ve harfler öğrenilmedikçe anlaşılamaz.  (Galileo Galilei)

XX_CİHAN_XX

C nin konforu tartışılmaz bile.
Tabii ki uzunca bir süre asm kullanmanın faydası da öyle...
Bir süredir Atmel - AVR  serileri üzerinde kod geliştiriyorum.
C kullanmanın bir faydasınıda daha önce PIC te yazdığım C kodlarını ufak değişikliklerle AVR lere taşıdığımda farkettim. Hani şu  meşhur taşınabilirlik özelliği :)
Ama bazı durumlar oluyor ki asm yi arıyorum. Tabiiki genel olarak baktığımda C kullanmayı ve gerektiği yerde asm ye geçmeyi tercih ediyorum.
Hele ki biraz daha yüksek performanslı serilere geçtiğimde C nin nerdeyse zorunluluğu birkez daha karşıma çıkıyor...
Sonuç olarak asm bilmenin çok büyük faydasını, C kullanmanında rahatlığını yaşıyorum diyebilirim :)
Yirmi yaşındaki bir insan, dünyayı değiştirmek ister . Yetmiş yaşına gelince , yine dünyayı değiştirmek ister, ama yapamayacağını bilir.

fatihinanc

Evet ben de öyle düşünüyorum asm yi iyi bilmek
çipin içinde olup bitenleri de çok iyi bilmek anlamına geliyor.
Hem C yi iyi kullanıp hem de asm yi çok iyi bilmek dediniz
gibi büyük bir avantaj ki C, asm ye göre kullanımı çok rahat bir dil.

Evet bir de meşhur taşınabilirlik özelliği var.
Ben de geçenlerde EEPROM a bilgi yazdırmak isterken
dizinin uzunluğunu da göreyim dedim.
Bununla ilgili string.h kütüphanesini var derslerde çok
kullanıyorduk.bunda da var mı acaba dedim. Varmış.
Baktım, denedim çatır çatır çalışıyor kodlar.Vay be Cdedim.
Sonra kütüphaneleri inceledim hemen hemen bütün kütüphaneler var.

Aynı şekilde yukarıda yazdığımız kodu da biz x86 da çalıştırdık.
AVR veya PIC e taşımak çok zor olmasa gerek.
printf ler yerine lcd ye göndeririz olur biter.
Kainat dediğimiz kitap, yazıldığı dil ve harfler öğrenilmedikçe anlaşılamaz.  (Galileo Galilei)

XX_CİHAN_XX

Evet taşınabilirlik ve standart C ye tam uyumluluk (gerek kütüphane gerekse yazım kuralları olarak) çok önemli.
Bu nedenle asm den sonra C yi benimsedim.
Ve gerektiği yerde her ikisini de kullanıyorum...
Yirmi yaşındaki bir insan, dünyayı değiştirmek ister . Yetmiş yaşına gelince , yine dünyayı değiştirmek ister, ama yapamayacağını bilir.

fatihinanc

Tabi sizin dediğiniz gibi C de de asm kullanmak zorunda kalınabiliyor biraz.
Bazıları ben asm yi sadece NOP için kullanırım diyor ama.
Başka durumlarda asm kullanmak gerekebiliyor bazen.
Kainat dediğimiz kitap, yazıldığı dil ve harfler öğrenilmedikçe anlaşılamaz.  (Galileo Galilei)

XX_CİHAN_XX

Evet misal,
C de << yada >> operatörlerini kullanarak kaydırdığımda
önce Carry biti temizleniyor sonra kaydırma işlemi yapılıyor.
Bu çoğu zaman istediğimiz bir durum olsa da bazen ben Carry bitinin temizlenmeden kaydırılmasını isteyebiliyorum. Bu gibi durumlarda bu kodun en verimli çalışan şeklini elde etmek için asm ye geçip yazmak gerekiyor. Ha tabi bu iş geçmeden de yapılabilir ama kulağı biraz daha tersten tutarak...
Bunun dışında  da hassas zamanlama gereken bir kod bloğunda da asm hayat kurtarabiliyor...
Daha başka kullanım yerleride var elbette...
Asm olayı C içersinde sade NOP tan ibaret olmamakla birlikte,
ASM yi bilen ve uzun süre kullanan bir kişinin programlama, kaliteli ve verimli kod yazma becerileride gelişiyor.
Bunada basit bir örnek vermek gerekirse aritmetiksel işlemler bilindiği gibi asm de C deki kadar kolay değil.
Bu durumda asm kullanıcısı bu işlemleri yapabilmek için birçok kestirme yöntemler bulabiliyor
örneğin sayıyı 3 defa sağa kaydırarak 8 e bölebiliyor :)
2 defa sola kaydırarak 4 ile çarpabiliyor. İlk üç biti maskeleyip alarak mod8 değerini elde edebiliyor.
Bu şekilde onlarca örnek verilebilir :)
Yirmi yaşındaki bir insan, dünyayı değiştirmek ister . Yetmiş yaşına gelince , yine dünyayı değiştirmek ister, ama yapamayacağını bilir.

fatihinanc

Evet carry biti ile ilgili yazınızı hatırlıyorum.
C de oluyordu fakat dediğiniz gibi
asm de iki satırlık kod
C de biraz daha uğraştırıcı oluyordu galiba.

Evet asm bilinince daha kısa nasıl kod yazarım
veya
yazdığım kodlar nasıl daha az yer tutar
gibi meseleleri halletmek daha kolay oluyor.

Ne olursa olsun bence Mikrodenetleyici programlaya
başlayacak bir kimse o denetleyicinin asm sini
mutlaka öğrenmeli.biraz zaman alıyor fakat programlama
mantığını oturtma konusunda çok faydalı olabiliyor.
Sonrası hangi dili iyi kullanıyorsa artık...
Kainat dediğimiz kitap, yazıldığı dil ve harfler öğrenilmedikçe anlaşılamaz.  (Galileo Galilei)

XX_CİHAN_XX

Merhabalar,

Birkaç kurcalamadan sonra farkettim ki bu şekilde dizi aktarımı yapıldığında dizi elemanı kadar değişken sarfiyatı oluyor. Oysa benim taşımak istediğim dizi const char tipinde. Dolayısıyla bu işi bu şekilde taşımak bir sürü gereksiz değişkeni kullanmak anlamına geliyor.
Yani bunu pointerlarla adres göstererek yapmak gerekiyor.
Ben birkaç deneme ve araştırma yapmama rağmen

incompatible pointer type

Hatasını aldım...
Yirmi yaşındaki bir insan, dünyayı değiştirmek ister . Yetmiş yaşına gelince , yine dünyayı değiştirmek ister, ama yapamayacağını bilir.

XX_CİHAN_XX

/*
 Method #2 (pointer to array, second dimension is explicitly specified)
 ======================================================================
 */

int func2(short (*mat)[3])
        {
        register short i, j;

        printf(" Declare as pointer to column, explicitly specify 2nd dim: ");
        for(i = 0 ; i < 3 ; i++)
                {
                printf("\n");
                for(j = 0 ; j < 3 ; j++)
                {
	                printf("%5.2d", mat[i][j]);
                }
        }
        printf("\n");

        return;
}

 /*

Bu metod işimi gördü...
Yirmi yaşındaki bir insan, dünyayı değiştirmek ister . Yetmiş yaşına gelince , yine dünyayı değiştirmek ister, ama yapamayacağını bilir.

fatihinanc

Hocam tamam da func2 adlı fonksiyonun başında yine bir dizi değişken tanımlanıyor...
Kainat dediğimiz kitap, yazıldığı dil ve harfler öğrenilmedikçe anlaşılamaz.  (Galileo Galilei)

XX_CİHAN_XX

func(dizi1);
func(dizi2);
func(dizi3);
Şeklinde 3 kere bu fonksiyonu çağıralım. Her çağırmada fonksiyona const char tipinde bir dizi gönderelim.

Eğer func fonksiyonunu ilk konuştuğumuz gibi yaparsam her bir çağırma için ayrı bir dizi değişkeni kullanıyor program. Bunu derleme sonucu gösterilen ram tüketiminden görebiliyorum.

Ama son gösterdiğim pointer metodu ile func fonksiyonunu yeniden düzenlediğimde bu fonksiyonu yukarıdaki gibi 3 kere yada n kere çağırsamda ram tüketimi hep sabit kalıyor.

Bu da pointer kullanmanın bir avantajı olsa gerek...
Yirmi yaşındaki bir insan, dünyayı değiştirmek ister . Yetmiş yaşına gelince , yine dünyayı değiştirmek ister, ama yapamayacağını bilir.