Tam Sürümünü Görmek İçin : Dennis Ritchie demiş ki:
http://www.linuxweb.com/lw_quotes.html
adresinde yazanları okurken, Ritchie amcamızın söylediği bir söz gözüme takıldı.
while (*p++ = *q++) ; (Dennis M. Ritchie)
ne demek istemiş? neden demiş? ne işe yarar? :garip:
En basit anlamda strcpy();
ergoktas
09/06/2006, 11:54
while(*q)
{
*p++ = *q++;
}gibi bişey, yani strcpy(p,q); ile aynı ...
tabi sonunda p yi nullamak lazım , *p = '\0'; ;)
myavuzselim
09/06/2006, 13:08
Sondaki noktali virgul bos bir blok yerine geciyor, yani {} yerine. Once *p=*q calistiriliyor, sonra p ve q bir arttiriliyor (**), sonra da while, *p'nin degerini test ediyor. Eger sonuc olumluysa dongu bir daha calisiyor.
Yani bence daha cok suna benziyor:
do {
*p = *q;
p++;
q++;
} while (*p);
(**) Aslinda sanirim soyle: *q'nun degerini al, q'yu artir, *p'nin degerini demin aldigin *q'nun degeri yap, p'yi artir. Ama sonucta pek birsey degismiyor.
peki nedir bu sözü meşhur kılan? neden o listede yer almış ?
kod aslında p ve q nun veri türüne göre değişir. ama döngünün son bulması için p ve q nun char türünden olması gerekir ki char türünden dizilerin donunda null karakteri var bu da döngünün son bulmasına yardımcı olur. aslında diğer veri türünden olan dizileri de birbirine kopyalar ama ilk 0 değerli eleman görülünce döngüden çıkar. kısaca stringlerde strcpy() işini dizilerde ise q nun ilk 0 değerli elemanına kadar ki kısmını p ye kopyalar.
bence bu sözle şunu demek istemiştir. c yi ne kadar geliştirirseniz geliştirin yine de öğreneceğiniz bişeyler mutlaka vardır.
iyi çalışmalar
do {
*p = *q;
p++;
q++;
} while (*p);
bu değil de bence daha cok suna benziyor:
Bence artırım işlemi daha önce gerçekleşir. Yani
do {
p++;
q++;
*p = *q;
} while (*p);
Neden ünlüdür ?
Benim öncelikle hoşuma gitti :) Yani benim için ünlü olması için yeterli sebep. Tarayıcım bahsi geçen sayfayı ne saçma bir nedenden açtırmıyor bilmiyorum o yüzden orada ne tür bir şey olarak yayınlanmıştır bilemeyeceğim ama;
"Al, geliştir ve kullan"'ı ifade ediyor olabilir.
p yi al, onu geliştir(++ operatörü ile) ve kullan(= operatörü ile)
Bu naçizane yorumumdur, çok mantıklı olmadı ama bu da bir önermedir diyelim :)
latroman
12/06/2006, 18:59
Bu kodu meşhur kılan simetrik olması.
üç beş harf rakam bişi karalamış Dennis Ritcihe.Ve burda böyle tartısılıyor.Kim bilir nerelerde ne kadar bahsedildi.Çok büyük saygı duydum.
wooodini
12/06/2006, 22:31
while (*p++ = *q++) ; (Dennis M. Ritchie)
ilk p=q şartına göre while döngüsü çalştırılıyor. sonra çalşmaya başlamadan önce
p++
ve
q++
işlemleri yapılır...
sonra p=q ile p nin yani (p++) nin değerine q yani(q++ daki) değer atanır.
yani şu demek
while (p!=q)
{
p++;
q++;
*p=*q;
}
adam 5 - 6 satırlık kodu bi satırda yazmış helal olsn falla:super:
wooodini
12/06/2006, 22:37
yalnız bu koşul sonlanmaz o da bi sorun... yani ram deki adreslerin sonuna gelinene kadar devam eder. bu da bi nevi komple bi kısım bilgiyi uçurmaktr
myavuzselim
13/06/2006, 00:26
Yani bence daha cok suna benziyor:
do {
*p = *q;
p++;
q++;
} while (*p);
Pardon, burada bir hata var.
acehreli
13/06/2006, 01:20
myavuzselim, son yazdigin kod dizgi sonlandirma karakterini kopyalamaz. Benim anladigim kadariyla, o tek satir kodun esdegeri su:
void kopyala(char * hedef, const char * kaynak)
{
char deger = '\0';
do {
deger = *kaynak;
*hedef = deger;
++hedef;
++kaynak;
}
while(deger);
}
Evet, tek satirda yazmak hos ama o zaman kod karisik oluyor. Zaten Ritchie de bugun olsa kodu daha okunur sekilde yazardi. Oyle karmasik yazmasinin nedeni, buyuk olasilikla, o zamanlar kullanilan derleyicilerin o sekilde yazildiginda daha hizli kod uretmesiydi.
Ali
Dennis M. Ritchie gercekten "while (*p++ = *q++) ;" diye bir soz soyledimi, soylemedi mi yada alintiyi yapan dogru mu yapti bilemem ama oldugu gibi soyledi ise bunu nasil yanlis program yazilir diye gostermistir eminim. Bu kodun oldugu hali ile calisacagini sanmam. Bana en yakin gelen benzetme asagidaki sekilde bir kullanim. Bence oldukca anlasilir ayni zamanda ama tercih meselesi.
void __strcpy(char *p, char *q) { while ( (*p++ = *q++) != '\0');}
acehreli
13/06/2006, 09:12
Sabahi, kod ilk goterildigi sekilde calisiyor cunku C'de
while (bir_sey != 0)
ile
while (bir_sey)
ayni anlama gelir ya... (Eger 'bir_sey' 0 degilse, boyle bir karsilastirmada kullanildiginda zaten dogruluk ifade eder.) Verilen kod o yuzden calisiyor.
Bu arada, verilen kodun Dennis Ritchie'nin "soyledigi" bir soz oldugu sanilmasin. Bu tur kodlar meshur The C Programming Language kitabinda bolca gecer. Kisaligi acisindan hos oldugu icin oradan alinmis ve onun soyledigi bir sozmus gibi sakaca sunulmus bence...
Ali
acehreli C programlarinda,
while (bir_sey != 0) veya while (bir_sey)
dendiginde eger bir_sey = negatif sayi olabiliyorsa her ikiside ayni sekilde mi calisir diyorsun?
acehreli
13/06/2006, 20:22
Evet. Dogruluk bekleyen her ifadede 0 'false' anlamina, 0'dan baska butun degerler 'true' anlamina gelir.
Ali
Bişi Anlamadım Gerizekalımıyım neyim:D
belki ASCII Kodlarındaki Benzerlikten Kaynaklanıyordur.
acehreli test condition icin soyledigin dogru fakat benim kullandigim ornekte baska bir amacla 0 karakter ile test sarti kullanmistim. Nedeni while (*p++ = *q++) olarak derledigimde derleme hatasi almadigim halde calisma aninda hataya neden oldu. Bende bazi C derleyicilerinde test condition olarak assigment statement kullanmanin hataya yol acabilecegini dusunerek test sartini explicit olarak yazdim. Ancak bir tek benim kullandigim derleyicide hataya yol aciyorsa o zaman bende hata var demektir.
Kodun çalışacağı bariz, kodu gören herkes kontrolsüz string kopyalama işlemi diyo, yani bellek bitene kadar belleği kaydıran bir program bu, bence çok hoş bir program. Yanına aynı satırda ufak bir kontrol deyimi de konulursa (mesela stringin boyutu ve o boyuttan küçük mü diye kontrol edilip arttırım yapılırsa değere) çok güzel bir string kopyalama kodu oluyor ve tek satırcık.
:ginginn:
acehreli
15/06/2006, 22:32
yeminer, bellek bitene kadar degil, dizgi (string) bitene kadar kopyaliyor zaten. Ayrica denetime gerek yok...
*p++ = *q++
atama isleminin "degeri", atanan degerdir. O satir dizginin sonundaki '\0' karakterini atadiktan sonra, while'a '\0' degeri verilmis oluyor. O da denetimin sonlanmasini sagliyor. (0 degeri boyle kosullarda 'false' anlamina geliyor ya...)
Ali
Buradaki puf nokta '\0' işaretinin sayı degeri olarak 0 (sifira) olmasıdır.
yani
char ch='\0';
ile
char ch=0;
aynı işi yapıyor..
aynı şeyi yapıyor ancak.
Aradaki farka dikkat biri karater diğeri değişmez değeridir.
Biribirine denkte olsa aradaki fark önemlidir.
Evet bunu fark etmemişim. Ben direk bir link olarak düşünmüştüm, ama ikinci kez düşününce herşey anlaşılıyo.
acehreli
18/06/2006, 21:43
shurzan; iki konuda ayni fikirdeyiz:
1) evet, arada fark var
2) evet, Revne'nin yazdigi iki kullanimda bu farkin onemi yok
Ama birisini "karakter" diye, otekini "degismez" diye adlandirmak dogru degil. Cunku hem '\0' hem de 0 degismez degerleridir. Biri char turundedir, digeri int turundedir.
Ali
Doğru hocam her ikiside değişmezdir.
Düzelttiğiniz için teşekkürler.
Forum Yazılımı : vBulletin v3.6.8, Copyright ©2000-2008, Jelsoft Enterprises Ltd.