Merhaba, tekrar hoş geldiniz. Bu derste, bir karakter
dizisi oluşturmaktan, özellikle de bunu c'de bir karakter dizisi
kullanarak nasıl yapabileceğinizden bahsetmek istiyorum.
Dize ve karakter dizisi terimlerini birbirinin yerine kullanma eğilimindeyim.
Ama aslında bir karakter dizisi, hakkında konuşacağımız char dizisidir.
Bu çok önemli bir kavram.
Artık programımızda her türlü şeyi yapmak için kelimeleri ve metinleri kullanabileceğiz.
Şimdi c'nin kendisi bir dizeyi temsil eden herhangi bir veri tipine sahip değildir.
Orada bir şey yok. Birçok dil ya bir nesneyi
ya da string türünde bir veri türünü destekler.
Şimdi string'de c veri tipi olmadığı için string üzerinde
hiçbir operatörü kullanamazsınız.
Sonunda yapacağımız şey, standart kütüphaneyi kullanmak olacak ve hakkında konuşacağımız
her türlü dize işlevi var.
Kullanabileceğiniz çeşitli dize işlevlerine adanmış üç dersimiz var.
Ve bu, dizeleri manipüle etmemize, dizeler hakkında bilgi almamıza yardımcı olacaktır.
Ancak dizeler üzerinde işleç kullanamazsınız, dizeleri artı veya eksi yapamazsınız,
buna benzer bir şey yapamazsınız.
c'deki dizeler char türünde bir dizide saklanır.
Dizinin ne olduğunu biliyoruz. Karakter türünün ne olduğunu biliyoruz.
char türü tek bir karakterdir, bir dizide aynı isimde birden
fazla eleman saklayabilirsiniz.
Bu nedenle, bir dizenin bir karakter dizisinin içinde olması mantıklıdır
çünkü bir dize çok sayıda karakterden oluşur.
Böylece bir dizenin karakterleri, hücre başına bir karakter olmak üzere bitişik bellek hücrelerinde saklanır.
Tıpkı bir diziye eriştiğiniz gibi buna da erişebilirsiniz.
Ancak bir diziyi gerçekte nasıl tanımlayacağınızı görmek için sadece char türünü ve ardından
boyutu belirtmek için parantezleri kullanırsınız, tıpkı farklı bir türde oluşturacak
olsaydınız normal bir dizi gibi.
Char ve ardından adınız her neyse ve ardından köşeli parantez
içinde karakter dizisinin boyutu.
C'de bir dizeyi bu şekilde bildirebilirsiniz.
Şimdi c'de dizeyi bu şekilde bildirdiğinizde, ilişkili
gerçek bir veri yoktur. Sadece boyutu belirtiyorsunuz.
En basit yolu bu.
Böylece değişken, en fazla 19 karakter içeren bir dizeyi barındırabilir.
Bu boş karakteri unutmayın.
Dize boyutunuzun 20 olacağını söylerseniz, bu aslında yalnızca 19 karakterin
saklanabileceği anlamına gelir çünkü null
için fazladan bir karaktere sahip olmanız gerekir.
Unutmayın, bir karakter dizisini 20 olarak bildirmek, orada 19 karakter
saklanabileceği anlamına gelir.
Bir dizeden önce kullanmak istediğiniz dizinin boyutunu belirttiğinizde - bir
dizeyi saklamak için, saklamak
istediğiniz dizedeki karakter sayısından en az bir büyük olmalıdır.
Derleyici her string sabitinin sonuna otomatik olarak null terminator ekleyecektir.
Dolayısıyla, bu karakter dizilerini oluştururken gerçekten
yapmanız gereken şey, onları başlatmak olmalıdır.
Böylece bir string değişkenini tıpkı bir diziyi başlatır gibi başlatabilirsiniz.
Her karakteri bu parantezlerin içine koyarsınız.
Yani bu, bir tamsayı dizisindeki öğeleri başlatmaya çok benziyor.
Ancak char sözcüğünü söyler ve sonra dalgalı parantezlerin
içine her bir karakteri koyarsanız, bu bir karakter dizisi
oluşturur.
Yani diğer dizi başlatma işlemleri ile aynıdır.
Boyut belirtilmediğinde, c derleyicisi otomatik
olarak dizideki eleman sayısını hesaplar ve ardından null sonlandırıcı için bir tane ekler.
Yani parantezler, küme parantezleri arasında sahip olduğunuz başlatıcıların
sayısına dayanır.
Bu deyim, tam olarak yedi karakter, h-e-l-l-o ünlem işareti ve
ardından null sonlandırıcı için yer
ve bellek ayıracaktır ve sağdaki bu küçük diyagram size bunu göstermektedir.
Otomatik olarak ve boş sonlandırıcı ekleyerek. Karakter dizilerinizi her
zaman tek tırnak ve ardından virgülle başlatmak
zorunda olsaydınız, bu gerçekten baş belası olurdu.
Yapabileceğiniz şey, kısaltılmış gösterim bile olsa, bunun etrafına çift tırnak işareti koymaktır.
Bu nedenle, ilk örnekte olduğu gibi dizeyi açıkça belirtebilir ve ardından
yalnızca veriyi uygulamak için bir dize işlevi kullanmanız
gerekir veya derleyicinin bunu
sizin için yapmasına izin verebilirsiniz.
Bunu açıkça yapmanın sorunu, null için fazladan karakter eklemeyi her zaman hatırlamak zorunda
olmanızdır.
Yani aslında yapmanız gereken derleyicinin bunu sizin için çözmesine izin vermektir.
Bu yüzden boyut için bu parantezlerin içine herhangi bir sayı koymayın.
Çünkü belirtilen boyut çok küçükse, derleyici dizinin sonuna
sonlandırıcı null karakterini sığdıramaz ve oraya bir tane koymaz ve
size oraya bir tane koymadığını söylemez.
Yani programınızda bir hata olacak ve siz bunun farkında bile olmayacaksınız.
En iyi uygulama, bir dize değişmezi kullandığınızda ve bir dizeyi
başlattığınızda, derleyicinin sizin için boyutu hesaplamasına izin vermektir.
Daha büyük bir boyut veya başka bir şey yapın ve sonra sadece oraya koyun ve sizin için boyutu bulacaktır.
Bu yüzden boyut belirtmeyin. Bırakın derleyici çözsün.
Bu şekilde doğru olacağından emin olabilirsiniz.
Bu parantezleri boş parantez olarak bırakın
ve atama operatörü ile atayın ve ardından çift tırnak
içine koyabilirsiniz. Köşeli parantezlere bile ihtiyacınız yok.
Bu en iyi uygulamadır. Bir örnek üzerinden gideceğiz.
Ayrıca char türünde elemanlardan oluşan bir dizinin
sadece bir kısmını bir dize ile başlatabilirsiniz.
Yani gerçekten büyük bir boyut oluşturduysanız ve sadece birkaç
karakter atadıysanız, bu da sorun değil, sadece
bazı karakterleri başlatıyorsunuz. Diğer tüm karakterler sadece
boş olacak.
Yani burada derleyici ilk beş öğeyi başlatacaktır.
Str sıfırdan str dörde kadar, string sabitinin
tüm bu karakterleri ve ardından string sub 5 null karakteri
içerecektir.
Dizideki 40 öğenin tamamı için hala yer ayrılacaktır,
ancak bunlardan yalnızca beşi kullanılacaktır, dört artı null karakteri.
Bu nedenle, yine en iyi uygulamanız boyutun içinde bir sayı belirtmeyin,
sadece çift tırnak kullanarak bir dize değişmezi atayın.
Sonunda göreceğiniz şey bu olacak.
Şimdi, eğer başlatma yapmadıysanız ve karakter dizisini bir
boyutla oluşturduysanız, içine tarihi nasıl koyarsınız.
Dizi olduğu için sadece veri atayamazsınız.
Bir tamsayı dizimiz olsaydı, bir tamsayı dizisine sadece
beş sayısını atayamayacağımızı, bunun mantıklı
olmadığını biliyoruz. Gerçek unsurları belirtmeniz gerekir.
İndeksleri belirtmeniz gerekir.
Yani 100 karakterli bir karakter dizisi bildirip ardından s eşittir hello demek
gibi bir şey yapamazsınız. Bu işe yaramayacak.
Çünkü, yine, s bir dizidir. Çift tırnak içinde bir dize olsa bile, bellekte hala bir dizidir.
Dolayısıyla, bir atama işlemi gerçekleştiriyorsanız, yukarıdaki gibi
bir karakter dizisini başka bir karakter dizisine atayamazsınız.
Bir karakter dizisini bildirdikten ve
ilklendirdikten sonra ona veri atamak isterseniz, str copy
adlı özel bir işlev kullanmanız gerekir.
Bu konu hakkında başka bir derste konuşacağız.
Bu noktaya kadar, dizelerinizi oluşturduğunuzda, dizge değişmezleri olacaklar,
çift tırnak içinde olacaklar ve onları asla değiştirmeyeceksiniz.
Dolayısıyla bu da tamamen geçerlidir. Aslında bu karakterlere ya da dizideki her
bir elemana indekse göre erişebilir ve her bir karakteri belirtebilirsiniz.
Yani s sub 0, s sub 1 ve ardından tek tırnak içine tek bir karakter koyun.
Bu şekilde atayabilirsiniz. Ancak elinizde 100 baytlık bir dize olduğunu düşünün.
Bu çok fazla kod satırı gerektirecek. Yani bunu yapmak istemezsiniz.
Yapmak isteyeceğiniz şey, boyutu olmadan bildirdiğinizde
onu başlatmak ve daha sonra değiştirmek isterseniz
kopyalayacağınızı belirtmektir.
Bir dizeyi çıktı olarak görüntülemek için hala printf fonksiyonunu kullanacağız.
Programınızın herhangi bir yerinde bir diziye başvurmak istediğinizde, dizi adını tek
başına kullanmanız yeterlidir.
Endeksleri belirtmek zorunda değilsiniz.
Çünkü dizinin içindeki indisler tek bir karakteri belirtecektir.
Dizenin tamamını istiyorsanız, sadece dizi adını kullanırsınız.
Dolayısıyla, çıktıyı görüntülemek için printf işlevini kullanıyorsanız,
sadece aşağıdakileri yaparsınız. Çift tırnak içinde, biçim belirteciniz
olarak bir yüzde s ve ardından sadece karakter dizisinin adını kullanırsınız.
Yani ona erişmek istediğinizde diğer diziler gibi davranmazsınız. Erişmek istediğinizde, gerçek indisler veya
parantezler olmadan sadece isim.
Yüzde olarak biçim belirteci ise boş sonlandırılmış bir dizenin
çıktısını almak içindir. Daha önce tam sayılar için yüzde d kullandığımızı
hatırlayın, karakterler için yüzde c kullanabilirsiniz.
Dizeler için yüzde s kullanırsınız ve bunlar karakter dizileridir.
Boş sonlandırılmış bir dize bekler.
Bu nedenle, dizeyi boyut olmadan başlattıysanız ve null sonlandırıcı
otomatik olarak eklendiyse veya
belirli bir boyutla oluşturduysanız ve eklediyseniz veya açıkça
eklediyseniz, fark etmez. Sadece boş sonlandırılmış olması gerekir.
printf işlevi, yüzde s biçim belirticisiyle karşılaşıldığında, ilgili bağımsız
değişkenin null karakteriyle sonlandırılan bir karakter dizesi olduğunu varsayar.
Beklentisi bu, o yüzden böyle olmak zorunda.
Bir dize girmek için, scanf kullanarak klavye aracılığıyla
diğer veri kümelerini nasıl gireceğimizi biliyoruz.
Aynı şeyi dizeleri girmek için de yapacağız.
Bir scanf fonksiyonu kullanacağız. scanf fonksiyonu ile, farklı
bir format belirteci kullanmanız dışında aynı şekilde olacaktır.
Yani dizeler için girdi olarak yüzde s kullanacaksınız.
Ve bu bir dize girmek için kullanılır.
Burada dikkat edilmesi gereken bir diğer husus da değişken adı için ve işareti kullanılmamasıdır
çünkü bu bir karakterdir. Hatırlayın, dizelerdeki işlecin adresini yalnızca
ve işaretini sağlamanız gerektiğinden bahsetmiştik.
Bunun nedeni, işaretçiler hakkında konuştuğumuzda daha açık olacak olmasıdır.
Ancak char girişi bir karakter dizisi olmasına
rağmen bir işaretçidir ve scanf ikinci argümanı olarak bir işaretçi alır.
İşte bu yüzden bunu yapmak zorunda değilsiniz. Tamsayılar ve çiftler bildirdiğinizde, bunlar işaretçi
değildir ve. Yani scanf kullanarak
klavyeden girdi okumak istiyorsanız, ikinci argüman bir adres geçmeniz gereken
bir işaretçi bekler.
Şimdi scanf ile bir dize yaptığınızda,
scanf yalnızca boşluğa kadar okuyacaktır.
Yani scanf yaparsanız ve Jason'ın bir eğitmen olduğunu
yazarsanız.
Girişte depolanacak tek şey Jason'dır. Çünkü bir kez o boşluğa denk geldiğinde,
dizenin geri kalanını okumayacaktır.
Dolayısıyla, tüm dizeyi okumak için kullanabileceğiniz başka işlevler de vardır.
Kullanacağımız örneklerden bazıları muhtemelen bunu yapacaktır. Klavyeden girdi okumanın başka bir
yolu olan ve boşluklardan bağımsız olarak tüm dizeyi okuyacak olan f get s gibi
şeyler yapabilirsiniz.
Ama sanırım C11 için get underscore s adında
bir tane daha var, ama bunun hakkında
daha fazla konuşacağız, ama bu dizeler için girdi okurken
hatırlamanız gereken sadece bir şey. Sadece boşluğa kadar olan kısmı okuyacak.
İki dizenin eşit olup olmadığını test etmeye ne dersiniz?
Bu noktaya kadar, eşit olup olmadıklarını görmek için
tüm değişkenleri test ettik, sadece eşittir eşittir kullanıyoruz.
Ancak ipler söz konusu olduğunda bu işe yaramayacaktır.
Eşitlik operatörü, hatırlayın, dizelerin karakter dizileri olduğunu söylemiştik, bu yüzden onlar üzerinde operatör kullanamazsınız.
Ve eşitlik operatörü yalnızca ints ve doubles veya floats veya karakterlere
uygulanabilir.
Yapılar veya diziler üzerinde çalışmaz. İki diziyi karşılaştıramazsınız.
Yani iplerle çalışmayacak. İki dizenin eşit olup olmadığını belirlemek istiyorsanız,
iki karakter dizesini karakter karakter açıkça karşılaştırmanız gerekir.
Yani dizideki her bir öğeye indeks indeks
bakmanız gerekir.
Ancak, bu gerçekten çok büyük bir sorun çünkü bu gerçekten sıkıcı olurdu.
Bu yüzden standart kütüphaneden bir str karşılaştırma fonksiyonu
kullanarak bunu nasıl kolayca yapabileceğinizden bahsedeceğiz, ancak
equals equals'ı kullanamazsınız bunu unutmayın.
Ve yine, sadece bir hatırlatma olarak, birkaç kez söyledim, tekrar söylemek
istiyorum, çift tırnak içindeki dize sabiti
x, tek tırnak içindeki karakter sabiti x ile aynı değildir.
Tek tırnak içindeki X temel bir türdür, sadece char veya
care'dir.
Çift tırnak içindeki X bir sürücü tipidir, char tipinde bir dizidir.
Çift tırnak içindeki X gerçekten iki karakterden oluşur, x ve null sonlandırıcı,
null karakteri, bu yüzden bunu aklınızda bulundurun.
Burada, stringleri bir boyutla
bildirerek ya da aynı satırda başlatarak nasıl
oluşturabileceğimize dair bir örnek verilmiştir.
İşte bu en iyi uygulamadır. Dize değişmezleri kullanacaksanız, benim
yapacağım şey burada söyleneni
yapmak, karakter dizisi oluşturmak, bir boyut belirtmemek ve atama
operatörünün sağında çift tırnak işareti bulundurmaktır.
Derleyici otomatik olarak doğru dizeyi oluşturacak ve ona bir null sonlandırıcı ekleyecektir.
Bir boyut belirtirseniz ve yeterli karakteriniz yoksa, bunu saklamayacaktır.
Bu nedenle, char veri türünü, değişkenin adını
ve ardından boş parantezleri kullanarak
karakter dizisi değişmezleri oluşturun.
Bu program sanırım bir dizideki karakterleri sayacak,
yani aslında dizenin uzunluğunu elde edecek.
Burada yaptığımız şey, iki farklı dizgiye sahip iki karakter dizisinde count
adında bir değişken oluşturmaktır; to be or not to
be ve ardından soru olan virgül.
Char str one, b'den sonra bir alternatöre sahip olacak ve str,
sorudan sonra bir alternatife sahip olacak.
Burada, count eşittir sıfırdan null sonlandırıcı
görene kadar ilk diziden geçecek bir döngümüz var.
Bu durumda eşit değil seçeneğini kullanabiliriz çünkü bir karakteri karşılaştırıyoruz.
Karakter olarak boş sonlandırıcı. Karakterleri karşılaştırmak gayet güzel.
Yani while döngümüz bir null sonlandırıcı görene kadar devam edecek.
Bir null terminatör gördüğümüzde, dışarı atlayacağız.
Count, bu dizedeki karakter sayısına eşit olacaktır.
Yani bu dizenin uzunluğu.
Bunu her iki tel için de yapıyoruz. Ve temelde her iki dizenin de doğru uzunluğa
sahip olacağını fark edeceksiniz çünkü sadece her birinin üzerinden geçiyoruz.
B yapmak ya da yapmamak 18 karakter gibi bir
şey olacak.
Artık böyle bir şey yapmanıza hiç gerek kalmayacak çünkü dizelerin
uzunluklarını bulmak için str length ile güzel bir yardımcı fonksiyonumuz var.
Ancak yine de, bunun gösterdiği şey bir dizi olduğu gerçeğidir.
Ve bir dizenin uzunluğunu karşılaştırmak veya bulmak istiyorsanız, not equals'ı
kullanabilir ve null terminator karakterine bakabilirsiniz.
Umarım bu yardımcı olmuştur. Dize değişmezlerini bu şekilde tanımlayacak ve başlatacağız.
Teşekkür ederim.