<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" ><generator uri="https://jekyllrb.com/" version="4.4.1">Jekyll</generator><link href="https://program.sonsuz.us/feed.xml" rel="self" type="application/atom+xml" /><link href="https://program.sonsuz.us/" rel="alternate" type="text/html" /><updated>2026-10-18T00:05:43+00:00</updated><id>https://program.sonsuz.us/feed.xml</id><title type="html">SonsuzUs</title><subtitle>Programlama ve Yazılım</subtitle><author><name>Sonsuz Us</name></author><entry><title type="html">Async Kodun Gizli Freni: Bloklayan Çağrılar Event Loop’u Nasıl Durdurur?</title><link href="https://program.sonsuz.us/posts/async-kodun-gizli-freni-bloklayan-cagrilar-event-loopu-nasil-durdurur/" rel="alternate" type="text/html" title="Async Kodun Gizli Freni: Bloklayan Çağrılar Event Loop’u Nasıl Durdurur?" /><published>2026-10-17T00:00:00+00:00</published><updated>2026-10-17T00:00:00+00:00</updated><id>https://program.sonsuz.us/posts/async-kodun-gizli-freni-bloklayan-cagrilar-event-loopu-nasil-durdurur</id><content type="html" xml:base="https://program.sonsuz.us/posts/async-kodun-gizli-freni-bloklayan-cagrilar-event-loopu-nasil-durdurur/"><![CDATA[<p>Python’da <code class="language-plaintext highlighter-rouge">async</code> ve <code class="language-plaintext highlighter-rouge">await</code> kullanmak, kodun otomatik olarak hızlı veya tamamen eşzamanlı çalışacağı anlamına gelmez. Asenkron bir fonksiyonun içine sıradan, bloklayan bir çağrı yerleştirirseniz diğer görevler beklemeye başlar. Tek şeritli bir yola park edilen kamyon gibi, küçücük görünen bu çağrı bütün event loop trafiğini durdurabilir.
``</p>

<h2 id="event-loop-gerçekte-ne-yapar">Event loop gerçekte ne yapar?</h2>

<p><code class="language-plaintext highlighter-rouge">asyncio</code> event loop, çalışmaya hazır görevleri sırayla ilerleten bir koordinatördür. Bir coroutine <code class="language-plaintext highlighter-rouge">await</code> ile kontrolü gönüllü biçimde bıraktığında loop başka bir göreve geçebilir. Buradaki kritik nokta şudur: Görev kontrolü bırakmazsa event loop onu zorla kenara çekmez.</p>

<p>Yaklaşık toplam bekleme süresini şöyle düşünebiliriz:</p>

\[T_{toplam} \approx \max(T_1, T_2, \ldots, T_n)\]

<p>Bu avantaj yalnızca görevler uygun noktalarda kontrolü event loop’a iade ederse geçerlidir. Bloklayan işlemler seri biçimde yürütülürse süre şu modele yaklaşır:</p>

\[T_{toplam} \approx \sum_{i=1}^{n} T_i\]

<table>
  <thead>
    <tr>
      <th>İşlem</th>
      <th style="text-align: right">Event loop’a kontrol verir mi?</th>
      <th>Sonuç</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">await asyncio.sleep(1)</code></td>
      <td style="text-align: right">Evet</td>
      <td>Diğer görevler çalışır</td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">time.sleep(1)</code></td>
      <td style="text-align: right">Hayır</td>
      <td>Tüm loop bir saniye donar</td>
    </tr>
    <tr>
      <td>Asenkron HTTP isteği</td>
      <td style="text-align: right">Evet</td>
      <td>Ağ beklenirken görev değişir</td>
    </tr>
    <tr>
      <td>Senkron dosya veya HTTP çağrısı</td>
      <td style="text-align: right">Hayır</td>
      <td>İşlem bitene kadar loop bekler</td>
    </tr>
    <tr>
      <td>Yoğun CPU hesabı</td>
      <td style="text-align: right">Hayır</td>
      <td>İş parçacığı uzun süre meşgul kalır</td>
    </tr>
  </tbody>
</table>

<h2 id="masum-görünen-hata">Masum görünen hata</h2>

<p>Aşağıdaki örnekte fonksiyon <code class="language-plaintext highlighter-rouge">async</code> olsa da içindeki <code class="language-plaintext highlighter-rouge">time.sleep</code> bloklayıcıdır:</p>

<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kn">import</span> <span class="n">asyncio</span>
<span class="kn">import</span> <span class="n">time</span>

<span class="k">async</span> <span class="k">def</span> <span class="nf">is_yap</span><span class="p">(</span><span class="n">no</span><span class="p">:</span> <span class="nb">int</span><span class="p">):</span>
    <span class="nf">print</span><span class="p">(</span><span class="sa">f</span><span class="sh">'</span><span class="si">{</span><span class="n">no</span><span class="si">}</span><span class="s"> başladı</span><span class="sh">'</span><span class="p">)</span>
    <span class="n">time</span><span class="p">.</span><span class="nf">sleep</span><span class="p">(</span><span class="mi">2</span><span class="p">)</span>  <span class="c1"># Event loop burada tamamen durur.
</span>    <span class="nf">print</span><span class="p">(</span><span class="sa">f</span><span class="sh">'</span><span class="si">{</span><span class="n">no</span><span class="si">}</span><span class="s"> bitti</span><span class="sh">'</span><span class="p">)</span>

<span class="k">async</span> <span class="k">def</span> <span class="nf">main</span><span class="p">():</span>
    <span class="k">await</span> <span class="n">asyncio</span><span class="p">.</span><span class="nf">gather</span><span class="p">(</span><span class="o">*</span><span class="p">(</span><span class="nf">is_yap</span><span class="p">(</span><span class="n">i</span><span class="p">)</span> <span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="nf">range</span><span class="p">(</span><span class="mi">3</span><span class="p">)))</span>

<span class="n">asyncio</span><span class="p">.</span><span class="nf">run</span><span class="p">(</span><span class="nf">main</span><span class="p">())</span>
</code></pre></div></div>

<p>Üç görev oluşturulmasına rağmen yaklaşık altı saniye beklenir. Çünkü ilk görev <code class="language-plaintext highlighter-rouge">time.sleep(2)</code> çalıştırırken diğer coroutine’ler işlemciye ulaşamaz. Fonksiyon başındaki <code class="language-plaintext highlighter-rouge">async</code> ifadesi, içindeki senkron kodu sihirli biçimde asenkronlaştırmaz.</p>

<p>Uyku yalnızca beklemeyi temsil ediyorsa doğru çözüm <code class="language-plaintext highlighter-rouge">asyncio.sleep</code> kullanmaktır:</p>

<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">async</span> <span class="k">def</span> <span class="nf">is_yap</span><span class="p">(</span><span class="n">no</span><span class="p">:</span> <span class="nb">int</span><span class="p">):</span>
    <span class="nf">print</span><span class="p">(</span><span class="sa">f</span><span class="sh">'</span><span class="si">{</span><span class="n">no</span><span class="si">}</span><span class="s"> başladı</span><span class="sh">'</span><span class="p">)</span>
    <span class="k">await</span> <span class="n">asyncio</span><span class="p">.</span><span class="nf">sleep</span><span class="p">(</span><span class="mi">2</span><span class="p">)</span>  <span class="c1"># Kontrol event loop'a geri verilir.
</span>    <span class="nf">print</span><span class="p">(</span><span class="sa">f</span><span class="sh">'</span><span class="si">{</span><span class="n">no</span><span class="si">}</span><span class="s"> bitti</span><span class="sh">'</span><span class="p">)</span>
</code></pre></div></div>

<p>Bu sürümde görevler birlikte ilerler ve toplam süre yaklaşık iki saniye olur.</p>

<h2 id="senkron-kütüphaneyi-çöpe-mi-atalım">Senkron kütüphaneyi çöpe mi atalım?</h2>

<p>Her bloklayan kütüphanenin asenkron alternatifi bulunmayabilir. Python 3.9 ve sonrasında <code class="language-plaintext highlighter-rouge">asyncio.to_thread</code>, bloklayan I/O işlemini ayrı bir iş parçacığında çalıştırmayı kolaylaştırır:</p>

<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kn">import</span> <span class="n">asyncio</span>
<span class="kn">import</span> <span class="n">time</span>

<span class="k">def</span> <span class="nf">eski_raporu_uret</span><span class="p">():</span>
    <span class="n">time</span><span class="p">.</span><span class="nf">sleep</span><span class="p">(</span><span class="mi">3</span><span class="p">)</span>
    <span class="k">return</span> <span class="sh">'</span><span class="s">Rapor hazır</span><span class="sh">'</span>

<span class="k">async</span> <span class="k">def</span> <span class="nf">main</span><span class="p">():</span>
    <span class="n">sonuc</span> <span class="o">=</span> <span class="k">await</span> <span class="n">asyncio</span><span class="p">.</span><span class="nf">to_thread</span><span class="p">(</span><span class="n">eski_raporu_uret</span><span class="p">)</span>
    <span class="nf">print</span><span class="p">(</span><span class="n">sonuc</span><span class="p">)</span>

<span class="n">asyncio</span><span class="p">.</span><span class="nf">run</span><span class="p">(</span><span class="nf">main</span><span class="p">())</span>
</code></pre></div></div>

<p>Burada event loop beklerken donmaz; başka görevleri yürütmeye devam eder. Ancak <code class="language-plaintext highlighter-rouge">to_thread</code> özellikle dosya, ağ veya eski SDK çağrıları gibi I/O ağırlıklı işler için uygundur.</p>

<h2 id="cpu-ağırlıklı-işler-farklıdır">CPU ağırlıklı işler farklıdır</h2>

<p>Büyük görüntü işleme, asal sayı arama veya karmaşık veri dönüşümü gibi CPU ağırlıklı işler de event loop’u bloke eder. Bunları bir thread’e taşımak, Python’ın GIL davranışı nedeniyle her zaman gerçek paralellik sağlamaz. Böyle durumlarda <code class="language-plaintext highlighter-rouge">ProcessPoolExecutor</code> daha doğru seçim olabilir:</p>

<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kn">import</span> <span class="n">asyncio</span>
<span class="kn">from</span> <span class="n">concurrent.futures</span> <span class="kn">import</span> <span class="n">ProcessPoolExecutor</span>

<span class="k">def</span> <span class="nf">agir_hesaplama</span><span class="p">(</span><span class="n">n</span><span class="p">:</span> <span class="nb">int</span><span class="p">):</span>
    <span class="k">return</span> <span class="nf">sum</span><span class="p">(</span><span class="n">i</span> <span class="o">*</span> <span class="n">i</span> <span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="nf">range</span><span class="p">(</span><span class="n">n</span><span class="p">))</span>

<span class="k">async</span> <span class="k">def</span> <span class="nf">main</span><span class="p">():</span>
    <span class="n">loop</span> <span class="o">=</span> <span class="n">asyncio</span><span class="p">.</span><span class="nf">get_running_loop</span><span class="p">()</span>
    <span class="k">with</span> <span class="nc">ProcessPoolExecutor</span><span class="p">()</span> <span class="k">as</span> <span class="n">havuz</span><span class="p">:</span>
        <span class="n">sonuc</span> <span class="o">=</span> <span class="k">await</span> <span class="n">loop</span><span class="p">.</span><span class="nf">run_in_executor</span><span class="p">(</span>
            <span class="n">havuz</span><span class="p">,</span> <span class="n">agir_hesaplama</span><span class="p">,</span> <span class="mi">20_000_000</span>
        <span class="p">)</span>
    <span class="nf">print</span><span class="p">(</span><span class="n">sonuc</span><span class="p">)</span>

<span class="n">asyncio</span><span class="p">.</span><span class="nf">run</span><span class="p">(</span><span class="nf">main</span><span class="p">())</span>
</code></pre></div></div>

<p>Kısacası <code class="language-plaintext highlighter-rouge">async/await</code>, bloklamayı ortadan kaldıran bir büyü değil, bekleme anlarını yönetme protokolüdür. Kod incelemesinde <code class="language-plaintext highlighter-rouge">time.sleep</code>, senkron HTTP istemcileri, ağır dosya işlemleri ve uzun döngüler özellikle aranmalıdır. Event loop’un sağlıklı kalmasının altın kuralı basittir: Ya kontrolü hızla geri verin ya da bloklayan işi uygun bir thread veya process havuzuna taşıyın.</p>

<p><img src="/img/async-kodun-gizli-69.svg" alt="async-kodun-gizli-69" /></p>]]></content><author><name>Sonsuz Us</name></author><category term="Bilgi" /><category term="python" /><category term="asyncio" /><category term="async-await" /><category term="event-loop" /><category term="eşzamanlılık" /><category term="performans" /><summary type="html"><![CDATA[Python’da async ve await kullanmak, kodun otomatik olarak hızlı veya tamamen eşzamanlı çalışacağı anlamına gelmez. Asenkron bir fonksiyonun içine sıradan, bloklayan bir çağrı yerleştirirseniz diğer görevler beklemeye başlar. Tek şeritli bir yola park edilen kamyon gibi, küçücük görünen bu çağrı bütün event loop trafiğini durdurabilir.]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://program.sonsuz.us/img/async-kodun-gizli-69.png" /><media:content medium="image" url="https://program.sonsuz.us/img/async-kodun-gizli-69.png" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">C++ Akış ve Dosya G/Ç Sistemi: Verinin Yolculuğunu Yönetmek</title><link href="https://program.sonsuz.us/posts/c-akis-ve-dosya-gc-sistemi-verinin-yolculugunu-yonetmek/" rel="alternate" type="text/html" title="C++ Akış ve Dosya G/Ç Sistemi: Verinin Yolculuğunu Yönetmek" /><published>2026-10-17T00:00:00+00:00</published><updated>2026-10-17T00:00:00+00:00</updated><id>https://program.sonsuz.us/posts/c-akis-ve-dosya-gc-sistemi-verinin-yolculugunu-yonetmek</id><content type="html" xml:base="https://program.sonsuz.us/posts/c-akis-ve-dosya-gc-sistemi-verinin-yolculugunu-yonetmek/"><![CDATA[<p>C++ programlarında veri bazen klavyeden gelir, bazen ekrana gider, bazen de bir dosyada yıllarca uyumayı bekler. Akış sistemi, verinin kaynağıyla hedefi arasındaki bu yolculuğu ortak ve nesne yönelimli bir arayüz üzerinden yönetir. Böylece geliştirici, klavye ile dosya arasında geçiş yaparken tamamen farklı yöntemler öğrenmek zorunda kalmaz.</p>

<p><img src="/img/c-akis-ve-62.svg" alt="c-akis-ve-62" /></p>

<p>``</p>

<h2 id="akış-mantığı-nedir">Akış Mantığı Nedir?</h2>

<p>Bir <strong>stream</strong>, sıralı biçimde taşınan karakter veya baytların oluşturduğu soyut bir kanaldır. Program çoğu zaman gerçek cihazla doğrudan ilgilenmez; akış nesnesine veri gönderir veya ondan veri ister. <code class="language-plaintext highlighter-rouge">std::cin</code>, <code class="language-plaintext highlighter-rouge">std::cout</code>, <code class="language-plaintext highlighter-rouge">std::cerr</code> ve dosya sınıfları bu yaklaşımın örnekleridir.</p>

<p>Akışların nesne yönelimli yapısı sınıf hiyerarşisine dayanır. <code class="language-plaintext highlighter-rouge">std::ios</code> biçimlendirme ve durum bilgisini taşırken <code class="language-plaintext highlighter-rouge">std::istream</code> okuma, <code class="language-plaintext highlighter-rouge">std::ostream</code> yazma davranışlarını sunar. <code class="language-plaintext highlighter-rouge">std::iostream</code> ise ikisini birleştirir. Dosya tarafındaki sınıflar aynı arayüzleri dosya tamponlarıyla ilişkilendirir.</p>

<table>
  <thead>
    <tr>
      <th>Sınıf</th>
      <th>Görevi</th>
      <th>Yaygın kullanım</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">std::ifstream</code></td>
      <td>Dosyadan okuma</td>
      <td>Yapılandırma yükleme</td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">std::ofstream</code></td>
      <td>Dosyaya yazma</td>
      <td>Rapor veya günlük oluşturma</td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">std::fstream</code></td>
      <td>Okuma ve yazma</td>
      <td>Kayıt güncelleme</td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">std::stringstream</code></td>
      <td>Bellekte metin akışı</td>
      <td>Ayrıştırma ve dönüştürme</td>
    </tr>
  </tbody>
</table>

<p>Tamponlama, her küçük işlemde diske erişilmesini engeller. Kabaca toplam maliyet</p>

\[T \approx n \cdot t_{işlem} + k \cdot t_{G/Ç}\]

<p>şeklinde düşünülebilir. Tampon kullanıldığında pahalı G/Ç sayısı olan $k$ azalır. <code class="language-plaintext highlighter-rouge">flush</code> işlemi tamponu zorla hedefe aktarır; gereksiz kullanılması performansı düşürebilir.</p>

<h2 id="nesne-yönelimli-dosya-okuma-ve-yazma">Nesne Yönelimli Dosya Okuma ve Yazma</h2>

<p>Dosya nesneleri kaynak yönetimini <strong>RAII</strong> yaklaşımıyla gerçekleştirir. Nesne kapsamdan çıktığında dosya otomatik olarak kapatılır. Yine de açılışın başarılı olup olmadığını kontrol etmek gerekir.</p>

<div class="language-cpp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="cp">#include</span> <span class="cpf">&lt;fstream&gt;</span><span class="cp">
#include</span> <span class="cpf">&lt;iostream&gt;</span><span class="cp">
#include</span> <span class="cpf">&lt;string&gt;</span><span class="cp">
</span>
<span class="kt">int</span> <span class="nf">main</span><span class="p">()</span> <span class="p">{</span>
    <span class="n">std</span><span class="o">::</span><span class="n">ofstream</span> <span class="n">cikti</span><span class="p">(</span><span class="s">"notlar.txt"</span><span class="p">,</span> <span class="n">std</span><span class="o">::</span><span class="n">ios</span><span class="o">::</span><span class="n">app</span><span class="p">);</span>

    <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="n">cikti</span><span class="p">)</span> <span class="p">{</span>
        <span class="n">std</span><span class="o">::</span><span class="n">cerr</span> <span class="o">&lt;&lt;</span> <span class="s">"Dosya açılamadı!</span><span class="se">\n</span><span class="s">"</span><span class="p">;</span>
        <span class="k">return</span> <span class="mi">1</span><span class="p">;</span>
    <span class="p">}</span>

    <span class="n">cikti</span> <span class="o">&lt;&lt;</span> <span class="s">"Akışlar nesne yönelimlidir."</span> <span class="o">&lt;&lt;</span> <span class="sc">'\n'</span><span class="p">;</span>
<span class="p">}</span>
</code></pre></div></div>

<p>Buradaki <code class="language-plaintext highlighter-rouge">std::ios::app</code>, yeni veriyi dosyanın sonuna ekler. Varsayılan davranışta <code class="language-plaintext highlighter-rouge">ofstream</code>, mevcut içeriği silebilir. Başlıca kipler şöyledir:</p>

<table>
  <thead>
    <tr>
      <th>Kip</th>
      <th>Anlamı</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">std::ios::in</code></td>
      <td>Okuma için açar</td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">std::ios::out</code></td>
      <td>Yazma için açar</td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">std::ios::app</code></td>
      <td>Sona ekler</td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">std::ios::trunc</code></td>
      <td>İçeriği temizler</td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">std::ios::binary</code></td>
      <td>İkili kip kullanır</td>
    </tr>
  </tbody>
</table>

<p>Metin dosyasını satır satır okumak için <code class="language-plaintext highlighter-rouge">std::getline</code> güvenli ve anlaşılır bir seçimdir:</p>

<div class="language-cpp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">std</span><span class="o">::</span><span class="n">ifstream</span> <span class="nf">girdi</span><span class="p">(</span><span class="s">"notlar.txt"</span><span class="p">);</span>
<span class="n">std</span><span class="o">::</span><span class="n">string</span> <span class="n">satir</span><span class="p">;</span>

<span class="k">while</span> <span class="p">(</span><span class="n">std</span><span class="o">::</span><span class="n">getline</span><span class="p">(</span><span class="n">girdi</span><span class="p">,</span> <span class="n">satir</span><span class="p">))</span> <span class="p">{</span>
    <span class="n">std</span><span class="o">::</span><span class="n">cout</span> <span class="o">&lt;&lt;</span> <span class="n">satir</span> <span class="o">&lt;&lt;</span> <span class="sc">'\n'</span><span class="p">;</span>
<span class="p">}</span>

<span class="k">if</span> <span class="p">(</span><span class="n">girdi</span><span class="p">.</span><span class="n">bad</span><span class="p">())</span> <span class="p">{</span>
    <span class="n">std</span><span class="o">::</span><span class="n">cerr</span> <span class="o">&lt;&lt;</span> <span class="s">"Fiziksel bir okuma hatası oluştu.</span><span class="se">\n</span><span class="s">"</span><span class="p">;</span>
<span class="p">}</span>
</code></pre></div></div>

<p>Döngü, okuma başarılı olduğu sürece çalışır. <code class="language-plaintext highlighter-rouge">while (!girdi.eof())</code> yaklaşımı önerilmez; çünkü EOF bayrağı ancak başarısız bir okuma denemesinden sonra etkinleşir.</p>

<h2 id="durum-bayrakları-ve-hata-yönetimi">Durum Bayrakları ve Hata Yönetimi</h2>

<p>Akış nesneleri kendi sağlık durumlarını saklar. <code class="language-plaintext highlighter-rouge">good()</code> sorun olmadığını, <code class="language-plaintext highlighter-rouge">eof()</code> dosya sonunu, <code class="language-plaintext highlighter-rouge">fail()</code> biçimsel veya mantıksal başarısızlığı, <code class="language-plaintext highlighter-rouge">bad()</code> ise daha ciddi G/Ç hatasını bildirir. Hata sonrasında <code class="language-plaintext highlighter-rouge">clear()</code> bayrakları sıfırlar; fakat hatalı karakterler hâlâ tampondaysa <code class="language-plaintext highlighter-rouge">ignore()</code> ile temizleme gerekebilir.</p>

<div class="language-cpp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kt">int</span> <span class="n">sayi</span><span class="p">;</span>
<span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="p">(</span><span class="n">std</span><span class="o">::</span><span class="n">cin</span> <span class="o">&gt;&gt;</span> <span class="n">sayi</span><span class="p">))</span> <span class="p">{</span>
    <span class="n">std</span><span class="o">::</span><span class="n">cin</span><span class="p">.</span><span class="n">clear</span><span class="p">();</span>
    <span class="n">std</span><span class="o">::</span><span class="n">cin</span><span class="p">.</span><span class="n">ignore</span><span class="p">(</span><span class="mi">10000</span><span class="p">,</span> <span class="sc">'\n'</span><span class="p">);</span>
    <span class="n">std</span><span class="o">::</span><span class="n">cout</span> <span class="o">&lt;&lt;</span> <span class="s">"Geçersiz sayı girdiniz.</span><span class="se">\n</span><span class="s">"</span><span class="p">;</span>
<span class="p">}</span>
</code></pre></div></div>

<h2 id="konumlandırma-ve-i̇kili-dosyalar">Konumlandırma ve İkili Dosyalar</h2>

<p><code class="language-plaintext highlighter-rouge">tellg()</code> ve <code class="language-plaintext highlighter-rouge">tellp()</code> mevcut okuma-yazma konumunu verir; <code class="language-plaintext highlighter-rouge">seekg()</code> ve <code class="language-plaintext highlighter-rouge">seekp()</code> konumu değiştirir. Bu özellik büyük dosyalarda doğrudan belirli bir kayda erişmeyi sağlar. İkili dosyalar <code class="language-plaintext highlighter-rouge">read()</code> ve <code class="language-plaintext highlighter-rouge">write()</code> ile işlenebilir; ancak sınıfları ham baytlarla kaydetmek taşınabilir değildir. Dolgulama, endian düzeni ve işaretçi üyeleri sorun çıkarabilir. Kalıcı veriler için açık bir serileştirme biçimi tasarlamak daha güvenlidir.</p>

<p>Sonuç olarak C++ akış sistemi yalnızca dosya açıp kapatan bir araç değildir. Ortak arayüzler, durum yönetimi, tamponlama ve RAII sayesinde farklı veri kaynaklarını aynı zihinsel model altında birleştiren güçlü bir soyutlamadır.</p>]]></content><author><name>Sonsuz Us</name></author><category term="Bilgi" /><category term="c++" /><category term="stream" /><category term="dosya işlemleri" /><category term="girdi çıktı" /><category term="oop" /><category term="fstream" /><summary type="html"><![CDATA[C++ programlarında veri bazen klavyeden gelir, bazen ekrana gider, bazen de bir dosyada yıllarca uyumayı bekler. Akış sistemi, verinin kaynağıyla hedefi arasındaki bu yolculuğu ortak ve nesne yönelimli bir arayüz üzerinden yönetir. Böylece geliştirici, klavye ile dosya arasında geçiş yaparken tamamen farklı yöntemler öğrenmek zorunda kalmaz.]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://program.sonsuz.us/img/c-akis-ve-62.png" /><media:content medium="image" url="https://program.sonsuz.us/img/c-akis-ve-62.png" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">C++ API Tasarımında Değer Semantiği mi, Referans Semantiği mi?</title><link href="https://program.sonsuz.us/posts/c-api-tasariminda-deger-semantigi-mi-referans-semantigi-mi/" rel="alternate" type="text/html" title="C++ API Tasarımında Değer Semantiği mi, Referans Semantiği mi?" /><published>2026-10-17T00:00:00+00:00</published><updated>2026-10-17T00:00:00+00:00</updated><id>https://program.sonsuz.us/posts/c-api-tasariminda-deger-semantigi-mi-referans-semantigi-mi</id><content type="html" xml:base="https://program.sonsuz.us/posts/c-api-tasariminda-deger-semantigi-mi-referans-semantigi-mi/"><![CDATA[<p><img src="/img/c-api-tasariminda-87.svg" alt="c-api-tasariminda-87" /></p>

<p>Bir C++ API’sinin bir nesneyi kopyalaması mı, yoksa mevcut nesneye erişim sağlaması mı gerektiği küçük bir imza tercihi gibi görünebilir. Oysa bu karar; sahiplikten performansa, hata ayıklamadan eşzamanlılığa kadar bütün tasarımı etkiler. Kısacası <code class="language-plaintext highlighter-rouge">Widget</code> ile <code class="language-plaintext highlighter-rouge">Widget&amp;</code> arasındaki tek karakterlik fark, bazen bakım maliyetinde destan yazdırır.</p>

<p>``</p>

<h2 id="i̇ki-semantiğin-temel-fikri">İki semantiğin temel fikri</h2>

<p><strong>Değer semantiğinde</strong> değişken, bağımsız bir değeri temsil eder. Kopyalanan iki nesne başlangıçta eşit olabilir; ancak biri değiştirildiğinde diğeri etkilenmez. <code class="language-plaintext highlighter-rouge">int</code>, <code class="language-plaintext highlighter-rouge">std::string</code> ve <code class="language-plaintext highlighter-rouge">std::vector</code> bu modele iyi örneklerdir.</p>

<p><strong>Referans semantiğinde</strong> ise farklı değişkenler aynı nesnenin kimliğine erişebilir. Nesne üzerindeki değişiklikler tüm gözlemciler tarafından görülebilir. Burada önemli olan yalnızca içerik değil, nesnenin <em>hangi nesne</em> olduğudur.</p>

<p>Matematiksel olarak değer kopyalamayı şöyle düşünebiliriz:</p>

\[b = copy(a) \Rightarrow a = b\]

<p>Ancak sonradan <code class="language-plaintext highlighter-rouge">b</code> değiştirildiğinde genellikle:</p>

\[modify(b) \nRightarrow modify(a)\]

<p>Referanslarda ise <code class="language-plaintext highlighter-rouge">a</code> ve <code class="language-plaintext highlighter-rouge">b</code> aynı nesneyi gösteriyorsa durum farklıdır:</p>

\[identity(a) = identity(b) \Rightarrow modify(b) = modify(a)\]

<table>
  <thead>
    <tr>
      <th>Ölçüt</th>
      <th>Değer semantiği</th>
      <th>Referans semantiği</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Sahiplik</td>
      <td>Genellikle açık ve yerel</td>
      <td>Haricen yönetilebilir</td>
    </tr>
    <tr>
      <td>Bağımsızlık</td>
      <td>Kopyalar bağımsızdır</td>
      <td>Aynı nesne paylaşılabilir</td>
    </tr>
    <tr>
      <td>Yaşam süresi</td>
      <td>Değerin kapsamına bağlıdır</td>
      <td>Dangling riski taşır</td>
    </tr>
    <tr>
      <td>Değişiklik etkisi</td>
      <td>Yereldir</td>
      <td>Uzak kodu etkileyebilir</td>
    </tr>
    <tr>
      <td>Eşzamanlılık</td>
      <td>Daha kolay yönetilir</td>
      <td>Senkronizasyon gerekebilir</td>
    </tr>
    <tr>
      <td>Polimorfizm</td>
      <td>Nesne dilimleme riski vardır</td>
      <td>Doğal biçimde desteklenir</td>
    </tr>
  </tbody>
</table>

<h2 id="parametrelerde-seçimin-anlamı">Parametrelerde seçimin anlamı</h2>

<p>Bir fonksiyon parametresini değerle almak, fonksiyonun kendi bağımsız nesnesine sahip olacağını anlatır:</p>

<div class="language-cpp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">class</span> <span class="nc">Report</span> <span class="p">{</span>
<span class="nl">public:</span>
    <span class="kt">void</span> <span class="n">addPage</span><span class="p">(</span><span class="kt">int</span> <span class="n">page</span><span class="p">);</span>
<span class="p">};</span>

<span class="kt">void</span> <span class="nf">archive</span><span class="p">(</span><span class="n">Report</span> <span class="n">report</span><span class="p">)</span> <span class="p">{</span>
    <span class="n">report</span><span class="p">.</span><span class="n">addPage</span><span class="p">(</span><span class="mi">42</span><span class="p">);</span>
    <span class="c1">// Çağıranın nesnesi değişmez.</span>
<span class="p">}</span>
</code></pre></div></div>

<p>Bu yaklaşım özellikle fonksiyon nesneyi saklayacaksa veya dönüştürecekse kullanışlıdır. Çağıran geçici bir değer ya da <code class="language-plaintext highlighter-rouge">std::move</code> ile taşıma sağladığında gereksiz kopyalar azaltılabilir.</p>

<p>Salt okuma amaçlı büyük nesnelerde <code class="language-plaintext highlighter-rouge">const T&amp;</code>, kopyalama maliyetini önler:</p>

<div class="language-cpp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kt">void</span> <span class="nf">print</span><span class="p">(</span><span class="k">const</span> <span class="n">Report</span><span class="o">&amp;</span> <span class="n">report</span><span class="p">)</span> <span class="p">{</span>
    <span class="c1">// report okunabilir fakat değiştirilemez.</span>
<span class="p">}</span>
</code></pre></div></div>

<p>Buradaki <code class="language-plaintext highlighter-rouge">const</code>, sahiplik vermez; yalnızca bu erişim yolu üzerinden değişikliği engeller. Fonksiyon referansı saklıyorsa çağıranın nesnesi daha erken yok olabilir. API, bu yaşam süresi sözleşmesini açıkça belirtmelidir.</p>

<p>Değiştirilebilir <code class="language-plaintext highlighter-rouge">T&amp;</code> ise fonksiyonun çağıranın nesnesini değiştireceğini bildirir:</p>

<div class="language-cpp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kt">void</span> <span class="nf">normalize</span><span class="p">(</span><span class="n">Report</span><span class="o">&amp;</span> <span class="n">report</span><span class="p">)</span> <span class="p">{</span>
    <span class="n">report</span><span class="p">.</span><span class="n">addPage</span><span class="p">(</span><span class="mi">1</span><span class="p">);</span>
<span class="p">}</span>
</code></pre></div></div>

<p>Böyle bir API etkili olsa da yan etki üretir. Sonuç döndüren değer tabanlı bir alternatif çoğu zaman daha anlaşılırdır:</p>

<div class="language-cpp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">Report</span> <span class="nf">normalized</span><span class="p">(</span><span class="n">Report</span> <span class="n">report</span><span class="p">)</span> <span class="p">{</span>
    <span class="n">report</span><span class="p">.</span><span class="n">addPage</span><span class="p">(</span><span class="mi">1</span><span class="p">);</span>
    <span class="k">return</span> <span class="n">report</span><span class="p">;</span>
<span class="p">}</span>
</code></pre></div></div>

<p>Modern C++’ta taşıma semantiği ve kopya eleme sayesinde bu sürüm, göründüğünden daha ucuz olabilir. Yaklaşık maliyeti $C_{copy}$ yerine çoğu durumda $C_{move}$ veya doğrudan $0$ olur.</p>

<h2 id="dönüş-değerleri-ve-sahiplik">Dönüş değerleri ve sahiplik</h2>

<p>Yeni bir nesne üreten fonksiyonun <code class="language-plaintext highlighter-rouge">T</code> döndürmesi genellikle en güvenli seçenektir. <code class="language-plaintext highlighter-rouge">T&amp;</code> döndürmek ise var olan bir nesneye takma ad verir; nesnenin yaşam süresi çağıranın kullanımından uzun olmalıdır. Yerel değişkene referans döndürmek kesinlikle hatalıdır.</p>

<p>Paylaşılan kimlik gerçekten gerekliyse akıllı işaretçiler sözleşmeyi görünür kılar:</p>

<ul>
  <li><code class="language-plaintext highlighter-rouge">std::unique_ptr&lt;T&gt;</code>: Tekil sahiplik aktarılır.</li>
  <li><code class="language-plaintext highlighter-rouge">std::shared_ptr&lt;T&gt;</code>: Sahiplik paylaşılır.</li>
  <li><code class="language-plaintext highlighter-rouge">std::weak_ptr&lt;T&gt;</code>: Sahip olmadan gözlem yapılır.</li>
  <li><code class="language-plaintext highlighter-rouge">T*</code> veya <code class="language-plaintext highlighter-rouge">T&amp;</code>: Genellikle sahip olunmayan erişim sunulur.</li>
</ul>

<h2 id="pratik-karar-rehberi">Pratik karar rehberi</h2>

<p>Para, koordinat, tarih ve yapılandırma gibi bağımsız kavramlarda değer semantiğini tercih edin. Veritabanı bağlantısı, pencere, cihaz, aktör veya polimorfik servis gibi kimliği önemli varlıklarda referans semantiği daha doğaldır.</p>

<p>API’nin davranışını şu sorularla sınayın: Nesne kopyalanınca anlam bozuluyor mu? Fonksiyon sahipliği devralıyor mu? Değişiklik çağırana yansımalı mı? Referansın geçerlilik süresi açık mı? Eşzamanlı erişim mümkün mü?</p>

<p>En iyi seçim her zaman en hızlı görünen seçenek değildir. İyi bir C++ API’si, sahiplik ve değişebilirlik niyetini tür sistemi üzerinden anlatır. Değer semantiği varsayılan güvenli liman; referans semantiği ise kimlik, paylaşım veya polimorfizm gerçekten gerektiğinde kullanılan güçlü ama dikkat isteyen araçtır.</p>]]></content><author><name>Sonsuz Us</name></author><category term="Bilgi" /><category term="c++" /><category term="api tasarımı" /><category term="değer semantiği" /><category term="referans semantiği" /><category term="bellek yönetimi" /><category term="modern c++" /><summary type="html"><![CDATA[Bir C++ API’sinin bir nesneyi kopyalaması mı, yoksa mevcut nesneye erişim sağlaması mı gerektiği küçük bir imza tercihi gibi görünebilir. Oysa bu karar; sahiplikten performansa, hata ayıklamadan eşzamanlılığa kadar bütün tasarımı etkiler. Kısacası Widget ile Widget&amp; arasındaki tek karakterlik fark, bazen bakım maliyetinde destan yazdırır.]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://program.sonsuz.us/img/c-api-tasariminda-87.png" /><media:content medium="image" url="https://program.sonsuz.us/img/c-api-tasariminda-87.png" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">C Fonksiyonları: Argümanlardan Özyinelemeye Tekrar Kullanılabilir Kod</title><link href="https://program.sonsuz.us/posts/c-fonksiyonlari-argumanlardan-ozyinelemeye-tekrar-kullanilabilir-kod/" rel="alternate" type="text/html" title="C Fonksiyonları: Argümanlardan Özyinelemeye Tekrar Kullanılabilir Kod" /><published>2026-10-17T00:00:00+00:00</published><updated>2026-10-17T00:00:00+00:00</updated><id>https://program.sonsuz.us/posts/c-fonksiyonlari-argumanlardan-ozyinelemeye-tekrar-kullanilabilir-kod</id><content type="html" xml:base="https://program.sonsuz.us/posts/c-fonksiyonlari-argumanlardan-ozyinelemeye-tekrar-kullanilabilir-kod/"><![CDATA[<p>C programlarında her işi <code class="language-plaintext highlighter-rouge">main</code> fonksiyonuna yüklemek, bütün eşyaları tek çekmeceye doldurmaya benzer: Başlangıçta kolay görünür, fakat aradığını bulmak kısa sürede işkenceye dönüşür. Fonksiyonlar, büyük problemleri adlandırılmış ve tekrar kullanılabilir küçük parçalara ayırır. Böylece kod daha okunabilir, test edilebilir ve değiştirilebilir hâle gelir.</p>

<p><img src="/img/c-fonksiyonlari-argumanlardan-91.svg" alt="c-fonksiyonlari-argumanlardan-91" /></p>

<p>``</p>

<h2 id="fonksiyonun-anatomisi">Fonksiyonun anatomisi</h2>

<p>Bir C fonksiyonu dönüş türü, ad, parametre listesi ve gövdeden oluşur. Fonksiyon kullanılmadan önce derleyicinin onun imzasını bilmesi gerekir. Bu nedenle prototipler çoğunlukla dosyanın üst bölümünde veya bir başlık dosyasında bulunur.</p>

<div class="language-c highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="cp">#include</span> <span class="cpf">&lt;stdio.h&gt;</span><span class="cp">
</span>
<span class="kt">int</span> <span class="nf">maksimum</span><span class="p">(</span><span class="kt">int</span> <span class="n">a</span><span class="p">,</span> <span class="kt">int</span> <span class="n">b</span><span class="p">);</span>  <span class="c1">// Fonksiyon prototipi</span>

<span class="kt">int</span> <span class="nf">main</span><span class="p">(</span><span class="kt">void</span><span class="p">)</span> <span class="p">{</span>
    <span class="kt">int</span> <span class="n">sonuc</span> <span class="o">=</span> <span class="n">maksimum</span><span class="p">(</span><span class="mi">12</span><span class="p">,</span> <span class="mi">7</span><span class="p">);</span>
    <span class="n">printf</span><span class="p">(</span><span class="s">"Büyük değer: %d</span><span class="se">\n</span><span class="s">"</span><span class="p">,</span> <span class="n">sonuc</span><span class="p">);</span>
    <span class="k">return</span> <span class="mi">0</span><span class="p">;</span>
<span class="p">}</span>

<span class="kt">int</span> <span class="nf">maksimum</span><span class="p">(</span><span class="kt">int</span> <span class="n">a</span><span class="p">,</span> <span class="kt">int</span> <span class="n">b</span><span class="p">)</span> <span class="p">{</span>
    <span class="k">return</span> <span class="p">(</span><span class="n">a</span> <span class="o">&gt;</span> <span class="n">b</span><span class="p">)</span> <span class="o">?</span> <span class="n">a</span> <span class="o">:</span> <span class="n">b</span><span class="p">;</span>
<span class="p">}</span>
</code></pre></div></div>

<p>Burada <code class="language-plaintext highlighter-rouge">a</code> ve <code class="language-plaintext highlighter-rouge">b</code> birer <strong>parametre</strong>, çağrıdaki <code class="language-plaintext highlighter-rouge">12</code> ve <code class="language-plaintext highlighter-rouge">7</code> ise <strong>argümandır</strong>. <code class="language-plaintext highlighter-rouge">int</code> dönüş türü, fonksiyonun çağırana bir tam sayı göndereceğini belirtir. Değer döndürmeyen fonksiyonlarda <code class="language-plaintext highlighter-rouge">void</code> kullanılır.</p>

<table>
  <thead>
    <tr>
      <th>Kavram</th>
      <th>Görevi</th>
      <th>Örnek</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Prototip</td>
      <td>Fonksiyonun imzasını bildirir</td>
      <td><code class="language-plaintext highlighter-rouge">int maksimum(int, int);</code></td>
    </tr>
    <tr>
      <td>Parametre</td>
      <td>Fonksiyonun aldığı yerel değişkendir</td>
      <td><code class="language-plaintext highlighter-rouge">int a</code></td>
    </tr>
    <tr>
      <td>Argüman</td>
      <td>Çağrı sırasında gönderilen değerdir</td>
      <td><code class="language-plaintext highlighter-rouge">maksimum(12, 7)</code></td>
    </tr>
    <tr>
      <td>Dönüş değeri</td>
      <td>Sonucu çağırana iletir</td>
      <td><code class="language-plaintext highlighter-rouge">return a;</code></td>
    </tr>
  </tbody>
</table>

<h2 id="cde-argüman-aktarımı">C’de argüman aktarımı</h2>

<p>C, argümanları varsayılan olarak <strong>değer ile</strong> aktarır. Yani fonksiyon, özgün değişkenin kendisini değil kopyasını alır. Matematiksel olarak bunu $p = x$ biçiminde düşünebiliriz: <code class="language-plaintext highlighter-rouge">p</code> başlangıçta <code class="language-plaintext highlighter-rouge">x</code> ile aynı değere sahiptir, ancak ayrı bir saklama alanıdır.</p>

<div class="language-c highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kt">void</span> <span class="nf">arttir</span><span class="p">(</span><span class="kt">int</span> <span class="n">sayi</span><span class="p">)</span> <span class="p">{</span>
    <span class="n">sayi</span><span class="o">++</span><span class="p">;</span>
<span class="p">}</span>
</code></pre></div></div>

<p>Bu fonksiyon çağıranın değişkenini değiştirmez. Kalıcı değişiklik için değişkenin adresi, yani bir işaretçi aktarılır:</p>

<div class="language-c highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kt">void</span> <span class="nf">arttir</span><span class="p">(</span><span class="kt">int</span> <span class="o">*</span><span class="n">sayi</span><span class="p">)</span> <span class="p">{</span>
    <span class="p">(</span><span class="o">*</span><span class="n">sayi</span><span class="p">)</span><span class="o">++</span><span class="p">;</span>
<span class="p">}</span>

<span class="kt">int</span> <span class="nf">main</span><span class="p">(</span><span class="kt">void</span><span class="p">)</span> <span class="p">{</span>
    <span class="kt">int</span> <span class="n">puan</span> <span class="o">=</span> <span class="mi">10</span><span class="p">;</span>
    <span class="n">arttir</span><span class="p">(</span><span class="o">&amp;</span><span class="n">puan</span><span class="p">);</span>  <span class="c1">// puan artık 11</span>
    <span class="k">return</span> <span class="mi">0</span><span class="p">;</span>
<span class="p">}</span>
</code></pre></div></div>

<p><code class="language-plaintext highlighter-rouge">&amp;puan</code> değişkenin adresini verir; <code class="language-plaintext highlighter-rouge">*sayi</code> ise o adresteki değere erişir. Diziler fonksiyonlara gönderildiğinde ilk elemanlarının adresine dönüştükleri için yapılan değişiklikler özgün dizi üzerinde görülebilir.</p>

<table>
  <thead>
    <tr>
      <th>Yaklaşım</th>
      <th>Fonksiyona giden</th>
      <th style="text-align: right">Özgün veri değişir mi?</th>
      <th>Kullanım</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Değer aktarımı</td>
      <td>Verinin kopyası</td>
      <td style="text-align: right">Hayır</td>
      <td>Küçük ve salt okunur veriler</td>
    </tr>
    <tr>
      <td>İşaretçi aktarımı</td>
      <td>Bellek adresi</td>
      <td style="text-align: right">Evet</td>
      <td>Çıktı üretme, dizi veya yapı güncelleme</td>
    </tr>
  </tbody>
</table>

<p>İşaretçiler güçlüdür; fakat <code class="language-plaintext highlighter-rouge">NULL</code> adresler ve geçersiz bellek erişimleri kontrol edilmezse programı beklenmedik bir maceraya çıkarabilir.</p>

<h2 id="özyineleme-fonksiyonun-kendisini-çağırması">Özyineleme: Fonksiyonun kendisini çağırması</h2>

<p>Özyinelemeli bir fonksiyon problemi daha küçük bir örneğine dönüştürerek kendisini çağırır. Her özyinelemede iki parça zorunludur: çağrıları durduran <strong>taban durum</strong> ve problemi küçülten <strong>özyinelemeli adım</strong>.</p>

<p>Faktöriyel matematiksel olarak şöyle tanımlanır:</p>

\[n! = n \times (n-1)!, \quad 0! = 1\]

<div class="language-c highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kt">unsigned</span> <span class="kt">long</span> <span class="kt">long</span> <span class="nf">faktoriyel</span><span class="p">(</span><span class="kt">unsigned</span> <span class="kt">int</span> <span class="n">n</span><span class="p">)</span> <span class="p">{</span>
    <span class="k">if</span> <span class="p">(</span><span class="n">n</span> <span class="o">==</span> <span class="mi">0</span><span class="p">)</span> <span class="p">{</span>              <span class="c1">// Taban durum</span>
        <span class="k">return</span> <span class="mi">1</span><span class="p">;</span>
    <span class="p">}</span>
    <span class="k">return</span> <span class="n">n</span> <span class="o">*</span> <span class="n">faktoriyel</span><span class="p">(</span><span class="n">n</span> <span class="o">-</span> <span class="mi">1</span><span class="p">);</span> <span class="c1">// Daha küçük problem</span>
<span class="p">}</span>
</code></pre></div></div>

<p><code class="language-plaintext highlighter-rouge">faktoriyel(4)</code> çağrısı, $4 \times 3 \times 2 \times 1$ sonucunu üretir. Her çağrı dönüş adresi ve yerel değişkenleriyle çağrı yığınına eklenir. Taban durum unutulursa çağrılar sürer ve sonunda <strong>stack overflow</strong> oluşabilir.</p>

<p>Bu örneğin zaman karmaşıklığı $T(n)=T(n-1)+O(1)$ olduğundan $O(n)$, çağrı yığını kullanımı da $O(n)$ olur. Döngülü sürüm aynı zaman karmaşıklığıyla genellikle $O(1)$ ek bellek tüketir. Buna karşılık ağaç dolaşma, böl-ve-yönet ve iç içe geçmiş yapılar özyineleme ile daha doğal ifade edilebilir.</p>

<p>Fonksiyon tasarlarken tek sorumluluk ilkesini benimsemek, açıklayıcı adlar seçmek ve gereksiz küresel değişkenlerden kaçınmak önemlidir. Kısacası fonksiyonlar yalnızca kod tekrarını azaltmaz; programın düşünce haritasını da oluşturur. İyi bölünmüş bir C programı, hem derleyicinin hem de gelecekteki sizin teşekkür edeceği bir programdır.</p>]]></content><author><name>Sonsuz Us</name></author><category term="Bilgi" /><category term="c" /><category term="fonksiyonlar" /><category term="programlama" /><category term="özyineleme" /><category term="algoritma" /><category term="parametreler" /><summary type="html"><![CDATA[C programlarında her işi main fonksiyonuna yüklemek, bütün eşyaları tek çekmeceye doldurmaya benzer: Başlangıçta kolay görünür, fakat aradığını bulmak kısa sürede işkenceye dönüşür. Fonksiyonlar, büyük problemleri adlandırılmış ve tekrar kullanılabilir küçük parçalara ayırır. Böylece kod daha okunabilir, test edilebilir ve değiştirilebilir hâle gelir.]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://program.sonsuz.us/img/c-fonksiyonlari-argumanlardan-91.png" /><media:content medium="image" url="https://program.sonsuz.us/img/c-fonksiyonlari-argumanlardan-91.png" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">C# Generics: Tür Güvenli ve Performanslı Koleksiyonların Sırrı</title><link href="https://program.sonsuz.us/posts/c-generics-tur-guvenli-ve-performansli-koleksiyonlarin-sirri/" rel="alternate" type="text/html" title="C# Generics: Tür Güvenli ve Performanslı Koleksiyonların Sırrı" /><published>2026-10-17T00:00:00+00:00</published><updated>2026-10-17T00:00:00+00:00</updated><id>https://program.sonsuz.us/posts/c-generics-tur-guvenli-ve-performansli-koleksiyonlarin-sirri</id><content type="html" xml:base="https://program.sonsuz.us/posts/c-generics-tur-guvenli-ve-performansli-koleksiyonlarin-sirri/"><![CDATA[<p>Bir kutuya kalem koyup daha sonra içinden kahve kupası çıkarmayı beklemezsiniz. C# koleksiyonlarında da benzer bir düzen gerekir: Eklenen ve alınan değerlerin türü önceden bilinmelidir. Genel türler, yani <em>generics</em>, bu düzeni derleme zamanında sağlayarak çalışma anındaki sürpriz tür dönüşümü hatalarını azaltır ve özellikle değer türlerinde daha iyi performans sunar.</p>

<p>``</p>

<h2 id="generic-yapı-nedir">Generic yapı nedir?</h2>

<p>Generic yapı; sınıf, metot, arayüz veya temsilcinin çalışacağı veri türünü baştan sabitlemek yerine bir tür parametresiyle tanımlamaktır. En yaygın gösterim olan <code class="language-plaintext highlighter-rouge">T</code>, İngilizce <em>type</em> kelimesinden gelir; ancak zorunlu bir isim değildir.</p>

<div class="language-csharp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">public</span> <span class="k">class</span> <span class="nc">Kutu</span><span class="p">&lt;</span><span class="n">T</span><span class="p">&gt;</span>
<span class="p">{</span>
    <span class="k">public</span> <span class="n">T</span> <span class="n">Deger</span> <span class="p">{</span> <span class="k">get</span><span class="p">;</span> <span class="k">set</span><span class="p">;</span> <span class="p">}</span>

    <span class="k">public</span> <span class="nf">Kutu</span><span class="p">(</span><span class="n">T</span> <span class="n">deger</span><span class="p">)</span>
    <span class="p">{</span>
        <span class="n">Deger</span> <span class="p">=</span> <span class="n">deger</span><span class="p">;</span>
    <span class="p">}</span>
<span class="p">}</span>

<span class="kt">var</span> <span class="n">sayiKutusu</span> <span class="p">=</span> <span class="k">new</span> <span class="n">Kutu</span><span class="p">&lt;</span><span class="kt">int</span><span class="p">&gt;(</span><span class="m">42</span><span class="p">);</span>
<span class="kt">var</span> <span class="n">metinKutusu</span> <span class="p">=</span> <span class="k">new</span> <span class="n">Kutu</span><span class="p">&lt;</span><span class="kt">string</span><span class="p">&gt;(</span><span class="s">"Merhaba"</span><span class="p">);</span>
</code></pre></div></div>

<p>Burada aynı <code class="language-plaintext highlighter-rouge">Kutu&lt;T&gt;</code> sınıfı hem <code class="language-plaintext highlighter-rouge">int</code> hem de <code class="language-plaintext highlighter-rouge">string</code> ile kullanılabilir. Buna rağmen iki kutunun kuralları birbirinden ayrıdır. Örneğin <code class="language-plaintext highlighter-rouge">sayiKutusu.Deger</code> özelliğine metin atanması derleme aşamasında engellenir.</p>

<h2 id="eski-yaklaşım-ve-tür-güvenliği">Eski yaklaşım ve tür güvenliği</h2>

<p>Generic koleksiyonlardan önce farklı türleri saklamak için sıklıkla <code class="language-plaintext highlighter-rouge">ArrayList</code> kullanılırdı. Bu koleksiyon elemanları <code class="language-plaintext highlighter-rouge">object</code> olarak tuttuğu için hemen her şeyi kabul eder.</p>

<div class="language-csharp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">using</span> <span class="nn">System.Collections</span><span class="p">;</span>

<span class="kt">var</span> <span class="n">liste</span> <span class="p">=</span> <span class="k">new</span> <span class="nf">ArrayList</span><span class="p">();</span>
<span class="n">liste</span><span class="p">.</span><span class="nf">Add</span><span class="p">(</span><span class="m">10</span><span class="p">);</span>
<span class="n">liste</span><span class="p">.</span><span class="nf">Add</span><span class="p">(</span><span class="s">"yirmi"</span><span class="p">);</span>

<span class="kt">int</span> <span class="n">toplam</span> <span class="p">=</span> <span class="p">(</span><span class="kt">int</span><span class="p">)</span><span class="n">liste</span><span class="p">[</span><span class="m">0</span><span class="p">]</span> <span class="p">+</span> <span class="p">(</span><span class="kt">int</span><span class="p">)</span><span class="n">liste</span><span class="p">[</span><span class="m">1</span><span class="p">];</span> <span class="c1">// Çalışma zamanı hatası</span>
</code></pre></div></div>

<p>Kod derlenir; fakat ikinci eleman <code class="language-plaintext highlighter-rouge">int</code> olmadığı için <code class="language-plaintext highlighter-rouge">InvalidCastException</code> oluşur. <code class="language-plaintext highlighter-rouge">List&lt;int&gt;</code> kullanıldığında yanlış değer daha program çalışmadan yakalanır:</p>

<div class="language-csharp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kt">var</span> <span class="n">sayilar</span> <span class="p">=</span> <span class="k">new</span> <span class="n">List</span><span class="p">&lt;</span><span class="kt">int</span><span class="p">&gt;();</span>
<span class="n">sayilar</span><span class="p">.</span><span class="nf">Add</span><span class="p">(</span><span class="m">10</span><span class="p">);</span>
<span class="c1">// sayilar.Add("yirmi"); // Derleme hatası</span>

<span class="kt">int</span> <span class="n">toplam</span> <span class="p">=</span> <span class="n">sayilar</span><span class="p">[</span><span class="m">0</span><span class="p">];</span> <span class="c1">// Dönüşüm gerekmiyor</span>
</code></pre></div></div>

<table>
  <thead>
    <tr>
      <th>Özellik</th>
      <th><code class="language-plaintext highlighter-rouge">ArrayList</code></th>
      <th><code class="language-plaintext highlighter-rouge">List&lt;T&gt;</code></th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Eleman türü</td>
      <td><code class="language-plaintext highlighter-rouge">object</code></td>
      <td>Belirlenen <code class="language-plaintext highlighter-rouge">T</code></td>
    </tr>
    <tr>
      <td>Hata tespiti</td>
      <td>Çalışma zamanında</td>
      <td>Derleme zamanında</td>
    </tr>
    <tr>
      <td>Açık dönüşüm</td>
      <td>Genellikle gerekli</td>
      <td>Gerekli değil</td>
    </tr>
    <tr>
      <td>Değer türü maliyeti</td>
      <td>Boxing/unboxing olabilir</td>
      <td>Genellikle önlenir</td>
    </tr>
    <tr>
      <td>Kod okunabilirliği</td>
      <td>Daha düşük</td>
      <td>Daha yüksek</td>
    </tr>
  </tbody>
</table>

<p><img src="/img/c-generics-tur-63.svg" alt="c-generics-tur-63" /></p>

<h2 id="performans-neden-artar">Performans neden artar?</h2>

<p><code class="language-plaintext highlighter-rouge">int</code>, <code class="language-plaintext highlighter-rouge">double</code> ve <code class="language-plaintext highlighter-rouge">bool</code> gibi değer türleri doğrudan değer taşır. Bunların <code class="language-plaintext highlighter-rouge">object</code> değişkenine yerleştirilmesine <strong>boxing</strong>, yeniden özgün türe çevrilmesine <strong>unboxing</strong> denir. Her boxing işlemi yönetilen bellekte ek bir nesne oluşturabilir ve dönüşüm maliyeti doğurabilir.</p>

<p>Basitleştirilmiş biçimde, $n$ elemanın boxing maliyeti $b$, unboxing maliyeti $u$ ise ek işlem yükü şöyle düşünülebilir:</p>

\[C_{eski} \approx n(b + u)\]

<p>Generic bir <code class="language-plaintext highlighter-rouge">List&lt;int&gt;</code> için bu dönüşümlerin çoğu ortadan kalktığından yaklaşık ek yük:</p>

\[C_{generic} \approx 0\]

<p>Gerçek performans donanıma, .NET sürümüne ve kullanım şekline bağlıdır; dolayısıyla bu eşitlik bir ölçüm değil, maliyet farkını anlatan zihinsel modeldir.</p>

<h2 id="generic-metotlar-ve-kısıtlar">Generic metotlar ve kısıtlar</h2>

<p>Generics yalnızca koleksiyonlara özgü değildir. Metotlar da tür parametresi alabilir:</p>

<div class="language-csharp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">static</span> <span class="n">T</span> <span class="n">IlkElemaniGetir</span><span class="p">&lt;</span><span class="n">T</span><span class="p">&gt;(</span><span class="n">IEnumerable</span><span class="p">&lt;</span><span class="n">T</span><span class="p">&gt;</span> <span class="n">kaynak</span><span class="p">)</span>
<span class="p">{</span>
    <span class="k">return</span> <span class="n">kaynak</span><span class="p">.</span><span class="nf">First</span><span class="p">();</span>
<span class="p">}</span>

<span class="kt">int</span> <span class="n">ilkSayi</span> <span class="p">=</span> <span class="nf">IlkElemaniGetir</span><span class="p">(</span><span class="k">new</span><span class="p">[]</span> <span class="p">{</span> <span class="m">7</span><span class="p">,</span> <span class="m">8</span><span class="p">,</span> <span class="m">9</span> <span class="p">});</span>
<span class="kt">string</span> <span class="n">ilkAd</span> <span class="p">=</span> <span class="nf">IlkElemaniGetir</span><span class="p">(</span><span class="k">new</span><span class="p">[]</span> <span class="p">{</span> <span class="s">"Ada"</span><span class="p">,</span> <span class="s">"Linus"</span> <span class="p">});</span>
</code></pre></div></div>

<p>Bazen <code class="language-plaintext highlighter-rouge">T</code> tamamen serbest bırakılmamalıdır. <code class="language-plaintext highlighter-rouge">where</code> kısıtları, kabul edilen türlerin sahip olması gereken özellikleri belirtir:</p>

<div class="language-csharp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">static</span> <span class="n">T</span> <span class="n">YeniOlustur</span><span class="p">&lt;</span><span class="n">T</span><span class="p">&gt;()</span> <span class="k">where</span> <span class="n">T</span> <span class="p">:</span> <span class="k">class</span><span class="err">,</span> <span class="nc">new</span><span class="p">()</span>
<span class="p">{</span>
    <span class="k">return</span> <span class="k">new</span> <span class="nf">T</span><span class="p">();</span>
<span class="p">}</span>
</code></pre></div></div>

<p>Bu metot yalnızca referans türleriyle çalışır ve parametresiz kurucu ister. Yaygın kısıtlar arasında <code class="language-plaintext highlighter-rouge">class</code>, <code class="language-plaintext highlighter-rouge">struct</code>, <code class="language-plaintext highlighter-rouge">notnull</code>, <code class="language-plaintext highlighter-rouge">new()</code> ve belirli bir arayüz bulunur.</p>

<h2 id="hangi-koleksiyon-seçilmeli">Hangi koleksiyon seçilmeli?</h2>

<table>
  <thead>
    <tr>
      <th>İhtiyaç</th>
      <th>Generic koleksiyon</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Sıralı eleman listesi</td>
      <td><code class="language-plaintext highlighter-rouge">List&lt;T&gt;</code></td>
    </tr>
    <tr>
      <td>Anahtar-değer eşleşmesi</td>
      <td><code class="language-plaintext highlighter-rouge">Dictionary&lt;TKey, TValue&gt;</code></td>
    </tr>
    <tr>
      <td>Benzersiz elemanlar</td>
      <td><code class="language-plaintext highlighter-rouge">HashSet&lt;T&gt;</code></td>
    </tr>
    <tr>
      <td>İlk giren ilk çıkar</td>
      <td><code class="language-plaintext highlighter-rouge">Queue&lt;T&gt;</code></td>
    </tr>
    <tr>
      <td>Son giren ilk çıkar</td>
      <td><code class="language-plaintext highlighter-rouge">Stack&lt;T&gt;</code></td>
    </tr>
  </tbody>
</table>

<p>Generics; tekrar kullanılabilirliği, tür güvenliğini ve okunabilirliği aynı yapıda buluşturur. En önemli kazanç yalnızca hız değildir: Hataları kullanıcıya ulaşmadan derleyicide durdurmaktır. Kısacası <code class="language-plaintext highlighter-rouge">T</code>, küçük bir harf olsa da C# dünyasında oldukça büyük bir güvenlik görevlisidir.</p>]]></content><author><name>Sonsuz Us</name></author><category term="Bilgi" /><category term="csharp" /><category term="generics" /><category term="koleksiyonlar" /><category term="tür güvenliği" /><category term="performans" /><category term="dotnet" /><summary type="html"><![CDATA[Bir kutuya kalem koyup daha sonra içinden kahve kupası çıkarmayı beklemezsiniz. C# koleksiyonlarında da benzer bir düzen gerekir: Eklenen ve alınan değerlerin türü önceden bilinmelidir. Genel türler, yani generics, bu düzeni derleme zamanında sağlayarak çalışma anındaki sürpriz tür dönüşümü hatalarını azaltır ve özellikle değer türlerinde daha iyi performans sunar.]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://program.sonsuz.us/img/c-generics-tur-63.png" /><media:content medium="image" url="https://program.sonsuz.us/img/c-generics-tur-63.png" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">C++ İçindeki C Alt Kümesi: Temelden Modern C++’a</title><link href="https://program.sonsuz.us/posts/c-icindeki-c-alt-kumesi-temelden-modern-ca/" rel="alternate" type="text/html" title="C++ İçindeki C Alt Kümesi: Temelden Modern C++’a" /><published>2026-10-17T00:00:00+00:00</published><updated>2026-10-17T00:00:00+00:00</updated><id>https://program.sonsuz.us/posts/c-icindeki-c-alt-kumesi-temelden-modern-ca</id><content type="html" xml:base="https://program.sonsuz.us/posts/c-icindeki-c-alt-kumesi-temelden-modern-ca/"><![CDATA[<p>C++, nesne yönelimli programlama, şablonlar ve standart kütüphane gibi güçlü özelliklere sahip olsa da dilin kalbinde C’den miras alınan önemli bir sözdizimi bulunur. Değişkenler, operatörler, koşullar, döngüler, fonksiyonlar, diziler ve işaretçiler bu ortak temelin parçalarıdır. Bu yapıları öğrenmek yalnızca eski C kodlarını anlamayı değil, C++’ın düşük seviyeli çalışma mantığını kavramayı da kolaylaştırır.</p>

<p>``</p>

<h2 id="c-alt-kümesi-ne-demektir">“C alt kümesi” ne demektir?</h2>

<p>C alt kümesi, C++ içinde kullanılabilen C benzeri özelliklerin öğretim amaçlı adıdır. Ancak C’nin bütünü teknik olarak C++’ın kusursuz bir alt kümesi değildir. Diller arasında anahtar kelimeler, tür dönüşümleri ve standartlar bakımından bazı uyumsuzluklar vardır. Buna rağmen pek çok temel program aşağı yukarı aynı biçimde derlenebilir.</p>

<table>
  <thead>
    <tr>
      <th>Özellik</th>
      <th>C yaklaşımı</th>
      <th>C++ yaklaşımı</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Temel türler</td>
      <td><code class="language-plaintext highlighter-rouge">int</code>, <code class="language-plaintext highlighter-rouge">char</code>, <code class="language-plaintext highlighter-rouge">double</code></td>
      <td>Aynı türler ve ek tür olanakları</td>
    </tr>
    <tr>
      <td>Ekrana yazma</td>
      <td><code class="language-plaintext highlighter-rouge">printf</code></td>
      <td><code class="language-plaintext highlighter-rouge">printf</code> veya <code class="language-plaintext highlighter-rouge">std::cout</code></td>
    </tr>
    <tr>
      <td>Bellek ayırma</td>
      <td><code class="language-plaintext highlighter-rouge">malloc</code> / <code class="language-plaintext highlighter-rouge">free</code></td>
      <td><code class="language-plaintext highlighter-rouge">new</code> / <code class="language-plaintext highlighter-rouge">delete</code>, tercihen kapsayıcılar</td>
    </tr>
    <tr>
      <td>Veri modeli</td>
      <td><code class="language-plaintext highlighter-rouge">struct</code></td>
      <td><code class="language-plaintext highlighter-rouge">struct</code> ve <code class="language-plaintext highlighter-rouge">class</code></td>
    </tr>
    <tr>
      <td>Tür güvenliği</td>
      <td>Daha esnek</td>
      <td>Genellikle daha katı</td>
    </tr>
  </tbody>
</table>

<p><img src="/img/c-icindeki-c-66.svg" alt="c-icindeki-c-66" /></p>

<p>Dolayısıyla “C tarzı C++”, modern C++’ın tamamı değil, üzerine yeni katların inşa edildiği temel zemin olarak düşünülmelidir.</p>

<h2 id="değişkenler-operatörler-ve-ifadeler">Değişkenler, operatörler ve ifadeler</h2>

<p>Temel değişken bildirimi iki dilde de benzerdir:</p>

<div class="language-cpp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kt">int</span> <span class="n">adet</span> <span class="o">=</span> <span class="mi">5</span><span class="p">;</span>
<span class="kt">double</span> <span class="n">fiyat</span> <span class="o">=</span> <span class="mf">12.5</span><span class="p">;</span>
<span class="kt">char</span> <span class="n">kod</span> <span class="o">=</span> <span class="sc">'A'</span><span class="p">;</span>

<span class="c1">// Aritmetik bir ifade hesaplar.</span>
<span class="kt">double</span> <span class="n">toplam</span> <span class="o">=</span> <span class="n">adet</span> <span class="o">*</span> <span class="n">fiyat</span><span class="p">;</span>
</code></pre></div></div>

<p>Bir ifadenin sonucu, operatör önceliğine göre belirlenir. Örneğin <code class="language-plaintext highlighter-rouge">a + b * c</code> ifadesinde önce çarpma yapılır. Matematiksel karşılığı $a + (b \times c)$ biçimindedir. Tam sayı bölmesinde ise kesirli bölüm atılır: <code class="language-plaintext highlighter-rouge">7 / 2</code> sonucu <code class="language-plaintext highlighter-rouge">3</code> olur. Gerçek sayı sonucu için <code class="language-plaintext highlighter-rouge">7.0 / 2.0</code> kullanılmalıdır.</p>

<h2 id="kontrol-akışı">Kontrol akışı</h2>

<p>C’den aktarılan <code class="language-plaintext highlighter-rouge">if</code>, <code class="language-plaintext highlighter-rouge">else</code>, <code class="language-plaintext highlighter-rouge">switch</code>, <code class="language-plaintext highlighter-rouge">for</code>, <code class="language-plaintext highlighter-rouge">while</code> ve <code class="language-plaintext highlighter-rouge">do-while</code> yapıları C++ programlarının da temel kontrol araçlarıdır.</p>

<div class="language-cpp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kt">int</span> <span class="n">toplam</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>

<span class="c1">// 1 ile 10 arasındaki çift sayıları toplar.</span>
<span class="k">for</span> <span class="p">(</span><span class="kt">int</span> <span class="n">i</span> <span class="o">=</span> <span class="mi">1</span><span class="p">;</span> <span class="n">i</span> <span class="o">&lt;=</span> <span class="mi">10</span><span class="p">;</span> <span class="o">++</span><span class="n">i</span><span class="p">)</span> <span class="p">{</span>
    <span class="k">if</span> <span class="p">(</span><span class="n">i</span> <span class="o">%</span> <span class="mi">2</span> <span class="o">==</span> <span class="mi">0</span><span class="p">)</span> <span class="p">{</span>
        <span class="n">toplam</span> <span class="o">+=</span> <span class="n">i</span><span class="p">;</span>
    <span class="p">}</span>
<span class="p">}</span>
</code></pre></div></div>

<p>Bu döngünün kaç kez çalıştığı $n$ ile ifade edilebilir ve doğrusal karmaşıklığı $O(n)$ olur. İç içe iki benzer döngü kullanıldığında işlem sayısı yaklaşık $n^2$ düzeyine çıkabilir. Böylece basit C sözdizimi, algoritma analizi için de güçlü bir başlangıç sunar.</p>

<h2 id="fonksiyonlar-ve-değer-aktarımı">Fonksiyonlar ve değer aktarımı</h2>

<p>Fonksiyonlar, kodu tekrar kullanılabilir parçalara ayırır. C tarzında parametreler varsayılan olarak değer üzerinden aktarılır; yani fonksiyon değişkenin kopyasını alır.</p>

<div class="language-cpp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kt">int</span> <span class="nf">kare</span><span class="p">(</span><span class="kt">int</span> <span class="n">sayi</span><span class="p">)</span> <span class="p">{</span>
    <span class="k">return</span> <span class="n">sayi</span> <span class="o">*</span> <span class="n">sayi</span><span class="p">;</span>
<span class="p">}</span>

<span class="kt">int</span> <span class="n">sonuc</span> <span class="o">=</span> <span class="n">kare</span><span class="p">(</span><span class="mi">6</span><span class="p">);</span> <span class="c1">// sonuc 36 olur</span>
</code></pre></div></div>

<p>Bir fonksiyon çağrılmadan önce bildirilmeli veya tanımlanmalıdır. C++ buna ek olarak fonksiyon aşırı yükleme ve referans parametreleri sunar; bunlar saf C yaklaşımının ötesindedir.</p>

<h2 id="diziler-ve-işaretçiler">Diziler ve işaretçiler</h2>

<p>C tarzı diziler sabit uzunluklu, ardışık bellek bölgeleridir:</p>

<div class="language-cpp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kt">int</span> <span class="n">sayilar</span><span class="p">[</span><span class="mi">4</span><span class="p">]</span> <span class="o">=</span> <span class="p">{</span><span class="mi">10</span><span class="p">,</span> <span class="mi">20</span><span class="p">,</span> <span class="mi">30</span><span class="p">,</span> <span class="mi">40</span><span class="p">};</span>
<span class="kt">int</span><span class="o">*</span> <span class="n">adres</span> <span class="o">=</span> <span class="n">sayilar</span><span class="p">;</span>

<span class="c1">// İşaretçi aritmetiğiyle ikinci elemana erişir.</span>
<span class="kt">int</span> <span class="n">ikinci</span> <span class="o">=</span> <span class="o">*</span><span class="p">(</span><span class="n">adres</span> <span class="o">+</span> <span class="mi">1</span><span class="p">);</span>
</code></pre></div></div>

<p>Dizi adı çoğu ifadede ilk elemanın adresine dönüşür. <code class="language-plaintext highlighter-rouge">adres + 1</code>, bellekte bir bayt değil, bir <code class="language-plaintext highlighter-rouge">int</code> kadar ilerler. Eğer <code class="language-plaintext highlighter-rouge">sizeof(int) = 4</code> ise gerçek adres değişimi 4 bayttır. Bu davranış hızlıdır; fakat sınır denetimi yapılmadığından hataya açıktır.</p>

<h2 id="manuel-bellek-yönetimi">Manuel bellek yönetimi</h2>

<p>C’den gelen yaklaşımda dinamik bellek <code class="language-plaintext highlighter-rouge">malloc</code> ile ayrılır ve <code class="language-plaintext highlighter-rouge">free</code> ile bırakılır. C++ bunu desteklese de tür dönüşümü ve nesne yaşam döngüsü nedeniyle doğrudan tercih edilmez. Modern C++’ta <code class="language-plaintext highlighter-rouge">std::vector</code>, <code class="language-plaintext highlighter-rouge">std::string</code> ve akıllı işaretçiler daha güvenlidir.</p>

<p>Özetle C alt kümesi; sözdizimini, belleği ve program akışını çıplak hâliyle öğretir. Bu temeli öğrenmek değerlidir, ancak gerçek C++ projelerinde kaynakları otomatik yöneten modern araçlara geçmek hem güvenliği hem de okunabilirliği artırır.</p>]]></content><author><name>Sonsuz Us</name></author><category term="Bilgi" /><category term="c++" /><category term="c" /><category term="sözdizimi" /><category term="programlama temelleri" /><category term="bellek yönetimi" /><summary type="html"><![CDATA[C++, nesne yönelimli programlama, şablonlar ve standart kütüphane gibi güçlü özelliklere sahip olsa da dilin kalbinde C’den miras alınan önemli bir sözdizimi bulunur. Değişkenler, operatörler, koşullar, döngüler, fonksiyonlar, diziler ve işaretçiler bu ortak temelin parçalarıdır. Bu yapıları öğrenmek yalnızca eski C kodlarını anlamayı değil, C++’ın düşük seviyeli çalışma mantığını kavramayı da kolaylaştırır.]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://program.sonsuz.us/img/c-icindeki-c-66.png" /><media:content medium="image" url="https://program.sonsuz.us/img/c-icindeki-c-66.png" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">C# İndeksleyiciler ve Özellikler: Nesnelere Kontrollü Erişim</title><link href="https://program.sonsuz.us/posts/c-indeksleyiciler-ve-ozellikler-nesnelere-kontrollu-erisim/" rel="alternate" type="text/html" title="C# İndeksleyiciler ve Özellikler: Nesnelere Kontrollü Erişim" /><published>2026-10-17T00:00:00+00:00</published><updated>2026-10-17T00:00:00+00:00</updated><id>https://program.sonsuz.us/posts/c-indeksleyiciler-ve-ozellikler-nesnelere-kontrollu-erisim</id><content type="html" xml:base="https://program.sonsuz.us/posts/c-indeksleyiciler-ve-ozellikler-nesnelere-kontrollu-erisim/"><![CDATA[<p>C#’ta bir nesnenin içindeki verilere erişmek için her zaman uzun metot çağrıları yazmak gerekmez. <strong>Özellikler (properties)</strong> alanları güvenli biçimde yönetirken, <strong>indeksleyiciler (indexers)</strong> nesnelerin dizi veya sözlük gibi kullanılmasını sağlar. Böylece hem okunabilir hem de kapsülleme ilkesine uygun sınıflar tasarlayabiliriz.</p>

<p>``</p>

<h2 id="özellikler-neden-gereklidir">Özellikler neden gereklidir?</h2>

<p>Bir sınıftaki alanı <code class="language-plaintext highlighter-rouge">public</code> yapmak, dışarıdaki kodun bu alanı hiçbir denetim olmadan değiştirebilmesine yol açar. Örneğin bir ürünün fiyatı negatif olmamalıdır. Alanı gizleyip erişimi bir özellik üzerinden yönetmek bu sorunu çözer.</p>

<div class="language-csharp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">public</span> <span class="k">class</span> <span class="nc">Urun</span>
<span class="p">{</span>
    <span class="k">private</span> <span class="kt">decimal</span> <span class="n">_fiyat</span><span class="p">;</span>

    <span class="k">public</span> <span class="kt">string</span> <span class="n">Ad</span> <span class="p">{</span> <span class="k">get</span><span class="p">;</span> <span class="k">set</span><span class="p">;</span> <span class="p">}</span> <span class="p">=</span> <span class="kt">string</span><span class="p">.</span><span class="n">Empty</span><span class="p">;</span>

    <span class="k">public</span> <span class="kt">decimal</span> <span class="n">Fiyat</span>
    <span class="p">{</span>
        <span class="k">get</span> <span class="p">=&gt;</span> <span class="n">_fiyat</span><span class="p">;</span>
        <span class="k">set</span>
        <span class="p">{</span>
            <span class="k">if</span> <span class="p">(</span><span class="k">value</span> <span class="p">&lt;</span> <span class="m">0</span><span class="p">)</span>
                <span class="k">throw</span> <span class="k">new</span> <span class="nf">ArgumentOutOfRangeException</span><span class="p">(</span>
                    <span class="k">nameof</span><span class="p">(</span><span class="k">value</span><span class="p">),</span> <span class="s">"Fiyat negatif olamaz."</span><span class="p">);</span>

            <span class="n">_fiyat</span> <span class="p">=</span> <span class="k">value</span><span class="p">;</span>
        <span class="p">}</span>
    <span class="p">}</span>
<span class="p">}</span>
</code></pre></div></div>

<p>Burada <code class="language-plaintext highlighter-rouge">Ad</code>, otomatik uygulanan bir özelliktir. Derleyici gerekli gizli alanı kendisi oluşturur. <code class="language-plaintext highlighter-rouge">Fiyat</code> ise özel bir doğrulama kuralına sahiptir. <code class="language-plaintext highlighter-rouge">value</code> anahtar sözcüğü, özelliğe atanmak istenen yeni değeri temsil eder.</p>

<p>Fiyat doğrulamasını matematiksel olarak şöyle ifade edebiliriz:</p>

\[Fiyat \in [0, \infty)\]

<p>Yani kabul edilen fiyat, sıfırdan büyük veya sıfıra eşit olmalıdır. Kullanım ise sıradan bir alan kadar sadedir:</p>

<div class="language-csharp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kt">var</span> <span class="n">kahve</span> <span class="p">=</span> <span class="k">new</span> <span class="n">Urun</span>
<span class="p">{</span>
    <span class="n">Ad</span> <span class="p">=</span> <span class="s">"Filtre Kahve"</span><span class="p">,</span>
    <span class="n">Fiyat</span> <span class="p">=</span> <span class="m">95.50m</span>
<span class="p">};</span>

<span class="n">Console</span><span class="p">.</span><span class="nf">WriteLine</span><span class="p">(</span><span class="n">kahve</span><span class="p">.</span><span class="n">Fiyat</span><span class="p">);</span>
</code></pre></div></div>

<h2 id="get-set-ve-init-arasındaki-fark"><code class="language-plaintext highlighter-rouge">get</code>, <code class="language-plaintext highlighter-rouge">set</code> ve <code class="language-plaintext highlighter-rouge">init</code> arasındaki fark</h2>

<p>Bir özelliğin nasıl kullanılabileceği erişimcileriyle belirlenir.</p>

<table>
  <thead>
    <tr>
      <th>Erişimci</th>
      <th>Görevi</th>
      <th>Tipik kullanım</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">get</code></td>
      <td>Değeri okur</td>
      <td>Hesaplanan veya salt okunur veri</td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">set</code></td>
      <td>Değeri değiştirir</td>
      <td>Sonradan güncellenebilen veri</td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">init</code></td>
      <td>Yalnızca oluşturma sırasında değer alır</td>
      <td>Değişmez nesne modelleri</td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">private set</code></td>
      <td>Dışarıya okuma, sınıfa yazma izni verir</td>
      <td>Kimlik ve durum alanları</td>
    </tr>
  </tbody>
</table>

<p>Örneğin <code class="language-plaintext highlighter-rouge">public int Id { get; private set; }</code> tanımı, kimliğin dışarıdan okunmasına izin verir; fakat değiştirilmesini sınıfın kendi metotlarıyla sınırlar.</p>

<h2 id="i̇ndeksleyici-nedir">İndeksleyici nedir?</h2>

<p>İndeksleyici, bir nesneye <code class="language-plaintext highlighter-rouge">nesne[indeks]</code> biçiminde erişilmesini sağlayan özel bir üyedir. Metot adı yerine <code class="language-plaintext highlighter-rouge">this</code> anahtar sözcüğü kullanılır. Aşağıdaki sınıf, öğrencilerin notlarını saklayan küçük bir koleksiyon gibi davranır:</p>

<div class="language-csharp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">public</span> <span class="k">class</span> <span class="nc">NotDefteri</span>
<span class="p">{</span>
    <span class="k">private</span> <span class="k">readonly</span> <span class="n">Dictionary</span><span class="p">&lt;</span><span class="kt">string</span><span class="p">,</span> <span class="kt">int</span><span class="p">&gt;</span> <span class="n">_notlar</span> <span class="p">=</span> <span class="k">new</span><span class="p">();</span>

    <span class="k">public</span> <span class="kt">int</span> <span class="k">this</span><span class="p">[</span><span class="kt">string</span> <span class="n">ogrenci</span><span class="p">]</span>
    <span class="p">{</span>
        <span class="k">get</span>
        <span class="p">{</span>
            <span class="k">if</span> <span class="p">(!</span><span class="n">_notlar</span><span class="p">.</span><span class="nf">TryGetValue</span><span class="p">(</span><span class="n">ogrenci</span><span class="p">,</span> <span class="k">out</span> <span class="kt">int</span> <span class="n">not</span><span class="p">))</span>
                <span class="k">throw</span> <span class="k">new</span> <span class="nf">KeyNotFoundException</span><span class="p">(</span><span class="s">"Öğrenci bulunamadı."</span><span class="p">);</span>

            <span class="k">return</span> <span class="n">not</span><span class="p">;</span>
        <span class="p">}</span>
        <span class="k">set</span>
        <span class="p">{</span>
            <span class="k">if</span> <span class="p">(</span><span class="k">value</span> <span class="k">is</span> <span class="p">&lt;</span> <span class="m">0</span> <span class="n">or</span> <span class="p">&gt;</span> <span class="m">100</span><span class="p">)</span>
                <span class="k">throw</span> <span class="k">new</span> <span class="nf">ArgumentOutOfRangeException</span><span class="p">(</span><span class="k">nameof</span><span class="p">(</span><span class="k">value</span><span class="p">));</span>

            <span class="n">_notlar</span><span class="p">[</span><span class="n">ogrenci</span><span class="p">]</span> <span class="p">=</span> <span class="k">value</span><span class="p">;</span>
        <span class="p">}</span>
    <span class="p">}</span>
<span class="p">}</span>
</code></pre></div></div>

<p>Bu indeksleyici <code class="language-plaintext highlighter-rouge">string</code> türünde bir anahtar alır ve <code class="language-plaintext highlighter-rouge">int</code> döndürür. Notların geçerli aralığı şu koşulla tanımlanır:</p>

\[0 \leq not \leq 100\]

<p>Nesne artık sözlük benzeri bir sözdizimiyle kullanılabilir:</p>

<div class="language-csharp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kt">var</span> <span class="n">defter</span> <span class="p">=</span> <span class="k">new</span> <span class="nf">NotDefteri</span><span class="p">();</span>
<span class="n">defter</span><span class="p">[</span><span class="s">"Ada"</span><span class="p">]</span> <span class="p">=</span> <span class="m">92</span><span class="p">;</span>
<span class="n">defter</span><span class="p">[</span><span class="s">"Mert"</span><span class="p">]</span> <span class="p">=</span> <span class="m">78</span><span class="p">;</span>

<span class="n">Console</span><span class="p">.</span><span class="nf">WriteLine</span><span class="p">(</span><span class="n">defter</span><span class="p">[</span><span class="s">"Ada"</span><span class="p">]);</span> <span class="c1">// 92</span>
</code></pre></div></div>

<h2 id="özellik-mi-indeksleyici-mi">Özellik mi, indeksleyici mi?</h2>

<table>
  <thead>
    <tr>
      <th>Yapı</th>
      <th>Erişim biçimi</th>
      <th>En uygun senaryo</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Özellik</td>
      <td><code class="language-plaintext highlighter-rouge">nesne.Fiyat</code></td>
      <td>Tek ve anlamlı bir değere erişmek</td>
    </tr>
    <tr>
      <td>İndeksleyici</td>
      <td><code class="language-plaintext highlighter-rouge">nesne[anahtar]</code></td>
      <td>Bir veri grubundaki elemana ulaşmak</td>
    </tr>
    <tr>
      <td>Metot</td>
      <td><code class="language-plaintext highlighter-rouge">nesne.Bul(anahtar)</code></td>
      <td>Karmaşık işlem veya yan etki oluşturmak</td>
    </tr>
  </tbody>
</table>

<p>Bir sınıf birden fazla indeksleyici tanımlayabilir; örneğin hem sayısal sıra hem de metinsel anahtar kabul edebilir. Ancak aşırı kullanım, nesnenin davranışını belirsizleştirir. İndeksleyiciyi yalnızca sınıf gerçekten koleksiyon benzeri bir anlam taşıyorsa seçmek daha doğrudur.</p>

<p>Özetle özellikler, veriye kontrollü bir kapı açar; indeksleyiciler ise bu kapıya numara veya anahtar etiketi ekler. Doğrulama kurallarını bu üyelerde merkezileştirmek, hatalı durumların oluşmasını engeller ve sınıfın iç yapısını dış dünyadan saklar.</p>

<p><img src="/img/c-indeksleyiciler-ve-77.svg" alt="c-indeksleyiciler-ve-77" /></p>]]></content><author><name>Sonsuz Us</name></author><category term="Bilgi" /><category term="csharp" /><category term="indeksleyiciler" /><category term="özellikler" /><category term="nesne yönelimli programlama" /><category term="kapsülleme" /><summary type="html"><![CDATA[C#’ta bir nesnenin içindeki verilere erişmek için her zaman uzun metot çağrıları yazmak gerekmez. Özellikler (properties) alanları güvenli biçimde yönetirken, indeksleyiciler (indexers) nesnelerin dizi veya sözlük gibi kullanılmasını sağlar. Böylece hem okunabilir hem de kapsülleme ilkesine uygun sınıflar tasarlayabiliriz.]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://program.sonsuz.us/img/c-indeksleyiciler-ve-77.png" /><media:content medium="image" url="https://program.sonsuz.us/img/c-indeksleyiciler-ve-77.png" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">C++ Kalıtım: Sınıflar Arasında Akıllı Bir Miras Sistemi</title><link href="https://program.sonsuz.us/posts/c-kalitim-siniflar-arasinda-akilli-bir-miras-sistemi/" rel="alternate" type="text/html" title="C++ Kalıtım: Sınıflar Arasında Akıllı Bir Miras Sistemi" /><published>2026-10-17T00:00:00+00:00</published><updated>2026-10-17T00:00:00+00:00</updated><id>https://program.sonsuz.us/posts/c-kalitim-siniflar-arasinda-akilli-bir-miras-sistemi</id><content type="html" xml:base="https://program.sonsuz.us/posts/c-kalitim-siniflar-arasinda-akilli-bir-miras-sistemi/"><![CDATA[<p>Bir yazılım projesinde aynı özellikleri tekrar tekrar yazmak hem zaman kaybettirir hem de bakım maliyetini artırır. C++ kalıtım (inheritance) mekanizması, mevcut bir sınıfın veri ve davranışlarını yeni sınıflara aktararak bu tekrarı azaltır. Kısacası kalıtım, kod dünyasındaki “aileden gelen özellikler” sistemidir; fakat hangi özelliğin kime kalacağını erişim belirleyicileri kontrol eder.
``</p>

<h2 id="kalıtımın-temel-mantığı">Kalıtımın temel mantığı</h2>

<p>Özellikleri aktarılan sınıfa <strong>temel sınıf</strong> (base class), bu sınıftan yararlanan yeni sınıfa ise <strong>türetilmiş sınıf</strong> (derived class) denir. Örneğin <code class="language-plaintext highlighter-rouge">Hayvan</code> genel bir sınıfken <code class="language-plaintext highlighter-rouge">Kedi</code> ve <code class="language-plaintext highlighter-rouge">Kopek</code>, onun daha özel türleri olabilir.</p>

<p>Bu ilişki matematiksel olarak bir alt küme yaklaşımıyla düşünülebilir:</p>

\[Kedi \subset Hayvan\]

<p>Her kedi bir hayvandır; ancak her hayvan bir kedi değildir. Nesne yönelimli tasarımda buna <strong>is-a</strong>, yani “bir türüdür” ilişkisi denir. Kalıtım kullanılmadan önce iki sınıf arasında gerçekten böyle bir ilişki bulunup bulunmadığı sorgulanmalıdır.</p>

<p>C++ kalıtımının temel sözdizimi şöyledir:</p>

<div class="language-cpp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">class</span> <span class="nc">TuretilmisSinif</span> <span class="o">:</span> <span class="k">public</span> <span class="n">TemelSinif</span> <span class="p">{</span>
    <span class="c1">// Yeni üyeler ve metotlar</span>
<span class="p">};</span>
</code></pre></div></div>

<p>Buradaki <code class="language-plaintext highlighter-rouge">public</code>, temel sınıf üyelerinin türetilmiş sınıfa hangi görünürlük kurallarıyla aktarılacağını belirten kalıtım türüdür.</p>

<h2 id="basit-bir-kalıtım-örneği">Basit bir kalıtım örneği</h2>

<div class="language-cpp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="cp">#include</span> <span class="cpf">&lt;iostream&gt;</span><span class="cp">
#include</span> <span class="cpf">&lt;string&gt;</span><span class="cp">
</span><span class="k">using</span> <span class="k">namespace</span> <span class="n">std</span><span class="p">;</span>

<span class="k">class</span> <span class="nc">Hayvan</span> <span class="p">{</span>
<span class="nl">protected:</span>
    <span class="n">string</span> <span class="n">isim</span><span class="p">;</span>

<span class="nl">public:</span>
    <span class="n">Hayvan</span><span class="p">(</span><span class="n">string</span> <span class="n">ad</span><span class="p">)</span> <span class="o">:</span> <span class="n">isim</span><span class="p">(</span><span class="n">ad</span><span class="p">)</span> <span class="p">{}</span>

    <span class="kt">void</span> <span class="n">yemekYe</span><span class="p">()</span> <span class="k">const</span> <span class="p">{</span>
        <span class="n">cout</span> <span class="o">&lt;&lt;</span> <span class="n">isim</span> <span class="o">&lt;&lt;</span> <span class="s">" yemek yiyor.</span><span class="se">\n</span><span class="s">"</span><span class="p">;</span>
    <span class="p">}</span>
<span class="p">};</span>

<span class="k">class</span> <span class="nc">Kedi</span> <span class="o">:</span> <span class="k">public</span> <span class="n">Hayvan</span> <span class="p">{</span>
<span class="nl">public:</span>
    <span class="n">Kedi</span><span class="p">(</span><span class="n">string</span> <span class="n">ad</span><span class="p">)</span> <span class="o">:</span> <span class="n">Hayvan</span><span class="p">(</span><span class="n">ad</span><span class="p">)</span> <span class="p">{}</span>

    <span class="kt">void</span> <span class="n">miyavla</span><span class="p">()</span> <span class="k">const</span> <span class="p">{</span>
        <span class="n">cout</span> <span class="o">&lt;&lt;</span> <span class="n">isim</span> <span class="o">&lt;&lt;</span> <span class="s">" miyavlıyor!</span><span class="se">\n</span><span class="s">"</span><span class="p">;</span>
    <span class="p">}</span>
<span class="p">};</span>

<span class="kt">int</span> <span class="nf">main</span><span class="p">()</span> <span class="p">{</span>
    <span class="n">Kedi</span> <span class="n">tekir</span><span class="p">(</span><span class="s">"Tekir"</span><span class="p">);</span>
    <span class="n">tekir</span><span class="p">.</span><span class="n">yemekYe</span><span class="p">();</span>
    <span class="n">tekir</span><span class="p">.</span><span class="n">miyavla</span><span class="p">();</span>
<span class="p">}</span>
</code></pre></div></div>

<p><code class="language-plaintext highlighter-rouge">Kedi</code>, <code class="language-plaintext highlighter-rouge">Hayvan</code> sınıfındaki <code class="language-plaintext highlighter-rouge">yemekYe()</code> metodunu yeniden yazmadan kullanır. Ayrıca kendisine özgü <code class="language-plaintext highlighter-rouge">miyavla()</code> davranışını ekler. <code class="language-plaintext highlighter-rouge">isim</code> üyesinin <code class="language-plaintext highlighter-rouge">protected</code> olması, ona sınıf dışından doğrudan erişilememesini; ancak türetilmiş sınıfların erişebilmesini sağlar. <code class="language-plaintext highlighter-rouge">Kedi</code> kurucusu da <code class="language-plaintext highlighter-rouge">Hayvan(ad)</code> ifadesiyle temel sınıf kurucusunu çağırır.</p>

<h2 id="erişim-belirleyicileri">Erişim belirleyicileri</h2>

<p>Temel sınıftaki üyelerin aktarım biçimi, üyenin görünürlüğüne ve kullanılan kalıtım türüne bağlıdır.</p>

<table>
  <thead>
    <tr>
      <th>Temel sınıftaki üye</th>
      <th><code class="language-plaintext highlighter-rouge">public</code> kalıtım</th>
      <th><code class="language-plaintext highlighter-rouge">protected</code> kalıtım</th>
      <th><code class="language-plaintext highlighter-rouge">private</code> kalıtım</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">public</code></td>
      <td><code class="language-plaintext highlighter-rouge">public</code> kalır</td>
      <td><code class="language-plaintext highlighter-rouge">protected</code> olur</td>
      <td><code class="language-plaintext highlighter-rouge">private</code> olur</td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">protected</code></td>
      <td><code class="language-plaintext highlighter-rouge">protected</code> kalır</td>
      <td><code class="language-plaintext highlighter-rouge">protected</code> kalır</td>
      <td><code class="language-plaintext highlighter-rouge">private</code> olur</td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">private</code></td>
      <td>Doğrudan erişilemez</td>
      <td>Doğrudan erişilemez</td>
      <td>Doğrudan erişilemez</td>
    </tr>
  </tbody>
</table>

<p><code class="language-plaintext highlighter-rouge">private</code> üyeler türetilmiş nesnenin içinde yer almaya devam eder; fakat türetilmiş sınıf onları doğrudan kullanamaz. Erişim gerekiyorsa temel sınıfta <code class="language-plaintext highlighter-rouge">public</code> veya <code class="language-plaintext highlighter-rouge">protected</code> metotlar sunulmalıdır. Bu yaklaşım kapsüllemeyi korur.</p>

<h2 id="metot-ezme-ve-sanal-fonksiyonlar">Metot ezme ve sanal fonksiyonlar</h2>

<p>Türetilmiş sınıf, temel sınıftaki bir davranışı değiştirmek isteyebilir. Çalışma zamanında doğru metodun seçilmesi için temel sınıf metodu <code class="language-plaintext highlighter-rouge">virtual</code>, türetilmiş metot ise <code class="language-plaintext highlighter-rouge">override</code> ile tanımlanır:</p>

<div class="language-cpp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">class</span> <span class="nc">Hayvan</span> <span class="p">{</span>
<span class="nl">public:</span>
    <span class="k">virtual</span> <span class="kt">void</span> <span class="n">sesCikar</span><span class="p">()</span> <span class="k">const</span> <span class="p">{</span>
        <span class="n">cout</span> <span class="o">&lt;&lt;</span> <span class="s">"Genel hayvan sesi</span><span class="se">\n</span><span class="s">"</span><span class="p">;</span>
    <span class="p">}</span>

    <span class="k">virtual</span> <span class="o">~</span><span class="n">Hayvan</span><span class="p">()</span> <span class="o">=</span> <span class="k">default</span><span class="p">;</span>
<span class="p">};</span>

<span class="k">class</span> <span class="nc">Kedi</span> <span class="o">:</span> <span class="k">public</span> <span class="n">Hayvan</span> <span class="p">{</span>
<span class="nl">public:</span>
    <span class="kt">void</span> <span class="n">sesCikar</span><span class="p">()</span> <span class="k">const</span> <span class="k">override</span> <span class="p">{</span>
        <span class="n">cout</span> <span class="o">&lt;&lt;</span> <span class="s">"Miyav!</span><span class="se">\n</span><span class="s">"</span><span class="p">;</span>
    <span class="p">}</span>
<span class="p">};</span>
</code></pre></div></div>

<p>Bu mekanizma <strong>çok biçimliliğin</strong> temelidir. Bir <code class="language-plaintext highlighter-rouge">Hayvan*</code> işaretçisi gerçekte <code class="language-plaintext highlighter-rouge">Kedi</code> nesnesini gösteriyorsa <code class="language-plaintext highlighter-rouge">sesCikar()</code> çağrısı kedinin metodunu çalıştırır. Sanal yıkıcı ise nesne temel sınıf işaretçisi üzerinden silindiğinde kaynakların doğru sırayla serbest bırakılmasını sağlar.</p>

<h2 id="ne-zaman-kullanılmalı">Ne zaman kullanılmalı?</h2>

<p>Kalıtım güçlüdür, ancak her kod tekrarının çözümü değildir. “Bir türüdür” ilişkisi varsa kalıtım; “bir şeye sahiptir” ilişkisi varsa composition tercih edilir.</p>

<table>
  <thead>
    <tr>
      <th>İlişki</th>
      <th>Uygun teknik</th>
      <th>Örnek</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Araba bir araçtır</td>
      <td>Kalıtım</td>
      <td><code class="language-plaintext highlighter-rouge">Araba : public Arac</code></td>
    </tr>
    <tr>
      <td>Arabanın motoru vardır</td>
      <td>Composition</td>
      <td><code class="language-plaintext highlighter-rouge">Araba</code> içinde <code class="language-plaintext highlighter-rouge">Motor</code></td>
    </tr>
  </tbody>
</table>

<p>İyi tasarlanmış kalıtım hiyerarşileri kod tekrarını azaltır, ortak davranışları merkezileştirir ve genişletilebilir sistemler oluşturur. Yine de hiyerarşiyi gereksiz yere derinleştirmemek gerekir; aile ağacı büyüdükçe kodun hangi büyükbabadan hangi özelliği aldığı şaşırtıcı hâle gelebilir!</p>

<p><img src="/img/c-kalitim-siniflar-53.svg" alt="c-kalitim-siniflar-53" /></p>]]></content><author><name>Sonsuz Us</name></author><category term="Bilgi" /><category term="c++" /><category term="kalıtım" /><category term="nesne yönelimli programlama" /><category term="sınıflar" /><category term="oop" /><summary type="html"><![CDATA[Bir yazılım projesinde aynı özellikleri tekrar tekrar yazmak hem zaman kaybettirir hem de bakım maliyetini artırır. C++ kalıtım (inheritance) mekanizması, mevcut bir sınıfın veri ve davranışlarını yeni sınıflara aktararak bu tekrarı azaltır. Kısacası kalıtım, kod dünyasındaki “aileden gelen özellikler” sistemidir; fakat hangi özelliğin kime kalacağını erişim belirleyicileri kontrol eder.]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://program.sonsuz.us/img/c-kalitim-siniflar-53.png" /><media:content medium="image" url="https://program.sonsuz.us/img/c-kalitim-siniflar-53.png" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">C Operatörler ve İfadeler: Sayılardan Bitlere İşlem Rehberi</title><link href="https://program.sonsuz.us/posts/c-operatorler-ve-ifadeler-sayilardan-bitlere-islem-rehberi/" rel="alternate" type="text/html" title="C Operatörler ve İfadeler: Sayılardan Bitlere İşlem Rehberi" /><published>2026-10-17T00:00:00+00:00</published><updated>2026-10-17T00:00:00+00:00</updated><id>https://program.sonsuz.us/posts/c-operatorler-ve-ifadeler-sayilardan-bitlere-islem-rehberi</id><content type="html" xml:base="https://program.sonsuz.us/posts/c-operatorler-ve-ifadeler-sayilardan-bitlere-islem-rehberi/"><![CDATA[<p>C dilinde değişkenler verileri saklarken operatörler bu verileri harekete geçirir. Toplama yapmak, iki değeri karşılaştırmak, koşulları birleştirmek veya sayının bitlerini değiştirmek için operatörlerden yararlanırız. Kısacası değişkenler mutfağın malzemeleriyse operatörler bıçak, kaşık ve mikserdir; doğru aracı doğru yerde kullanmak gerekir.</p>

<p>``</p>

<h2 id="i̇fade-ve-operatör-nedir">İfade ve operatör nedir?</h2>

<p>Bir <strong>operatör</strong>, bir veya daha fazla değer üzerinde işlem yapan semboldür. İşleme katılan değerlere <strong>operand</strong>, operatör ve operandların oluşturduğu yapıya ise <strong>ifade</strong> denir.</p>

<div class="language-c highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kt">int</span> <span class="n">sonuc</span> <span class="o">=</span> <span class="mi">8</span> <span class="o">+</span> <span class="mi">4</span> <span class="o">*</span> <span class="mi">2</span><span class="p">;</span>
</code></pre></div></div>

<p>Burada <code class="language-plaintext highlighter-rouge">+</code> ve <code class="language-plaintext highlighter-rouge">*</code> operatör, sayılar operand, <code class="language-plaintext highlighter-rouge">8 + 4 * 2</code> ise bir ifadedir. İşlem önceliği nedeniyle önce çarpma yapılır:</p>

\[8 + 4 \times 2 = 16\]

<p>Sonucun 24 olmasını isteseydik <code class="language-plaintext highlighter-rouge">(8 + 4) * 2</code> yazmamız gerekirdi. Kararsız kaldığınızda parantez kullanmak, hem derleyiciyi hem de kodu okuyacak insanı mutlu eder.</p>

<h2 id="aritmetik-operatörler">Aritmetik operatörler</h2>

<p>Aritmetik operatörler sayısal hesaplamalarda kullanılır.</p>

<table>
  <thead>
    <tr>
      <th>Operatör</th>
      <th>İşlem</th>
      <th>Örnek</th>
      <th>Sonuç</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">+</code></td>
      <td>Toplama</td>
      <td><code class="language-plaintext highlighter-rouge">7 + 3</code></td>
      <td><code class="language-plaintext highlighter-rouge">10</code></td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">-</code></td>
      <td>Çıkarma</td>
      <td><code class="language-plaintext highlighter-rouge">7 - 3</code></td>
      <td><code class="language-plaintext highlighter-rouge">4</code></td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">*</code></td>
      <td>Çarpma</td>
      <td><code class="language-plaintext highlighter-rouge">7 * 3</code></td>
      <td><code class="language-plaintext highlighter-rouge">21</code></td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">/</code></td>
      <td>Bölme</td>
      <td><code class="language-plaintext highlighter-rouge">7 / 3</code></td>
      <td><code class="language-plaintext highlighter-rouge">2</code></td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">%</code></td>
      <td>Kalan</td>
      <td><code class="language-plaintext highlighter-rouge">7 % 3</code></td>
      <td><code class="language-plaintext highlighter-rouge">1</code></td>
    </tr>
  </tbody>
</table>

<p><img src="/img/c-operatorler-ve-63.svg" alt="c-operatorler-ve-63" /></p>

<p>C dilinde iki <code class="language-plaintext highlighter-rouge">int</code> değerin bölümü tam sayı üretir. Ondalıklı sonuç için operandlardan en az biri kayan noktalı olmalıdır.</p>

<div class="language-c highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="cp">#include</span> <span class="cpf">&lt;stdio.h&gt;</span><span class="cp">
</span>
<span class="kt">int</span> <span class="nf">main</span><span class="p">(</span><span class="kt">void</span><span class="p">)</span> <span class="p">{</span>
    <span class="kt">int</span> <span class="n">a</span> <span class="o">=</span> <span class="mi">7</span><span class="p">,</span> <span class="n">b</span> <span class="o">=</span> <span class="mi">3</span><span class="p">;</span>

    <span class="n">printf</span><span class="p">(</span><span class="s">"Tam sayi bolme: %d</span><span class="se">\n</span><span class="s">"</span><span class="p">,</span> <span class="n">a</span> <span class="o">/</span> <span class="n">b</span><span class="p">);</span>
    <span class="n">printf</span><span class="p">(</span><span class="s">"Ondalikli bolme: %.2f</span><span class="se">\n</span><span class="s">"</span><span class="p">,</span> <span class="p">(</span><span class="kt">double</span><span class="p">)</span><span class="n">a</span> <span class="o">/</span> <span class="n">b</span><span class="p">);</span>
    <span class="n">printf</span><span class="p">(</span><span class="s">"Kalan: %d</span><span class="se">\n</span><span class="s">"</span><span class="p">,</span> <span class="n">a</span> <span class="o">%</span> <span class="n">b</span><span class="p">);</span>
    <span class="k">return</span> <span class="mi">0</span><span class="p">;</span>
<span class="p">}</span>
</code></pre></div></div>

<p>Tür dönüşümü yapan <code class="language-plaintext highlighter-rouge">(double)a</code>, bölmenin <code class="language-plaintext highlighter-rouge">2.33</code> üretmesini sağlar. <code class="language-plaintext highlighter-rouge">%</code> operatörü ise bir sayının tek veya çift olduğunu belirlemek gibi işlerde oldukça kullanışlıdır.</p>

<h2 id="i̇lişkisel-operatörler">İlişkisel operatörler</h2>

<p>İlişkisel operatörler iki değeri karşılaştırır ve doğruysa <code class="language-plaintext highlighter-rouge">1</code>, yanlışsa <code class="language-plaintext highlighter-rouge">0</code> üretir.</p>

<table>
  <thead>
    <tr>
      <th>Operatör</th>
      <th>Anlamı</th>
      <th>Örnek</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">==</code></td>
      <td>Eşittir</td>
      <td><code class="language-plaintext highlighter-rouge">a == b</code></td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">!=</code></td>
      <td>Eşit değildir</td>
      <td><code class="language-plaintext highlighter-rouge">a != b</code></td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">&gt;</code> / <code class="language-plaintext highlighter-rouge">&lt;</code></td>
      <td>Büyük / küçük</td>
      <td><code class="language-plaintext highlighter-rouge">a &gt; b</code></td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">&gt;=</code> / <code class="language-plaintext highlighter-rouge">&lt;=</code></td>
      <td>Büyük eşit / küçük eşit</td>
      <td><code class="language-plaintext highlighter-rouge">a &gt;= b</code></td>
    </tr>
  </tbody>
</table>

<p>Buradaki klasik tuzak, atama operatörü <code class="language-plaintext highlighter-rouge">=</code> ile eşitlik operatörü <code class="language-plaintext highlighter-rouge">==</code> arasındaki farktır. <code class="language-plaintext highlighter-rouge">a = 5</code> değeri değiştirir; <code class="language-plaintext highlighter-rouge">a == 5</code> ise karşılaştırma yapar.</p>

<h2 id="mantıksal-operatörler">Mantıksal operatörler</h2>

<p>Mantıksal operatörler birden fazla koşulu birleştirir.</p>

<table>
  <thead>
    <tr>
      <th>Operatör</th>
      <th>Anlamı</th>
      <th>Matematiksel karşılık</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">&amp;&amp;</code></td>
      <td>VE</td>
      <td>$A \land B$</td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">||</code></td>
      <td>VEYA</td>
      <td>$A \lor B$</td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">!</code></td>
      <td>DEĞİL</td>
      <td>$\neg A$</td>
    </tr>
  </tbody>
</table>

<div class="language-c highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kt">int</span> <span class="n">yas</span> <span class="o">=</span> <span class="mi">22</span><span class="p">;</span>
<span class="kt">int</span> <span class="n">biletiVar</span> <span class="o">=</span> <span class="mi">1</span><span class="p">;</span>

<span class="k">if</span> <span class="p">(</span><span class="n">yas</span> <span class="o">&gt;=</span> <span class="mi">18</span> <span class="o">&amp;&amp;</span> <span class="n">biletiVar</span><span class="p">)</span> <span class="p">{</span>
    <span class="n">printf</span><span class="p">(</span><span class="s">"Giris onaylandi.</span><span class="se">\n</span><span class="s">"</span><span class="p">);</span>
<span class="p">}</span>
</code></pre></div></div>

<p><code class="language-plaintext highlighter-rouge">&amp;&amp;</code> kullanıldığında bütün koşullar doğru olmalıdır. C ayrıca <strong>kısa devre değerlendirmesi</strong> yapar: <code class="language-plaintext highlighter-rouge">A &amp;&amp; B</code> ifadesinde <code class="language-plaintext highlighter-rouge">A</code> yanlışsa <code class="language-plaintext highlighter-rouge">B</code> çalıştırılmaz. <code class="language-plaintext highlighter-rouge">A || B</code> ifadesinde ise <code class="language-plaintext highlighter-rouge">A</code> doğruysa ikinci koşula bakılmaz.</p>

<h2 id="bitsel-operatörler">Bitsel operatörler</h2>

<p>Bitsel operatörler sayıların ikili gösterimi üzerinde çalışır. Örneğin $12<em>{10}=1100_2$ ve $10</em>{10}=1010_2$ olur.</p>

<table>
  <thead>
    <tr>
      <th>Operatör</th>
      <th>İşlem</th>
      <th><code class="language-plaintext highlighter-rouge">12</code> ve <code class="language-plaintext highlighter-rouge">10</code> sonucu</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">&amp;</code></td>
      <td>Bitsel VE</td>
      <td><code class="language-plaintext highlighter-rouge">8</code></td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">|</code></td>
      <td>Bitsel VEYA</td>
      <td><code class="language-plaintext highlighter-rouge">14</code></td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">^</code></td>
      <td>Bitsel XOR</td>
      <td><code class="language-plaintext highlighter-rouge">6</code></td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">~</code></td>
      <td>Bitleri ters çevirme</td>
      <td>Türe bağlı</td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">&lt;&lt;</code></td>
      <td>Sola kaydırma</td>
      <td><code class="language-plaintext highlighter-rouge">12 &lt;&lt; 1</code> → <code class="language-plaintext highlighter-rouge">24</code></td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">&gt;&gt;</code></td>
      <td>Sağa kaydırma</td>
      <td><code class="language-plaintext highlighter-rouge">12 &gt;&gt; 1</code> → <code class="language-plaintext highlighter-rouge">6</code></td>
    </tr>
  </tbody>
</table>

<div class="language-c highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kt">unsigned</span> <span class="kt">int</span> <span class="n">izinler</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
<span class="k">const</span> <span class="kt">unsigned</span> <span class="kt">int</span> <span class="n">OKUMA</span> <span class="o">=</span> <span class="mi">1u</span> <span class="o">&lt;&lt;</span> <span class="mi">0</span><span class="p">;</span>
<span class="k">const</span> <span class="kt">unsigned</span> <span class="kt">int</span> <span class="n">YAZMA</span> <span class="o">=</span> <span class="mi">1u</span> <span class="o">&lt;&lt;</span> <span class="mi">1</span><span class="p">;</span>

<span class="n">izinler</span> <span class="o">|=</span> <span class="n">OKUMA</span><span class="p">;</span>             <span class="c1">// Okuma bitini açar.</span>
<span class="n">izinler</span> <span class="o">|=</span> <span class="n">YAZMA</span><span class="p">;</span>             <span class="c1">// Yazma bitini açar.</span>
<span class="n">izinler</span> <span class="o">&amp;=</span> <span class="o">~</span><span class="n">YAZMA</span><span class="p">;</span>            <span class="c1">// Yazma bitini kapatır.</span>

<span class="k">if</span> <span class="p">((</span><span class="n">izinler</span> <span class="o">&amp;</span> <span class="n">OKUMA</span><span class="p">)</span> <span class="o">!=</span> <span class="mi">0</span><span class="p">)</span> <span class="p">{</span>
    <span class="n">printf</span><span class="p">(</span><span class="s">"Okuma izni var.</span><span class="se">\n</span><span class="s">"</span><span class="p">);</span>
<span class="p">}</span>
</code></pre></div></div>

<p>Bu yaklaşım izinler, donanım kayıtları ve performans odaklı yapılarda kullanılır. Bitsel işlemlerde işaretli sayıların davranışına takılmamak için çoğunlukla <code class="language-plaintext highlighter-rouge">unsigned</code> türler tercih edilir.</p>

<h2 id="öncelik-konusunda-son-uyarı">Öncelik konusunda son uyarı</h2>

<p>Aritmetik, ilişkisel, mantıksal ve bitsel operatörlerin öncelikleri farklıdır. <code class="language-plaintext highlighter-rouge">x &amp; 1 == 0</code> gibi belirsiz görünen ifadeler yerine <code class="language-plaintext highlighter-rouge">(x &amp; 1) == 0</code> yazmak daha güvenlidir. C operatörlerini ezberlemek faydalıdır; ancak okunabilir parantezler kullanmak çok daha değerlidir.</p>]]></content><author><name>Sonsuz Us</name></author><category term="Bilgi" /><category term="c" /><category term="operatörler" /><category term="ifadeler" /><category term="aritmetik" /><category term="mantıksal işlemler" /><category term="bitsel işlemler" /><summary type="html"><![CDATA[C dilinde değişkenler verileri saklarken operatörler bu verileri harekete geçirir. Toplama yapmak, iki değeri karşılaştırmak, koşulları birleştirmek veya sayının bitlerini değiştirmek için operatörlerden yararlanırız. Kısacası değişkenler mutfağın malzemeleriyse operatörler bıçak, kaşık ve mikserdir; doğru aracı doğru yerde kullanmak gerekir.]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://program.sonsuz.us/img/c-operatorler-ve-63.png" /><media:content medium="image" url="https://program.sonsuz.us/img/c-operatorler-ve-63.png" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">C# Veri Tipleri ve Literaller: Stack, Heap ve Kimlik Meselesi</title><link href="https://program.sonsuz.us/posts/c-veri-tipleri-ve-literaller-stack-heap-ve-kimlik-meselesi/" rel="alternate" type="text/html" title="C# Veri Tipleri ve Literaller: Stack, Heap ve Kimlik Meselesi" /><published>2026-10-17T00:00:00+00:00</published><updated>2026-10-17T00:00:00+00:00</updated><id>https://program.sonsuz.us/posts/c-veri-tipleri-ve-literaller-stack-heap-ve-kimlik-meselesi</id><content type="html" xml:base="https://program.sonsuz.us/posts/c-veri-tipleri-ve-literaller-stack-heap-ve-kimlik-meselesi/"><![CDATA[<p>C#’ta bir değişken tanımlarken yalnızca hangi veriyi saklayacağımızı değil, o verinin nasıl kopyalanacağını, nerede tutulacağını ve yaşam döngüsünün nasıl yönetileceğini de seçeriz. Bu seçimin merkezinde değer tipleri (<code class="language-plaintext highlighter-rouge">struct</code>) ile referans tipleri (<code class="language-plaintext highlighter-rouge">class</code>) bulunur. İkisi bazen aynı görünebilir; fakat atama işlemi gerçekleştiğinde sahne arkasında bambaşka davranırlar.</p>

<p>``</p>

<h2 id="tip-sistemi-ve-bellek-mantığı">Tip Sistemi ve Bellek Mantığı</h2>

<p>C# güçlü ve statik tipli bir dildir. Her değişkenin derleme zamanında bilinen bir tipi vardır. Temel ayrım şöyledir:</p>

<ul>
  <li><strong>Değer tipleri:</strong> Verinin kendisini temsil eder. <code class="language-plaintext highlighter-rouge">int</code>, <code class="language-plaintext highlighter-rouge">double</code>, <code class="language-plaintext highlighter-rouge">bool</code>, <code class="language-plaintext highlighter-rouge">char</code>, <code class="language-plaintext highlighter-rouge">enum</code> ve kullanıcı tanımlı <code class="language-plaintext highlighter-rouge">struct</code> türleri bu gruptadır.</li>
  <li><strong>Referans tipleri:</strong> Bir nesneye erişmek için kullanılan referansı temsil eder. <code class="language-plaintext highlighter-rouge">class</code>, <code class="language-plaintext highlighter-rouge">string</code>, diziler, delegeler ve arayüzler bu gruptadır.</li>
</ul>

<p>“Değer tipleri daima stack’te, referans tipleri daima heap’te bulunur” açıklaması öğretici ama eksiktir. Yerleşim, değişkenin kullanıldığı bağlama bağlıdır. Bir sınıfın alanı olan <code class="language-plaintext highlighter-rouge">int</code>, sınıf nesnesiyle birlikte yönetilen bellekte bulunabilir. Esas fark <strong>konum değil, semantiktir</strong>: değer tipi kopyalandığında veri; referans tipi kopyalandığında referans kopyalanır.</p>

<table>
  <thead>
    <tr>
      <th>Özellik</th>
      <th>Değer tipi (<code class="language-plaintext highlighter-rouge">struct</code>)</th>
      <th>Referans tipi (<code class="language-plaintext highlighter-rouge">class</code>)</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Atamada kopyalanan</td>
      <td>Değerin tamamı</td>
      <td>Nesne referansı</td>
    </tr>
    <tr>
      <td>Varsayılan değer</td>
      <td>Sıfırlanmış değer</td>
      <td><code class="language-plaintext highlighter-rouge">null</code></td>
    </tr>
    <tr>
      <td>Kimlik kavramı</td>
      <td>Genellikle yoktur</td>
      <td>Nesne kimliği vardır</td>
    </tr>
    <tr>
      <td>Kalıtım</td>
      <td>Başka struct’tan kalıtım alamaz</td>
      <td>Sınıf kalıtımını destekler</td>
    </tr>
    <tr>
      <td>Uygun kullanım</td>
      <td>Küçük, tek parça değerler</td>
      <td>Kimliği ve davranışı olan nesneler</td>
    </tr>
  </tbody>
</table>

<h2 id="kopyalama-davranışı">Kopyalama Davranışı</h2>

<p>Aşağıdaki örnek farkı görünür hâle getirir:</p>

<div class="language-csharp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">public</span> <span class="k">struct</span> <span class="nc">Point</span>
<span class="p">{</span>
    <span class="k">public</span> <span class="kt">int</span> <span class="n">X</span><span class="p">;</span>
<span class="p">}</span>

<span class="k">public</span> <span class="k">class</span> <span class="nc">Player</span>
<span class="p">{</span>
    <span class="k">public</span> <span class="kt">int</span> <span class="n">Score</span><span class="p">;</span>
<span class="p">}</span>

<span class="n">Point</span> <span class="n">p1</span> <span class="p">=</span> <span class="k">new</span> <span class="n">Point</span> <span class="p">{</span> <span class="n">X</span> <span class="p">=</span> <span class="m">10</span> <span class="p">};</span>
<span class="n">Point</span> <span class="n">p2</span> <span class="p">=</span> <span class="n">p1</span><span class="p">;</span>
<span class="n">p2</span><span class="p">.</span><span class="n">X</span> <span class="p">=</span> <span class="m">99</span><span class="p">;</span>

<span class="n">Player</span> <span class="n">a</span> <span class="p">=</span> <span class="k">new</span> <span class="n">Player</span> <span class="p">{</span> <span class="n">Score</span> <span class="p">=</span> <span class="m">10</span> <span class="p">};</span>
<span class="n">Player</span> <span class="n">b</span> <span class="p">=</span> <span class="n">a</span><span class="p">;</span>
<span class="n">b</span><span class="p">.</span><span class="n">Score</span> <span class="p">=</span> <span class="m">99</span><span class="p">;</span>

<span class="n">Console</span><span class="p">.</span><span class="nf">WriteLine</span><span class="p">(</span><span class="n">p1</span><span class="p">.</span><span class="n">X</span><span class="p">);</span>      <span class="c1">// 10</span>
<span class="n">Console</span><span class="p">.</span><span class="nf">WriteLine</span><span class="p">(</span><span class="n">a</span><span class="p">.</span><span class="n">Score</span><span class="p">);</span>   <span class="c1">// 99</span>
</code></pre></div></div>

<p><code class="language-plaintext highlighter-rouge">p2</code>, <code class="language-plaintext highlighter-rouge">p1</code> değerinin bağımsız kopyasıdır. Buna karşılık <code class="language-plaintext highlighter-rouge">a</code> ve <code class="language-plaintext highlighter-rouge">b</code>, aynı <code class="language-plaintext highlighter-rouge">Player</code> nesnesini gösterir. Bunu basitçe şöyle düşünebiliriz:</p>

\[p2 = copy(p1)\]

\[b = reference(a)\]

<p>Büyük struct’ların sık kopyalanması maliyet oluşturabilir. Salt okunur parametrelerde <code class="language-plaintext highlighter-rouge">in</code>, kopyalama ihtiyacını azaltabilir. Yine de performans kararı ölçüm yapılarak verilmelidir; “struct her zaman hızlıdır” diye sihirli bir kural yoktur.</p>

<h2 id="literaller-değerleri-kodda-yazmak">Literaller: Değerleri Kodda Yazmak</h2>

<p>Literal, bir değerin kaynak kodundaki doğrudan gösterimidir. C# farklı türler için çeşitli literal biçimleri sunar:</p>

<div class="language-csharp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kt">int</span> <span class="n">decimalNumber</span> <span class="p">=</span> <span class="m">42</span><span class="p">;</span>
<span class="kt">int</span> <span class="n">binaryNumber</span> <span class="p">=</span> <span class="m">0b_101010</span><span class="p">;</span>
<span class="kt">int</span> <span class="n">hexNumber</span> <span class="p">=</span> <span class="m">0x2A</span><span class="p">;</span>
<span class="kt">long</span> <span class="n">population</span> <span class="p">=</span> <span class="m">8_000_000_000L</span><span class="p">;</span>
<span class="kt">float</span> <span class="n">ratio</span> <span class="p">=</span> <span class="m">1.5F</span><span class="p">;</span>
<span class="kt">decimal</span> <span class="n">price</span> <span class="p">=</span> <span class="m">19.99M</span><span class="p">;</span>
<span class="kt">char</span> <span class="n">letter</span> <span class="p">=</span> <span class="sc">'A'</span><span class="p">;</span>
<span class="kt">string</span> <span class="n">message</span> <span class="p">=</span> <span class="s">"Merhaba"</span><span class="p">;</span>
<span class="kt">bool</span> <span class="n">isReady</span> <span class="p">=</span> <span class="k">true</span><span class="p">;</span>
<span class="kt">object</span><span class="p">?</span> <span class="n">missing</span> <span class="p">=</span> <span class="k">null</span><span class="p">;</span>
</code></pre></div></div>

<p>Alt çizgiler sayının okunmasını kolaylaştırır ve değeri değiştirmez. <code class="language-plaintext highlighter-rouge">F</code>, <code class="language-plaintext highlighter-rouge">M</code>, <code class="language-plaintext highlighter-rouge">L</code> gibi sonekler ise literal türünü belirtir. Örneğin <code class="language-plaintext highlighter-rouge">1.5</code> varsayılan olarak <code class="language-plaintext highlighter-rouge">double</code>, <code class="language-plaintext highlighter-rouge">1.5F</code> ise <code class="language-plaintext highlighter-rouge">float</code> kabul edilir.</p>

<table>
  <thead>
    <tr>
      <th>Literal</th>
      <th>Varsayılan veya belirtilen tip</th>
      <th>Not</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">42</code></td>
      <td><code class="language-plaintext highlighter-rouge">int</code></td>
      <td>Tam sayı</td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">42L</code></td>
      <td><code class="language-plaintext highlighter-rouge">long</code></td>
      <td><code class="language-plaintext highlighter-rouge">L</code> soneki kullanır</td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">3.14</code></td>
      <td><code class="language-plaintext highlighter-rouge">double</code></td>
      <td>Varsayılan ondalıklı tip</td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">3.14M</code></td>
      <td><code class="language-plaintext highlighter-rouge">decimal</code></td>
      <td>Finansal hesaplara uygundur</td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">'C'</code></td>
      <td><code class="language-plaintext highlighter-rouge">char</code></td>
      <td>Tek tırnak kullanır</td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">"C#"</code></td>
      <td><code class="language-plaintext highlighter-rouge">string</code></td>
      <td>Çift tırnak kullanır</td>
    </tr>
  </tbody>
</table>

<h2 id="boxing-ve-unboxing">Boxing ve Unboxing</h2>

<p>Değer tipi, <code class="language-plaintext highlighter-rouge">object</code> veya bir arayüz türüne dönüştürüldüğünde <strong>boxing</strong> gerçekleşebilir:</p>

<div class="language-csharp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kt">int</span> <span class="n">score</span> <span class="p">=</span> <span class="m">100</span><span class="p">;</span>
<span class="kt">object</span> <span class="n">boxed</span> <span class="p">=</span> <span class="n">score</span><span class="p">;</span>       <span class="c1">// Boxing: değer nesne olarak paketlenir</span>
<span class="kt">int</span> <span class="n">restored</span> <span class="p">=</span> <span class="p">(</span><span class="kt">int</span><span class="p">)</span><span class="n">boxed</span><span class="p">;</span>  <span class="c1">// Unboxing: değer geri çıkarılır</span>
</code></pre></div></div>

<p>Boxing ek tahsis ve kopyalama oluşturabileceği için yoğun döngülerde önem kazanabilir. Generic koleksiyonlar bu maliyeti çoğu durumda önler; <code class="language-plaintext highlighter-rouge">ArrayList</code> yerine <code class="language-plaintext highlighter-rouge">List&lt;int&gt;</code> kullanmak buna güzel bir örnektir.</p>

<p>Özetle <code class="language-plaintext highlighter-rouge">struct</code>, koordinat veya renk gibi küçük ve değer odaklı modellerde; <code class="language-plaintext highlighter-rouge">class</code> ise kullanıcı ya da sipariş gibi kimliği, paylaşılan durumu ve yaşam döngüsü bulunan modellerde güçlüdür. Doğru seçim, yalnızca belleğin nerede olduğuna değil, modellediğiniz kavramın “değer mi, nesne mi?” olduğuna bağlıdır.</p>

<p><img src="/img/c-veri-tipleri-44.svg" alt="c-veri-tipleri-44" /></p>]]></content><author><name>Sonsuz Us</name></author><category term="Bilgi" /><category term="csharp" /><category term="veri tipleri" /><category term="struct" /><category term="class" /><category term="bellek yönetimi" /><category term="literaller" /><summary type="html"><![CDATA[C#’ta bir değişken tanımlarken yalnızca hangi veriyi saklayacağımızı değil, o verinin nasıl kopyalanacağını, nerede tutulacağını ve yaşam döngüsünün nasıl yönetileceğini de seçeriz. Bu seçimin merkezinde değer tipleri (struct) ile referans tipleri (class) bulunur. İkisi bazen aynı görünebilir; fakat atama işlemi gerçekleştiğinde sahne arkasında bambaşka davranırlar.]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://program.sonsuz.us/img/c-veri-tipleri-44.png" /><media:content medium="image" url="https://program.sonsuz.us/img/c-veri-tipleri-44.png" xmlns:media="http://search.yahoo.com/mrss/" /></entry></feed>