{"id":286,"date":"2015-02-10T18:47:06","date_gmt":"2015-02-10T16:47:06","guid":{"rendered":"http:\/\/ozenozkaya.com\/blog\/?p=286"},"modified":"2017-07-07T19:55:35","modified_gmt":"2017-07-07T16:55:35","slug":"gomulu-sistemler-23-gomulu-c-yapilar","status":"publish","type":"post","link":"http:\/\/ozenozkaya.com\/blog\/?p=286","title":{"rendered":"G\u00f6m\u00fcl\u00fc C &#8211; 12 : Yap\u0131lar"},"content":{"rendered":"<p>Merhabalar, bug\u00fcnk\u00fc yaz\u0131mda C dilindeki yap\u0131lardan bahsedece\u011fim. Ancak bu bahsedi\u015f esasen bir girizgah \u015feklinde olacak. \u00c7\u00fcnk\u00fc yap\u0131sal bir dil olan C dilinde, tasar\u0131m\u0131n temel yap\u0131 ta\u015f\u0131, bir manada tu\u011flas\u0131, s\u0131vas\u0131 yap\u0131lar oldu\u011fundan bu yap\u0131lar\u0131 tek bir yap\u0131da anlatmak olduk\u00e7a zor olacakt\u0131r. Bunu yapmaya \u00e7al\u0131\u015f\u0131p eksik \u00e7ok say\u0131da nokta b\u0131rakmak yerine, \u00f6nce \u00e7ok derinlere inmeden sizlere yap\u0131sal tasar\u0131m elemanlarn\u0131 ve bunlar\u0131n temel psikolojilerini aktar\u0131p, ard\u0131ndan ilerleyen konularda bunlar\u0131n sanatsal kullan\u0131mlar\u0131n\u0131 sunman\u0131n pe\u015findeyim. Bunun daha faydal\u0131 olaca\u011f\u0131na inan\u0131yorum. Dilerim sizlere azami fayday\u0131 sa\u011flayacak format\u0131, bir \u015fekilde tutturabilirim \ud83d\ude42<\/p>\n<p>Bence bir yaz\u0131, lap diye konuya dalmadan \u00f6nce ne vadetti\u011fini anlatmal\u0131, amac\u0131n\u0131 a\u00e7\u0131klamal\u0131d\u0131r. Ben de struct, enum, union diye ba\u015flamadan \u00f6nce sizlere bunlarla ne yapaca\u011f\u0131m\u0131z\u0131 aktarmaya \u00e7al\u0131\u015faca\u011f\u0131m. Haydi ba\u015flayal\u0131m&#8230;<\/p>\n<p>Daha \u00f6nce de s\u00f6yledi\u011fim gibi, bir program\u0131n amac\u0131, ger\u00e7ek hayattaki bir problemi \u00e7\u00f6zmektir. G\u00f6m\u00fcl\u00fc sistemlere \u00f6zg\u00fc olarak sunulan \u00e7\u00f6z\u00fcm, ger\u00e7ek hayat\u0131 fiziksel olarak do\u011frudan etkiler. Yani bir g\u00f6m\u00fcl\u00fc sistem, genellikle hayatla do\u011frudan temas halindedir. Ger\u00e7ek hayattaki bu problemin \u00e7\u00f6z\u00fclebilmesi i\u00e7in, sisteme problemin ve \u00e7\u00f6z\u00fcm\u00fcn tan\u0131m\u0131n\u0131n, \u00e7ok iyi yap\u0131lmas\u0131 gerekir. \u0130\u015fte ger\u00e7ek hayat\u0131n unsurlar\u0131n\u0131n, bizim tasar\u0131m ortam\u0131m\u0131za aktar\u0131lmas\u0131 i\u015fine modelleme denir. Modelleme, m\u00fchendisli\u011fin en temel konular\u0131ndan biri olmakla birlikte, tasar\u0131m\u0131n olmazsa olmaz\u0131d\u0131r. Laf\u0131 uzatmayay\u0131m. C dilinin yap\u0131sal bir dil olarak s\u0131n\u0131fland\u0131r\u0131lmas\u0131n\u0131n sebebi, modellemenin yap\u0131lar ile yap\u0131lmas\u0131d\u0131r. Bu vesileyle bir dile s\u0131n\u0131f\u0131n\u0131 verecek kadar \u00f6nemli bir konuya ge\u00e7ti\u011fimizi belirtmek istiyorum \ud83d\ude42 Yap\u0131lar\u0131 hakk\u0131yla kullanmay\u0131 bilmeden, kar\u015f\u0131la\u015ft\u0131\u011f\u0131m\u0131z problemlere g\u00fczel \u00e7\u00f6z\u00fcmler \u00fcretebilmemiz m\u00fcmk\u00fcn olmayacakt\u0131r. Bu sebeple l\u00fctfen, bu yaz\u0131dan ya da ba\u015fka bir kaynaktan, yap\u0131lar\u0131 hakk\u0131 ile \u00f6\u011frenmeye, hakk\u0131yla biliyorsan\u0131z bile bu i\u015fi bir ad\u0131m da olsa ileriye ta\u015f\u0131maya gayret edininiz.<\/p>\n<p>\u015eimdi, C dilindeki struct, enum ve union&#8217;un suyunu s\u0131kmaya ba\u015flayal\u0131m. Bakal\u0131m neler \u00e7\u0131kacak \ud83d\ude42<\/p>\n<p><strong>STRUCT<\/strong><\/p>\n<p>Struct, g\u00f6m\u00fcl\u00fc yaz\u0131l\u0131mda \u00e7ok \u00e7ok \u00e7ok b\u00fcy\u00fck \u00f6neme sahip. Bu sebeple aff\u0131n\u0131za s\u0131\u011f\u0131narak, uzatarak da olsa basit\u00e7e a\u00e7\u0131klamaya \u00e7al\u0131\u015faca\u011f\u0131m. Bunu yaparken diziler ile analoji kurarak struct&#8217;u\u00a0sizlere a\u00e7\u0131klamaya \u00e7al\u0131\u015faca\u011f\u0131m.<\/p>\n<p>Bildi\u011finiz \u00fczere diziler, ayn\u0131 veri tipindeki birden fazla de\u011fi\u015fkeni bellekte saklamak i\u00e7in kullan\u0131l\u0131rlar. Ancak bu veri g\u00fcruhu ya da veri dizisi bellekte saklan\u0131rken yan yana saklan\u0131r. Yani \u00e7ok s\u0131ra d\u0131\u015f\u0131 bir durum yok ise bir dizinin t\u00fcm elemanlar\u0131 belle\u011fe ard\u0131 s\u0131ra yerle\u015fir. Dizi tan\u0131m\u0131n\u0131n en \u00f6nemli iki \u00f6zelli\u011fini bu ba\u011flamda tekrar s\u0131ralarsak :<\/p>\n<ol>\n<li>Dizinin t\u00fcm elemanlar\u0131n\u0131n ayn\u0131 veri tipinde olmas\u0131<\/li>\n<li>Dizinin elemanlar\u0131n\u0131n belle\u011fe ard\u0131\u015f\u0131l yerle\u015ftirilmesi.<\/li>\n<\/ol>\n<p>Daha dizilere de\u011finmedim ama, bu iki \u00f6zellik diziler hakk\u0131nda ayan beyan g\u00f6r\u00fclen ilk iki \u00f6zelik. Struct veri tipi de (dizilere benzer \u015fekilde) bir veri toplulu\u011funu ifade eder ancak bu topluluktaki her bir veri (de\u011fi\u015fken), farkl\u0131 tipte olabilir. Yine struct i\u00e7indeki bir veriye ( yani struct eleman\u0131na), dizi indeksi gibi bir indeks yerine, bu\u00a0verinin ismiyle eri\u015filir.<\/p>\n<p>Struct, birbiriyle ilintili birden fazla farkl\u0131 kavram\u0131 birle\u015ftirerek bir context(konu) \u00e7er\u00e7evesinde toplamaya yarayan \u00e7ok g\u00fc\u00e7l\u00fc bir modelleme arac\u0131d\u0131r. G\u00fc\u00e7l\u00fc olmas\u0131n\u0131n sebebi ise, farkl\u0131 veri tiplerini ayn\u0131 yap\u0131 i\u00e7inde paketleyebilmesinden gelir.<\/p>\n<p>Struct&#8217;un bellek kullan\u0131m\u0131 dizilere benzerdir yani struct i\u00e7indeki elemanlar belle\u011fe ard\u0131\u015f\u0131l olarak yerle\u015fir. Ancak e\u011fer struct i\u00e7indeki elemanlar, kodlaman\u0131n yap\u0131ld\u0131\u011f\u0131 hedef platformun adres geni\u015fli\u011fine tam oturmuyorsa, <a href=\"http:\/\/en.wikipedia.org\/wiki\/Data_structure_alignment\" target=\"_blank\" rel=\"noopener\">struct alignment problem<\/a> denilen problem ortaya \u00e7\u0131kar. Bu durumda, struct elemanlar\u0131 bellek adresinin bir veya bir ka\u00e7\u0131n\u0131 tam olarak dolduramad\u0131\u011f\u0131ndan, derleyici bu sorunu gidermek i\u00e7in arada kayd\u0131rmalar ya da bo\u015f yer b\u0131rakmalar gibi operasyonlara gider. Bu durumun bilincinde olmakta b\u00fcy\u00fck faydalar var.<\/p>\n<p>Struct tan\u0131m\u0131 birde farkl\u0131 \u015fekilde yap\u0131lailiyor. Dilim d\u00f6nd\u00fc\u011f\u00fcnce her birini anlatmaya \u00e7al\u0131\u015faca\u011f\u0131m.<\/p>\n<p>Etiketlenmi\u015f\u00a0(tagged) struct tan\u0131m\u0131 a\u015fa\u011f\u0131daki gibi yap\u0131l\u0131r:<\/p>\n<pre class=\"lang:c decode:true\">struct Part {\r\n int32_t number;\r\n int32_t on_hand;\r\n char name [ NAME_LEN + 1 ] ;\r\n double_t priceInEU;\r\n};<\/pre>\n<p>Yukar\u0131daki \u00f6rnek kodda, yeni tan\u0131mlanan struct&#8217;\u0131n etiketi Part&#8217;d\u0131r. Ve bu struct&#8217;un elemanlar\u0131 s\u0131ras\u0131yla number, on_hand, name ve price&#8217;d\u0131r. Bir struct i\u00e7indeki elemanlar\u0131n t\u00fcm\u00fcn\u00fcn farkl\u0131 tipte olabilece\u011fini ancak bunun bir zorunluluk olmad\u0131\u011f\u0131n\u0131 l\u00fctfen unutmay\u0131n\u0131z.<\/p>\n<p>Bu noktada, &#8220;struct Part&#8221; tan\u0131m\u0131n\u0131n, bir veri tipi oldu\u011funu ve &#8220;struct Part&#8221; tipinden de\u011fi\u015fkenlerin yarat\u0131labilece\u011fini unutmay\u0131n\u0131z. \u00d6rne\u011fin &#8220;sruct Part MonopolyGame;&#8221; dedi\u011fimizde Part tipinde bir monopoly oyunu yaratm\u0131\u015f oluruz. Ve \u00f6rne\u011fin bu oyunun fiyat\u0131na \u015f\u00f6yle eri\u015febiliriz.<\/p>\n<pre class=\"lang:c decode:true\">struct Part {\r\n int32_t number;\r\n int32_t on_hand;\r\n char name [ NAME_LEN + 1 ] ;\r\n double_t priceInEU;\r\n};\r\n\r\nint main()\r\n{\r\n struct Part MonopolyGame;\r\n MonopolyGame.priceInEu = 23.50;\r\nreturn 0;\r\n}<\/pre>\n<p>Etiketli struct tan\u0131n\u0131mda, struct tipini tan\u0131mlarken ayn\u0131 zamanda de\u011fi\u015fkenleri de tan\u0131mlamak m\u00fcmk\u00fcnd\u00fcr.<\/p>\n<pre class=\"lang:c decode:true\">struct Student {\r\nint32_t nClasses;\r\nchar name [ NAME_LEN + 1 ] ;\r\ndouble_t gpa;\r\n} joe, sue, mary;<\/pre>\n<p>G\u00f6rd\u00fc\u011f\u00fcn\u00fcz gibi yukar\u0131daki kodda joe, sue ve mary isimli \u00fc\u00e7 \u00f6\u011frenci tan\u0131mlanm\u0131\u015f. Tabi bu tan\u0131mlar\u0131 yukar\u0131daki \u015fekilde yapmak, sonradan yeni elemanlar tan\u0131mlanamayaca\u011f\u0131 anlam\u0131na gelmez. Pekala da sonras\u0131nda da yeni elemanlar tan\u0131mlayabiliriz.<\/p>\n<pre class=\"lang:c decode:true \">struct Student mike, carla;<\/pre>\n<p>Yukar\u0131daki y\u00f6nteme ek olarak, struct tipi tan\u0131mlamadan, struct \u015feklinde de\u011fi\u015fkenler tan\u0131mlamak da m\u00fcmk\u00fcnd\u00fcr. Ancak bu durumda, ayn\u0131 tipten yeni de\u011fi\u015fkenler tan\u0131mlamak m\u00fcmk\u00fcn olmayacakt\u0131r. Ayn\u0131 zamanda bunlar\u0131n bir fonksiyona arg\u00fcman olarak verilmesi de kolay yoldan m\u00fcmk\u00fcn olmayacakt\u0131r. Esasen bu da ak\u0131ll\u0131ca de\u011ferlendirilip, kullan\u0131m\u0131 k\u0131s\u0131tlama ama\u00e7l\u0131 olarak kullan\u0131labilecek bir \u00f6zelliktir. Ancak bu durum, tekrar kullan\u0131labilirli\u011fi de \u00f6ld\u00fcrece\u011finden dikkatlice kullan\u0131lmal\u0131d\u0131r. \u015eimdi bu tarif etti\u011fim duruma bir \u00f6rnek vereyim:<\/p>\n<pre class=\"lang:c decode:true\">struct {\r\nint32_t nClasses;\r\nchar name [ NAME_LEN + 1 ] ;\r\ndouble_t gpa;\r\n} alice, bill; \/\/ alice and bill are of the same type, but not the same as struct Student\r\n\r\nstruct {\r\nint32_t nClasses;\r\nchar name [ NAME_LEN + 1 ] ;\r\ndouble_t gpa;\r\n} charlie, daniel; \/\/ charlie and daniel are the same type as each other, but not anyone else<\/pre>\n<p>Temel anlamda struct tan\u0131m\u0131n\u0131 \u00f6\u011frendik. \u015eimdi bir sonraki seviyeye ge\u00e7elim \ud83d\ude42<\/p>\n<p><strong>Typedef&#8217;in Struct ile Kullan\u0131lmas\u0131<\/strong><\/p>\n<p><em>typedef<\/em>, programlama yapan kimselerin kendi veri tiplerini tan\u0131mlayabilmelerini sa\u011flar. Bu veri tipi, basit veri tipi (uint8_t gibi) olabilece\u011fi gibi; complex (birden fazla \u00a0veri tipini ayn\u0131 anda i\u00e7inde bar\u0131nd\u0131ran) yap\u0131da da olabilir.<\/p>\n<p>\u0130yi de yaz\u0131l\u0131mc\u0131 kendi veri tipini tan\u0131mlamaya neden ihtiya\u00e7 duysun ki? \u00c7\u00fcnk\u00fc temel veri tipleri sadece genel ama\u00e7lar i\u00e7indir. Ve modellenen problemler genellikle \u00f6zel problemlerdir ve bu probleme \u00f6zg\u00fc bilgi setlerini bar\u0131nd\u0131r\u0131rlar. \u0130\u015fte bu bilgi setlerini modeleyebilmek ve bu modeli tekrar kullanabilmek i\u00e7in typedef s\u00f6zc\u00fc\u011f\u00fcnden faydalan\u0131r\u0131z.<\/p>\n<p>Hemen \u00f6rnek verelim:<\/p>\n<pre class=\"lang:c decode:true \">typedef int Integer;\r\nInteger nStudents, nCourses, studentID;<\/pre>\n<p>Yukar\u0131da Integer olarak adland\u0131r\u0131lan, asl\u0131nda int tipinin ayn\u0131s\u0131 olan yeni bir veri tipi tan\u0131mlanarak bu veri tipindn 3 adet de\u011fi\u015fken yarat\u0131lm\u0131\u015ftr. B\u00f6yle bir \u015fey ilk bak\u0131\u015fta sa\u00e7ma gelebilir ancak burada b\u00fcy\u00fck ibretler vard\u0131r. Misal verecek olusak:<\/p>\n<ol>\n<li>Integer isimli bir veri tipi, okunabilirlik a\u00e7\u0131s\u0131ndan int&#8217;den \u00e7ok daha iyidir.<\/li>\n<li>Gerek duyulursa typedef ileride farkl\u0131 \u015fekilde de\u011fi\u015ftirilebilir. \u00d6rne\u011fin &#8220;typedef long Integer&#8221;. Bu sayede Integer tipinden tan\u0131mlanm\u0131\u015f t\u00fcm de\u011fi\u015fkenler bundan etkilenir. (Bunun dezavantaj olu\u015fturdu\u011fu durumlar da vard\u0131r)<\/li>\n<\/ol>\n<p>Ayr\u0131ca bu sayede, \u00f6rne\u011fin C dilini T\u00fcrk\u00e7ele\u015ftirmek bile m\u00fcmk\u00fcnd\u00fcr \ud83d\ude42<\/p>\n<p>Hemen misal verelim:<\/p>\n<pre class=\"lang:c decode:true\" title=\"turkce_c.h\">#include &lt;stdio.h&gt;\r\n#include &lt;stdint.h&gt;\r\n\r\ntypedef int Sayi;\r\ntypedef char Karakter;\r\ntypedef long Uzun;\r\ntypedef float OndalikliSayi;\r\ntypedef double UzunOndalikliSayi;\r\ntypedef void HerhangiVeri\r\n\r\n#define ISARETSIZ unsigned\r\n#define EGER if\r\n#define OYLE_DEGILSE else\r\n#define OLDUGU_SURECE for\r\n#define OLDUKCA while\r\n\r\n#define ANA_PROGRAM main\r\n\r\n#define BASLIGI_EKLE include\r\n\r\n#define FONKSIYONDAN_CIK_VE_ILET_SU_DEGERI return\r\n\r\n#define YAZDIR printf<\/pre>\n<pre class=\"lang:default decode:true\">#BASLIGI_EKLE \"turkce_c.h\"\r\n\r\nSayi ANA_PROGRAM ()\r\n{\r\n  Uzun Sayi bizimSayac = 0;\r\n  OLDUGU_SURECE(bizmSayac = 0; bizimSayac&lt;2015; bizimSayac++)\r\n  {\r\n    EGER(bizimSayac == 1920 )\r\n    {\r\n       YAZDIR(\"Bu ne guzel gundur :)\");\r\n    }\r\n    OYLE_DEGILSE EGER(bizimSayac == 1923)\r\n    {\r\n       YAZDIR(\"Bu da cok guzel gundur :)\");\r\n    }\r\n    OYLE_DEGILSE\r\n    {\r\n       YAZDIR(\"Hedef 2023 :P\");\r\n    }\r\n  }\r\n  FONKSIYONDAN_CIK_VE_ILET_SU_DEGERI(42);\r\n}<\/pre>\n<p>Epey e\u011flendik ama art\u0131k C \u00fczerine kurulmu\u015f\u00a0k\u00fc\u00e7\u00fck bir programlama dilimiz oldu. Hem de\u00a0 T\u00dcRK\u00c7E!<\/p>\n<p>T\u00fcm bu e\u011flenceye ek olarak, typedef tan\u0131m\u0131n\u0131n as\u0131l g\u00fcc\u00fc, kompleks veri tiplerinin tan\u0131mlanmas\u0131nda ortaya \u00e7\u0131kar. Bu da tam olarak struct&#8217;\u0131 anlatmaktad\u0131r.<\/p>\n<p>Di\u011fer de\u011fi\u015fkenler i\u00e7in ge\u00e7erli olan scope kavram\u0131, struct i\u00e7in de aynen ge\u00e7erlidir. Typedef olsun ya da olmas\u0131n, struct tipi tan\u0131mland\u0131\u011f\u0131 yerin scope&#8217;u kadarl\u0131k bir b\u00f6lgede tan\u0131ml\u0131 olur. Ne demek istiyorum? Misal typedef struct ile yap\u0131lan bir veri tipi tan\u0131m\u0131 bir fonksiyonun i\u00e7inde yap\u0131ld\u0131ysa, o de\u011fi\u015fken tipi ancak o fonksiyonun i\u00e7inde kullan\u0131labilecektir. Her yerde kullan\u0131lmas\u0131n\u0131 istedi\u011finiz bir veri tipi tan\u0131mlamak i\u00e7in, onu h dosyas\u0131nda tan\u0131mlaman\u0131z yeterli olacakt\u0131r. Bu sayede o h dosyas\u0131n\u0131 include ile ekleyen her c dosyas\u0131, tan\u0131mlanan bu yeni veri tipini kullanabilecektir.<\/p>\n<p>\u015eimdi bizim \u00f6\u011frenci \u00f6rne\u011fini typedef ile yapal\u0131m.<\/p>\n<pre class=\"lang:c decode:true\">#define NAME_LEN (20)\r\ntypedef struct Student {\r\nint32_t nClasses;\r\nchar name [ NAME_LEN + 1 ] ;\r\ndouble_t gpa;\r\n} Student;<\/pre>\n<p>Art\u0131k, Student tipi yeni bir veri tipi olarak tan\u0131mland\u0131\u011f\u0131ndan, Student tipinden yeni de\u011fi\u015fkenler yarataca\u011f\u0131m\u0131z zaman art\u0131k bir daha struct yazmaya gerek kalmaks\u0131z\u0131n de\u011fi\u015fken tan\u0131m\u0131 yapabilece\u011fiz. Misal \u015f\u00f6yle:<\/p>\n<pre class=\"lang:c decode:true\">Student phil, georgina;<\/pre>\n<p>Yukar\u0131daki \u00f6rnekte, struct&#8217;un etiketi ile veri tipi ayn\u0131 tan\u0131mlanm\u0131\u015ft\u0131r. Bu m\u00fcmk\u00fcn olmakla birlikte zorunlu de\u011fildir. A\u015fa\u011f\u0131daki tan\u0131m, yukar\u0131daki ile ayn\u0131d\u0131r.<\/p>\n<pre class=\"lang:default decode:true\">typedef struct {\r\nint32_t nClasses;\r\nchar name [ NAME_LEN + 1 ] ;\r\ndouble_t gpa;\r\n} Student;<\/pre>\n<p>Ben genelde struct tan\u0131mlar\u0131n\u0131 yukar\u0131daki gibi yap\u0131yorum. Kullan\u0131m\u0131 daha kolay geliyor \ud83d\ude42 Ayn\u0131 zamanda kod bence daha anla\u015f\u0131l\u0131r oluyor ancak bu k\u0131sm\u0131 tart\u0131\u015fmaya tamamen a\u00e7\u0131k bir yorum.<\/p>\n<p><strong>Struct&#8217;a \u0130lk De\u011fer Atamas\u0131 Yapmak ve Struct&#8217;lar\u0131n Birbirine Atanmas\u0131<\/strong><\/p>\n<p>Struct tipinde olan de\u011fi\u015fkenlere de farkl\u0131 \u015fekillerde ilk de\u011fer atamas\u0131 yap\u0131labilir. S\u00fcsl\u00fc parantez i\u00e7inde, her bir eleman s\u0131ras\u0131 ile virg\u00fcl ile ayr\u0131larak ilk de\u011fer atamas\u0131 yapmak m\u00fcmk\u00fcnd\u00fcr. Misal verelim:<\/p>\n<pre class=\"lang:c decode:true\">Student john = { 3, \"John Doe\", 4. 0 }, susie = { 5, \"Susie Jones\" }; \/\/ Susie has a gpa of 0. 0<\/pre>\n<p>Yukar\u0131daki \u00f6rnekte susie adl\u0131 \u00a0\u00f6\u011frencinin gpa yani not de\u011feri girlmedi\u011finden ilk de\u011fer olarak 0.0 de\u011ferinin not olarak atanmas\u0131 beklenir. Ancak bu beklenti ger\u00e7ekle\u015fmeyebilir. \u0130lk de\u011fer atamas\u0131 yap\u0131lmayan de\u011ferler her zaman risk unsurudur ve m\u00fcmk\u00fcnse t\u00fcm verilere ilk de\u011fer atamas\u0131 yap\u0131lmal\u0131d\u0131r. Neyse \ud83d\ude42<\/p>\n<p>\u0130lk de\u011fer atamas\u0131 bundan farkl\u0131 \u015fekillerde de yap\u0131labilmektedir. \u00d6rne\u011fin Linux kaynak dosyalar\u0131nda s\u0131kl\u0131kla g\u00f6rece\u011finiz bir de\u011fer atama \u015fekli a\u015fa\u011f\u0131daki gibidir:<\/p>\n<pre class=\"lang:c decode:true \">Student jane = { . gpa = 4. 0 }, sue = { . name = \"Sue Smith\", 3. 5 };<\/pre>\n<p>Yukar\u0131daki y\u00f6ntem C&#8217;nin C99 destekleyen derleyicileri ile m\u00fcmk\u00fcnd\u00fcr ve bu sayede struct i\u00e7indeki de\u011fi\u015fkenlerin s\u0131ras\u0131 \u00f6nemsiz olmaktad\u0131r. \u00c7\u00fcnk\u00fc zaten &#8220;.isim&#8221; ile hangi elemana ilk de\u011fer atamas\u0131 yapt\u0131\u011f\u0131m\u0131z\u0131 belirtmi\u015f oluyoruz. Bu y\u00f6ntemin, di\u011fer y\u00f6nteme g\u00f6re \u00e7i\u00e7ek gibi bir g\u00fczelli\u011fi vard\u0131r. Haydi diyelim bir struct tan\u0131mlad\u0131n\u0131z, sonra g\u00fcnlerden bir g\u00fcn i\u00e7iniz elvermedi ve structa bir eleman daha eklediniz. E\u011fer s\u0131ral\u0131 ilk de\u011fer atamas\u0131 yaparsan\u0131z (ilk \u00f6rnekteki gibi) ba\u015f\u0131n\u0131z dertte demektir \u00e7\u00fcnk\u00fc yaratt\u0131\u011f\u0131n\u0131z her bir sturct de\u011fi\u015fkeni i\u00e7in s\u0131ray\u0131 tek tek bulup do\u011fru yere ilk de\u011fer atamas\u0131n\u0131 yazman\u0131z gerekir. \u0130kinci y\u00f6ntemde ise koyun noktay\u0131 yaz\u0131n yeni de\u011fi\u015fkenin ad\u0131n\u0131, atay\u0131n de\u011feri ve arkan\u0131za yaslarken build tu\u015funa bas\u0131n \ud83d\ude42 Linuxcu day\u0131lardan al\u0131nacak \u00e7ok ibret var ama, burada da bu y\u00f6ntemi se\u00e7erken bir bildikleri oldu\u011funu g\u00f6r\u00fcyoruz.<\/p>\n<p><strong>Struct&#8217;lar\u0131n Birbirlerine Atanmas\u0131<\/strong><\/p>\n<p>Ayn\u0131 tipteki iki de\u011fi\u015fken birbirine atanabilir. Bu ba\u011flamda ayn\u0131 struct tipindeki iki de\u011fi\u015fken de do\u011frudan birbirlerine atanabilecektir. Yaln\u0131z struct&#8217;lar\u0131n birbirlerine atanmalar\u0131 \u00e7ok s\u0131k\u0131nt\u0131l\u0131 ve dikkat edilmesi gereken bir mevzudur. Hatta struct&#8217;un herhangi bir \u015feye atanmas\u0131 dikkatle yap\u0131lmas\u0131 gereken bir i\u015flemdir ve baz\u0131 riskler bar\u0131nd\u0131r\u0131r.<\/p>\n<p>Ne demek istiyorum? Diyelim ki sturct i\u00e7inde bir pointer var. Bu pointer bir yer i\u015faret ediyor.\u00a0Bir struct de\u011fi\u015fkenini bir ba\u015fkas\u0131na atamak, o structu kopyalamak anlam\u0131na gelmez. Sadece iki sturct&#8217;un da ayn\u0131 yeri g\u00f6stermesi anlam\u0131na gelir.<\/p>\n<p>Bu k\u0131s\u0131m biraz uzayacak olsa da, \u00f6nemli oldu\u011fundan detayl\u0131ca anlatmaya \u00e7al\u0131\u015faca\u011f\u0131m. Bizim Student sturct&#8217;\u0131n\u0131n tipindeki de\u011fi\u015fkenleri birbirine atamak\/kopyalamak filan isteyelim. \u0130lk anda akla gelen 3 temel yol var.<\/p>\n<pre class=\"lang:c decode:true \">typedef struct {\r\nint32_t nClasses;\r\nchar name [ NAME_LEN + 1 ] ;\r\ndouble_t gpa;\r\n} Student;\r\n\r\nStudent Ali, Veli;\r\n\/\/...\r\n\r\n\/\/yontem 1!!!\r\nAli.nClasses = Veli.nClasses;\r\nstrncopy(Ali.name, Veli.name, (NAME_LEN + 1));\r\nAli.gpa= Veli.gpa;\r\n\r\n\/\/yontem 2!!!\r\nmemcpy(&amp;Ali,&amp;Veli, sizeof(Student));\r\n\r\n\/\/yontem 3!!!\r\nAli = Veli;\r\n\r\n<\/pre>\n<p>\u0130lk y\u00f6ntem, camiada amele y\u00f6ntemi olarak (asla hakaret\/a\u015fa\u011f\u0131lama ama\u00e7l\u0131 de\u011fildir!) bilinir ve \u00e7ok da tercih edilmez. Sonu\u00e7ta Veli&#8217;nin t\u00fcm bilgilerini Ali&#8217;ye atamak istiyorsak bunun daha g\u00fczel yollar\u0131 var.<\/p>\n<p>\u0130kinci y\u00f6ntem atamadan \u00e7ok kopyalamad\u0131r. Ad\u0131 \u00fcst\u00fcnde iki de\u011fi\u015fkenin i\u015faret etti\u011fi ya da tutuldu\u011fu bellek alanlar\u0131n\u0131 verilen uzunluk (sizeof Student) kadar byte kopyalar. Bu olay hard copy olarak ge\u00e7er ve bellek i\u00e7eri\u011fi tamamen kopyalan\u0131r. Yani ayn\u0131 bilgileri ta\u015f\u0131yan iki farkl\u0131 adres b\u00f6lgesi olur. Bu y\u00f6ntem \u00e7ok belay\u0131 def eder. Ali&#8217;nin bilgilerini Veli&#8217;ye aktar\u0131p sonra Veli&#8217;yi okuldan kovmak istiyorsan\u0131z bu y\u00f6ntem birebirdir \u00e7\u00fcnk\u00fc Veli&#8217;yi kovsan\u0131z bile, Veli&#8217;nin bilgileri Ali&#8217;nin akl\u0131nda ayr\u0131 bir yerde saklanm\u0131\u015f durumda olur.<\/p>\n<p>\u00dc\u00e7\u00fcnc\u00fc y\u00f6ntem k\u0131sa g\u00f6z\u00fckmekle birlikte derleyiciye \u00e7ok daha fazla optimizasyon \u015fans\u0131 b\u0131rak\u0131r. Bu da beklemedi\u011finiz baz\u0131 davran\u0131\u015flar\u0131 beraberinde getirebilir. Okunurluk a\u00e7\u0131s\u0131ndan da iki de\u011fi\u015fkeni birbirine atamak, kopyalamaktan daha farkl\u0131 bir mesaj verir ve do\u011fal olarak = operat\u00f6r\u00fc burda kopyalama de\u011fil atama i\u015fi yapar. Yani bizim Veli bildi\u011fimiz ki\u015fi art\u0131k ayn\u0131 zamanda Ali&#8217;dir. Bu durumda Veli&#8217;nin ba\u015f\u0131na bir\u015fey gelirse Ali&#8217;nin de ba\u015f\u0131na bir \u015fey gelecektir. Bu da \u00e7ok b\u00fcy\u00fck bela demektir.<\/p>\n<p>Sizlere nacizane tavsiyem, bu y\u00f6ntemler \u00fczerinde denemeler yaparak davran\u0131\u015f\u0131 bir kez de kendiniz g\u00f6r\u00fcn\u00fcz. Sonra bir g\u00fcn ba\u015f\u0131n\u0131za gelir, \u00f6yle okuyup ge\u00e7erseniz hat\u0131rlamazs\u0131n\u0131z bile \ud83d\ude42 Bu konunun oturmas\u0131 i\u00e7in bu atamalar\u0131 yap\u0131p, alt\u0131nda printf ile struct adreslerinin ve struct elemanlar\u0131n\u0131n yazd\u0131r\u0131lmas\u0131 \u015fart. Belki aran\u0131zda sturct adresi nas\u0131l yazd\u0131r\u0131l\u0131r bilmeyen olabilir, onun i\u00e7in de hemen \u015f\u00f6yle ufac\u0131ktan yaz\u0131verelim:<\/p>\n<pre class=\"lang:default decode:true \">printf(\"Ali'nin adresi :%d[%x]\",&amp;Ali,&amp;Ali);\r\n<\/pre>\n<p>Ba\u015f\u0131n\u0131z a\u011fr\u0131mas\u0131n istiyorsan\u0131z, yukar\u0131daki ama\u00e7 i\u00e7in y\u00f6ntem 2&#8217;yi \u00f6neririm. Ne yapt\u0131\u011f\u0131n\u0131z\u0131 \u00e7ok iyi biliyorsan\u0131z y\u00f6ntem 3&#8217;\u00fcn de avantaj getirece\u011fi durumlar vard\u0131r. Misal daha az bellek kullan\u0131rs\u0131n\u0131z. Ama \u00e7ok dikkat etmeniz gerekir. Hem de e\u011fer kodu tak\u0131m olarak geli\u015ftiriyorsan\u0131z, sizin \u00e7ok dikkat etmeniz yetmez, arkada\u015flar\u0131n\u0131z\u0131n da ayn\u0131 dikkati g\u00f6stermesi gerekir. E\u011fer tak\u0131m arkada\u015flar\u0131n\u0131z\u0131 seviyorsan\u0131z, onlara dikkat etmeleri gereken yeni \u015feyler vermeyin. Zorla\u015ft\u0131rmay\u0131n, kolayla\u015ft\u0131r\u0131n \ud83d\ude42<\/p>\n<p><strong>Struct&#8217;lar\u0131n\u00a0Pointer(\u0130\u015faret\u00e7i) ile \u0130mtihan\u0131<\/strong><\/p>\n<p>\u015eimdi daha i\u015faret\u00e7ileri anlatmad\u0131m ama, zaten bu yaz\u0131 dizisinin do\u011fas\u0131 gere\u011fi sizin onu referans verilen kaynaklardan ya da ba\u015fka yerlerden \u00f6\u011frenmi\u015f olman\u0131z ya da zaten biliyor olman\u0131z gerekiyor. Ki burada olay\u0131n biraz daha ince detaylar\u0131n\u0131, felsefi y\u00f6nlerini de\u011ferlendirelim \ud83d\ude42<\/p>\n<p>Pointer yani i\u015faret\u00e7i dedi\u011fimiz nane, herhangi bir \u015feyin adresini tutabilir. Zaten i\u015faret etti\u011fi \u015fey de o adresin i\u00e7indeki veridir. Pislik yap\u0131p farkl\u0131 t\u00fcrde i\u015faret\u00e7iler ile bamba\u015fka t\u00fcrden verileri i\u015faret etmek de \u00e7irkin olsa da m\u00fcmk\u00fcnd\u00fcr. Ama \u00f6yle \u015feyler yapmayaca\u011f\u0131z, pointer hangi tipte veriyi i\u015faret edecekse o tipi g\u00f6sterecek.<\/p>\n<pre class=\"lang:c decode:true\">int32_t index, numOfVars;\r\nint32_t *indextPtr = &amp;index;\r\nstruct Student alice, bob, carol;\r\nstruct Student *sptr = &amp;alice;<\/pre>\n<p>\u00d6rnek kodumuzda, sptr de\u011fikeni struct Student* (struct Student i\u015faret\u00e7isi) tipinde bir i\u015faret\u00e7idir ve haliyle struct Student tipinden bir veriyi i\u015faret etmek ister. Nitekim bu i\u015faret\u00e7i, iste\u011fine kavu\u015fup alice&#8217;i i\u015faret etmi\u015ftir. Struct&#8217;lar\u0131 fonksiyona arg\u00fcman olarak filan verecekken t\u00fcm veriyi kopyalamak feci derecede k\u00f6t\u00fc bir tercihtir. Bu gibi durumlarda struct&#8217;\u0131n kendisini kopyalamak yerine, bellek adresini kopyalamak daha mant\u0131kl\u0131d\u0131r. Misal bizim Student struct&#8217;\u0131 nereden baksan\u0131z 28 Byte filan vard\u0131r. Oysa 32-bit&#8217;lik bir platformda her adres 4 Byte&#8217;d\u0131r. Bu sayede fonksiyona bu bilgiyi aktar\u0131rken 28 byte yerine 4 byte kopyalayarak, tam 24 byte kara ge\u00e7mi\u015f olduk. \u00a0B\u00f6yle g\u00fczide bir fonksiyon \u00f6rne\u011fini a\u015fa\u011f\u0131da hizmetinize sunuyorum.<\/p>\n<pre class=\"lang:default decode:true\">void printStudentName( const struct Student *imaStudent );<\/pre>\n<pre class=\"lang:default decode:true\">void printStudentName( const struct Student *myStudent)\r\n{\r\n   printf(\"Name is %sn\",myStudent-&gt;name);\r\n}<\/pre>\n<p>Bu fonksiyonu \u00e7a\u011f\u0131rmak i\u00e7in de a\u015fa\u011f\u0131daki gibi \u00a0adresi(&amp;) operat\u00f6r\u00fcn\u00fc kullanabiliriz.<\/p>\n<pre class=\"lang:c decode:true \">printStudentName( &amp;bob );<\/pre>\n<p>Dikkat ederseniz implementasyonda myStudent.name yerine\u00a0myStudent-&gt;name yapt\u0131k. Bunun sebebi, myStudent bir pointer oldu\u011fundan onun g\u00f6sterdi\u011fi bellek alan\u0131n\u0131 struct olarak d\u00fc\u015f\u00fcn\u00fcp oradaki name de\u011ferine ula\u015fmay\u0131 sa\u011flayan operat\u00f6r\u00fcn -&gt; operat\u00f6r\u00fc olmas\u0131d\u0131r.\u00a0myStudent de\u011fi\u015fkeninin tipi struct olmad\u0131\u011f\u0131ndan (\u00e7\u00fcnk\u00fc struct i\u015faret\u00e7isidir), nokta ile elemana ula\u015fmak do\u011fal olarak m\u00fcmk\u00fcn olmaz. Ancak <em>myStudent dedi\u011fimiz zaman art\u0131k \u00a0<\/em>(myStudent) ifadesinin tipi bir struct olacakt\u0131r. Dolay\u0131s\u0131yla onda nokta ile eri\u015fim yapmak a\u015fa\u011f\u0131daki t\u00fcm \u015fekillerde m\u00fcmk\u00fcnd\u00fcr.<\/p>\n<pre class=\"lang:c decode:true \">*sptr.gpa = 4.0;\r\n\r\n\/\/ya da \r\n(*sptr).gpa = 4.0; \r\n\r\n\/\/ya da \r\nsptr-&gt;gpa = 4.0;\r\n\r\n\/\/ ve hatta ya da\r\ndouble *gpaPtr = &amp;carol.gpa;\r\n*gpaPtr = 4.0;<\/pre>\n<p>Bizim yap\u0131lar (struct&#8217;lar) i\u00e7lerinde temel tiplerin ya da kompleks tiplerin i\u015faret\u00e7ilerini ta\u015f\u0131yabilir. G\u00f6r\u00fcrseniz garibinize gitmesi i\u00e7in bir sebep yoktur.<\/p>\n<pre class=\"lang:c decode:true\">struct Employee {\r\n       char *name;\r\n       struct Date * hiringDate;\r\n    };<a>Insert shortcode<\/a><\/pre>\n<p>Sturct i\u00e7inde i\u015faret\u00e7i g\u00f6r\u00fcrseniz, sturct atamas\u0131 yaparken iki defa d\u00fc\u015f\u00fcn\u00fcn ve y\u00f6ntem 2&#8217;yi akl\u0131n\u0131zda tutun l\u00fctfen \ud83d\ude42<\/p>\n<p><strong>Struct Bit Eri\u015fimi<\/strong><\/p>\n<p>Bu k\u0131s\u0131m \u00e7ok \u00e7ok \u00e7ok \u00e7ok \u00f6nemli. Dataheet modelleme ve s\u00fcr\u00fcc\u00fc yazma i\u015flerinde buray\u0131 bilhassa \u00e7ok kullanaca\u011f\u0131z. E\u011fer bu konuda \u00f6\u011frenebilece\u011finiz yeni bir \u015feyler var ise, l\u00fctfen dikkatle okuyunuz.(Zaten okumadan bunu kimse bilemeyecek \ud83d\ude00 )<\/p>\n<p>C dilindeki standart veri tipleri ile, en k\u00fc\u00e7\u00fck BYTE eri\u015fimi yapabilirsiniz. Oysa stuct ile belle\u011fi bit bit modellemek m\u00fcmk\u00fcnd\u00fcr. Bu hem bellekten kazan\u00e7 sa\u011flar, hem de \u00f6rne\u011fin datasheet modellemesinde, \u00e7i\u00e7ek gibi modelleme yapma imkan\u0131 sunar. Datasheet modellemeyi ileride anlataca\u011f\u0131m ancak, l\u00fctfen bu k\u0131sm\u0131n \u00e7ok \u00f6nemli oldu\u011funu unutmay\u0131n\u0131z, unutturmay\u0131n\u0131z.<\/p>\n<p>Hemen h\u0131zl\u0131ca \u00f6rnek kodu yazal\u0131m.<\/p>\n<pre class=\"lang:c decode:true\">#define NUM_OF_INVENTORY (100)\r\n    struct Packed_data {\r\n       uint32_t  is_element:1;   \/* = 1 if element *\r\n       uint32_t  is_reactant:1;\r\n       uint32_t  is_product:1;\r\n       uint32_t  is_catalyst:1;\r\n       uint32_t  reserved:4;\r\n       uint32_t  atomic_number:8;     \/* Maximum 255 *\/\r\n       uint32_t  Stock_Index:16; \/* Maximum 65,535 *\/\r\n    } chemical_inventory[ NUM_OF_INVENTORY ];<\/pre>\n<p>is_element:1 demek, is_element de\u011fi\u015fkeni 1 bit yer kaplayacak demek. Bu durumda bu de\u011fi\u015fken ger\u00e7ek bir bool oluyor. atomic_number:8 demek,\u00a0atomic_number 8 byte yer kaplayacak demek. Bu durumda en fazla 255&#8217;e kadar de\u011fer alabilecek bu numara.<\/p>\n<p>Her \u015fey tamam da uint32_t ve reserved niye var. Sebebi \u015fu; 1 bit i\u015faret edebiliyorsunuz diye bellek i\u00e7indeki her bir biti can\u0131n\u0131z istedi\u011fi \u015fekilde y\u00f6netemezsiniz. Ne demek istiyorum? 32 bit&#8217;lik bit platformda her bellek g\u00f6z\u00fc 32&#8217;bit olacakt\u0131r. Ve siz bir bit&#8217;lik bir sturct tan\u0131mlasan\u0131z bile, daha \u00f6nce bahsetti\u011fim <a href=\"http:\/\/en.wikipedia.org\/wiki\/Data_structure_alignment\" target=\"_blank\" rel=\"noopener\">sturct alignment<\/a>\u00a0problemi y\u00fcz\u00fcnden geriye kalan 31 bit israf olacakt\u0131r. Derleyici buray\u0131 optimize etmek isterse de vay halinize \u00e7\u00fcnk\u00fc sizin 1 bitiniz ciddi olmayan bir az\u0131nl\u0131k oldu\u011fundan, \u00e7o\u011funlu\u011fun bekas\u0131 i\u00e7in feda edilebilir. Bunu engellemek i\u00e7in struct&#8217;umuzun boyutunu 32 bite tamamlad\u0131k. Nas\u0131l yani; 1+1+1+1+4+8+16 = 32 oldu. 32 bite tamamlayaca\u011f\u0131m\u0131z\u0131 pe\u015fin pe\u015fin s\u00f6ylemek i\u00e7inde \u00a0her eleman\u0131n tipini uint32_t: yapt\u0131k. Bu sayede hem olas\u0131 yanl\u0131\u015f optimizasyonlar\u0131 engelledik hem de kimyasal envanter i\u00e7in gerekli onca bilgiyi 32 bit&#8217;de saklad\u0131k. Peki b\u00f6yle yapmasayd\u0131k da a\u015fa\u011f\u0131daki gibi yapsayd\u0131k ne olurdu?<\/p>\n<pre class=\"lang:c decode:true\">bool  is_element;   \/\/1 byte in\u015f\r\nbool  is_reactant; \/\/1 byte in\u015f\r\nbool  is_product; \/\/1 byte in\u015f\r\nbool  is_catalyst; \/\/1 byte in\u015f\r\nuint8_t  atomic_number;     \/\/1 byte \r\nuint16_t  Stock_Index; \/\/2 byte<\/pre>\n<p>Bu durumda bizim kimyasal envanter 7 byte yani 56 bit tutacakt\u0131 \u00e7\u00fcnk\u00fc bool tipi asla 1 bit tutmaz genelde 1 byte tutar. Struct memory alingment olaca\u011f\u0131ndan bu itina ile 64 byte&#8217;a tamamlanacakt\u0131. Yani tam 2 kat\u0131 bellek kullanm\u0131\u015f olacakt\u0131k. 1000 envanterde kaybedine tam 4000 Byte \ud83d\ude41 Hi\u00e7 gerek yok \ud83d\ude42<\/p>\n<p>Sturct i\u00e7in ilk turda bu kadar\u0131 yeterli.<\/p>\n<p><strong>ENUM<\/strong><\/p>\n<p>Enumerasyon diye T\u00fcrk\u00e7eye ittirilmeye \u00e7al\u0131\u015f\u0131lan bu terim asl\u0131nda etiketlenmi\u015f say\u0131 y\u0131\u011f\u0131n\u0131ndan ba\u015fka bir\u015fey de\u011fil. \u00a0Benim bildi\u011fim tam bir \u00e7evirisi olmamakla birlikte, say\u0131m etiketi olarak isimlendirmek m\u00fcmk\u00fcn olabilir. Ya da k\u0131saca enum da denebilir. Enum say\u0131 gibidir demi\u015ftik ama baz\u0131 farklar\u0131 var tabi\u00a0(o\u00a0farknan da \u00e7ok g\u00fczel oldu). Enum tipinde:<\/p>\n<ul>\n<li>Sadece \u00f6nceden belirlenmi\u015f sabit de\u011ferlere izin verilir.<\/li>\n<li>Tan\u0131mlanm\u0131\u015f her bir de\u011fer isim ikilisi vard\u0131r. Bu sebeple enum ile \u00e7al\u0131\u015f\u0131rken say\u0131lar yerine ilgili de\u011fere kar\u015f\u0131 d\u00fc\u015fen isim kullan\u0131l\u0131r.<\/li>\n<\/ul>\n<p>Burada \u00e7okca feyizler vard\u0131r. &#8220;#define ile benzer bu&#8221; diyenler olabilir. Oraya da gelece\u011fiz.<\/p>\n<p>Hemen bir ka\u00e7 tan\u0131mlama \u00f6rne\u011fi patlatal\u0131m yine:<\/p>\n<pre class=\"lang:c decode:true\">enum suits { CLUBS, HEARTS, SPADES, DIAMONDS, NOTRUMP } trump;\r\nenum suits ew_bid, ns_bid;<\/pre>\n<pre class=\"lang:default decode:true\">typedef enum Direction{ NORTH, SOUTH, EAST, WEST } Direction;\r\nDirection nextMove = SOUTH;<\/pre>\n<p>&nbsp;<\/p>\n<p>Ben yine yaz\u0131m olarak ve tan\u0131m olarak a\u015fa\u011f\u0131daki \u015fekli daha \u015f\u0131k buluyorum:<\/p>\n<pre class=\"lang:c decode:true\">typedef enum \r\n{ \r\n  E_DIRECTION_NONE=0,\r\n  E_DIRECTION_NORTH,\r\n  E_DIRECTION_SOUTH,\r\n  E_DIRECTION_EAST,\r\n  E_DIRECTION_WEST \r\n}tE_Direction;\r\n\r\ntE_Direction eNextMove = E_DIRECTION_SOUTH;<\/pre>\n<p>Burada oyunun kurallar\u0131 basit:<\/p>\n<ul>\n<li>Herhangi bir enum eleman\u0131na, \u00f6zel bir de\u011fer atanabilir: misal E_DIRECTION_NONE say\u0131m etiketine 0 de\u011feri atad\u0131k.<\/li>\n<li>De\u011fer atanmayan say\u0131m etiketleri, bir \u00f6nceki etiketten bir fazla de\u011fer al\u0131r. Buna g\u00f6re\u00a0E_DIRECTION_NORTH etiketinin de\u011feri 1,\u00a0E_DIRECTION_SOUTH etiketinin de\u011feri 2 oldu vs.<\/li>\n<li>E\u011fer ilk etikete de\u011fer atanmad\u0131ysa, ona otomatik olarak s\u0131f\u0131r de\u011feri atan\u0131r.<\/li>\n<\/ul>\n<p>Esasen size bir s\u0131r vereyim, ayn\u0131 de\u011feri birden fazla etikete atamak m\u00fcmk\u00fcnd\u00fcr. Ama inan\u0131n bana bu alenen \u00e7irkinle\u015fmektir, ve \u00e7irkinle\u015fmenin hi\u00e7 ama hi\u00e7 luzumu yoktur!<\/p>\n<p><strong>Enum ve Define Kar\u015f\u0131 Kar\u015f\u0131ya<\/strong><\/p>\n<p>H\u0131zl\u0131ca \u00f6zetlemek gerekirse; enum bir veri tipidir, define ise derleyicinin kopyala yap\u0131\u015ft\u0131r yapt\u0131\u011f\u0131 bir etikettir. Do\u011fal olarak enum tipinde de\u011fi\u015fken tan\u0131mlayabiliyoruz, nitekim tan\u0131mlad\u0131k. Bu de\u011fi\u015fkenler do\u011fal olarak RAM&#8217;de tutulur (const tan\u0131mlanmad\u0131larsa!). Define her yere aynen yap\u0131\u015ft\u0131r\u0131laca\u011f\u0131ndan, geni\u015fletilebilirlik a\u00e7\u0131s\u0131ndan enum kullanmak \u00e7ok faydal\u0131d\u0131r. Enumerasyon yapmak i\u00e7in define kullanmay\u0131n\u0131z, enum kullan\u0131n\u0131z. Etiketleme (define) yapmak i\u00e7in enum kullanmay\u0131n\u0131z, define kullan\u0131n\u0131z.<\/p>\n<p>Diyelim bir durum makinas\u0131n\u0131n durumlar\u0131n\u0131 saklayacaks\u0131n\u0131z. Burada enum kullanmak gerekir \u00e7\u00fcnk\u00fc e\u011fer define kullan\u0131rsan\u0131z, yar\u0131n yeni bir state eklendi\u011finde ve onun ara de\u011ferde olmas\u0131 gerekti\u011finde, t\u00fcm define&#8217;lar\u0131 teker teker de\u011fi\u015ftirmeniz gerekir. Oysa enumda rastgele bir yere yazd\u0131\u011f\u0131n\u0131zda su akacak ve yolunu en g\u00fczel \u015fekilde bulacakt\u0131r.<\/p>\n<p>\u015eimdi enum ile ilgiliverdi\u011fimiz bu \u00f6rne\u011fi kod olaraktan aktaral\u0131m:<\/p>\n<pre class=\"lang:c decode:true \">typedef enum \r\n{\r\n E_STATE_NONE=0,\r\n E_STATE_START,\r\n E_STATE_SEND,\r\n E_STATE_RECEIVE,\r\n E_STATE_STOP,\r\n E_STATE_LAST\r\n}tE_STATE; \r\n\r\ntE_STATE eState = E_STATE_NONE; \r\n\r\nswitch(eState)\r\n{\r\n  case E_STATE_NONE:\r\n     DoJobForNone();\r\n  break;\r\n  case E_STATE_START:\r\n     DoJobForStart();\r\n  break;\r\n  case E_STATE_SEND:\r\n     DoJobForSend();\r\n  break;\r\n  case E_STATE_RECEIVE:\r\n     DoJobForReceive();\r\n  break;\r\n  case E_STATE_STOP:\r\n     DoJobForStop();\r\n  break;\r\n  default:\r\n     DoErrorRecovery();\r\n  break;\r\n\r\n}<\/pre>\n<p>G\u00f6rd\u00fc\u011f\u00fcn\u00fcz \u00fczere \u00e7i\u00e7ek gibi oldu \u00e7i\u00e7ek \ud83d\ude42<\/p>\n<p><strong>UNION<\/strong><\/p>\n<p>Geldik \u00fc\u00e7 silah\u015f\u00f6rlerin \u00fc\u00e7\u00fcnc\u00fcs\u00fcne&#8230; Union yani birlik!<\/p>\n<p>Bizim unionlar aynen struct gibi tan\u0131mlan\u0131r ve kullan\u0131m \u015fekilleri (kullan\u0131m yerleri de\u011fil) \u00e7ok \u00e7ok benzerdir. Ancak \u00e7ok \u00f6nemli bir fark vard\u0131r:<\/p>\n<p>Struct&#8217;lar i\u00e7lerindeki verileri ard\u0131\u015f\u0131l olarak saklayabilecek kadar belle\u011fi kendilerine ay\u0131r\u0131rlar. Union&#8217;da ise union&#8217;un boyutu, union i\u00e7indeki en b\u00fcy\u00fck boyutlu eleman\u0131n boyutu kadard\u0131r \u00e7\u00fcnk\u00fc union&#8217;un t\u00fcm elemanlar\u0131 asl\u0131nda belle\u011fin ayn\u0131 g\u00f6z\u00fcn\u00fc (ayn\u0131 adresi) g\u00f6sterirler. Bu \u00f6zellik ba\u015fta i\u015fe yaramaz gibi g\u00f6z\u00fckse de, \u00f6zellikle verinin bilgiye d\u00f6n\u00fc\u015ft\u00fcr\u00fclmesinde yani yorumlanmas\u0131nda \u00e7ok i\u015fe yarar \u015fekilde kar\u015f\u0131m\u0131za \u00e7\u0131kmaktad\u0131r.<\/p>\n<p>Hemen ibretlik bir kod payla\u015fal\u0131m.<\/p>\n<p>&nbsp;<\/p>\n<pre class=\"lang:c decode:true \">   #define FLIGHT_CAPACITY (100)\r\n   typedef struct Flight {\r\n       enum { PASSENGER, CARGO } type;\r\n       union {\r\n           uint32_t nPassengers;\r\n           float_t tonnages;  \/\/ Units are not necessarily tons.\r\n       } cargo;\r\n   } Flight;\r\n\r\n   Flight flights[FLIGHT_CAPACITY];\r\n\r\n   flights[42].type = PASSENGER;\r\n   flights[42].cargo.nPassengers = 150;\r\n\r\n   flights[20].type = CARGO;\r\n   flights[20].cargo.tonnages = 356.78;\r\n<\/pre>\n<p>Burada union kullan\u0131larak 4 byte&#8217;dan kar edildi. \u00c7\u00fcnk\u00fc ayn\u0131 u\u00e7u\u015f sturct&#8217;\u0131 i\u00e7inde e\u011fer u\u00e7u\u015f tipi kargo ise float olarak tonaj de\u011fi\u015fkeni, e\u011fer u\u00e7u\u015f tipi yolcu ise uint32_t olarak nPassengers (yolcu say\u0131s\u0131) de\u011fi\u015fkeni ayn\u0131 bellek g\u00f6z\u00fcn\u00fc g\u00f6sterir. Bu olay, inan\u0131lmaz zekice bir olayd\u0131r ve anla\u015f\u0131lmay\u0131 hak etmektedir.<\/p>\n<p>Burada union kullan\u0131lmasa idi, haybeye 4 byte harcanacakt\u0131. Bu durumda nPassengers ve tonnages de\u011fi\u015fkenleri belle\u011fe ard\u0131\u015f\u0131l olarak yerle\u015fecekti. Halbuki d\u00fc\u015f\u00fcn\u00fcnce b\u00f6yle bir ihtiya\u00e7 ger\u00e7ekte yok \u00e7\u00fcnk\u00fc bu iki de\u011fi\u015fken asla ayn\u0131 anda kullan\u0131lamayacak. \u0130\u015fte burada union geldi ve bir Flight i\u00e7in 4 byte, 100 Flight i\u00e7in 400 byte kar etmemizi sa\u011flad\u0131.<\/p>\n<p>Kodun ne kadar karizmatik oldu\u011funa de\u011finmiyorum bile. Belki oradan al\u0131p y\u00fcr\u00fcyecekler de olabilir.<\/p>\n<p>Hemen eski yaz\u0131lar\u0131m\u0131zda a\u00e7\u0131klad\u0131\u011f\u0131m\u0131z ibretlik bir \u00f6rne\u011fi daha sizlerle payla\u015f\u0131yorum:<\/p>\n<pre class=\"lang:c decode:true \">uint32_t nRead;\r\n   uint32_t index;\r\n   typedef union {\r\n       uint32_t u32Data;\r\n       int16_t  as16Data[2];\r\n       int8_t   as8Data[4];\r\n   }tu_DataGroup32;\r\n\r\n   tu_DataGroup32 UData;\r\n   \/\/ ( Code to read in nRead, from the user or a file, has been omitted in this example )\r\n    UData.u32Data = nRead;\r\n    for(  index= 0; index &lt; sizeof(uint32_t); index++ )\r\n    {\r\n        printf( \"Byte number %d of %ud is %udn\", index, nRead, UData.int8_t[index] );\r\n    }<\/pre>\n<p>Burada da union ile yine bit kayd\u0131rma, maskeleme i\u015flerini hi\u00e7 yapmadan 32 bitlik bir veriye hem byte byte, hem 2 byte 2 byte hem de t\u00fcmden eri\u015febiliyoruz. Bu olay\u0131 da \u00f6zellikle haberle\u015fme yaz\u0131l\u0131mlar\u0131nda s\u0131k\u00e7a kullanaca\u011f\u0131z. \u00d6rnek kodlarla bunlar\u0131 denemeyi unutmay\u0131n\u0131z \ud83d\ude42<\/p>\n<p>Yaz\u0131lar\u0131 be\u011fendiyseniz e\u011fer, \u00a0faydalanabilecek arkada\u015flar\u0131n\u0131zla da payla\u015fabilirseniz sevinirim \ud83d\ude09<\/p>\n<p>\u015eimdi devam&#8230;<\/p>\n<a href=\"http:\/\/ozenozkaya.com\/blog\/?p=282\" class=\"su-button su-button-style-3d\" style=\"color:#FFFFFF;background-color:#2D89EF;border-color:#246ec0;border-radius:5px\" target=\"_self\"><span style=\"color:#FFFFFF;padding:6px 16px;font-size:13px;line-height:20px;border-color:#6cadf4;border-radius:5px;text-shadow:none\"><i class=\"sui sui-arrow-circle-o-left\" style=\"font-size:13px;color:#FFFFFF\"><\/i> \u00d6nceki Sayfa<\/span><\/a> \u00a0<a href=\"http:\/\/ozenozkaya.com\/blog\/?p=294\" class=\"su-button su-button-style-3d\" style=\"color:#FFFFFF;background-color:#2D89EF;border-color:#246ec0;border-radius:5px\" target=\"_self\"><span style=\"color:#FFFFFF;padding:6px 16px;font-size:13px;line-height:20px;border-color:#6cadf4;border-radius:5px;text-shadow:none\"><i class=\"sui sui-arrow-circle-right\" style=\"font-size:13px;color:#FFFFFF\"><\/i> Sonraki Sayfa<\/span><\/a>\n<p>&nbsp;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Merhabalar, bug\u00fcnk\u00fc yaz\u0131mda C dilindeki yap\u0131lardan bahsedece\u011fim. Ancak bu bahsedi\u015f esasen bir girizgah \u015feklinde olacak. \u00c7\u00fcnk\u00fc yap\u0131sal bir dil olan C dilinde, tasar\u0131m\u0131n temel yap\u0131 ta\u015f\u0131, bir manada tu\u011flas\u0131, s\u0131vas\u0131 yap\u0131lar oldu\u011fundan bu yap\u0131lar\u0131 tek bir yap\u0131da anlatmak olduk\u00e7a zor olacakt\u0131r. Bunu yapmaya \u00e7al\u0131\u015f\u0131p eksik \u00e7ok say\u0131da nokta b\u0131rakmak yerine, \u00f6nce \u00e7ok derinlere inmeden sizlere <a class=\"read-more\" href=\"http:\/\/ozenozkaya.com\/blog\/?p=286\">Read more<\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_tr_post_content":"Merhabalar, bug\u00fcnk\u00fc yaz\u0131mda C dilindeki yap\u0131lardan bahsedece\u011fim. Ancak bu bahsedi\u015f esasen bir girizgah \u015feklinde olacak. \u00c7\u00fcnk\u00fc yap\u0131sal bir dil olan C dilinde, tasar\u0131m\u0131n temel yap\u0131 ta\u015f\u0131, bir manada tu\u011flas\u0131, s\u0131vas\u0131 yap\u0131lar oldu\u011fundan bu yap\u0131lar\u0131 tek bir yap\u0131da anlatmak olduk\u00e7a zor olacakt\u0131r. Bunu yapmaya \u00e7al\u0131\u015f\u0131p eksik \u00e7ok say\u0131da nokta b\u0131rakmak yerine, \u00f6nce \u00e7ok derinlere inmeden sizlere yap\u0131sal tasar\u0131m elemanlarn\u0131 ve bunlar\u0131n temel psikolojilerini aktar\u0131p, ard\u0131ndan ilerleyen konularda bunlar\u0131n sanatsal kullan\u0131mlar\u0131n\u0131 sunman\u0131n pe\u015findeyim. Bunun daha faydal\u0131 olaca\u011f\u0131na inan\u0131yorum. Dilerim sizlere azami fayday\u0131 sa\u011flayacak format\u0131, bir \u015fekilde tutturabilirim :)\r\n\r\nBence bir yaz\u0131, lap diye konuya dalmadan \u00f6nce ne vadetti\u011fini anlatmal\u0131, amac\u0131n\u0131 a\u00e7\u0131klamal\u0131d\u0131r. Ben de struct, enum, union diye ba\u015flamadan \u00f6nce sizlere bunlarla ne yapaca\u011f\u0131m\u0131z\u0131 aktarmaya \u00e7al\u0131\u015faca\u011f\u0131m. Haydi ba\u015flayal\u0131m...\r\n\r\nDaha \u00f6nce de s\u00f6yledi\u011fim gibi, bir program\u0131n amac\u0131, ger\u00e7ek hayattaki bir problemi \u00e7\u00f6zmektir. G\u00f6m\u00fcl\u00fc sistemlere \u00f6zg\u00fc olarak sunulan \u00e7\u00f6z\u00fcm, ger\u00e7ek hayat\u0131 fiziksel olarak do\u011frudan etkiler. Yani bir g\u00f6m\u00fcl\u00fc sistem, genellikle hayatla do\u011frudan temas halindedir. Ger\u00e7ek hayattaki bu problemin \u00e7\u00f6z\u00fclebilmesi i\u00e7in, sisteme problemin ve \u00e7\u00f6z\u00fcm\u00fcn tan\u0131m\u0131n\u0131n, \u00e7ok iyi yap\u0131lmas\u0131 gerekir. \u0130\u015fte ger\u00e7ek hayat\u0131n unsurlar\u0131n\u0131n, bizim tasar\u0131m ortam\u0131m\u0131za aktar\u0131lmas\u0131 i\u015fine modelleme denir. Modelleme, m\u00fchendisli\u011fin en temel konular\u0131ndan biri olmakla birlikte, tasar\u0131m\u0131n olmazsa olmaz\u0131d\u0131r. Laf\u0131 uzatmayay\u0131m. C dilinin yap\u0131sal bir dil olarak s\u0131n\u0131fland\u0131r\u0131lmas\u0131n\u0131n sebebi, modellemenin yap\u0131lar ile yap\u0131lmas\u0131d\u0131r. Bu vesileyle bir dile s\u0131n\u0131f\u0131n\u0131 verecek kadar \u00f6nemli bir konuya ge\u00e7ti\u011fimizi belirtmek istiyorum :) Yap\u0131lar\u0131 hakk\u0131yla kullanmay\u0131 bilmeden, kar\u015f\u0131la\u015ft\u0131\u011f\u0131m\u0131z problemlere g\u00fczel \u00e7\u00f6z\u00fcmler \u00fcretebilmemiz m\u00fcmk\u00fcn olmayacakt\u0131r. Bu sebeple l\u00fctfen, bu yaz\u0131dan ya da ba\u015fka bir kaynaktan, yap\u0131lar\u0131 hakk\u0131 ile \u00f6\u011frenmeye, hakk\u0131yla biliyorsan\u0131z bile bu i\u015fi bir ad\u0131m da olsa ileriye ta\u015f\u0131maya gayret edininiz.\r\n\r\n\u015eimdi, C dilindeki struct, enum ve union'un suyunu s\u0131kmaya ba\u015flayal\u0131m. Bakal\u0131m neler \u00e7\u0131kacak :)\r\n\r\n<strong>STRUCT<\/strong>\r\n\r\nStruct, g\u00f6m\u00fcl\u00fc yaz\u0131l\u0131mda \u00e7ok \u00e7ok \u00e7ok b\u00fcy\u00fck \u00f6neme sahip. Bu sebeple aff\u0131n\u0131za s\u0131\u011f\u0131narak, uzatarak da olsa basit\u00e7e a\u00e7\u0131klamaya \u00e7al\u0131\u015faca\u011f\u0131m. Bunu yaparken diziler ile analoji kurarak struct'u\u00a0sizlere a\u00e7\u0131klamaya \u00e7al\u0131\u015faca\u011f\u0131m.\r\n\r\nBildi\u011finiz \u00fczere diziler, ayn\u0131 veri tipindeki birden fazla de\u011fi\u015fkeni bellekte saklamak i\u00e7in kullan\u0131l\u0131rlar. Ancak bu veri g\u00fcruhu ya da veri dizisi bellekte saklan\u0131rken yan yana saklan\u0131r. Yani \u00e7ok s\u0131ra d\u0131\u015f\u0131 bir durum yok ise bir dizinin t\u00fcm elemanlar\u0131 belle\u011fe ard\u0131 s\u0131ra yerle\u015fir. Dizi tan\u0131m\u0131n\u0131n en \u00f6nemli iki \u00f6zelli\u011fini bu ba\u011flamda tekrar s\u0131ralarsak :\r\n<ol>\r\n \t<li>Dizinin t\u00fcm elemanlar\u0131n\u0131n ayn\u0131 veri tipinde olmas\u0131<\/li>\r\n \t<li>Dizinin elemanlar\u0131n\u0131n belle\u011fe ard\u0131\u015f\u0131l yerle\u015ftirilmesi.<\/li>\r\n<\/ol>\r\nDaha dizilere de\u011finmedim ama, bu iki \u00f6zellik diziler hakk\u0131nda ayan beyan g\u00f6r\u00fclen ilk iki \u00f6zelik. Struct veri tipi de (dizilere benzer \u015fekilde) bir veri toplulu\u011funu ifade eder ancak bu topluluktaki her bir veri (de\u011fi\u015fken), farkl\u0131 tipte olabilir. Yine struct i\u00e7indeki bir veriye ( yani struct eleman\u0131na), dizi indeksi gibi bir indeks yerine, bu\u00a0verinin ismiyle eri\u015filir.\r\n\r\nStruct, birbiriyle ilintili birden fazla farkl\u0131 kavram\u0131 birle\u015ftirerek bir context(konu) \u00e7er\u00e7evesinde toplamaya yarayan \u00e7ok g\u00fc\u00e7l\u00fc bir modelleme arac\u0131d\u0131r. G\u00fc\u00e7l\u00fc olmas\u0131n\u0131n sebebi ise, farkl\u0131 veri tiplerini ayn\u0131 yap\u0131 i\u00e7inde paketleyebilmesinden gelir.\r\n\r\nStruct'un bellek kullan\u0131m\u0131 dizilere benzerdir yani struct i\u00e7indeki elemanlar belle\u011fe ard\u0131\u015f\u0131l olarak yerle\u015fir. Ancak e\u011fer struct i\u00e7indeki elemanlar, kodlaman\u0131n yap\u0131ld\u0131\u011f\u0131 hedef platformun adres geni\u015fli\u011fine tam oturmuyorsa, <a href=\"http:\/\/en.wikipedia.org\/wiki\/Data_structure_alignment\" target=\"_blank\" rel=\"noopener\">struct alignment problem<\/a> denilen problem ortaya \u00e7\u0131kar. Bu durumda, struct elemanlar\u0131 bellek adresinin bir veya bir ka\u00e7\u0131n\u0131 tam olarak dolduramad\u0131\u011f\u0131ndan, derleyici bu sorunu gidermek i\u00e7in arada kayd\u0131rmalar ya da bo\u015f yer b\u0131rakmalar gibi operasyonlara gider. Bu durumun bilincinde olmakta b\u00fcy\u00fck faydalar var.\r\n\r\nStruct tan\u0131m\u0131 birde farkl\u0131 \u015fekilde yap\u0131lailiyor. Dilim d\u00f6nd\u00fc\u011f\u00fcnce her birini anlatmaya \u00e7al\u0131\u015faca\u011f\u0131m.\r\n\r\nEtiketlenmi\u015f\u00a0(tagged) struct tan\u0131m\u0131 a\u015fa\u011f\u0131daki gibi yap\u0131l\u0131r:\r\n<pre class=\"lang:c decode:true\">struct Part {\r\n int32_t number;\r\n int32_t on_hand;\r\n char name [ NAME_LEN + 1 ] ;\r\n double_t priceInEU;\r\n};<\/pre>\r\nYukar\u0131daki \u00f6rnek kodda, yeni tan\u0131mlanan struct'\u0131n etiketi Part'd\u0131r. Ve bu struct'un elemanlar\u0131 s\u0131ras\u0131yla number, on_hand, name ve price'd\u0131r. Bir struct i\u00e7indeki elemanlar\u0131n t\u00fcm\u00fcn\u00fcn farkl\u0131 tipte olabilece\u011fini ancak bunun bir zorunluluk olmad\u0131\u011f\u0131n\u0131 l\u00fctfen unutmay\u0131n\u0131z.\r\n\r\nBu noktada, \"struct Part\" tan\u0131m\u0131n\u0131n, bir veri tipi oldu\u011funu ve \"struct Part\" tipinden de\u011fi\u015fkenlerin yarat\u0131labilece\u011fini unutmay\u0131n\u0131z. \u00d6rne\u011fin \"sruct Part MonopolyGame;\" dedi\u011fimizde Part tipinde bir monopoly oyunu yaratm\u0131\u015f oluruz. Ve \u00f6rne\u011fin bu oyunun fiyat\u0131na \u015f\u00f6yle eri\u015febiliriz.\r\n<pre class=\"lang:c decode:true\">struct Part {\r\n int32_t number;\r\n int32_t on_hand;\r\n char name [ NAME_LEN + 1 ] ;\r\n double_t priceInEU;\r\n};\r\n\r\nint main()\r\n{\r\n struct Part MonopolyGame;\r\n MonopolyGame.priceInEu = 23.50;\r\nreturn 0;\r\n}<\/pre>\r\nEtiketli struct tan\u0131n\u0131mda, struct tipini tan\u0131mlarken ayn\u0131 zamanda de\u011fi\u015fkenleri de tan\u0131mlamak m\u00fcmk\u00fcnd\u00fcr.\r\n<pre class=\"lang:c decode:true\">struct Student {\r\nint32_t nClasses;\r\nchar name [ NAME_LEN + 1 ] ;\r\ndouble_t gpa;\r\n} joe, sue, mary;<\/pre>\r\nG\u00f6rd\u00fc\u011f\u00fcn\u00fcz gibi yukar\u0131daki kodda joe, sue ve mary isimli \u00fc\u00e7 \u00f6\u011frenci tan\u0131mlanm\u0131\u015f. Tabi bu tan\u0131mlar\u0131 yukar\u0131daki \u015fekilde yapmak, sonradan yeni elemanlar tan\u0131mlanamayaca\u011f\u0131 anlam\u0131na gelmez. Pekala da sonras\u0131nda da yeni elemanlar tan\u0131mlayabiliriz.\r\n<pre class=\"lang:c decode:true \">struct Student mike, carla;<\/pre>\r\nYukar\u0131daki y\u00f6nteme ek olarak, struct tipi tan\u0131mlamadan, struct \u015feklinde de\u011fi\u015fkenler tan\u0131mlamak da m\u00fcmk\u00fcnd\u00fcr. Ancak bu durumda, ayn\u0131 tipten yeni de\u011fi\u015fkenler tan\u0131mlamak m\u00fcmk\u00fcn olmayacakt\u0131r. Ayn\u0131 zamanda bunlar\u0131n bir fonksiyona arg\u00fcman olarak verilmesi de kolay yoldan m\u00fcmk\u00fcn olmayacakt\u0131r. Esasen bu da ak\u0131ll\u0131ca de\u011ferlendirilip, kullan\u0131m\u0131 k\u0131s\u0131tlama ama\u00e7l\u0131 olarak kullan\u0131labilecek bir \u00f6zelliktir. Ancak bu durum, tekrar kullan\u0131labilirli\u011fi de \u00f6ld\u00fcrece\u011finden dikkatlice kullan\u0131lmal\u0131d\u0131r. \u015eimdi bu tarif etti\u011fim duruma bir \u00f6rnek vereyim:\r\n<pre class=\"lang:c decode:true\">struct {\r\nint32_t nClasses;\r\nchar name [ NAME_LEN + 1 ] ;\r\ndouble_t gpa;\r\n} alice, bill; \/\/ alice and bill are of the same type, but not the same as struct Student\r\n\r\nstruct {\r\nint32_t nClasses;\r\nchar name [ NAME_LEN + 1 ] ;\r\ndouble_t gpa;\r\n} charlie, daniel; \/\/ charlie and daniel are the same type as each other, but not anyone else<\/pre>\r\nTemel anlamda struct tan\u0131m\u0131n\u0131 \u00f6\u011frendik. \u015eimdi bir sonraki seviyeye ge\u00e7elim :)\r\n\r\n<strong>Typedef'in Struct ile Kullan\u0131lmas\u0131<\/strong>\r\n\r\n<em>typedef<\/em>, programlama yapan kimselerin kendi veri tiplerini tan\u0131mlayabilmelerini sa\u011flar. Bu veri tipi, basit veri tipi (uint8_t gibi) olabilece\u011fi gibi; complex (birden fazla \u00a0veri tipini ayn\u0131 anda i\u00e7inde bar\u0131nd\u0131ran) yap\u0131da da olabilir.\r\n\r\n\u0130yi de yaz\u0131l\u0131mc\u0131 kendi veri tipini tan\u0131mlamaya neden ihtiya\u00e7 duysun ki? \u00c7\u00fcnk\u00fc temel veri tipleri sadece genel ama\u00e7lar i\u00e7indir. Ve modellenen problemler genellikle \u00f6zel problemlerdir ve bu probleme \u00f6zg\u00fc bilgi setlerini bar\u0131nd\u0131r\u0131rlar. \u0130\u015fte bu bilgi setlerini modeleyebilmek ve bu modeli tekrar kullanabilmek i\u00e7in typedef s\u00f6zc\u00fc\u011f\u00fcnden faydalan\u0131r\u0131z.\r\n\r\nHemen \u00f6rnek verelim:\r\n<pre class=\"lang:c decode:true \">typedef int Integer;\r\nInteger nStudents, nCourses, studentID;<\/pre>\r\nYukar\u0131da Integer olarak adland\u0131r\u0131lan, asl\u0131nda int tipinin ayn\u0131s\u0131 olan yeni bir veri tipi tan\u0131mlanarak bu veri tipindn 3 adet de\u011fi\u015fken yarat\u0131lm\u0131\u015ftr. B\u00f6yle bir \u015fey ilk bak\u0131\u015fta sa\u00e7ma gelebilir ancak burada b\u00fcy\u00fck ibretler vard\u0131r. Misal verecek olusak:\r\n<ol>\r\n \t<li>Integer isimli bir veri tipi, okunabilirlik a\u00e7\u0131s\u0131ndan int'den \u00e7ok daha iyidir.<\/li>\r\n \t<li>Gerek duyulursa typedef ileride farkl\u0131 \u015fekilde de\u011fi\u015ftirilebilir. \u00d6rne\u011fin \"typedef long Integer\". Bu sayede Integer tipinden tan\u0131mlanm\u0131\u015f t\u00fcm de\u011fi\u015fkenler bundan etkilenir. (Bunun dezavantaj olu\u015fturdu\u011fu durumlar da vard\u0131r)<\/li>\r\n<\/ol>\r\nAyr\u0131ca bu sayede, \u00f6rne\u011fin C dilini T\u00fcrk\u00e7ele\u015ftirmek bile m\u00fcmk\u00fcnd\u00fcr :)\r\n\r\nHemen misal verelim:\r\n<pre class=\"lang:c decode:true\" title=\"turkce_c.h\">#include &lt;stdio.h&gt;\r\n#include &lt;stdint.h&gt;\r\n\r\ntypedef int Sayi;\r\ntypedef char Karakter;\r\ntypedef long Uzun;\r\ntypedef float OndalikliSayi;\r\ntypedef double UzunOndalikliSayi;\r\ntypedef void HerhangiVeri\r\n\r\n#define ISARETSIZ unsigned\r\n#define EGER if\r\n#define OYLE_DEGILSE else\r\n#define OLDUGU_SURECE for\r\n#define OLDUKCA while\r\n\r\n#define ANA_PROGRAM main\r\n\r\n#define BASLIGI_EKLE include\r\n\r\n#define FONKSIYONDAN_CIK_VE_ILET_SU_DEGERI return\r\n\r\n#define YAZDIR printf<\/pre>\r\n<pre class=\"lang:default decode:true\">#BASLIGI_EKLE \"turkce_c.h\"\r\n\r\nSayi ANA_PROGRAM ()\r\n{\r\n  Uzun Sayi bizimSayac = 0;\r\n  OLDUGU_SURECE(bizmSayac = 0; bizimSayac&lt;2015; bizimSayac++)\r\n  {\r\n    EGER(bizimSayac == 1920 )\r\n    {\r\n       YAZDIR(\"Bu ne guzel gundur :)\");\r\n    }\r\n    OYLE_DEGILSE EGER(bizimSayac == 1923)\r\n    {\r\n       YAZDIR(\"Bu da cok guzel gundur :)\");\r\n    }\r\n    OYLE_DEGILSE\r\n    {\r\n       YAZDIR(\"Hedef 2023 :P\");\r\n    }\r\n  }\r\n  FONKSIYONDAN_CIK_VE_ILET_SU_DEGERI(42);\r\n}<\/pre>\r\nEpey e\u011flendik ama art\u0131k C \u00fczerine kurulmu\u015f\u00a0k\u00fc\u00e7\u00fck bir programlama dilimiz oldu. Hem de\u00a0 T\u00dcRK\u00c7E!\r\n\r\nT\u00fcm bu e\u011flenceye ek olarak, typedef tan\u0131m\u0131n\u0131n as\u0131l g\u00fcc\u00fc, kompleks veri tiplerinin tan\u0131mlanmas\u0131nda ortaya \u00e7\u0131kar. Bu da tam olarak struct'\u0131 anlatmaktad\u0131r.\r\n\r\nDi\u011fer de\u011fi\u015fkenler i\u00e7in ge\u00e7erli olan scope kavram\u0131, struct i\u00e7in de aynen ge\u00e7erlidir. Typedef olsun ya da olmas\u0131n, struct tipi tan\u0131mland\u0131\u011f\u0131 yerin scope'u kadarl\u0131k bir b\u00f6lgede tan\u0131ml\u0131 olur. Ne demek istiyorum? Misal typedef struct ile yap\u0131lan bir veri tipi tan\u0131m\u0131 bir fonksiyonun i\u00e7inde yap\u0131ld\u0131ysa, o de\u011fi\u015fken tipi ancak o fonksiyonun i\u00e7inde kullan\u0131labilecektir. Her yerde kullan\u0131lmas\u0131n\u0131 istedi\u011finiz bir veri tipi tan\u0131mlamak i\u00e7in, onu h dosyas\u0131nda tan\u0131mlaman\u0131z yeterli olacakt\u0131r. Bu sayede o h dosyas\u0131n\u0131 include ile ekleyen her c dosyas\u0131, tan\u0131mlanan bu yeni veri tipini kullanabilecektir.\r\n\r\n\u015eimdi bizim \u00f6\u011frenci \u00f6rne\u011fini typedef ile yapal\u0131m.\r\n<pre class=\"lang:c decode:true\">#define NAME_LEN (20)\r\ntypedef struct Student {\r\nint32_t nClasses;\r\nchar name [ NAME_LEN + 1 ] ;\r\ndouble_t gpa;\r\n} Student;<\/pre>\r\nArt\u0131k, Student tipi yeni bir veri tipi olarak tan\u0131mland\u0131\u011f\u0131ndan, Student tipinden yeni de\u011fi\u015fkenler yarataca\u011f\u0131m\u0131z zaman art\u0131k bir daha struct yazmaya gerek kalmaks\u0131z\u0131n de\u011fi\u015fken tan\u0131m\u0131 yapabilece\u011fiz. Misal \u015f\u00f6yle:\r\n<pre class=\"lang:c decode:true\">Student phil, georgina;<\/pre>\r\nYukar\u0131daki \u00f6rnekte, struct'un etiketi ile veri tipi ayn\u0131 tan\u0131mlanm\u0131\u015ft\u0131r. Bu m\u00fcmk\u00fcn olmakla birlikte zorunlu de\u011fildir. A\u015fa\u011f\u0131daki tan\u0131m, yukar\u0131daki ile ayn\u0131d\u0131r.\r\n<pre class=\"lang:default decode:true\">typedef struct {\r\nint32_t nClasses;\r\nchar name [ NAME_LEN + 1 ] ;\r\ndouble_t gpa;\r\n} Student;<\/pre>\r\nBen genelde struct tan\u0131mlar\u0131n\u0131 yukar\u0131daki gibi yap\u0131yorum. Kullan\u0131m\u0131 daha kolay geliyor :) Ayn\u0131 zamanda kod bence daha anla\u015f\u0131l\u0131r oluyor ancak bu k\u0131sm\u0131 tart\u0131\u015fmaya tamamen a\u00e7\u0131k bir yorum.\r\n\r\n<strong>Struct'a \u0130lk De\u011fer Atamas\u0131 Yapmak ve Struct'lar\u0131n Birbirine Atanmas\u0131<\/strong>\r\n\r\nStruct tipinde olan de\u011fi\u015fkenlere de farkl\u0131 \u015fekillerde ilk de\u011fer atamas\u0131 yap\u0131labilir. S\u00fcsl\u00fc parantez i\u00e7inde, her bir eleman s\u0131ras\u0131 ile virg\u00fcl ile ayr\u0131larak ilk de\u011fer atamas\u0131 yapmak m\u00fcmk\u00fcnd\u00fcr. Misal verelim:\r\n<pre class=\"lang:c decode:true\">Student john = { 3, \"John Doe\", 4. 0 }, susie = { 5, \"Susie Jones\" }; \/\/ Susie has a gpa of 0. 0<\/pre>\r\nYukar\u0131daki \u00f6rnekte susie adl\u0131 \u00a0\u00f6\u011frencinin gpa yani not de\u011feri girlmedi\u011finden ilk de\u011fer olarak 0.0 de\u011ferinin not olarak atanmas\u0131 beklenir. Ancak bu beklenti ger\u00e7ekle\u015fmeyebilir. \u0130lk de\u011fer atamas\u0131 yap\u0131lmayan de\u011ferler her zaman risk unsurudur ve m\u00fcmk\u00fcnse t\u00fcm verilere ilk de\u011fer atamas\u0131 yap\u0131lmal\u0131d\u0131r. Neyse :)\r\n\r\n\u0130lk de\u011fer atamas\u0131 bundan farkl\u0131 \u015fekillerde de yap\u0131labilmektedir. \u00d6rne\u011fin Linux kaynak dosyalar\u0131nda s\u0131kl\u0131kla g\u00f6rece\u011finiz bir de\u011fer atama \u015fekli a\u015fa\u011f\u0131daki gibidir:\r\n<pre class=\"lang:c decode:true \">Student jane = { . gpa = 4. 0 }, sue = { . name = \"Sue Smith\", 3. 5 };<\/pre>\r\nYukar\u0131daki y\u00f6ntem C'nin C99 destekleyen derleyicileri ile m\u00fcmk\u00fcnd\u00fcr ve bu sayede struct i\u00e7indeki de\u011fi\u015fkenlerin s\u0131ras\u0131 \u00f6nemsiz olmaktad\u0131r. \u00c7\u00fcnk\u00fc zaten \".isim\" ile hangi elemana ilk de\u011fer atamas\u0131 yapt\u0131\u011f\u0131m\u0131z\u0131 belirtmi\u015f oluyoruz. Bu y\u00f6ntemin, di\u011fer y\u00f6nteme g\u00f6re \u00e7i\u00e7ek gibi bir g\u00fczelli\u011fi vard\u0131r. Haydi diyelim bir struct tan\u0131mlad\u0131n\u0131z, sonra g\u00fcnlerden bir g\u00fcn i\u00e7iniz elvermedi ve structa bir eleman daha eklediniz. E\u011fer s\u0131ral\u0131 ilk de\u011fer atamas\u0131 yaparsan\u0131z (ilk \u00f6rnekteki gibi) ba\u015f\u0131n\u0131z dertte demektir \u00e7\u00fcnk\u00fc yaratt\u0131\u011f\u0131n\u0131z her bir sturct de\u011fi\u015fkeni i\u00e7in s\u0131ray\u0131 tek tek bulup do\u011fru yere ilk de\u011fer atamas\u0131n\u0131 yazman\u0131z gerekir. \u0130kinci y\u00f6ntemde ise koyun noktay\u0131 yaz\u0131n yeni de\u011fi\u015fkenin ad\u0131n\u0131, atay\u0131n de\u011feri ve arkan\u0131za yaslarken build tu\u015funa bas\u0131n :) Linuxcu day\u0131lardan al\u0131nacak \u00e7ok ibret var ama, burada da bu y\u00f6ntemi se\u00e7erken bir bildikleri oldu\u011funu g\u00f6r\u00fcyoruz.\r\n\r\n<strong>Struct'lar\u0131n Birbirlerine Atanmas\u0131<\/strong>\r\n\r\nAyn\u0131 tipteki iki de\u011fi\u015fken birbirine atanabilir. Bu ba\u011flamda ayn\u0131 struct tipindeki iki de\u011fi\u015fken de do\u011frudan birbirlerine atanabilecektir. Yaln\u0131z struct'lar\u0131n birbirlerine atanmalar\u0131 \u00e7ok s\u0131k\u0131nt\u0131l\u0131 ve dikkat edilmesi gereken bir mevzudur. Hatta struct'un herhangi bir \u015feye atanmas\u0131 dikkatle yap\u0131lmas\u0131 gereken bir i\u015flemdir ve baz\u0131 riskler bar\u0131nd\u0131r\u0131r.\r\n\r\nNe demek istiyorum? Diyelim ki sturct i\u00e7inde bir pointer var. Bu pointer bir yer i\u015faret ediyor.\u00a0Bir struct de\u011fi\u015fkenini bir ba\u015fkas\u0131na atamak, o structu kopyalamak anlam\u0131na gelmez. Sadece iki sturct'un da ayn\u0131 yeri g\u00f6stermesi anlam\u0131na gelir.\r\n\r\nBu k\u0131s\u0131m biraz uzayacak olsa da, \u00f6nemli oldu\u011fundan detayl\u0131ca anlatmaya \u00e7al\u0131\u015faca\u011f\u0131m. Bizim Student sturct'\u0131n\u0131n tipindeki de\u011fi\u015fkenleri birbirine atamak\/kopyalamak filan isteyelim. \u0130lk anda akla gelen 3 temel yol var.\r\n<pre class=\"lang:c decode:true \">typedef struct {\r\nint32_t nClasses;\r\nchar name [ NAME_LEN + 1 ] ;\r\ndouble_t gpa;\r\n} Student;\r\n\r\nStudent Ali, Veli;\r\n\/\/...\r\n\r\n\/\/yontem 1!!!\r\nAli.nClasses = Veli.nClasses;\r\nstrncopy(Ali.name, Veli.name, (NAME_LEN + 1));\r\nAli.gpa= Veli.gpa;\r\n\r\n\/\/yontem 2!!!\r\nmemcpy(&amp;Ali,&amp;Veli, sizeof(Student));\r\n\r\n\/\/yontem 3!!!\r\nAli = Veli;\r\n\r\n<\/pre>\r\n\u0130lk y\u00f6ntem, camiada amele y\u00f6ntemi olarak (asla hakaret\/a\u015fa\u011f\u0131lama ama\u00e7l\u0131 de\u011fildir!) bilinir ve \u00e7ok da tercih edilmez. Sonu\u00e7ta Veli'nin t\u00fcm bilgilerini Ali'ye atamak istiyorsak bunun daha g\u00fczel yollar\u0131 var.\r\n\r\n\u0130kinci y\u00f6ntem atamadan \u00e7ok kopyalamad\u0131r. Ad\u0131 \u00fcst\u00fcnde iki de\u011fi\u015fkenin i\u015faret etti\u011fi ya da tutuldu\u011fu bellek alanlar\u0131n\u0131 verilen uzunluk (sizeof Student) kadar byte kopyalar. Bu olay hard copy olarak ge\u00e7er ve bellek i\u00e7eri\u011fi tamamen kopyalan\u0131r. Yani ayn\u0131 bilgileri ta\u015f\u0131yan iki farkl\u0131 adres b\u00f6lgesi olur. Bu y\u00f6ntem \u00e7ok belay\u0131 def eder. Ali'nin bilgilerini Veli'ye aktar\u0131p sonra Veli'yi okuldan kovmak istiyorsan\u0131z bu y\u00f6ntem birebirdir \u00e7\u00fcnk\u00fc Veli'yi kovsan\u0131z bile, Veli'nin bilgileri Ali'nin akl\u0131nda ayr\u0131 bir yerde saklanm\u0131\u015f durumda olur.\r\n\r\n\u00dc\u00e7\u00fcnc\u00fc y\u00f6ntem k\u0131sa g\u00f6z\u00fckmekle birlikte derleyiciye \u00e7ok daha fazla optimizasyon \u015fans\u0131 b\u0131rak\u0131r. Bu da beklemedi\u011finiz baz\u0131 davran\u0131\u015flar\u0131 beraberinde getirebilir. Okunurluk a\u00e7\u0131s\u0131ndan da iki de\u011fi\u015fkeni birbirine atamak, kopyalamaktan daha farkl\u0131 bir mesaj verir ve do\u011fal olarak = operat\u00f6r\u00fc burda kopyalama de\u011fil atama i\u015fi yapar. Yani bizim Veli bildi\u011fimiz ki\u015fi art\u0131k ayn\u0131 zamanda Ali'dir. Bu durumda Veli'nin ba\u015f\u0131na bir\u015fey gelirse Ali'nin de ba\u015f\u0131na bir \u015fey gelecektir. Bu da \u00e7ok b\u00fcy\u00fck bela demektir.\r\n\r\nSizlere nacizane tavsiyem, bu y\u00f6ntemler \u00fczerinde denemeler yaparak davran\u0131\u015f\u0131 bir kez de kendiniz g\u00f6r\u00fcn\u00fcz. Sonra bir g\u00fcn ba\u015f\u0131n\u0131za gelir, \u00f6yle okuyup ge\u00e7erseniz hat\u0131rlamazs\u0131n\u0131z bile :) Bu konunun oturmas\u0131 i\u00e7in bu atamalar\u0131 yap\u0131p, alt\u0131nda printf ile struct adreslerinin ve struct elemanlar\u0131n\u0131n yazd\u0131r\u0131lmas\u0131 \u015fart. Belki aran\u0131zda sturct adresi nas\u0131l yazd\u0131r\u0131l\u0131r bilmeyen olabilir, onun i\u00e7in de hemen \u015f\u00f6yle ufac\u0131ktan yaz\u0131verelim:\r\n<pre class=\"lang:default decode:true \">printf(\"Ali'nin adresi :%d[%x]\",&amp;Ali,&amp;Ali);\r\n<\/pre>\r\nBa\u015f\u0131n\u0131z a\u011fr\u0131mas\u0131n istiyorsan\u0131z, yukar\u0131daki ama\u00e7 i\u00e7in y\u00f6ntem 2'yi \u00f6neririm. Ne yapt\u0131\u011f\u0131n\u0131z\u0131 \u00e7ok iyi biliyorsan\u0131z y\u00f6ntem 3'\u00fcn de avantaj getirece\u011fi durumlar vard\u0131r. Misal daha az bellek kullan\u0131rs\u0131n\u0131z. Ama \u00e7ok dikkat etmeniz gerekir. Hem de e\u011fer kodu tak\u0131m olarak geli\u015ftiriyorsan\u0131z, sizin \u00e7ok dikkat etmeniz yetmez, arkada\u015flar\u0131n\u0131z\u0131n da ayn\u0131 dikkati g\u00f6stermesi gerekir. E\u011fer tak\u0131m arkada\u015flar\u0131n\u0131z\u0131 seviyorsan\u0131z, onlara dikkat etmeleri gereken yeni \u015feyler vermeyin. Zorla\u015ft\u0131rmay\u0131n, kolayla\u015ft\u0131r\u0131n :)\r\n\r\n<strong>Struct'lar\u0131n\u00a0Pointer(\u0130\u015faret\u00e7i) ile \u0130mtihan\u0131<\/strong>\r\n\r\n\u015eimdi daha i\u015faret\u00e7ileri anlatmad\u0131m ama, zaten bu yaz\u0131 dizisinin do\u011fas\u0131 gere\u011fi sizin onu referans verilen kaynaklardan ya da ba\u015fka yerlerden \u00f6\u011frenmi\u015f olman\u0131z ya da zaten biliyor olman\u0131z gerekiyor. Ki burada olay\u0131n biraz daha ince detaylar\u0131n\u0131, felsefi y\u00f6nlerini de\u011ferlendirelim :)\r\n\r\nPointer yani i\u015faret\u00e7i dedi\u011fimiz nane, herhangi bir \u015feyin adresini tutabilir. Zaten i\u015faret etti\u011fi \u015fey de o adresin i\u00e7indeki veridir. Pislik yap\u0131p farkl\u0131 t\u00fcrde i\u015faret\u00e7iler ile bamba\u015fka t\u00fcrden verileri i\u015faret etmek de \u00e7irkin olsa da m\u00fcmk\u00fcnd\u00fcr. Ama \u00f6yle \u015feyler yapmayaca\u011f\u0131z, pointer hangi tipte veriyi i\u015faret edecekse o tipi g\u00f6sterecek.\r\n<pre class=\"lang:c decode:true\">int32_t index, numOfVars;\r\nint32_t *indextPtr = &amp;index;\r\nstruct Student alice, bob, carol;\r\nstruct Student *sptr = &amp;alice;<\/pre>\r\n\u00d6rnek kodumuzda, sptr de\u011fikeni struct Student* (struct Student i\u015faret\u00e7isi) tipinde bir i\u015faret\u00e7idir ve haliyle struct Student tipinden bir veriyi i\u015faret etmek ister. Nitekim bu i\u015faret\u00e7i, iste\u011fine kavu\u015fup alice'i i\u015faret etmi\u015ftir. Struct'lar\u0131 fonksiyona arg\u00fcman olarak filan verecekken t\u00fcm veriyi kopyalamak feci derecede k\u00f6t\u00fc bir tercihtir. Bu gibi durumlarda struct'\u0131n kendisini kopyalamak yerine, bellek adresini kopyalamak daha mant\u0131kl\u0131d\u0131r. Misal bizim Student struct'\u0131 nereden baksan\u0131z 28 Byte filan vard\u0131r. Oysa 32-bit'lik bir platformda her adres 4 Byte'd\u0131r. Bu sayede fonksiyona bu bilgiyi aktar\u0131rken 28 byte yerine 4 byte kopyalayarak, tam 24 byte kara ge\u00e7mi\u015f olduk. \u00a0B\u00f6yle g\u00fczide bir fonksiyon \u00f6rne\u011fini a\u015fa\u011f\u0131da hizmetinize sunuyorum.\r\n<pre class=\"lang:default decode:true\">void printStudentName( const struct Student *imaStudent );<\/pre>\r\n<pre class=\"lang:default decode:true\">void printStudentName( const struct Student *myStudent)\r\n{\r\n   printf(\"Name is %sn\",myStudent-&gt;name);\r\n}<\/pre>\r\nBu fonksiyonu \u00e7a\u011f\u0131rmak i\u00e7in de a\u015fa\u011f\u0131daki gibi \u00a0adresi(&amp;) operat\u00f6r\u00fcn\u00fc kullanabiliriz.\r\n<pre class=\"lang:c decode:true \">printStudentName( &amp;bob );<\/pre>\r\nDikkat ederseniz implementasyonda myStudent.name yerine\u00a0myStudent-&gt;name yapt\u0131k. Bunun sebebi, myStudent bir pointer oldu\u011fundan onun g\u00f6sterdi\u011fi bellek alan\u0131n\u0131 struct olarak d\u00fc\u015f\u00fcn\u00fcp oradaki name de\u011ferine ula\u015fmay\u0131 sa\u011flayan operat\u00f6r\u00fcn -&gt; operat\u00f6r\u00fc olmas\u0131d\u0131r.\u00a0myStudent de\u011fi\u015fkeninin tipi struct olmad\u0131\u011f\u0131ndan (\u00e7\u00fcnk\u00fc struct i\u015faret\u00e7isidir), nokta ile elemana ula\u015fmak do\u011fal olarak m\u00fcmk\u00fcn olmaz. Ancak <em>myStudent dedi\u011fimiz zaman art\u0131k \u00a0<\/em>(myStudent) ifadesinin tipi bir struct olacakt\u0131r. Dolay\u0131s\u0131yla onda nokta ile eri\u015fim yapmak a\u015fa\u011f\u0131daki t\u00fcm \u015fekillerde m\u00fcmk\u00fcnd\u00fcr.\r\n<pre class=\"lang:c decode:true \">*sptr.gpa = 4.0;\r\n\r\n\/\/ya da \r\n(*sptr).gpa = 4.0; \r\n\r\n\/\/ya da \r\nsptr-&gt;gpa = 4.0;\r\n\r\n\/\/ ve hatta ya da\r\ndouble *gpaPtr = &amp;carol.gpa;\r\n*gpaPtr = 4.0;<\/pre>\r\nBizim yap\u0131lar (struct'lar) i\u00e7lerinde temel tiplerin ya da kompleks tiplerin i\u015faret\u00e7ilerini ta\u015f\u0131yabilir. G\u00f6r\u00fcrseniz garibinize gitmesi i\u00e7in bir sebep yoktur.\r\n<pre class=\"lang:c decode:true\">struct Employee {\r\n       char *name;\r\n       struct Date * hiringDate;\r\n    };<a>Insert shortcode<\/a><\/pre>\r\nSturct i\u00e7inde i\u015faret\u00e7i g\u00f6r\u00fcrseniz, sturct atamas\u0131 yaparken iki defa d\u00fc\u015f\u00fcn\u00fcn ve y\u00f6ntem 2'yi akl\u0131n\u0131zda tutun l\u00fctfen :)\r\n\r\n<strong>Struct Bit Eri\u015fimi<\/strong>\r\n\r\nBu k\u0131s\u0131m \u00e7ok \u00e7ok \u00e7ok \u00e7ok \u00f6nemli. Dataheet modelleme ve s\u00fcr\u00fcc\u00fc yazma i\u015flerinde buray\u0131 bilhassa \u00e7ok kullanaca\u011f\u0131z. E\u011fer bu konuda \u00f6\u011frenebilece\u011finiz yeni bir \u015feyler var ise, l\u00fctfen dikkatle okuyunuz.(Zaten okumadan bunu kimse bilemeyecek :D )\r\n\r\nC dilindeki standart veri tipleri ile, en k\u00fc\u00e7\u00fck BYTE eri\u015fimi yapabilirsiniz. Oysa stuct ile belle\u011fi bit bit modellemek m\u00fcmk\u00fcnd\u00fcr. Bu hem bellekten kazan\u00e7 sa\u011flar, hem de \u00f6rne\u011fin datasheet modellemesinde, \u00e7i\u00e7ek gibi modelleme yapma imkan\u0131 sunar. Datasheet modellemeyi ileride anlataca\u011f\u0131m ancak, l\u00fctfen bu k\u0131sm\u0131n \u00e7ok \u00f6nemli oldu\u011funu unutmay\u0131n\u0131z, unutturmay\u0131n\u0131z.\r\n\r\nHemen h\u0131zl\u0131ca \u00f6rnek kodu yazal\u0131m.\r\n<pre class=\"lang:c decode:true\">#define NUM_OF_INVENTORY (100)\r\n    struct Packed_data {\r\n       uint32_t  is_element:1;   \/* = 1 if element *\r\n       uint32_t  is_reactant:1;\r\n       uint32_t  is_product:1;\r\n       uint32_t  is_catalyst:1;\r\n       uint32_t  reserved:4;\r\n       uint32_t  atomic_number:8;     \/* Maximum 255 *\/\r\n       uint32_t  Stock_Index:16; \/* Maximum 65,535 *\/\r\n    } chemical_inventory[ NUM_OF_INVENTORY ];<\/pre>\r\nis_element:1 demek, is_element de\u011fi\u015fkeni 1 bit yer kaplayacak demek. Bu durumda bu de\u011fi\u015fken ger\u00e7ek bir bool oluyor. atomic_number:8 demek,\u00a0atomic_number 8 byte yer kaplayacak demek. Bu durumda en fazla 255'e kadar de\u011fer alabilecek bu numara.\r\n\r\nHer \u015fey tamam da uint32_t ve reserved niye var. Sebebi \u015fu; 1 bit i\u015faret edebiliyorsunuz diye bellek i\u00e7indeki her bir biti can\u0131n\u0131z istedi\u011fi \u015fekilde y\u00f6netemezsiniz. Ne demek istiyorum? 32 bit'lik bit platformda her bellek g\u00f6z\u00fc 32'bit olacakt\u0131r. Ve siz bir bit'lik bir sturct tan\u0131mlasan\u0131z bile, daha \u00f6nce bahsetti\u011fim <a href=\"http:\/\/en.wikipedia.org\/wiki\/Data_structure_alignment\" target=\"_blank\" rel=\"noopener\">sturct alignment<\/a>\u00a0problemi y\u00fcz\u00fcnden geriye kalan 31 bit israf olacakt\u0131r. Derleyici buray\u0131 optimize etmek isterse de vay halinize \u00e7\u00fcnk\u00fc sizin 1 bitiniz ciddi olmayan bir az\u0131nl\u0131k oldu\u011fundan, \u00e7o\u011funlu\u011fun bekas\u0131 i\u00e7in feda edilebilir. Bunu engellemek i\u00e7in struct'umuzun boyutunu 32 bite tamamlad\u0131k. Nas\u0131l yani; 1+1+1+1+4+8+16 = 32 oldu. 32 bite tamamlayaca\u011f\u0131m\u0131z\u0131 pe\u015fin pe\u015fin s\u00f6ylemek i\u00e7inde \u00a0her eleman\u0131n tipini uint32_t: yapt\u0131k. Bu sayede hem olas\u0131 yanl\u0131\u015f optimizasyonlar\u0131 engelledik hem de kimyasal envanter i\u00e7in gerekli onca bilgiyi 32 bit'de saklad\u0131k. Peki b\u00f6yle yapmasayd\u0131k da a\u015fa\u011f\u0131daki gibi yapsayd\u0131k ne olurdu?\r\n<pre class=\"lang:c decode:true\">bool  is_element;   \/\/1 byte in\u015f\r\nbool  is_reactant; \/\/1 byte in\u015f\r\nbool  is_product; \/\/1 byte in\u015f\r\nbool  is_catalyst; \/\/1 byte in\u015f\r\nuint8_t  atomic_number;     \/\/1 byte \r\nuint16_t  Stock_Index; \/\/2 byte<\/pre>\r\nBu durumda bizim kimyasal envanter 7 byte yani 56 bit tutacakt\u0131 \u00e7\u00fcnk\u00fc bool tipi asla 1 bit tutmaz genelde 1 byte tutar. Struct memory alingment olaca\u011f\u0131ndan bu itina ile 64 byte'a tamamlanacakt\u0131. Yani tam 2 kat\u0131 bellek kullanm\u0131\u015f olacakt\u0131k. 1000 envanterde kaybedine tam 4000 Byte :( Hi\u00e7 gerek yok :)\r\n\r\nSturct i\u00e7in ilk turda bu kadar\u0131 yeterli.\r\n\r\n<strong>ENUM<\/strong>\r\n\r\nEnumerasyon diye T\u00fcrk\u00e7eye ittirilmeye \u00e7al\u0131\u015f\u0131lan bu terim asl\u0131nda etiketlenmi\u015f say\u0131 y\u0131\u011f\u0131n\u0131ndan ba\u015fka bir\u015fey de\u011fil. \u00a0Benim bildi\u011fim tam bir \u00e7evirisi olmamakla birlikte, say\u0131m etiketi olarak isimlendirmek m\u00fcmk\u00fcn olabilir. Ya da k\u0131saca enum da denebilir. Enum say\u0131 gibidir demi\u015ftik ama baz\u0131 farklar\u0131 var tabi\u00a0(o\u00a0farknan da \u00e7ok g\u00fczel oldu). Enum tipinde:\r\n<ul>\r\n \t<li>Sadece \u00f6nceden belirlenmi\u015f sabit de\u011ferlere izin verilir.<\/li>\r\n \t<li>Tan\u0131mlanm\u0131\u015f her bir de\u011fer isim ikilisi vard\u0131r. Bu sebeple enum ile \u00e7al\u0131\u015f\u0131rken say\u0131lar yerine ilgili de\u011fere kar\u015f\u0131 d\u00fc\u015fen isim kullan\u0131l\u0131r.<\/li>\r\n<\/ul>\r\nBurada \u00e7okca feyizler vard\u0131r. \"#define ile benzer bu\" diyenler olabilir. Oraya da gelece\u011fiz.\r\n\r\nHemen bir ka\u00e7 tan\u0131mlama \u00f6rne\u011fi patlatal\u0131m yine:\r\n<pre class=\"lang:c decode:true\">enum suits { CLUBS, HEARTS, SPADES, DIAMONDS, NOTRUMP } trump;\r\nenum suits ew_bid, ns_bid;<\/pre>\r\n<pre class=\"lang:default decode:true\">typedef enum Direction{ NORTH, SOUTH, EAST, WEST } Direction;\r\nDirection nextMove = SOUTH;<\/pre>\r\n&nbsp;\r\n\r\nBen yine yaz\u0131m olarak ve tan\u0131m olarak a\u015fa\u011f\u0131daki \u015fekli daha \u015f\u0131k buluyorum:\r\n<pre class=\"lang:c decode:true\">typedef enum \r\n{ \r\n  E_DIRECTION_NONE=0,\r\n  E_DIRECTION_NORTH,\r\n  E_DIRECTION_SOUTH,\r\n  E_DIRECTION_EAST,\r\n  E_DIRECTION_WEST \r\n}tE_Direction;\r\n\r\ntE_Direction eNextMove = E_DIRECTION_SOUTH;<\/pre>\r\nBurada oyunun kurallar\u0131 basit:\r\n<ul>\r\n \t<li>Herhangi bir enum eleman\u0131na, \u00f6zel bir de\u011fer atanabilir: misal E_DIRECTION_NONE say\u0131m etiketine 0 de\u011feri atad\u0131k.<\/li>\r\n \t<li>De\u011fer atanmayan say\u0131m etiketleri, bir \u00f6nceki etiketten bir fazla de\u011fer al\u0131r. Buna g\u00f6re\u00a0E_DIRECTION_NORTH etiketinin de\u011feri 1,\u00a0E_DIRECTION_SOUTH etiketinin de\u011feri 2 oldu vs.<\/li>\r\n \t<li>E\u011fer ilk etikete de\u011fer atanmad\u0131ysa, ona otomatik olarak s\u0131f\u0131r de\u011feri atan\u0131r.<\/li>\r\n<\/ul>\r\nEsasen size bir s\u0131r vereyim, ayn\u0131 de\u011feri birden fazla etikete atamak m\u00fcmk\u00fcnd\u00fcr. Ama inan\u0131n bana bu alenen \u00e7irkinle\u015fmektir, ve \u00e7irkinle\u015fmenin hi\u00e7 ama hi\u00e7 luzumu yoktur!\r\n\r\n<strong>Enum ve Define Kar\u015f\u0131 Kar\u015f\u0131ya<\/strong>\r\n\r\nH\u0131zl\u0131ca \u00f6zetlemek gerekirse; enum bir veri tipidir, define ise derleyicinin kopyala yap\u0131\u015ft\u0131r yapt\u0131\u011f\u0131 bir etikettir. Do\u011fal olarak enum tipinde de\u011fi\u015fken tan\u0131mlayabiliyoruz, nitekim tan\u0131mlad\u0131k. Bu de\u011fi\u015fkenler do\u011fal olarak RAM'de tutulur (const tan\u0131mlanmad\u0131larsa!). Define her yere aynen yap\u0131\u015ft\u0131r\u0131laca\u011f\u0131ndan, geni\u015fletilebilirlik a\u00e7\u0131s\u0131ndan enum kullanmak \u00e7ok faydal\u0131d\u0131r. Enumerasyon yapmak i\u00e7in define kullanmay\u0131n\u0131z, enum kullan\u0131n\u0131z. Etiketleme (define) yapmak i\u00e7in enum kullanmay\u0131n\u0131z, define kullan\u0131n\u0131z.\r\n\r\nDiyelim bir durum makinas\u0131n\u0131n durumlar\u0131n\u0131 saklayacaks\u0131n\u0131z. Burada enum kullanmak gerekir \u00e7\u00fcnk\u00fc e\u011fer define kullan\u0131rsan\u0131z, yar\u0131n yeni bir state eklendi\u011finde ve onun ara de\u011ferde olmas\u0131 gerekti\u011finde, t\u00fcm define'lar\u0131 teker teker de\u011fi\u015ftirmeniz gerekir. Oysa enumda rastgele bir yere yazd\u0131\u011f\u0131n\u0131zda su akacak ve yolunu en g\u00fczel \u015fekilde bulacakt\u0131r.\r\n\r\n\u015eimdi enum ile ilgiliverdi\u011fimiz bu \u00f6rne\u011fi kod olaraktan aktaral\u0131m:\r\n<pre class=\"lang:c decode:true \">typedef enum \r\n{\r\n E_STATE_NONE=0,\r\n E_STATE_START,\r\n E_STATE_SEND,\r\n E_STATE_RECEIVE,\r\n E_STATE_STOP,\r\n E_STATE_LAST\r\n}tE_STATE; \r\n\r\ntE_STATE eState = E_STATE_NONE; \r\n\r\nswitch(eState)\r\n{\r\n  case E_STATE_NONE:\r\n     DoJobForNone();\r\n  break;\r\n  case E_STATE_START:\r\n     DoJobForStart();\r\n  break;\r\n  case E_STATE_SEND:\r\n     DoJobForSend();\r\n  break;\r\n  case E_STATE_RECEIVE:\r\n     DoJobForReceive();\r\n  break;\r\n  case E_STATE_STOP:\r\n     DoJobForStop();\r\n  break;\r\n  default:\r\n     DoErrorRecovery();\r\n  break;\r\n\r\n}<\/pre>\r\nG\u00f6rd\u00fc\u011f\u00fcn\u00fcz \u00fczere \u00e7i\u00e7ek gibi oldu \u00e7i\u00e7ek :)\r\n\r\n<strong>UNION<\/strong>\r\n\r\nGeldik \u00fc\u00e7 silah\u015f\u00f6rlerin \u00fc\u00e7\u00fcnc\u00fcs\u00fcne... Union yani birlik!\r\n\r\nBizim unionlar aynen struct gibi tan\u0131mlan\u0131r ve kullan\u0131m \u015fekilleri (kullan\u0131m yerleri de\u011fil) \u00e7ok \u00e7ok benzerdir. Ancak \u00e7ok \u00f6nemli bir fark vard\u0131r:\r\n\r\nStruct'lar i\u00e7lerindeki verileri ard\u0131\u015f\u0131l olarak saklayabilecek kadar belle\u011fi kendilerine ay\u0131r\u0131rlar. Union'da ise union'un boyutu, union i\u00e7indeki en b\u00fcy\u00fck boyutlu eleman\u0131n boyutu kadard\u0131r \u00e7\u00fcnk\u00fc union'un t\u00fcm elemanlar\u0131 asl\u0131nda belle\u011fin ayn\u0131 g\u00f6z\u00fcn\u00fc (ayn\u0131 adresi) g\u00f6sterirler. Bu \u00f6zellik ba\u015fta i\u015fe yaramaz gibi g\u00f6z\u00fckse de, \u00f6zellikle verinin bilgiye d\u00f6n\u00fc\u015ft\u00fcr\u00fclmesinde yani yorumlanmas\u0131nda \u00e7ok i\u015fe yarar \u015fekilde kar\u015f\u0131m\u0131za \u00e7\u0131kmaktad\u0131r.\r\n\r\nHemen ibretlik bir kod payla\u015fal\u0131m.\r\n\r\n&nbsp;\r\n<pre class=\"lang:c decode:true \">   #define FLIGHT_CAPACITY (100)\r\n   typedef struct Flight {\r\n       enum { PASSENGER, CARGO } type;\r\n       union {\r\n           uint32_t nPassengers;\r\n           float_t tonnages;  \/\/ Units are not necessarily tons.\r\n       } cargo;\r\n   } Flight;\r\n\r\n   Flight flights[FLIGHT_CAPACITY];\r\n\r\n   flights[42].type = PASSENGER;\r\n   flights[42].cargo.nPassengers = 150;\r\n\r\n   flights[20].type = CARGO;\r\n   flights[20].cargo.tonnages = 356.78;\r\n<\/pre>\r\nBurada union kullan\u0131larak 4 byte'dan kar edildi. \u00c7\u00fcnk\u00fc ayn\u0131 u\u00e7u\u015f sturct'\u0131 i\u00e7inde e\u011fer u\u00e7u\u015f tipi kargo ise float olarak tonaj de\u011fi\u015fkeni, e\u011fer u\u00e7u\u015f tipi yolcu ise uint32_t olarak nPassengers (yolcu say\u0131s\u0131) de\u011fi\u015fkeni ayn\u0131 bellek g\u00f6z\u00fcn\u00fc g\u00f6sterir. Bu olay, inan\u0131lmaz zekice bir olayd\u0131r ve anla\u015f\u0131lmay\u0131 hak etmektedir.\r\n\r\nBurada union kullan\u0131lmasa idi, haybeye 4 byte harcanacakt\u0131. Bu durumda nPassengers ve tonnages de\u011fi\u015fkenleri belle\u011fe ard\u0131\u015f\u0131l olarak yerle\u015fecekti. Halbuki d\u00fc\u015f\u00fcn\u00fcnce b\u00f6yle bir ihtiya\u00e7 ger\u00e7ekte yok \u00e7\u00fcnk\u00fc bu iki de\u011fi\u015fken asla ayn\u0131 anda kullan\u0131lamayacak. \u0130\u015fte burada union geldi ve bir Flight i\u00e7in 4 byte, 100 Flight i\u00e7in 400 byte kar etmemizi sa\u011flad\u0131.\r\n\r\nKodun ne kadar karizmatik oldu\u011funa de\u011finmiyorum bile. Belki oradan al\u0131p y\u00fcr\u00fcyecekler de olabilir.\r\n\r\nHemen eski yaz\u0131lar\u0131m\u0131zda a\u00e7\u0131klad\u0131\u011f\u0131m\u0131z ibretlik bir \u00f6rne\u011fi daha sizlerle payla\u015f\u0131yorum:\r\n<pre class=\"lang:c decode:true \">uint32_t nRead;\r\n   uint32_t index;\r\n   typedef union {\r\n       uint32_t u32Data;\r\n       int16_t  as16Data[2];\r\n       int8_t   as8Data[4];\r\n   }tu_DataGroup32;\r\n\r\n   tu_DataGroup32 UData;\r\n   \/\/ ( Code to read in nRead, from the user or a file, has been omitted in this example )\r\n    UData.u32Data = nRead;\r\n    for(  index= 0; index &lt; sizeof(uint32_t); index++ )\r\n    {\r\n        printf( \"Byte number %d of %ud is %udn\", index, nRead, UData.int8_t[index] );\r\n    }<\/pre>\r\nBurada da union ile yine bit kayd\u0131rma, maskeleme i\u015flerini hi\u00e7 yapmadan 32 bitlik bir veriye hem byte byte, hem 2 byte 2 byte hem de t\u00fcmden eri\u015febiliyoruz. Bu olay\u0131 da \u00f6zellikle haberle\u015fme yaz\u0131l\u0131mlar\u0131nda s\u0131k\u00e7a kullanaca\u011f\u0131z. \u00d6rnek kodlarla bunlar\u0131 denemeyi unutmay\u0131n\u0131z :)\r\n\r\nYaz\u0131lar\u0131 be\u011fendiyseniz e\u011fer, \u00a0faydalanabilecek arkada\u015flar\u0131n\u0131zla da payla\u015fabilirseniz sevinirim ;)\r\n\r\n\u015eimdi devam...\r\n\r\n[su_button url=\"http:\/\/ozenozkaya.com\/blog\/?p=282\" style=\"3d\"\u00a0icon=\"icon: arrow-circle-o-left\"]\u00d6nceki Sayfa[\/su_button] \u00a0[su_button url=\"http:\/\/ozenozkaya.com\/blog\/?p=294\" style=\"3d\" icon=\"icon: arrow-circle-right\"]Sonraki Sayfa[\/su_button]\r\n\r\n&nbsp;","_tr_post_name":"gomulu-sistemler-23-gomulu-c-yapilar","_tr_post_excerpt":"","_tr_post_title":"G\u00f6m\u00fcl\u00fc C - 12 : Yap\u0131lar","_en_post_content":"","_en_post_name":"","_en_post_excerpt":"","_en_post_title":"","edit_language":"tr","jetpack_post_was_ever_published":false,"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_memberships_contains_paid_content":false,"footnotes":"","jetpack_publicize_message":"","jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":true,"jetpack_social_options":{"image_generator_settings":{"template":"highway","default_image_id":0,"enabled":false},"version":2}},"categories":[2,3],"tags":[],"class_list":["post-286","post","type-post","status-publish","format-standard","hentry","category-elektronik","category-gomulu-sistemler"],"jetpack_publicize_connections":[],"jetpack_featured_media_url":"","jetpack_sharing_enabled":true,"jetpack_shortlink":"https:\/\/wp.me\/p5gWM6-4C","jetpack-related-posts":[],"_links":{"self":[{"href":"http:\/\/ozenozkaya.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/286","targetHints":{"allow":["GET"]}}],"collection":[{"href":"http:\/\/ozenozkaya.com\/blog\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/ozenozkaya.com\/blog\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/ozenozkaya.com\/blog\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"http:\/\/ozenozkaya.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=286"}],"version-history":[{"count":2,"href":"http:\/\/ozenozkaya.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/286\/revisions"}],"predecessor-version":[{"id":595,"href":"http:\/\/ozenozkaya.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/286\/revisions\/595"}],"wp:attachment":[{"href":"http:\/\/ozenozkaya.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=286"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/ozenozkaya.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=286"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/ozenozkaya.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=286"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}