Selam,
Bugün diziler konusuna devam ediyorum. Bu sefer “karakter dizisi“ni öğrenmeye çalışacağım. Dizgi, katar ya da string olarakta adlanırılabiliyor. Aslında string
modern programlama dillerine ait bir terim. Metinsel verileri saklamak için kullanılan değişken türünü ifade ediyor ama C dilinde string
veri tipi yok. Bunun yerine karakterleri (char
) bir araya getirerek bir dizi oluşturuyoruz. Yine de ben karakter dizisi
yerine string
terimini kullanacağım.
Önce basitçe bir karakter dizisi tanımlamakla başlıyorum. Dizilerde geçerli olan kurallar stringler içinde geçerli.
char karakterDizisi[] = {'S','E','L','A','M'};
Bir dizi tanımlandığı zaman bellekte ardışık olarak yer ayrılıyordu. karakterDizisi
nin indislerine göre adreslerini yazdıralım:
int i; for(i=0;i<5;i++) { printf("%u ", &karakterDizisi[i]); }
Çıktı:
2337488 2337489 2337490 2337491 2337492
Görüldüğü üzere adresler birer birer artıyor. İlk derslerde öğrendiğim hangi veri tipinin bellekte ne kadar yer kapladığı meselesi şimdi daha da netleşti.
String tanımlamanın başka bir yolu ise çift tırnakları (” “) kullanmak. Bu şekilde metni bir bütün olarak yazabiliriz.
char baskaKarakterDizisi[] = "Hırs, hasaret ve muvaffakiyetsizliğin sebebidir.";
Çift tırnaklar içinde bazı özel karakterleri kullanmak istediğimde, kaçış karakterini kullanmam gerektiğini de öğrenmiştim. Yani \ karakterini.
char string[] = "\"İslamiyetin menşei, ilim; esası, akıldır.\"";
Stringler konusunda önemli bir nokta ise, her zaman “null
” karakteri ile sonlandıkları. Yani “\0
” karakteri ile. \0
ASCII tablosundaki değeri 0 dır.
Stringler de bir dizi olduğuna göre tek tek elemanlarına erişebiliriz demektir.
char film[10] = "Matrix";
Yukarıdaki dizi için,
film[0]: M film[1]: a film[2]: t film[3]: r film[4]: i film[5]: x film[6]: '\0'
demektir. Şimdi bunu bir do-while
döngüsüyle görelim. Döngü ‘\0
‘ karakterini görene kadar devam etsin. Bakalım ne kadar dönecek?
int i=0; do { printf("film[%d]: %c \n", i, film[i]); i++; }while(film[i] != '\0');
Çıktı:
film[0]: M film[1]: a film[2]: t film[3]: r film[4]: i film[5]: x
Bir string
in boyutunu gereğinden az verirsek C bize hata vermez ama fazla olan veriler saklanmaz.
char film[3] = "Matrix";
Bu string
i ekrana yazdırıyorum. Bu arada puts()
diğer kullanım şeklini de öğrenmiş oluyorum.
puts(film);
Çıktı:
Mat
Buraya kadar olan kısımda zaten bunları yaptım ama hızlıca tekrar değineceğim. Karakter dizilerine şu şekillerde ilk atamlar yapılabilir:
Pointer
kullanarak (pointer
kavramını henüz öğrenmedim)Bir diziye boyutunu belirlemeden elemanları girdiğim zaman benim için elemanları sayıp boyutunu otomatik hesaplıyordu. Aynı durum karakter dizileri için de geçerli. Elemanları yine { } içine yazıyorum ama bu kez her bir elemanı ‘ ‘ içinde belirtiyorum. Ve dizinin sonuna ulaştığımı bildirmek için null
karakterini yani '\0'
eklemeyi unutmamak gerek.
char name [] = {'Y', 'U', 'S', 'U', 'F', '\0'};
En pratik ilk değer ataması bu şekilde oluyor. ” ” arasına metinsel ifadeyi giriyoruz. Üstelik bu yöntemle sonlandırı karakteri yani ‘\0
‘ elle girmeme gerek kalmıyor çünkü benim için derleyici bunu yapıyor.
Pointer
kavramını henüz öğrenmediğim için bunu şimdi atlıyorum ama isteyenler olursa buraya linki bırakıyorum.
3 tane fonksiyon kullanabiliriz
getchar()
gets()
scanf()
getchar()
fonksiyonu enter girilene kadar klavyeden veri almaya devam eder ama sadece ilk girilen karakteri saklar. Eğer bir string saklamak istersek şu şekilde kullanabiliriz.
int i = 0; char name[20]; puts("Lütfen isminizi girin:"); while((name[i] = getchar())!='\n') i++ ; puts(name);
Yukarıdaki kod enter girilene kadar girilen karakterleri name
içine atıyor. Bu sırada her karakter girişinde i
değeri 1 artarak dizinin indisi ilerletiliyor. Son olarak entera basıldıktan sonra ekrana girilen değeri yazdırıyor.
gets()
fonksiyonu da enter girilene kadar boşluklar da dahil olmak üzere girilen karakterleri saklar ve dizinin sonuna otomatik olarak ‘\0
‘ karakterini de ekler.
Aşağıda gets() fonksiyonun kullanım şeklini görüyoruz:
char name[20]; puts("Lütfen isminizi girin:"); gets(name);
gets()
ile stringleri almak pratik gözükse de kötü bir yanı var. Yukarıda name[20]
için 20 karakterlik bir alan belirlenmiş olsa da gets() bunu dikkate almaz. 30 karakter girilse de bunu saklamaya çalışır. Bu durumda “overflow” yaşanabilir ve program çökebilir.
Bu fonksiyonu daha önce birçok kez kullanmıştım zaten. Şimdi de string ifadeler için kullanım şekline bakalım:
char name[20]; puts("Lütfen isminizi girin:"); scanf("%s",name);
İlk dikkat ettiğim nokta stringler için placeholer %s
. Diğer nokta ise &
operatörü kullanılmamış.
scanf()
, gets()
ve getchar()
dan farklı olarak, entera kadar olan tüm karakterleri değil boşluğa kadar olan karakterleri kabul ediyor. Yani yukarıdaki kod için name
değişkenine “Yusuf Karaçin” yazarsam sadece “Yusuf” saklanır.
scanf()
fonksiyonu ile boşlukları da saklamak istersek şu kodu kullanabiliriz:
scanf("%[^\n]s",name);
Yalnız scanf()
fonksiyonu da overflow a açıktır. Overflowlarla baş etmeyi ilerledikçe öğrenmeyi umut ediyorum. Ayrıca stringleri alırken neden & kullanmadığımıza gelirsek bu da pointerlarla alakalı bir konu olduğu için şimdilik atlıyorum.
Yukarıda örnekleri gördüm ama yine hızlıca değinmek istiyorum:
putchar()
puts()
printf()
Adından anlaşıldığı üzere tek bir karakter yazdırmak için kullanılıyor. 3 farklı şekilde kullanabiliriz:
char a = 'Y'; char isim[] = "Yusuf"; putchar('a'); // a yazar putchar(a); // a değişkeni içindeki değeri yazar. Yani Y putchar(isim[1]); //isim dizisinin 1. indisini yazar. Yani u
Kullanıcıya bildirmek vermek istediğim zaman sıklıkla tercih ettiğim fonksiyon. Kullanım şekillerini hızlıca hatırlayalım:
char isim[] = "Yusuf"; puts(isim); //isim değişkenini, yani Yusuf yazar puts("Hoşgeldiniz!"); // hoşgeldiniz! yazar
İlk konularda uzunca incelemiştim. Şimdi de stringler için kısaca göz atıyorum:
char isim[] = "Yusuf"; char x = 'a'; printf("Merhaba, %s", isim); //Merhaba, Yusuf yazar printf("\n Hoşgeldiniz!"); // bir sayır aşağıya iner ve hoşgeldiniz! yazar printf("%d",x); // 97 yazar
Stringler için placeholderın %s
olduğunu bir kez daha görmüş oldum.
Bazen metinsel bir ifade aslında sayısal bir değer taşıyor olabilir. Mesela kullanıcıdan string olarak “17” değerini aldık. Bunun üzerinde matematiksel işlemler yapmak istersek öncelikle sayısal veri tipine çevirmemiz gerekir. Bunun için de atoi()
fonksiyonunu kullanıyoruz.
atoi = A to I =Alphabet to Integer
int num; num = atoi("98"); printf("\nNum: %d",num);
ya da
int num; char marks[3] = "98"; num = atoi(marks); printf("\nNum : %d",num);
şeklinde kullanabiliriz.
string
C dilinde karakter dizisi
dir.putchar()
tek bir karakter yazdırır, getchar()
tek bir karakter alır.atoi()
fonksiyonu kullanılabilir.Celery ile alakalı "best practice"leri ve faydalı araçları bir araya getiren güzel bir checklist'e denk…
Diziler en temel ve sık kullandığımız araçlardan... Kod yazarken işimizi kolaylaştıracak, daha temiz kod yazmamızı…
listve tuple bilginizi test etmek ister misiniz? realpython.com da keşfettiğim ve Türkçe'ye çevirdiğim mini teste…
Rehberlik sağlaması ve bilgi tazelemesi açısından faydalı olduğunu düşündüğüm bir Toptal blog paylaşımınıTürkçe'ye çevirdim.Devamını okuyunBilmeniz…
Angular componentlerine console üzerinden hızlıca erişmek için kullanılan bir teknik. Unutmamak için kendime not düşüyorum.Devamını…
Geçtiğimiz günlerde keşfettiğim ve oldukça da hoşuma giden repoyu paylaşmak istiyorum: lydiahallie/javascript-questions Genel olarak temel…