Gönderen Konu: while(!feof)  (Okunma sayısı 866 defa)

0 Üye ve 1 Ziyaretçi konuyu incelemekte.

Çevrimdışı Alpyre

  • RAAT
  • Retroman
  • *
  • İleti: 51
Ynt: while(!feof)
« Yanıtla #15 : 05 Kasım 2018, 00:22:46 »
Hmm. Şimdi anladım. Ama senin kod integerchar'a döndürmüyor ki, bir pointerstring'e döndürüyor.
Çünkü fonksiyonun uchar* id alıyor. Yani bir pointer alıyor.
Neden pointer alıyor ki? Sanırım id'yi pass by reference yapmak istiyorsun...

Bence buna gerek yok. Yani fonksiyonun uchar id alabilir.

Ha ille de pass by reference olması gerekiyorsa (yani fonksiyonun uchar* id alacaksa), o halde itoa() çağırırken id'yi dereference etmelisin:
Kod: [Seç]
itoa(*id, buffer, 10);...id'nin değerinin de 9'dan büyük olmayacağı garanti edilmeli. Büyük olursa yine memory trashing olur.

Hem ayrıca buffer ve filename'i de malloc()'la tahsis etmene gerek yok. Doğrudan stack üzerinde tahsis edebilirsin:
Kod: [Seç]
uchar buffer[1];
uchar filename[8];

Çevrimdışı wizofwor

  • RAAT
  • Tedavideki Retromanik
  • *
  • İleti: 312
Ynt: while(!feof)
« Yanıtla #16 : 09 Kasım 2018, 02:45:22 »
Pointer kullanmamın sebebi pass by value / pass by reference muhabbeti değil. 8-bit mimaride çalışacak program için ezbere optimizasyon yapmaya çalışmam. Ezbere dememin sebebi şu:

6502 CPU'da fonksiyona değer göndermenin maliyeti çok yüksek. C ile kod yazarken mümkünse global değişkenler kullanın veya pointer gönderin deniyor. Ancak senin sorun üzerine düşününce benim göndermekten imtina ettiğim değişken (unsigned char) 1 byte yerine gönderdiğim pointer 2 byte.

Dereference konusuna gelince. Kodu aşağıdaki şekilde denediğimde sorunsuz şekilde derleniyordu.

Kod: [Seç]
itoa((uchar)id, buffer, 10);
Uyarın üzerine uchar'ı uchar* yaptım. Bu şekilde "Converting pointer to integer without a cast" uyarısı alıyorum. Ama çalışıyor.

Kod: [Seç]
itoa((uchar*)id, buffer, 10);
Son olarak id'nin önüne yıdız koydum. Bu şekilde uyarı vermiyor ama dosyayı da bulamıyor.

Kod: [Seç]
itoa((uchar)*id, buffer, 10);
Gosub ile gidilen yerden goto ile dönen adam

Çevrimdışı nightlord

  • RAAT
  • Tedavideki Retromanik
  • *
  • İleti: 383
    • Night Network
Ynt: while(!feof)
« Yanıtla #17 : 09 Kasım 2018, 22:34:56 »
Selam wizofwor,

Söylemekten kendimi alamadığım bir nokta olacak:

C ile ilgili çalışmalarını neden cc65 üzerinde yapıyorsun?

Her ne kadar C64'ün kalbimdeki yeri bütün platformlardan öte olsa da, C'yi öğrenmek ve kendini geliştirmek için C64'ün doğru platform olmadığını düşünüyorum. C'nin bellek, stack, değişken yönetimi zaten yeterince tuzak içeriyor. C64 gibi 8 bitlik bir mimarinin limitleri için düşünülmüş cc65 gibi bir derleyici, dil ve standart kütüphane desteği bakımından ne noktadadır ben şüpheye düşerdim. Hatta dünyadaki bütün c derleyici ve kütüphane implementasyonlarını "bütünlük ve destek" yönünden sıraya dizmeye kalksak, ve cc65 bu sıralamada sonlarda çıksa şaşırmam. İlaveten elinde bir debugger olması ve kodun içinde debugger ile satır satır ilerleyebilmek, veri yapılarını inceleyebilmek vs, öğrenmeyi hızlandırıyor bence.

Elbette bu iş zevk işi ve sen iyi vakit geçiriyorsan sorun yok. Ancak ben olsam, önce pc'de en iyi desteklenen, en iyi debugger'ı olan 2-3 aday derleyiciden biri ile önce oturur C'ye yüklenirdim. Bu hakimiyeti kazandıktan sonra cc65'in C64'e has inceliklerini vs öğrenip öyle kullanırdım.

Umarım yol tıkayıcı bir mesaj olarak algılamazsın. Sevgiler.

Çevrimdışı wizofwor

  • RAAT
  • Tedavideki Retromanik
  • *
  • İleti: 312
Ynt: while(!feof)
« Yanıtla #18 : 10 Kasım 2018, 01:34:22 »
Tavsiyen için çok teşekkür ederim. Ben programlamaya hobi olarak yaklaşıyorum ve olaya biraz daha farklı açıdan bakıyorum. C64 haricindeki işler beni heyecanlandırmıyor. 6502'nin C için ciddi handikapları olduğunun farkındayım. Bu yüzden belli limitler dahilinde kodlamaya çalışıyorum. Amacım C öğrenmekten çok C64 üzerinde bir şeyler geliştirmek.



Gosub ile gidilen yerden goto ile dönen adam

Çevrimdışı Alpyre

  • RAAT
  • Retroman
  • *
  • İleti: 51
Ynt: while(!feof)
« Yanıtla #19 : 11 Kasım 2018, 15:55:23 »
Tekrar selam wizofwor

Pass by pointer ve dereference konularında bir tekrar okuma yapman gerekiyor diye düşünüyorum. Çünkü:
Kod: [Seç]
itoa((uchar*)id, buffer, 10);
...bu yazdığın dereference değil, bir type cast.

Ha bak bu olur:
Son olarak id'nin önüne yıdız koydum. Bu şekilde uyarı vermiyor ama dosyayı da bulamıyor.
Kod: [Seç]
itoa((uchar)*id, buffer, 10);
...ama (uchar) yazmana gerek yok. Çünkü zaten bir uchar pointer'ı dereference ettiğinde uchar bir değer elde edersin. Yani yazman gereken ilk yanıtımda yazdığım gibi sadece: *id

Eğer dosyayı bulamıyorsa, pass ettiğin *id değerinde bir yanlışlık olabilir (gerçi buna neden olacak başka yanlışlar da var).

Bu arada böyle mikro optimizasyon yapacaksak, pass by value maliyetinden daha büyük itoa() maliyeti var orada.
Sana tek basamaklı bir değeri 1 ascii değerine çevirecek bir işlem lazım o kadar. Bunu id'nin değerine 48 ekleyerek halledebilirsin (C64'te string'ler ascii'dir herhalde).

Yanlış anlamadıysam sen şöyle dosya adları istiyorsun:
id = 0 ise "tdat0"
id = 1 ise "tdat1"
...
id = 9 ise "tdat9"
ve "tdat10" kesinlikle yok, 9'a kadar (1 uchar'lık buffer tahsis etmiş olmandan çıkarıyorum bunu).

Eğer bu çıkarımlarım doğruysa... sen yine id'yi pointer'ı ile pass et...
...fakat file_name'i şöyle oluştur:
Kod: [Seç]
uchar file_name[6] = "tdat0";  // 6 çünkü NULL terminator için byte daha lazım.
file_name[4] = *id + 48;       // 48 çünkü ascii 48 '0' demek.

Al sana sade çok optimize (itoa, strcpy ve strcat'den kurtuldun) hem de doğru çalışacak bir kod. ;)

Çevrimdışı wizofwor

  • RAAT
  • Tedavideki Retromanik
  • *
  • İleti: 312
Ynt: while(!feof)
« Yanıtla #20 : 12 Kasım 2018, 15:39:15 »
Program boyutunu düşürmek için kütüphaneleri kaldırmaya başladım. string.h ve stdlib.h kütüphanelerini kaldırınca itoa ve strcopy'de gitti. id'yi decimal yerine, read_three(0) yerine read_three("0") şeklinde, ASCII olarak gönderiyorum. Bu şekilde yapınca herhangi bir modifikasyon yapmadan doğrudan string'in sonuna ekleyebildim.

Kod: [Seç]
uchar file_name[8];

char_cpy(file_name,"tdat");
concat(file_name, id);

...

void char_cpy(char * dest, char * src)
{
while(*src)
*dest++ = *src++;
*dest = '\0';
}

void concat(char * dest, char * src)
{
char i;
while(*dest)
*dest++;
while(*src)
*dest++ = *src++;
*dest = '\0';
}

Tahminin doğru
read_three("0") , tdat0 dosyasını,
read_three("1"), tdat1 dosyasını okuyor.
Gosub ile gidilen yerden goto ile dönen adam

Çevrimdışı Alpyre

  • RAAT
  • Retroman
  • *
  • İleti: 51
Ynt: while(!feof)
« Yanıtla #21 : 12 Kasım 2018, 19:58:52 »
Değer olarak göndersen concat'ten de kurtulutdun.

Ayrıca for döngüsünde falan kullanırdın id'yi gerekirse, ama yine sen bilirsin:)

Çevrimdışı emarti

  • Retroman
  • ***
  • İleti: 38
  • emarti@Amiosnux:~$ make bzImage █
Ynt: while(!feof)
« Yanıtla #22 : 14 Kasım 2018, 22:03:53 »
@wizofwor abi CC65 ile GEOS üzerinde de uygulamalar bekliyoruz senden.
Stay with the C= Amiga!