AMİGA C
Retro bilgisayar
Selam! Bu ayki yazıma, baskıdan kaynaklanan bir sorunu size aktararak başlıyorum. Baskının yapıldığı karakter setinde ters bölü işareti olmadığından, geçen sayılardaki birkaç yerde hatalar olmuştu. Dördüncü sayıdaki düzeltmelerde bunu belirtmiş ve doğrusunu yazmıştım. Fakat bu ters bölü '\' karakterinin bulunmayışı hata düzeltme satırlarında da hata yaratmış ve yazıda bazı boş karakterler ortaya çıkmış. Dolayısıyla bir yerde boşluk fark ettiyseniz, oraya ters bölü işaretinin geleceğini varsayın.
Geçen ay, bu ayki konumuzun diziler ve fonksiyonlara giriş olacağını belirtmiştim. O halde haydi dizileri incelemeye başlayalım.
DİZİLER
Basic'ten hatırlayacağınız gibi diziler, aynı türden birçok değişkeni bir tablo halinde bellekte tutmaya ve gerektiğinde, bu tablodan bazı parametreler (satır ve sütun numarası) verilerek değişkenleri kullanabilmeye yaramaktadır. Hemen hemen aynı dizi kavramı C dilinde de bulunmaktadır. Dizileri incelemek amacıyla geçen aylarda yaptığımız programların tümü gibi olan bir program yazalım. Bu program, girişindeki her rakamı, boşluk, tab, yeni satır karakterlerini ve bunların dışındaki karakterlerin sayısını saymaya yarayan bir program. Programın yazımı için lütfen birinci kutudaki adımları izleyin.
Programdaki;
int nba| I0|;
satırı, nba değişkeninin 10 elemandan oluşan veya boyutu 10 olan bir dizi olduğunu belirtir. C dilinde dizi indisleri sıfırdan başlar. Bu durum Basic ve Fortran gibi dillerin indis başlangıç değeri olan birden farklıdır. Yani nba dizisinin elemanları nba[0], nba[1], nba[2],...., nba[9] adlı elemanlardır. Zaten for döngüsünden de bu durum anlaşılabilmektedir. Çünkü for döngüsü sıfırdan ona kadar (on hariç) için çalışmaktadır.
Bir indis herhangi bir tamsayı değer olabilir. Dolayısıyla indis herhangi bir sabit sayı olabileceği gibi (nba[1]), herhangi bir tamsayı değişken de olabilir (nba[i]).
yapılır. Bu demektir ki, karakterler aritmetik işlemlerde birer tamsayıdan başka bir şey değildir. Bu oldukça doğal ve kullanışlıdır. Örneğimizdeki c-'0' aslında değeri sıfır ile dokuz arasında oynayan ve c karakterinin aldığı rakama göre değişen bir tamsayıdır. Böylece bir dizi indisinin sadece tamsayı olabileceği kuralı da sağlanmış olur. Çünkü, c-'0' değeri daha sonra nba dizisine indis olarak verilmektedir. Girişteki karakterin türü:
Program büyük ölçüde rakamların karakter olarak ifade edilmelerine bağlıdır. Örneğin:
if(c>='0'&&c<='9')
++nba[c-'0'];
else if(c==' '||c=="||c=='\t')
++nb; if(c>='0'&&c<='9') satırı, girişteki karakterin rakam olup olmadığını belirler. Eğer karakterse, nümerik değer karakterin değerinden '0' karakterinin değeri çıkarılarak bulunur. Böylece dizideki gerekli indis hesaplanmış olur ve program bu indisdeki sayıyı bir artırma işlemini gerçekleştirmek için kullanır. Doğal olarak bu, ancak '0','1' v.b. karakter değerlerinin pozitif ve birbirlerini izler şekilde olmaları sayesinde gerçekleşebilir. Bu varsayımlar, hemen hemen kullanılan bütün karakter setleri için doğrudur.
else ++nd;
testinde belirlenmektedir.
Yazılış biçimi olarak:
if (koşul)
komutlar else if (koşul) komutlar else komutlar C dilinde tanım olarak, eğer karakterler ve tamsayılar arasında bir aritmetik işlem yapılıyorsa, bütün karakterler tamsayı kodlarına çevrilir ve işlem ondan sonra yapılır. Bu yazım, programlarda birkaç yönden test edilmesi gereken durumlarda oldukça sık kullanılmaktadır. Bu tür bir yazımın çalış-
--------------------------------------------- KUTU 1 --------------------------------------------------- 1> Aşağıdaki programı yazıp RAM Diske kaydedin.
/* K&R'ın kitabından alınarak Amiga ya
uyarlanmıştır. V
#define EOF -1
main()
{
int c,i,nb,nd;
int nba[10]:
nb=nd=0;
for(i=0;i<10;++i)
nba[i]=0;
while((c=getchar())!=EOF)
if(c>='0'&&c<='9')
++nba[c-'0'];
else if(c==* '||c==M||c==,\r)
++nb;
else
++nd;
Printf(basamaklar =");
for(i=0;i<10;++i)
printf(" %d",nba[i]);
printf("beyaz karakterler = %d",nb);
printf(", diğerleri = %d",nd);
}
2> Şimdi programı "cc ram:program-ismi.c" ile compile edin. 3> Şimdi de "ln ram:program-ismi.o -lc" ile link edin. 4> Programı çalıştırmak için ram:program-ismi yazın. Bu durumda program sizin klavyeden girdiğiniz karakterler üzerinde işlem yapacaktır. Bu moddan çıkmak için Ctrl-\ (Control ve ters bölü tuşlarına birlikte) tuşlarına basmalısınız. Eğer programa bir text dosyasından redirection (Türkçe: yeniden yönlendirme) verirseniz program text dosyasının bitimiyle beraber size yaptığı işlemlerin sonuçlarını yazacaktır.
DERLEYİCİLER
ma ilkesi şöyledir: Önce ilk koşul kontrol edilir. Eğer bu doğruysa, hemen sonraki komut veya komutlar grubu (komutlar grubu süslü parantezler içinde olmalıdır) çalıştırılır ve program testten çıkarak çalışmasına devam eder. Eğer bu koşul doğru değilse, ikinci koşul kontrol edilir. İkinci koşul doğruysa program ikinci if'ten sonraki komut ya da komutları çalıştırır ve testten çıkılarak programın çalışması devam ettirilir. Eğer ikinci koşul da yanlışsa, program ikinci else'den sonraki komut veya komutlar grubunu çalıştırır ve test bitmiş olur. İkinci else ve üçüncü komutlar bölümü yoksa (bu bölümler isteğe bağlıdır), hiçbir işlem yapılmadan testten çıkılır. Programlarınızın içinde istediğiniz kadar;
else if(koşul)
komutlar bölümü bulunabilir. Fakat benim size tavsiyem, buradakinden daha fazlasını kullanmamanız. Çünkü bu, programınızın anlaşılabilirliğini azaltacaktır.
FONKSİYONLAR
C dilindeki fonksiyon kavramı, Basic'teki subrutinlere benzer. Bir fonksiyon, bazı hesaplamaların programdan bağımsız bir yerde yapılabilmesine olanak tanıyan bir yapıdır. Fonksiyonların asıl amacı, karışık ve uzun problemlerin daha kolay ve kısa olan parçalara bölünmesi ve bütün parçaların birleştirilmesiyle kısa, hızlı, daha kolay bir yoldan çözülebilmesidir. Uygun düzenlenmiş fonksiyonlarla, bir işin nasıl yapıldığı önemsenmeyebilir. Yani, sadece sonuç olarak neyin gerçekleştiğini bilmek yeterlidir. C dili fonksiyonları iyi, kolay, uygulanma alanı çok ve kullanım faydaları fazla olacak bir şekilde işleyebilmek için dizayn edilmiştir. C dilinde, sadece birkaç satırdan oluşan fonksiyonlar oldukça sık görülecektir. Bunların amacı, programın daha rahat anlaşılmasını sağlamak, daha sonra program üzerinde yapılacak değişikliklerin kolaylıkla yapılabilmesi olanağını vermek ve bir fonksiyonun birden çok programda kullanılabilmesini sağlamaktır.
Şu ana kadar bizim için daha önceden hazırlanmış olan printf, getchar, putchar gibi fonksiyonları kullandık. Fakat hiç kendi yazdığımız bir fonksiyonu kullanmadık. Sanırım artık bunun zamanı geldi. Örnek olarak, C dilinde üs alma operatörü olmadığı için, verilen bir sayının tamsayı üssünü alan bir power(m,n) fonksiyonu yazmayı seçtik. Tabii ki bu fonksiyon, tüm üs alma işlemlerini yapamamaktadır. Çünkü üs değeri olarak sadece tamsayılar verilebilmektedir.
Şimdi, ikinci kutudaki ana programı ve altındaki power fonksiyonunu yazarak kutudaki adımlar yardımıyla programı çalışır hale getirin.
Programdaki main fonksiyonu, sadece power fonksiyonunu test etmek için kullanılmıştır. Çünkü bütün C programlarında programın çalışabilmesi için bir yerde mutlaka main fonksiyonu olmalıdır.
C dilindeki tüm fonksiyonlar aynı düzende yazılırlar:
fonksiyon-adı(eğer varsa argüman adları)
eğer varsa argüman tanımlamaları { tanımlamalar komutlar } power fonksiyonu,
printf("%d %d %d",i,power(2i),(power(3j));
satırında, iki defa çağrılmaktadır. Her çağrılmada, power fonksiyonuna iki tane argüman geçirilmektedir ve power fonksiyonu da sonuçta ana fonksiyona (main'e) bir sayıyı geri göndermektedir. Power fonksiyonunun geri gönderdiği sayı, bir tamsayı olduğundan, printf de %d yardımıyla basılabilmektedir. Doğal olarak C dilinde her fonksiyon mutlaka tamsayı bir değeri geri göndermek zorunda değildir. Fakat bunlarla ilgili bilgileri daha sonraki sayılarda size vereceğim.
power fonksiyonundaki argümanlar, doğru olarak tanımlanmalıdırlar ki program tarafından doğru olarak kullanılabilsin. Bu işlem:
int x,n;
satırı ile yapılmaktadır. Argüman tanımlamaları, fonksiyon adı ve açma süslü parantezi ({) arasında yer almalı ve her tanımlamanın sonuna, noktalı virgül konmalıdır. Power'ın argümanları için kullanılan isimler (x, n) tamamen o fonksiyona aittir ve başka fonksiyonlar içinde bir karışıklık yaratmadan kullanılabilir. Bu aynı zamanda fonksiyonun içindeki i, p gibi değişkenler için de geçerlidir. Yani main fonksiyonundaki i değişkeni ile, power fonksiyonundaki i değişkeninin birbiri ile hiçbir ilgisi yoktur ve bu durum programın işlemesi açısından bir karışıklık yaratmaz.
power'ın hesapladığı değer, fonksiyona bir return komutu yardımıyla gönderilmektedir. Return fonksiyonunun parantezleri içinde, herhangi bir ifade bulunabilir. Bir fonksiyon, mutlaka bir sayı geri göndermek (İng. return) zorunda değildir. Parantezleri içinde hiçbir ifade bulunmayan return komutu, kontrolün çağıran fonksiyona dönmesini (doğaldır ki hiçbir değeri olmayan bir değerle) sağlar. Çağıran fonksiyona dönmenin bir başka yolu da, return komutu yazılmadan süslü parantez ile kapatmaktır.
Bu aylıkta bu kadar. Gelecek ay fonksiyonların ve programımızın incelenmesine devam edeceğiz. Hoşçakalın.

-------------------------------KUTU 2 -------------------------------
1> Aşağıdaki programı yazıp, Ram Disk'e kaydedin.
/* K&Rın kitabından alınarak Amiga ya
uyarlanmıştır. V
main()
{
int i;
for(i=0;i<10;++i)
printf("%d %d %d",i,power(2,i),power(3,i));
power(x,n)
int x,n;
{
int i,p;
p=1;
for(i=1;i<=n;++i)
p=p*x;
return(p);
}
2> Şimdi programı "cc ram:program-ismi.c" ile compile edin. 3> Şimdi de "ln ram:program-ismi.o -lc" ile link edin. 4> Programı çalıştırmak için ram:program-ismi yazın.