+ Cevap Yaz
Toplam 3 sayfadan 2. sayfa
İlkİlk 1 2 3 En SonEn Son
27 sonuçtan 11 ile 20 arası gösteriliyor

Konu: Dizi yazdırma sorunları

  1. #11
    Üye
    Üyelik Tarihi
    01/2010
    Mesaj
    48

    Yaşar hocam int *a deyip de a = dizi diyebiliyoruz o zaman bu sadece pointerlar için geçerli demekki.
    Yani kelime,harf veya sayı doğrudan diziye atanamıyor ancak onun indisi ile atanabiliyor.
    scanf("%d,&sayi")
    dizi[]=sayi // atanamıyor
    dizi[10]=sayi//11. elamınına atanıyor,yani indis vasıtasıyla
    Ancak sanırım şöyle oluyor:
    char dizi[5]={ 's', 'a', 'y', 'i', '\0' };
    char dizi[2] ---> y olmuş oluyor
    Yani özetle diziye indissiz atama yapılamıyor,ekleme-çıkarma yapılamıyor anladığım kadarıyla.Mutlaka indisinin belirtilmesi gerekiyor.
    int dizi[2]=2 / /3.elemanına 2 yi atadık
    int dizi[3] // [0][1][2] // yani int [0] int [1] int [2]

    2 sorum daha olacak:

    int dizi[10] --- bu ifadeyi for ile kullanmak istediğimiz zaman i<10 değil i<9 olarak yazdıracağız yani indis sayısının 1 eksiği doğru anlamış mıyım?

    (sizeof(dizi) / sizeof(dizi[0]) - 1)
    Ben bu kodu ilk defa sizden görüyorum,bu kod kullanıcı ile etkileşimli programlar için sanırım.(scanf,gets)Çok işe yarar gibi.

  2. #12
    Ali Çehreli
    Üyelik Tarihi
    10/2002
    Mesaj
    2,892

    Alıntı shurzan, mesajından alıntı: Mesajı Gör
    int dizi[10]; olarak tanımladığında,
    bellekte, 10 adet ardışık duran int değişken tanımlıyorsun.
    Şekillendirmek gerekirse

    [0][1][2][3][4][5][6][7][8][9]

    Bu hücrelerin her biri birer integer değişkenlerdir her biri bellekte Windows işletim sisteminde 4 bayt yer kaplar.

    ve bu dizinin bellekte bulunduğu konum (adres) bir göstericiye atanımıştır.
    Burada bir düzeltme yapmak gerek. Ben bunu çok sayıda kişiden duyuyorum.

    Biz programcılar dizinin ismini ayrı bir gösterici gibi düşünürüz ve çoğu işlem sanki öyleymiş gibi çalışır ama dizi tanımlandığında ayrıca bir de gösterici tanımlanmaz.

    int dizi[10]; yazıldığında yalnızca ve yalnızca 10 adet int tanımlanmış olur. Ayrıca bir şey tanımlanmaz.

    Bu konudaki karışıklığın nedeni, C'nin artık yarardan çok zarar getirdiğine inandığım son derece gereksiz bir kuralıdır:

    C (ve C++ kuralı): Dizinin ismi, ilk elemanının adresi yerine kullanılabilir.

    Eğer ayrıca bir gösterici olsa, onun kendi adresi olur ve sizeof(dizi) diye baktığımızda, değer olarak gösterici büyüklüğü görmeyi bekleriz. Ama öyle değildir:

    Özet:

    - int d[10]; on adet int tanımlar
    - d, bunların hepsini birden temsil eder
    - diziler, diğer bütün türlerin tersine, işlevlere kopyalanmadan gönderilirler
    - dizilerin ismi, ilk elemanının adresi yerine geçer

    C de dizinin adı bu elemanların bellekteki konumunun başladığı adrese sahip bir göstericidir yani dizi[0].
    Dizinin adı, ilk elemanının gösteren gösterici yerine geçer. Ayrı bir gösterici yoktur.

    dizinin bu göstericisi consttır yani sabittir her zaman bu hücrelerin olduğu yeri gösterir ve bu gösterici başka bir yeri gösterecek şekilde değiştirilemez.
    O kurallar hep 'dizi' bütün elemanları gösterdiği için öyledir.
    dizi = sayi; sayi değişkeninde olan değeri bir adres bilgisi gibi ismi dizi olan göstericiye atanmaya çalışıyorsun.
    O işlem, bir diziye bir tamsayı atamaya çalışır. C'de böyle bir işlem tanımlı olmadığı için hatalı oluyor. Derleyici zaten on elemandan hangisin(lerini) değiştireceğine karar vermez.

    dizinin adı diziyi gösteren göstericidir.
    Dizinin adı, bütün elemanların hepsini birden temsil eder.

    dizi = 1; atama yapılamaz!
    Çünkü bütün diziye bir elemanını atama işlemi C dilinde tanımlanmamıştır.

    Ali

  3. #13
    Üye
    Üyelik Tarihi
    01/2010
    Mesaj
    48

    http://forum.ceviz.net/c-c/88741-diz...tml#post545438 (Dizi yazdırma sorunları)
    acehreli burada yazdıklarımda bir yanlışlık var mı acaba?

    Bir de

    Kod:
    #include<stdio.h>
    int main()
    {
        int i;
        int dizi[];
        for(i=0;i<(sizeof(dizi) / sizeof(dizi[0]) - 1);i++){
        /*int dizi[4];
        for(i=0;i<4;i++)  yapınca derliyor ama bu seferde printf(" dizi[1]dizi[2]dizi[3] "); bu satır gözükmüyor*/
        printf("sayi gir");
        scanf("%d", &dizi[i]);
        }
        printf(" dizi[1]dizi[2]dizi[3] ");
        
        getchar();    
    return 0;
    }
    

  4. #14
    Ali Çehreli
    Üyelik Tarihi
    10/2002
    Mesaj
    2,892

    Alıntı openrlerv, mesajından alıntı: Mesajı Gör
    int *a deyip de a = dizi diyebiliyoruz
    "Dizini adı ilk elemanının adresine dönüşebilir" kuralı gereği, evet, 'a' dizinin ilk elemanını göstermeye başlıyor. Yukarıdaki satır şunun aynısıdır:

    [code]int *a = &dizi[0];[/code

    Eşdeğeri bile değildir; *aynısıdır*.

    Bir kere dizinin ilk elemanının adresini eline geçirince, oradan ilerleyerek diğer elemanlara en yapılacağı programcıya kalmıştır.

    o zaman bu sadece pointerlar için geçerli demekki.
    O garip kural "gerektiğinde ilk elemanının adresine dönüşebilir" olduğu için, evet, diziyi ilk elemanını gösteren gösterici yerine kullanırken geçerli...

    Yani kelime,harf veya sayı doğrudan diziye atanamıyor ancak onun indisi ile atanabiliyor.
    Doğru, çünkü C böyle bir işlem tanımlamamıştır. Örneğin şöyle diyebilirmiş: "tek bir eleman atandığında dizinin bütün elemanlarını ona eşitle". Ama böyle bir işlem yok.

    scanf("%d,&sayi")
    dizi[]=sayi // atanamıyor
    dizi[10]=sayi//11. elamınına atanıyor,yani indis vasıtasıyla
    Ancak sanırım şöyle oluyor:
    char dizi[5]={ 's', 'a', 'y', 'i', '\0' };
    char dizi[2] ---> y olmuş oluyor
    Yani özetle diziye indissiz atama yapılamıyor,ekleme-çıkarma yapılamıyor anladığım kadarıyla.Mutlaka indisinin belirtilmesi gerekiyor.
    int dizi[2]=2 / /3.elemanına 2 yi atadık
    int dizi[3] // [0][1][2] // yani int [0] int [1] int [2]
    Hepsi doğru.

    2 sorum daha olacak:

    int dizi[10] --- bu ifadeyi for ile kullanmak istediğimiz zaman i<10 değil i<9 olarak yazdıracağız yani indis sayısının 1 eksiği doğru anlamış mıyım?
    Geçerli indisler 0'dan 9'a kadardır. i<9 olmaz herhalde değil mi? O zaman [0,8] aralığını kullanmış olursun.

    Şunların hepsi olur:

    i < 10
    i <= 9
    i != 10

    (sizeof(dizi) / sizeof(dizi[0]) - 1)
    Hangi bağlamda geçtiğini hatırlamadığım için nedenini anlamıyorum, ama eğer dizideki eleman sayısını hesaplamak istiyorsak sonundaki -1 yanlış olur.

    sizeof(dizi), bütün dizinin büyüklüğüdür (örneğin 10 int için 40 bayti). sizeof(dizi[0]) tek elemanının büyüklüğüdür (örneğin int için 4).

    40/4 zaten 10 olduğu için, eleman sayısını hesaplarken ayrıca -1 kullanılmaz.

    Hatta kullanılırsa, elemanlarının boyu 1 olan türlerde sıfıra bölme hatasına neden olur.

    Ben bu kodu ilk defa sizden görüyorum,bu kod kullanıcı ile etkileşimli programlar için sanırım.(scanf,gets)Çok işe yarar gibi.
    Yalnızca kullanıcı etkileşimi için değildir. Eleman sayısını otomatik olarak ve derleme zamanında hesaplamak için kullanılır. Örneğin 10 olduğunu bilsek bile sabit olarak 10 yazmayız, her zaman için o hesabı kullanırız. Yoksa dizinin boyu değişince her yerdeki 10'u değiştirmek hem külfet olur, hem de unutulursa hata...

    Bu arada, gets kullanılamayacak kadar güvensiz bir işlevdir. Onun yerine fgets'i kullan.

    Ali

  5. #15
    Ali Çehreli
    Üyelik Tarihi
    10/2002
    Mesaj
    2,892

    Alıntı openrlerv, mesajından alıntı: Mesajı Gör
    http://forum.ceviz.net/c-c/88741-diz...tml#post545438 (Dizi yazdırma sorunları)
    acehreli burada yazdıklarımda bir yanlışlık var mı acaba?
    Bütün yazılanları hepimiz okuyoruz. Tekrar sormaya gerek olmamalı herhalde.

    Kod:
    #include<stdio.h>
    int main()
    {
        int i;
        int dizi[];
    
    Derleyici o satır için uyarı vermiyor mu? Uzunluğu belirtilmeyen dizi tanımlayabiliyor musun? Öğrenmekte olan birisi olarak *hiçbir* derleyici uyarısını gözardı etmemeni öneririm. Derlediğin programlar kesinlikle sıfır uyarı ile derlenmeli.

    Eğer elemanı olmayan bir dizi ile çalışıyorsan, belki de programın geri kalanındaki hatalar o yüzdendir.

    Kod:
        for(i=0;i<(sizeof(dizi) / sizeof(dizi[0]) - 1);i++){
    
    Oradaki -1 gereksiz ve bazı durumlarda yanlış.

    Kod:
        /*int dizi[4];
        for(i=0;i<4;i++)  yapınca derliyor ama bu seferde printf(" dizi[1]dizi[2]dizi[3] "); bu satır gözükmüyor*/
    
    İç içe döngü kullanılınca içerdeki döngü değişkenine normalde farklı bir isim verilir: i yerine j gibi... Belki ondandır.

    Bu arada, eğer tarih öncesi bir derleyici kullanmıyorsan, ve mecbur değilsen döngü değişkenlerini döngü içinde tanımlamanı öneririm:

    Kod:
    for(int i = 0;
    
    Yani 'int i'yi döngü içinde...

    Ali

  6. #16
    Üye
    Üyelik Tarihi
    01/2010
    Mesaj
    48

    Derleyici o satır için uyarı vermiyor mu?
    Valla uyarıları pek anlamadığım için anlayamıyorum,o yüzden size sordum,doğrusunu anlamak için.Ama dizi prototipi ile karıştırmışım demekki.

    Bu arada, eğer tarih öncesi bir derleyici kullanmıyorsan, ve mecbur değilsen döngü değişkenlerini döngü içinde tanımlamanı öneririm:
    Bir ara öyle tanımlamıştım ama derleyici hata verince böyle yazmaya başladım.Verdiğiniz bilgiler çok faydalı oldu,kafamda baya bir şeyler şekillenmeye başladı.Ben tek boyutlu dizileri bildiğimi sanıyordum ancak çok eksiğim varmış.Umarım aynı konuları tekrar sormaya gerek kalmaz.

  7. #17
    Üye
    Üyelik Tarihi
    10/2009
    Mesaj
    43

    Dizileri kullanırken boyutlarının sonradan değiştirilememesi ve boyutunu verirken eğer boyutunu bir değişkenden vereceksek bu değişkenin const olma zorunluluğu yüzünden artık dizi yerine vector kullanıyorum.hem diziler kadar zorunluluğu yok ve çok yararlı fonksiyonları var.

  8. #18
    Ali Çehreli
    Üyelik Tarihi
    10/2002
    Mesaj
    2,892

    Evet, C++'da kesinlikle std::vector.

    Ama openrlerv C öğreniyor ve zaten C'de dizi boyutu değişken olabilir.

    Ali

  9. #19
    Üye
    Üyelik Tarihi
    01/2010
    Mesaj
    48

    Alıntı acehreli, mesajından alıntı: Mesajı Gör
    Bu arada, gets kullanılamayacak kadar güvensiz bir işlevdir. Onun yerine fgets'i kullan.

    Ali
    gets veriyi klavyeden,fgets ise dosyadan almıyor mu? O zaman scanf kullanalım sadece.Bir de, gets hakkında söylediklerin belli bir karaktere kadar okuma kabiliyeti ile mi alakalı?

  10. #20
    Ziraat Mühendisi _Onk@_ Adlı Üyenin Profil Grafiği
    Üyelik Tarihi
    09/2008
    Yer
    Ankara
    Mesaj
    696

    Alıntı openrlerv, mesajından alıntı: Mesajı Gör
    gets veriyi klavyeden,fgets ise dosyadan almıyor mu? O zaman scanf kullanalım sadece.Bir de, gets hakkında söylediklerin belli bir karaktere kadar okuma kabiliyeti ile mi alakalı?
    Not: Standart C kütüphanesi gerçekten titiz çalışmalar sonucunda oluşturulmuştur. scanf'nin yanında (eşdeğer değiller dikkat ediniz) gets'in de sunulmasının mantıklı bir sebebi olduğu açıktır.

    Scanf boşluk karakterinden sonraki karakterleri de alıyor mu? Önce bunun cevabını vermek gerekli.

    [kod=c]
    #include <stdio.h>
    #include <stdlib.h>


    int main()
    {
    char str1[100];
    char str2[100];

    printf("scanf islevi ile okuma:\nlutfen bosluk karakteri iceren bir seyler yaziniz:");
    scanf("%s",str1);
    printf("scanf ile okudugum metin: %s\n\n",str1);
    printf("--------------------------------------\n\n");

    fflush(stdin);//Ali Hocam kızacak ama Düzgün çözüm yolunu unuttum, önerilmeyen çözüm.

    printf("fgets islevi ile okuma:\nlutfen bosluk karakteri iceren bir seyler yaziniz:");
    fgets(str2,100,stdin);

    printf("fgets ile okudugum metin: %s\n\n",str2);

    return 0;
    }
    [/kod]

    Çıktı:
    Kod:
    C:\projeler\getsvsscanf>gcc main.c
    
    C:\projeler\getsvsscanf>a
    scanf islevi ile okuma:
    lutfen bosluk karakteri iceren bir seyler yaziniz:deneme bir iki üç
    scanf ile okudugum metin: deneme
    
    --------------------------------------
    
    fgets islevi ile okuma:
    lutfen bosluk karakteri iceren bir seyler yaziniz:deneme bir iki üç
    fgets ile okudugum metin: deneme bir iki üç
    
    Ekleme: Görüldüğü gibi stdin fopen ile sabit diskinizden açabileceğiniz bir dosya gibi aynen. Sonuçta hepsi akış. Fark önemli değil, farkın belirlenebilmesi de önemli değil. stdin tuştakımından başka bir şeye de yönlenmiş olabilir (eski bilgisayarlarda delikli kart okuyucu gibi örneğin).
    Günümüzde genelde:
    stdin=tuş takımı;
    stdout=ekran, daha açık bir ifadeyle konsol ekranı;
    stderr=hataların yakalandığı akış diyebiliriz.

+ Cevap Yaz

Thread Information

Users Browsing this Thread

There are currently 1 users browsing this thread. (0 members and 1 guests)

     

Bookmarks

Mesaj Yazma Hakları

  • Yeni mesajgöndermezsiniz
  • Cevap yazamazsınız
  • Dosya ekleyemezsiniz
  • Mesajınızı düzenleyemezsiniz