Merhaba, tekrar hoş geldiniz. Heyecan verici bir konferans daha. Bu derste, dizeler ve dize
işlevleri hakkında daha fazla konuşacağız,
özellikle de dizeleri arama ve analiz etme yeteneği.
Şimdi biraz daha dize fonksiyonlarından bahsedelim. Bir dize aranıyor.
Bir dize aranıyor.
Tüm bu işlevler dize başlığında yer alacaktır.
Belirli bir karakteri veya bir alt dizeyi bulabileceğiniz
özel kullanımlı bazı dize arama işlevleri vardır.
Bu işlevlerin adları strchr ve
strstr'dir.
Bir dizenin içindeki tek bir karakteri veya alt dizeyi bulma.
Bu konuda bazı örnekler vereceğiz.
Ayrıca bir dizeyi belirtmek için bazı yetenekler de vardır.
Bir dizeyi tokenize etmek nedir diyebilirsiniz. İlk olarak, bir tokenin ne olduğunu tanımlamanız gerekir.
Belirteç, bir dize içinde bir sınırlayıcı ile sınırlandırılmış bir karakter dizisidir.
Sınırlayıcı, dizede bulunan ve özel bir anlamı olduğunu
fark ettiğiniz bir şeydir.
Dolayısıyla, tam bir dizeniz varsa, bu Jason'dır ve boşluklarla
ayrılmışsa bir belirteç olabilir.
Bir belirteç bu olabilir, diğeri is olabilir, bir diğeri Jason olabilir.
Bir dizenin tamamını alıp bir sınırlayıcıya dayalı olarak belirli sınırlar
içinde parçalamanın bir yoludur.
Ve sınırlayıcınızın gerçek dizede geçerli olan bir
şey olmadığından emin olmak istersiniz. Dolayısıyla, dosyalardan okurken de sınırlayıcılar
kullanırsınız, aynı türden bir kavram.
Bir cümleyi kelimelere böldüğünüzde, buna tokenize etme denir. strtok adlı bu fonksiyonu
kullanacağız.
Ayrıca bazı analiz dizelerinden de bahsetmek istiyorum. Karakterlerin küçük
harf mi yoksa büyük harf mi ya da alfanümerik mi yoksa
rakam mı olduğunu kontrol etmek için bunlardan
bir sürü var.
Bunlar esas olarak karakterler üzerinde yapılır, ancak yan dizelerdeki karakterler
ve bunları tüm dizelere de uygulayabilirsiniz.
Şimdi dizeler hakkında biraz daha ayrıntıya giriyoruz.
Ve bu işlevlerden bazılarını anlamak için, işaretçiler hakkında biraz konuşmamız gerekir.
Pointer'lar c'de büyük bir kavramdır.
İşaretçilere ayrılmış koca bir bölümümüz olacak.
Muhtemelen bir sonraki ya da ondan sonraki.
Ve çok fazla tartışma var. Muhtemelen dilin en kafa karıştırıcı konusudur.
Şu anda bu konuyu ayrıntılı olarak ele almak istemiyorum çünkü konuyla ilgisi yok.
Kullanacağımız fonksiyonlardan bazılarını anlayabilmeniz için sadece işaretçinin
ne olduğuna dair küçük bir ön bilgi vermek istiyorum.
Bunun tek amacı bu. Bu nedenle, bu birkaç slayttan sonra bu noktada
işaretçileri tam olarak anlamadıysanız, endişelenmeyin.
Pointer kavramını daha sonra ayrıntılı olarak tartışacağız.
Ancak bu dize işlevlerinden bazılarını anlamak için size hızlıca bir göz atmak istiyorum.
C, işaretçi adı verilen oldukça kullanışlı bir değişken türü sağlar.
Bunun hakkında konuşuyordum. Bunun bellek ve bellek tahsisi ile ilgisi var.
Daha önce programlama yaptıysanız ve programlama konusunda tamamen
yeni değilseniz, bazı diller sizin için otomatik olarak bellek yönetimi yapacaktır.
Sizin için bellek ayırır ve silerler, java gibi bir dil bunu yapar.
Buna çöp toplayıcı deniyor. C gibi bir dil bunu yapmaz.
Dolayısıyla, işaretçileri kullanmak için bellek oluşturduğunuzda,
bu belleği silmeniz gerekir.
Ancak pointer çok kullanışlıdır ve
bir adresi saklayan bir değişkendir.
Bir adres, hatırlayın, bellekteki bir şeydir.
Genellikle onaltılıktır.
Adresteki değer bellekte başka bir konumdadır.
İşaretçi sadece adresin bir değer içerdiği bir adrese işaret eder.
Aslında geçmişte scanf fonksiyonu ile adresleri kullanmıştık.
Kullandığımız ve işareti sembolünün operatörün adresi olduğunu hatırlayın.
Scanf fonksiyonu ikinci parametresi olarak
veriyi saklamak istediğiniz bir değişken almalıdır,
bu değişken bir işaretçi olmalıdır.
Bu yüzden scanf işlevi bir işaretçi bekliyordu.
Kendi başına bir tamsayı oluşturmak için, bu bir işaretçi değildir,
ancak adresini alırsanız, artık bir işaretçi olur.
Yani ilkel bir veri türünün adresini almak için ve işaretini kullanıyoruz.
Yani adres kavramına biraz aşinasınız.
Unutmayın, şu andan itibaren işaretçilerle
int sayısı oluşturursunuz ve bu bir işaretçi
değildir ve 25'e eşittir.
Ancak bunun adresi olan ampersand'i alırsanız, bunu bir işaretçiye atayabilirsiniz.
Pointer'ın c'de özel bir sözdizimi vardır, yıldız işareti bir pointer'ı temsil eder.
Böylece 25 değerine sahip bir sayı değişkeni bildirdik ve ardından
pNumber adlı yıldız işaretini kullanarak sayının adresini
içeren bir işaretçi bildirdik.
Ve yine, yıldız işareti işaretçiyi bildirmek için kullanılır, bunun bir işaretçi
veri türü olduğunu bu şekilde anlarsınız.
p sayısı değişkeninin değerini almak için
çünkü p sayısı nedir? Bu bir işaretçidir ve bellekteki bir adrese işaret eder.
Sadece p numarasının değerine bakmaya çalışırsanız, size adresi verecektir.
Adresin işaret ettiği şeyin değerini almak istiyorsanız, referansı kaldırmanız gerekir.
Bu yüzden c'nin kullandığı
özel bir sözdizimi vardır, buna yıldız işareti ve değişkenin adı denir, değeri
içeren bellek konumuna bu şekilde erişebilirsiniz.
Dolayısıyla, bu bellek konumuna veri atamak istiyorsanız, yıldız p numarasını söylemeniz gerekir.
Yine etki, işaretçi tarafından belirtilen adreste depolanan verilere erişmesidir.
Bu yüzden işaretçiler hakkında konuştuğumuzda çok kafa karıştırıcı olur çünkü bu kavrama alışık değilsinizdir.
Bir değişkenin bir değeri olduğunu düşünürsünüz, hepsi bu. Ancak bir değişken bir adrese sahip olabilir
ve adres de bir değere sahip olabilir.
Bu slayt az önce bahsettiklerimi örneklendirmeye çalışmaktadır.
Bunu okuduğum bir kitapta buldum.
Bellekte işaretçi kavramını ve adreslerle işlerin nasıl yürüdüğünü
gösteren bir slayttır.
Bu yüzden az önce söylediklerimi tekrarlıyorum.
Ancak ampersand sayısının değeri, sayının bulunduğu adrestir.
Yani iki değişkeniniz varsa, number ve p number,
p number bir işaretçi, number bir int, bu arada işaretçinin
türünü de belirtmeniz gerekir.
İşaretçi bir adres olsa da, yine
de adresin türünü veya nereye işaret ettiğini belirtirsiniz.
Yani int star p sayısı, sayının adresine eşit olacaktır.
Sayı bellektedir ve örneğin binlik
bir adrese işaret eder ve 25 değerine sahiptir.
P numarasının gerçek p numarası için
105 adresi vardır, ancak bu adresin
değeri 1000 adresidir.
p sayısının değerini elde etmek için, size 25 değerini verecek olan 1000 referansını
kaldırmanız gerekir.
İşaretçilerle ilgili tüm bu konulardan bahsetmemin
nedeni, birçok dize işlevinin işaretçi döndürmesidir.
O kadar da önemli değil.
Yalnızca bir dizi içinde belirli bir karakteri nasıl elde ettiğinizi anlamak istediğinizde önemlidir.
Ancak onlardan kısaca bahsetmek istedim.
Kavramın şu anda anlaşılmaması sorun değil çünkü daha sonraki bir bölümde bu
konuyu ayrıntılı olarak ele alacağız.
Ancak, şimdi kullanacağımız dize işlevlerinin işaretçi döndüreceğini ve daha
sonra bu dönüşü yararlı bir şey yapmak için kullanacağınızı anlayın.
Geçmişte str kopyalarını ve str karşılaştırmalarını kullandığımızda, işaretçileri
geçirdik ancak hiçbir zaman işaretçi döndürmedi, bu işaretçiyi kullanmak zorunda kalmadık.
Şimdi işaretçiyi kullanmamız gerektiğine göre, bunun ne anlama geldiğine dair küçük bir açıklama yapmak istiyorum.
Pointer sadece bir adresi işaret edecektir.
Ve sonra bu adresi ayrıştırma yapmak veya ne yapmanız gerekiyorsa yapmak için kullanabilirsiniz.
Umarım bu sizi bunaltmamıştır. Yine, tam olarak anlamadıysanız endişelenmeyin.
Şimdi dizeleri analiz etmek, belirtmek
ve aramak için bazı örnekler üzerinden geçeceğiz.
Bir dizeyi aramak için strchr ya da strstr kullanacağınızı söylemiştik.
strchr, verilen bir dizeyi tek bir karakter için arar.
Fonksiyonun ilk argümanı, bir karakter dizisinin
adresi olacak şekilde aranacak dizedir.
İkinci bağımsız değişken aradığınız karakterdir.
Birazdan bir örnek vereceğiz. Dolayısıyla, işlev dizeyi baştan
başlayarak arayacak ve karakterin
bulunduğu dizedeki ilk konuma bir işaretçi döndürecektir.
İşaretçinin şu anda önemli olmasının nedeni budur, çünkü
tüm bir değeri döndürmüyoruz, bir dizenin içindeki bir karaktere
bir işaretçi döndürüyoruz
ve bu adres aslında bir dizinin indeksini temsil ediyor.
Bellekteki bu konumun adresi, karakter yıldızı tipindedir ve bellekteki
tek bir karakter olan char karakterine
bir işaretçi olarak tanımlanır.
Döndürülen değeri saklamak için, bir karakterin adresini saklayabilecek bir değişken oluşturmanız gerekir,
böylece bir işaretçi oluşturmanız gerekir.
Karakter şimdi bulunursa, fonksiyon null olan özel bir değer döndürür.
Null, işaretçinin hiçbir şeyi işaret etmediği anlamına gelir.
İşaretçilerden bahsederken null kullanırız ve null sadece
hiçbir şey bulamadığını söyler. Yani hiçbir şeye işaret etmiyor.
Bir şeyi işaret ettiğinde, o karakteri bulduğunuz yerin adresini işaret eder ve sonra
oradan ayrıştırmaya başlayabilirsiniz.
Çünkü daha önceki derslerden hatırlayacağınız
üzere, bellekte bir karakter dizisi oluşturduğunuzda,
her karakteri bir bayt olarak temsil edersiniz.
Bir dizeyi çözümlüyorsanız ve belirli
bir karakterin o dizede nerede başladığını görmek istiyorsanız, o baytı döndürürsünüz
ve sonra oradan aramaya başlayabilirsiniz.
Yani str char, bunu nasıl kullanıyorsunuz?
Bir karakter dizisi oluşturduğunuzu söylüyorsunuz ve onu burada
hızlı kahverengi tilki ile başlatıyoruz.
Daha sonra tek bir karakter oluşturuyoruz ve bunu q ile başlatıyoruz.
Sonra bir işaretçi oluşturuyoruz çünkü str char'dan döndürülen şey bu olduğu için bir işaretçi oluşturmamız gerekiyor,
bu da karakter dizisinin neresinde bir karakter bulduğumuzu görmemizi sağlıyor.
İşaretçimizi null olarak başlatacağız. Çünkü şu anda hiçbir şeye işaret etmeyecek.
Sonra str char'ı çağıracağız, hızlı kahverengi tilki olan dizemizi geçireceğiz ve
q olan tek karakterimizi geçireceğiz.
Olacak olan şey, hızlı kahverengi tilkinin içine bakmak olacak.
Ve ilk kez bir q bulduğunda, o q'nun adresini döndürecektir.
Yani p got char gerçekten str'nin
dördüncü indisine işaret ediyor olacak.
Çünkü t sıfırın altında, h birin altında, e ikinin altında,
boşluk üçün altında, q dördün altında.
Yani p'nin karakteri hızlı kahverengi tilkideki q'ya işaret edecek.
Ve böylece o karakterin dizede tam olarak nerede başladığını görebilirsiniz.
Yani str char'ın ilk argümanı aranacak ilk konumun adresidir, bu da
arama dizesidir.
İkinci argüman aranan karakterdir, aramak istediğiniz karakter, tek
bir karakter.
İkinci bağımsız değişkenin int türünde olmasını bekler.
Yani teknik olarak str char, ikinci argümanı alır.
Ancak c derleyicisi grafiği otomatik olarak bir int'e dönüştürecektir.
Esasen ASCII değerini alacaktır.
Yani aslında q tek karakterini tek bir
char yerine int olarak tanımlayabilirsiniz.
Bu sadece bilmenizi istediğim teknik bir ayrıntı.
Ancak p got char değeri quick brown fox değerine işaret edecektir
çünkü q ile başlayacak ve yazdırmaya çalışırsanız null sonlandırıcıya gidecektir.
Yani bu örneği çalıştırdığınızda aslında hızlı kahverengi tilki olacak.
Bir dizenin tamamında tek bir karakteri bu şekilde arayabilirsiniz.
Str char kullanın, ardından işaretçiyi kullanın ve ardından işaretçiyi görüntüleyin.
Peki bu işaretçiyi nasıl gösteriyorsunuz? Diğer karakterleri görüntülediğiniz gibi printf, yüzde s kullanın.
Yani bu, bir dizenin tamamındaki karakterleri aramak için güzel bir mekanizmadır.
Bir dizenin içinde bir dize aramak istiyorsanız, ki bu bir alt dize olacaktır,
strstr kullanırsınız.
Bu muhtemelen tüm arama işlevleri arasında en kullanışlı olanıdır.
Bir alt dizenin oluşumu için bir dizeyi arar.
Ve alt dizenin bulunduğu ilk dizedeki konuma bir işaretçi döndürür,
str char'a çok benzer, ancak tüm dizeyi arar. Herhangi bir eşleşme bulamazsa null döndürür.
İlk argüman, tıpkı str char gibi aranacak dizedir.
İkincisi, aradığınız alt dize, başka bir dize. İşte bir örnek.
Tek bir karakter aramak yerine bir kelime, bir dize arıyor
olmamız dışında diğerine çok benziyor.
Yani elimizde köpekle eşit olan bir kelime var.
Ve her köpeğin bir günü olduğuna dair bir mesajımız var.
İşaretçimizi tekrar oluşturuyoruz çünkü öyle olması gerekiyor - fonksiyonun döndürdüğü şey bu.
strstr'yi çağırdığımızda, bakmak istediğimiz dizeyi metin olarak iletiriz.
İkinci bağımsız değişken ise bu dizenin içinde aramak istediğimiz sözcüktür.
Böylece, word'de depolanan dizenin ilk geçtiği metni arayacaktır.
Köpek dizesi metnin yedinci karakterinde görünür.
Eğer metne bakarsan.
Metin 6'nın altı köpekle eşit olacak, her şey burada başlıyor.
Böylece işaretçi text artı 6 dog adresini gösterecek ve oradan başlayacak
ve sonra null sonlandırıcıya gidecektir.
Yani köpeğin bir günü var.
Ayrıca arama büyük/küçük harfe duyarlı olduğu için dikkatli olun.
Eğer gerçekten büyük harfle D-O-G yazdıysanız, hiçbir şey bulamayacaksınız,
sadece doğru durumu arayacak.
Ancak bu, alt dizeleri ve dizeleri bulmak için kullanılır, çok kullanışlıdır
çünkü bir programda çoğu zaman bu dize bu dizenin içinde mi diyeceksiniz
çünkü Linux'ta grep kullandıysanız neredeyse grep'e benzer.
Umarım bu mantıklıdır. Bir dizeyi simgeleştirme.
Bir token, biri bir sınırlayıcı ile sınırlandırılmış bir karakter dizisidir, bunu biliyoruz.
Sınırlayıcı herhangi bir şey olabilir, ancak bu dizeye özgü bir şey olmalıdır.
"A" gibi bir sınırlayıcıya sahip olmayın çünkü şimdi bu dizede bir kelimede
geçerli bir şey bulacaktır.
Boşluk veya virgül gibi benzersiz bir şey yapın. Bu, yine, genellikle tek bir dizideki sözcükler
için bir sınır olarak kullanılır.
Yani bir cümleyi kelimelere ayırır, buna tokenize etme denir.
Bu strtok fonksiyonu bir dizeyi belirtmek için kullanılır.
İki argüman gerektirir.
Jetonlanacak dize, boşlukları olan ve sınırlayıcılara sahip olan tüm dizedir.
Ve sonra tüm pozitif sınırlı karakterleri içeren dize.
Sınır olarak neyi belirlemek istediğinizi belirtebilirsiniz.
İşte bir örnek.
Bir karakter dizisi 80 oluşturuyoruz.
Merhaba, nasılsın, senin adın Dash benim adım Dash Jason diyor.
Daha sonra, eksi tire olan sınırlayıcıyı temsil eden sabit
bir dize oluşturuyoruz. Biraz farklı görünüyor, ama yine de eksi, çizgi,
ikisi de çizgi.
Ve sonra token olan işaretçimizi oluşturuyoruz.
Çünkü strtok her bir belirtecimizi
döndürecektir.
Dolayısıyla, strtok'umuzu çağırırsak ve string'i geçirirsek
ve sınırlayıcılarımızı s olarak geçirirsek,
token bulduğu ilk şeye eşit olacaktır.
Yani strtok'u ilk kez çağırdığınızda, hello how are you space'e
eşit olacak ve ardından tire ile eşleşmeyi bulacaktır.
Ve eğer ikinci kez ararsanız,
adımın bu olduğunu yazacak.
Üçüncü kez çağırırsanız, tire işaretlerinden
geçtiği için Jason çıktısı alacaktır.
İşte bu yüzden burada bir while döngüsü var. Belirteç null'a eşit değilken belirteci
yazdır diyoruz.
Ve sonra strtok'u çağırarak bir sonraki belirteci alırız.
İlk parametremiz olarak null ve ikinci parametremiz
olarak s diyoruz ve ardından görüntülüyoruz.
Daha
anlaşılır olacağı için bunu kod blokları halinde inceleyelim.
Hadi şunu inşa edelim. Az önce bu örnek üzerinden geçtik.
Size çıktının ne olduğunu göstermek istiyorum, böylece burada neler olup bittiği anlaşılabilir.
Burada, hello how are you olan ilk belirteci
yazdırdığını göreceksiniz.
Yaptığı ilk şey ilk belirteci bulmak,
yazdırmak, merhaba nasılsın, benim adım ve sonra Jason.
Şimdi merhaba nasılsın var, ilk
çizgiyi buluyor, yazdırıyor. Benim adım bir sonraki simgeyi bulur,
üçüncüsü de Jason'dır. Ancak her bir jetonu almak için jetonu
üç kez çağırmanız gerekir.
İlki str üzerinde tokenize edecektir.
Bir sonrakini null olarak geçebilirsiniz çünkü tekrar bakmak istemezsiniz, sadece bir sonraki belirteci almak istersiniz.
Böylece ikincisine bir null geçirirsiniz ve sadece bir s geçirirsiniz.
Size zaten tok olan str'nin bir sonraki token'ını verecektir.
İşte strtok'u bu şekilde kullanabilirsiniz. Ayrıştırmaya çok yardımcı olur.
Bir şeyi ayrıştırabilir ve belirli sınırları ortaya çıkarabilirsiniz.
Bahsetmek istediğim son fonksiyonlar, dizgi fonksiyonlarını analiz eden fonksiyonlardır.
Bir sürü var, bu yüzden burada küçük bir tablo sundum.
Aşağı, yukarı. Tam olarak düşündüğünüz şeyi yapıyor.
Bir karakterin küçük harf mi yoksa büyük harf mi olduğunu test eder.
Belirli karakterleri test ediyoruz, ancak bunlar dizelerin içinde kullanılıyor.
Bu fonksiyonların her birinin argümanı, aramak istediğiniz karakterdir.
Ve sonra tüm bu fonksiyonlar, karakter test edilen küme
içindeyse int türünde sıfır olmayan bir değer döndürür.
Bu yüzden kelimelerin içini aramak için int karakterlerini içeriye geçireceğiz.
Eğer bir kelimenin içinde büyük harf varsa, bunu bize söyleyecektir ve biz de
bunu tek tek öğeleri karakter olarak ayrıştırmak için kullanabiliriz.
Böylece geri dönüş değerleri doğru veya yanlışa dönüşür, böylece
bunları Boolean olarak da kullanabilirsiniz, bu da güzeldir.
Yani is lower, bir kelime veya karakter
küçük harfe sahipse true değerini döndürür.
İşte size, bir dizenin tamamındaki
harf basamaklarının sayısını sayacak güzel bir örnek.
Şimdi bunu çalıştıralım çünkü bu açık olacaktır,
ancak fark etmeniz gereken şey bir tampon oluşturuyoruz,
giriş tamponumuz ve sonra saymak için üç tamsayı oluşturuyoruz.
Kullanıcıya şu kadar karakterden daha az bir dize
girmesini söylüyoruz, sonra bunu okuyoruz.
Daha sonra belirli karakterleri içerip içermediğini
görmek için bu dizeye bakacağız.
Ve böylece dizideki her bir indise bakarak
bu dize boyunca yineleyeceğiz.
İşte örneğimiz.
Yine buffer, girdileri depolayacak
olan karakter dizimizdir. Bunu doldurmak için scanf kullanacağız.
Dizgimizi boşluk bırakmadan yazmalıyız, bu tek bir dizgidir.
Bunun üzerinden geçeceğiz, tampondaki her bir öğeyi inceleyeceğiz ve sonra
bu karakterlerin orada olup olmadığını görmek için is alpha, is digit
veya is punct fonksiyonlarını çağıracağız
ve sonra bunun doğru veya yanlış dönüp dönmediğine bağlı olarak artacak ve sonra bu dizenin
içinde kaç harf, rakam ve noktalama karakteri olduğunu gösterecektir.
Şunu çalıştıralım.
Sadece birkaç büyük harf ve belki birkaç rakam içeren
bir şey gireceğim.
Sonra return tuşuna bastığımda her şeyi sayacak. Yani direksiyonumun
24 harf, 4 rakam ve 1 noktalama karakteri, iki nokta üst
üste içerdiğini söylüyor.
Bu karakter fonksiyonlarını kullanan küçük, güzel bir programdır
ancak bir dizeyi analiz ederken kullanışlıdır çünkü yaptığınız
şey budur, dizeyi analiz edersiniz, ancak sadece karakter
karakter ilerlersiniz. Teşekkür ederim.