Merhaba, tekrar hoş geldiniz. Yapılarla ilgili olarak bahsetmek istediğim
son şey, yapıların fonksiyonlarla nasıl ilişkili olduğu, yapıları
bir parametreye ve bir fonksiyona argüman olarak nasıl geçirebileceğiniz ve bunun nasıl
daha verimli olduğudur.
Yani fonksiyonlara argüman olarak yapılar.
Aile adında bir yapı bildirdikten
sonra. Bu örnekte adlandırılmış bir aile oluşturacağız,
bu yapıyı bir fonksiyona argüman olarak nasıl aktaracağız.
Bu yüzden Aile adında bir yapımız var.
Burada bir grup karakter dizimiz
var isim, baba ve anne ve sonra bir int yaşımız var.
Bu bizim yapı tanımımız.
Bunun bir yapı olduğunu biliyoruz çünkü struct anahtar sözcüğünün ardından küme parantezlerimiz
ve benzeri etiket adımız var.
Şimdi bu yapıyı siblings adlı bir fonksiyona
nasıl aktaracağız?
Bunu tıpkı yapıyı bildirdiğiniz gibi yaparsınız,
parametre adı olarak türü söylersiniz.
Çok basit. Yani bu durumda Boolean kardeşlerimiz var.
Siblings bir Boolean döndürüyor.
Ve iki parametre alıyor, iki yapı parametresi.
struct ailesi türü olan struct türünü tanımlamanız gerekir.
Şimdi daha gelişmiş c'de, aslında bu struct üzerinde
bir typedf yapabilir ve ona başka bir isim verebilirsiniz ve buradaki ismi kısaltabilirsiniz,
ancak typed'lerden bahsetmedik.
Bu muhtemelen daha iyi olurdu.
Ancak bunu gerçekten bu şekilde yapmanız gerekir. Diğer parametrelerde olduğu gibi struct
ailesi olan tüm türü ve ardından değişken adını tanımlamanız gerekir.
Burada üye bir ve üye iki olmak üzere iki parametre giriyoruz.
İkisi de tip yapı ailesinden.
Daha sonra fonksiyonumuzun içinde, üyelere erişmek istersek,
normal şekilde erişiriz.
Üye bir ve üye iki, işaretçi değildir, bu nedenle tire sonra büyüktür ifadesini kullanmayız, bunu yalnızca işaretçilerde
yaparız çünkü neye işaret ettiklerini görmek için onları referans dışı bırakmamız gerekir.
İşaretçi olmadıkları için sadece nokta yapabiliriz. Yani üye bir nokta anne, üye iki nokta anne.
Üye bir nokta anne ve anne iki nokta anne karakter
dizileridir ve karakter dizileri esasen işaretçilerdir.
Böylece bunları str karşılaştırmasına aktarabiliriz. Str karşılaştırması, aynı olmaları durumunda eşittir sonucunu
verecektir. Yani burada yaptığımız şey, üye bir anne ile üye iki
annenin aynı olup olmadığını kontrol etmektir. Eğer öyleyse, true değerini döndüreceğiz.
Çünkü eğer ikisi de aynı isme sahipse ve bu gerçekten
soyadı olacaksa, o zaman kardeştirler.
Oldukça basit.
Fonksiyon bildiriminde struct tipi
olduğu sürece fonksiyonlara argüman aktarmak kolaydır.
Yani bu fonksiyon, yine, her biri aile tipinde bir yapı olan iki parametreye
sahiptir.
Peki ya fonksiyon argümanları olarak yapılara işaretçiler kullanmak istersek ne olacak?
Daha önce de belirttiğim gibi, değer ve c ile geçiş yaptığımız
için bunu yapmak daha iyidir.
Değere göre geçiş yaptığınızda kopyalarsınız.
Çok fazla veri içeren bir yapınız varsa, argüman
olarak çok sayıda büyük yapı varsa, bu
yapıdaki her şeyi asıl işleve kopyalamanız
gerekir.
Bu yüzden bu büyük yapıları kopyalamak
biraz zaman alabilir.
Eğer bir işaretçiniz varsa, tek yapmanız gereken adresi kopyalamaktır
ki bu çok daha hızlıdır. Bu nedenle, bellek tüketiminden
ve tüm yapıların kopyalanması için gereken zamandan kaçınmak için
yapılara işaretçiler parametre ve işlev olarak kullanılır.
Şimdi, küçük bir yapınız varsa, önemli değil, ancak
kesinlikle büyük olan işaretçileri ve yapıları kullanmak istersiniz.
Peki bu durumda ne yaparsınız, hala yapı türlerinin adını belirtirsiniz, sadece
yıldız işaretini önceden koyarsınız,
çok basit. Ve yapının içindeki verilerin
hiçbirinin değişmesini istemiyorsanız, yapı türünden önce sabit kullanabilirsiniz.
Adresin değişmesini istemiyorsanız, struct aile işaretçisinden sonra sabit koyarsınız.
Ama burada da aynı şeyi yapıyoruz. Ancak şimdi buna farklı bir şekilde
erişeceğiz çünkü artık bir işaretçi olduğu için nokta kullanmak yerine
erişmek için bu yeni sembol olan tire büyüktür'ü kullanabiliriz.
Burada nokta kullanmak zorunda değiliz. Çünkü unutmayın, işaretçilerin
önce referansını kaldırmanız gerekir, bu yüzden parantez içine koymanız gerekir, işaretçinin referansını
kaldırmak daha fazla sözdizimidir, daha sonra noktayı parantezin dışına koymanız gerekir, çünkü daha yüksek
önceliğe sahiptir, tire kullanmak daha büyük olandan çok daha kolaydır.
Tire ve anneden büyük, tire ve anneden
büyük her ikisi de işaretçidir, str karşılaştırmasında geçirilebilirler.
Eğer aynıysa, true değerini döndürür. Aksi takdirde, false döndürür, oldukça basittir.
Yapının üyeleri üzerinde herhangi bir değişikliğe izin vermek istemiyorsanız,
bahsettiğim gibi const değiştiricisini de kullanabilirsiniz.
Yapı neye işaret ediyorsa, const işaretini işaretçinin önüne koyarsınız.
Aslında const kelimesini aileden önce de koyabilirsiniz.
Bu durumda, ailenin bir tipi vardır.
Yani burada gerçekten
construct family veya struct family const pointer olacaktır.
Ve sonra yine aynı şekilde erişin, hiçbir şeyi değiştirmiyorsunuz. Yani gitmeye hazırsın.
Derleyici şikayet etmeyecektir.
Adresin kendisinde herhangi bir değişikliğe izin vermek istemiyorsanız sabit değiştiriciyi
de kullanabilirsiniz.
Bu yapıları değiştirmeye yönelik herhangi bir girişim derleme sırasında bir hata mesajına neden olacaktır.
Yani burada aile yıldızı dersiniz
ve yıldızdan sonra sabiti koyarsınız.
Bu da p-member'ın değerini, yani bir adres olan
işaretçinin değerini değiştiremeyeceğinizi söylüyor.
Ancak yine, bu çok kullanışlı değildir çünkü değerle
geçtiğinizde, aslında adresin bir kopyasını geçirmiş olursunuz.
Yani bu gereksiz, bunu yapmanıza gerek yok ama yapabilirsiniz.
Ve burada, yine, p üyesinin ne olduğunun adresini değiştirebilmek istiyorsunuz.
Ve bu durumda, eşit olup olmadıklarını görmek için zaten verilere erişiyorsunuz.
Her parametre tanımındaki dolaylama operatörü artık constant anahtar
sözcüğünün önünde yer almaktadır.
Bu yıldız işareti, parametre adının önünde değil.
İşaretçilerde saklanan adresi değiştiremezsiniz çünkü yıldız işaretinden sonradır.
Parametre adı türünün önündeyse, işaret ettiği
gerçek şeyi değiştirebilmek istersiniz.
Parametre adının önünde bu dolaylama operatörü olsaydı, önündeki sabitte
ne olurdu, bu, işaret ettiği şeyi değiştirebilmek
istediğiniz anlamına gelirdi. Bu sadece adresi söylemek.
Dolayısıyla, işaretçilerde saklanan adresi değiştiremezsiniz.
Burada korunan işaretçilerdir, işaret ettikleri yapılar
değil, tıpkı sabit ve diğer işaretçi parametreleri gibi, yapılarla bir fark yoktur.
Gösterici olan bir işlevden bir yapı döndürmek istiyorsanız,
işlev prototipinin bu dönüş değerini bildirimde normal şekilde belirtmesi
gerekir.
Yani burada benim eğlenceli işaretçime
vurun ya da vurmayın demek zorundasınız,
fark etmez. Bu, date türünde bir yapı döndüren ve argüman almayan bir fonksiyonun
prototipidir, bir fonksiyondan bir yapı döndürmek çok kolaydır. Peki bunun değeri nedir?
Artık bir fonksiyondan birden fazla
eleman veya bir veri öğesi döndürebiliriz.
Bir struct döndürüyorsanız, 10 değer, 10 farklı veri öğesi döndürebilirsiniz.
Ne kadar havalı. struct, bir fonksiyondan birden fazla döndürmenize olanak tanır.
Çok, çok değerli.
Bu nedenle, sadece yapı yerine bir yapıya işaretçi döndürmek genellikle daha uygundur.
Bir yapıya işaretçi döndürdüğünüzde, bu yapı heap üzerinde oluşturulur, çünkü tüm
işaretçiler heap üzerinde oluşturulur.
Bu, biraz daha uzun süre ortalıkta olacağı anlamına geliyor.
Bu da onu silebileceğiniz ve istediğiniz zaman yönetebileceğiniz anlamına gelir.
Bu örnekte, funds adında bir yapı oluşturuyoruz.
Banka adlı bir karakter dizisi içerir,
bir çift içerir, belirli bir uzunlukta kaydedilmiş adlı
başka bir karakter içerir. Sadece eğlence uzunluğunun 50'ye eşit olduğunu varsaydım.
Ve sonra çift kaydedilmiş bir tane var.
Bu yapıyı parametre olarak alan sum adında bir fonksiyonumuz var.
Ve bunun içinde yaptığımız tek şey, ilk yapıdaki
banka fonu artı tasarruf fonunu iade etmek ve bu da bankalarında
sahip oldukları tutarı iade edecek.
Bu örnekte, toplam sadece bir çifttir.
Bir işaretçi döndürmüyoruz. Parametre olarak sadece bir işaretçi alıyoruz.
Ana fonksiyonumuzda, struct funds türünde stan adında
bir yapı değişkeni oluşturuyoruz.
Bunu bazı değerlerle başlatıyoruz ve ardından toplamı çağırarak
toplamı yazdırıyoruz. Ve bu yapıyı herhangi bir değişkeni geçirdiğimiz gibi geçiririz.
İşaretçi olmadığı için referansını kaldırmamız gerekmez. Özel bir şey yapmamıza gerek yok.
Sadece fonksiyon bildiriminde struct tipinin orada olduğundan emin oluruz, ancak
diğer her şey normal görünür.
Birkaç hatırlatma.
Daha önce yapıları bir fonksiyona aktarırken her zaman işaretçi kullanmanız gerektiğinden bahsetmiştim.
Neden? Çünkü unutmayın, c'nin eski sürümleri
yapıların aktarılmasına
izin vermez, ancak işaretçilere izin verir.
Böylece her türlü geriye dönük uyumluluktan kaçınabilirsiniz.
Eğer c'nin eski bir sürümünü kullanıyorsanız, programınız çalışacaktır.
Dolayısıyla, zaman kopyalama nedeniyle sadece
bu tek adresi geçmek de daha verimlidir.
Ancak bunu yaparsanız, bir işlevin içindeki bir yapıya işaretçi olan
bir parametre geçirirseniz, verileriniz için daha az koruma sağlar.
Dolayısıyla, çağrılan işlevdeki bazı işlemler yanlışlıkla orijinal yapıdaki
verileri etkileyebilir.
İşte bu noktada const niteleyicisini kullanmak istersiniz.
Ve const'ı gerçek türden önce kullanırsınız,
yıldız işaretinden sonra ve parametre adından
önce değil, türden önce.
Yapıları geçirmenin avantajı argümanlardır, fonksiyon
orijinal verilerin kopyalarıyla çalışır.
Orijinal verilerle çalışmaktan daha güvenlidir.
Dolayısıyla, bir işaretçi olmayan bir yapıyı argüman olarak iletmek istediğiniz tek zaman budur.
Ve programlama tarzı biraz daha net olma eğilimindedir.
Yapısal bir işaretçiyi argüman olarak geçirmenin aksine yapıları argüman olarak geçirmenin
ana dezavantajları, eski uygulamaların kodu işleyememesi,
zaman ve alan israfı ve özellikle her üye için çok fazla kopyalama
yapmak zorunda olduğumuz büyük yapılara sahip
olduğunuzda savurganlıktır.
Bu yüzden bunu aklınızda tutun.
Çoğunlukla yapılara işaretçi aktarmak istersiniz,
bu çok daha etkilidir ve zaman kazandırır.
Programcılar verimlilik nedeniyle yapı işaretçilerini fonksiyon argümanı olarak kullanırlar
ve gerektiğinde sabit kullanırlar. Ve yapmak istediğiniz kombinasyon budur.
Koruma konusunda endişeleriniz varsa, verimlilik için
işlev işaretçisini kullanın ve ardından
const const kullanın, böylece işlevin içinde hiçbir
şey mahvolmaz, tıpkı normal işaretçiler gibi,
ancak işaretçilerle büyük yapılar nedeniyle verimlilik daha da
önemlidir.
Yapıları değere göre aktarmak genellikle küçük yapılar için yapılır ve bunlar
düşünmek istediğiniz kurallardır.
Küçük olduğu sürece işaretçi olmayan bir yapı aktarmak sorun değildir.
Yine, yapılarla ilgili bazı önemli kavramlar ve işaretçilerin
parametre, argüman olarak geçirilmesi ve işaretçilerin
döndürülmesi. Artık bunların bir kısmını uygulamaya
başlayabiliriz. Birçok örnek sunuyoruz. Kavramları anlıyoruz. Sözdizimini anlıyoruz.
Şimdi size bunu gerçekten yapmanızı sağlayacak, sözdizimini ezberlemenizi sağlayacak birkaç zorluk
sunmak istiyorum, öyle ki artık programda bir yapı oluşturmak istediğinizde bunu nasıl yapacağınızı
avucunuzun içi gibi biliyorsunuz.
Bu nedenle, önümüzdeki birkaç dersimizde yapılarla ilgili konuştuğumuz
tüm bu şeylere aşina olmanızı sağlamak için birkaç zorluğumuz olacak.
Teşekkür ederim.