Şimdi Ara

Dizide arttırma operatörünü kullanınca niye doğru sonuç vermiyor?

Daha Fazla
Bu Konudaki Kullanıcılar: Daha Az
2 Misafir - 2 Masaüstü
5 sn
6
Cevap
0
Favori
141
Tıklama
Daha Fazla
İstatistik
  • Konu İstatistikleri Yükleniyor
0 oy
Öne Çıkar
Sayfa: 1
Giriş
Mesaj
  • Kodum bu:
    #include <stdio.h>
    int main(){
    int a[] = {10};
    printf("%d,%d,",++a[0],a[0]);
    printf("%d",a[0]);
    return 0;}

    Çıktı : 11,10,11

    a[0]'ı ikinci kere yazdırdığımda neden 11 değil 10 yazıyor?

    Sayıyı dizi elemanı değil sadece bir değişken olarak alırsam çıktı 11,11,11 oluyor.
    Yada kodumu
    #include <stdio.h>
    int main(){
    int a[] = {10};
    printf("%d,%d,",a[0],++a[0]);
    printf("%d",a[0]);
    return 0;}
    şeklinde değiştirirsem çıktı 11,11,11 oluyor.



    < Bu mesaj bu kişi tarafından değiştirildi hynx -- 17 Nisan 2017; 13:47:2 >



  • printf bir fonksiyon olarak değişken listesini en sondan işlemeye başlar yani önce a[0] işlendiği için onu 10 olarak yazıyor, sonra ++ ile a[0] yani a dizisine ayrılan hafıza bölgesinin 0. (int; 4 byte'lık) adımındaki değer 11 yapılıyor, o yüzden alt satırda yeniden printf işleme girdiğinde o değeri 11'i alıyor. alt satırda değil aynı printf içine koysaydın o yüzden sonuç 11, 10, 10 olacaktı.



    Olay genel olarak C compiler'ın değil, printf fonksiyonunun kendisindeki gariplikten kaynaklanıyor. printf'nin kaynak kodlarına bakarak bu durum daha netleştirebilirsin. Sorun fonksiyonun implementasyonunda old için aynı sorun Python, Ruby gibi diğer dillerde de olabilirdi, bence hiç ciddi bir sorun değil.

    < Bu ileti mini sürüm kullanılarak atıldı >
  • a[0] yerine bir x değişkeni koyarsam sırayla değil hepsinde değiştiriyor, ikisi arasındaki fark nedir? Bence de ciddi bir sorun değil ama kendimce cevap bulmaya çalıştım bulamayınca da aklıma takıldı.
  • x direkt değişken. a[] ise bir dizi. printf, scanf, bunlar dizi ve string gibi dolaylı değişkenlerle farklı, int gibi direkt değişkenlerle farklı çalışan fonksiyonlar, örneğin (zaten biliyorsundur) printf içinde a[0] yerine sadece a veya *a da girebilirsin, ilkinde a dizisinin RAM'deki adresi gösterilir, ikincisinde de işaretçi gösterimi dolayısıyla RAM adresindeki ilk elemanın değeri. Ancak aynı şeyleri direkt değişkenle yapamazsın. İşte o yüzden, printf dizi değişkenini en sondaki ifadeden işlemeye başlarken , direkt değişkeni en baştan işlemeye başlıyor olabilir. Bu konuda son sözü, printf kaynak kodu söyler ki o da burada:http://sourceware.org/git/?p=glibc.git;a=blob;f=stdio-common/vfprintf.c;h=fc370e8cbc4e9652a2ed377b1c6f2324f15b1bf9;hb=3321010338384ecdc6633a8b032bb0ed6aa9b19a bu kodu tamamen analiz ettiğinde neden diziyi farklı, int değişkeni farklı işlediğini bulabilirsin :

    < Bu ileti mini sürüm kullanılarak atıldı >




  • Programlama hayatımda karşılaşmadığım problemlerle bu forumda karşılaşıyorum Gerçekten çok acayip kodları merak ediyorsunuz..

    printf("%d,%d,",++a[0],a[0]); Çıktı:11, 10

    printf("%d,%d,",a[0],++a[0]); Çıktı:11, 11

    Öncelikle bu şekilde bir çağırma gerçekten problemli, yani şu an elimde c derleyici yok sizin yazdıklarınıza inanarak cevap yazacağım. Bunun çıktısını tahmin edebilen adama da helal olsun derim.

    Bence iki ihtimal olabilir, derleyici bu girdiyi çok saçma bulmuştur ve kafasına göre bir tercih yapıyor olabilir.
    Derleyici "" arasını soldan sağa, virgül sonrasını sağdan sola okuyor olabilir.(%d sırası aynı, çalışma sırası farklı)
    Buna göre ilk çıktıda 11, 10 olması beklenir, çünkü a[0] ilk okunduğundan ikinci %d için 10 yazdırılır.
    İkinci çıktıda ++a[0] ile ikinci %d için 11 yazdırılır, a artık değiştiğinden ilk %d için de 11 yazdırılır.




  • quote:

    Orijinalden alıntı: assembly_bilmeyenassembler

    Programlama hayatımda karşılaşmadığım problemlerle bu forumda karşılaşıyorum Gerçekten çok acayip kodları merak ediyorsunuz..

    printf("%d,%d,",++a[0],a[0]); Çıktı:11, 10

    printf("%d,%d,",a[0],++a[0]); Çıktı:11, 11

    Öncelikle bu şekilde bir çağırma gerçekten problemli, yani şu an elimde c derleyici yok sizin yazdıklarınıza inanarak cevap yazacağım. Bunun çıktısını tahmin edebilen adama da helal olsun derim.

    Bence iki ihtimal olabilir, derleyici bu girdiyi çok saçma bulmuştur ve kafasına göre bir tercih yapıyor olabilir.
    Derleyici "" arasını soldan sağa, virgül sonrasını sağdan sola okuyor olabilir.(%d sırası aynı, çalışma sırası farklı)
    Buna göre ilk çıktıda 11, 10 olması beklenir, çünkü a[0] ilk okunduğundan ikinci %d için 10 yazdırılır.
    İkinci çıktıda ++a[0] ile ikinci %d için 11 yazdırılır, a artık değiştiğinden ilk %d için de 11 yazdırılır.

    ben derleyici ile denedim, aynen bahsettiği gibi çıkıyor sonuç.



    Derleyici "" arasını soldan sağa, virgül sonrasını sağdan sola okuyor olabilir.(%d sırası aynı, çalışma sırası farklı)



    kısmında dediğin gibi virgül sonrasını sağdan sola okuyor; bundan başka mantıklı bir açıklaması yok. Ancak olay C Compiler 'dan cok printf implementasyonu ile ilgili. Standart printf implementasyonu ise "GNU C Library" kapsamında yani GNU'daki C programcıları tarafından yapılmış. Yani; onların kodlarını modifiye ederek printf de virgül sonrası da soldan sağa okutma sağlanabilir.



    İlgili olarak: Geçen seneye kadar Unix programlarını Windows MSYS2 ortamında kullanabilmek için standart C kütüphane kodları olmasa da, temel sayılabilecek bazı C kodlarını kendim bayağı modifiye ettim örneğin pure-ftpd, Wget ve w3m gibi Unix paketlerini Windows MSYS2 'de komut satırında çalışacak hale getirdim; bir tek pure-ftpd'de select.h ya da ona benzer Unix 'e özel bir kod çok uğraştırdığı için pes edip bıraktım, diğer ikisi çalışıyor.

    < Bu ileti mini sürüm kullanılarak atıldı >




  • 
Sayfa: 1
- x
Bildirim
mesajınız kopyalandı (ctrl+v) yapıştırmak istediğiniz yere yapıştırabilirsiniz.