<?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-19T00:05:53+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">C++ Fonksiyon Aşırı Yükleme: Tek İsim, Birden Fazla Yetenek</title><link href="https://program.sonsuz.us/posts/c-fonksiyon-asiri-yukleme-tek-isim-birden-fazla-yetenek/" rel="alternate" type="text/html" title="C++ Fonksiyon Aşırı Yükleme: Tek İsim, Birden Fazla Yetenek" /><published>2026-10-18T00:00:00+00:00</published><updated>2026-10-18T00:00:00+00:00</updated><id>https://program.sonsuz.us/posts/c-fonksiyon-asiri-yukleme-tek-isim-birden-fazla-yetenek</id><content type="html" xml:base="https://program.sonsuz.us/posts/c-fonksiyon-asiri-yukleme-tek-isim-birden-fazla-yetenek/"><![CDATA[<p>Bir hesap makinesindeki “topla” düğmesinin tam sayılar, ondalıklı sayılar ve hatta metinler için farklı davranabildiğini düşünün. C++ fonksiyon aşırı yükleme sayesinde benzer işlemleri yapan fonksiyonlara aynı ismi verebilir, kullanım sırasında hangi sürümün çalışacağını derleyiciye bırakabiliriz. Böylece <code class="language-plaintext highlighter-rouge">toplaTamSayilari</code>, <code class="language-plaintext highlighter-rouge">toplaOndalikliSayilari</code> gibi isimler üretmek yerine daha sade ve anlaşılır bir arayüz oluştururuz.</p>

<p>``</p>

<h2 id="fonksiyon-aşırı-yükleme-nedir">Fonksiyon aşırı yükleme nedir?</h2>

<p>Function overloading, aynı kapsam içerisinde aynı isimli fakat farklı parametre listelerine sahip birden fazla fonksiyon tanımlamaktır. Parametre listesindeki tür, sayı veya sıralama değiştiğinde yeni bir overload meydana gelir.</p>

<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="kt">int</span> <span class="nf">topla</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="n">a</span> <span class="o">+</span> <span class="n">b</span><span class="p">;</span>
<span class="p">}</span>

<span class="kt">double</span> <span class="nf">topla</span><span class="p">(</span><span class="kt">double</span> <span class="n">a</span><span class="p">,</span> <span class="kt">double</span> <span class="n">b</span><span class="p">)</span> <span class="p">{</span>
    <span class="k">return</span> <span class="n">a</span> <span class="o">+</span> <span class="n">b</span><span class="p">;</span>
<span class="p">}</span>

<span class="n">std</span><span class="o">::</span><span class="n">string</span> <span class="nf">topla</span><span class="p">(</span><span class="k">const</span> <span class="n">std</span><span class="o">::</span><span class="n">string</span><span class="o">&amp;</span> <span class="n">a</span><span class="p">,</span> <span class="k">const</span> <span class="n">std</span><span class="o">::</span><span class="n">string</span><span class="o">&amp;</span> <span class="n">b</span><span class="p">)</span> <span class="p">{</span>
    <span class="k">return</span> <span class="n">a</span> <span class="o">+</span> <span class="n">b</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">std</span><span class="o">::</span><span class="n">cout</span> <span class="o">&lt;&lt;</span> <span class="n">topla</span><span class="p">(</span><span class="mi">4</span><span class="p">,</span> <span class="mi">7</span><span class="p">)</span> <span class="o">&lt;&lt;</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="n">topla</span><span class="p">(</span><span class="mf">2.5</span><span class="p">,</span> <span class="mf">1.8</span><span class="p">)</span> <span class="o">&lt;&lt;</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="n">topla</span><span class="p">(</span><span class="n">std</span><span class="o">::</span><span class="n">string</span><span class="p">(</span><span class="s">"Merhaba "</span><span class="p">),</span> <span class="n">std</span><span class="o">::</span><span class="n">string</span><span class="p">(</span><span class="s">"C++"</span><span class="p">));</span>
<span class="p">}</span>
</code></pre></div></div>

<p>Burada <code class="language-plaintext highlighter-rouge">topla(4, 7)</code> çağrısı <code class="language-plaintext highlighter-rouge">int</code> sürümünü, ondalıklı argümanlar <code class="language-plaintext highlighter-rouge">double</code> sürümünü seçer. Son sürüm ise iki metni birleştirir. <code class="language-plaintext highlighter-rouge">const std::string&amp;</code> kullanılması, metinlerin gereksiz yere kopyalanmasını önler.</p>

<h2 id="derleyici-doğru-fonksiyonu-nasıl-seçer">Derleyici doğru fonksiyonu nasıl seçer?</h2>

<p>Derleyici, çağrıdaki argümanları mevcut adayların parametreleriyle karşılaştırır. Bu sürece <strong>overload resolution</strong> denir. Basitleştirilmiş biçimde her aday için bir dönüşüm maliyeti düşünülebilir:</p>

\[S = C_1 + C_2 + \cdots + C_n\]

<p>Burada $C_i$, ilgili argümanın parametre türüne dönüştürülme maliyetidir. En düşük $S$ değerine sahip aday seçilir. Tam eşleşme genellikle standart tür dönüşümünden, standart dönüşüm de kullanıcı tanımlı dönüşümden daha güçlüdür.</p>

<table>
  <thead>
    <tr>
      <th>Eşleşme türü</th>
      <th>Örnek</th>
      <th>Tercih düzeyi</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Tam eşleşme</td>
      <td><code class="language-plaintext highlighter-rouge">int</code> → <code class="language-plaintext highlighter-rouge">int</code></td>
      <td>En yüksek</td>
    </tr>
    <tr>
      <td>Terfi</td>
      <td><code class="language-plaintext highlighter-rouge">char</code> → <code class="language-plaintext highlighter-rouge">int</code></td>
      <td>Yüksek</td>
    </tr>
    <tr>
      <td>Standart dönüşüm</td>
      <td><code class="language-plaintext highlighter-rouge">int</code> → <code class="language-plaintext highlighter-rouge">double</code></td>
      <td>Orta</td>
    </tr>
    <tr>
      <td>Kullanıcı tanımlı dönüşüm</td>
      <td>Sınıf dönüşümü</td>
      <td>Daha düşük</td>
    </tr>
  </tbody>
</table>

<p><img src="/img/c-fonksiyon-asiri-87.svg" alt="c-fonksiyon-asiri-87" /></p>

<h2 id="neler-overload-oluşturur">Neler overload oluşturur?</h2>

<p>Aşağıdaki fonksiyonlar geçerli biçimde aşırı yüklenebilir:</p>

<div class="language-cpp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kt">void</span> <span class="nf">yazdir</span><span class="p">(</span><span class="kt">int</span> <span class="n">deger</span><span class="p">);</span>
<span class="kt">void</span> <span class="nf">yazdir</span><span class="p">(</span><span class="kt">double</span> <span class="n">deger</span><span class="p">);</span>
<span class="kt">void</span> <span class="nf">yazdir</span><span class="p">(</span><span class="kt">int</span> <span class="n">deger</span><span class="p">,</span> <span class="kt">int</span> <span class="n">tekrar</span><span class="p">);</span>
<span class="kt">void</span> <span class="nf">yazdir</span><span class="p">(</span><span class="k">const</span> <span class="n">std</span><span class="o">::</span><span class="n">string</span><span class="o">&amp;</span> <span class="n">metin</span><span class="p">);</span>
</code></pre></div></div>

<p>Birincisi ve ikincisi parametre türüyle, üçüncüsü parametre sayısıyla ayrılır. Ancak yalnızca dönüş türünü değiştirmek yeterli değildir:</p>

<div class="language-cpp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kt">int</span> <span class="nf">hesapla</span><span class="p">(</span><span class="kt">int</span> <span class="n">x</span><span class="p">);</span>
<span class="c1">// double hesapla(int x); // Hata: Parametre listesi aynı!</span>
</code></pre></div></div>

<p>Çağıran kod yalnızca <code class="language-plaintext highlighter-rouge">hesapla(5)</code> yazdığında hangi dönüş türünü istediğini derleyici kesin olarak anlayamaz. Bu nedenle dönüş türü, fonksiyon aşırı yükleme imzasının ayırt edici parçası değildir.</p>

<h2 id="belirsizlik-tuzağı">Belirsizlik tuzağı</h2>

<p>Dönüşümler eşit derecede uygun olduğunda derleyici seçim yapamaz:</p>

<div class="language-cpp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kt">void</span> <span class="nf">goster</span><span class="p">(</span><span class="kt">long</span> <span class="n">deger</span><span class="p">)</span> <span class="p">{}</span>
<span class="kt">void</span> <span class="nf">goster</span><span class="p">(</span><span class="kt">double</span> <span class="n">deger</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="c1">// goster(10); // Belirsiz çağrı</span>
    <span class="n">goster</span><span class="p">(</span><span class="mi">10L</span><span class="p">);</span>   <span class="c1">// long sürümü</span>
    <span class="n">goster</span><span class="p">(</span><span class="mf">10.0</span><span class="p">);</span>  <span class="c1">// double sürümü</span>
<span class="p">}</span>
</code></pre></div></div>

<p><code class="language-plaintext highlighter-rouge">10</code>, <code class="language-plaintext highlighter-rouge">int</code> türündedir ve hem <code class="language-plaintext highlighter-rouge">long</code> hem de <code class="language-plaintext highlighter-rouge">double</code> türüne dönüştürülebilir. <code class="language-plaintext highlighter-rouge">L</code> ve <code class="language-plaintext highlighter-rouge">.0</code> ekleriyle niyet açıkça belirtilir. Benzer sorunlar varsayılan parametrelerle de oluşabilir.</p>

<table>
  <thead>
    <tr>
      <th>Yaklaşım</th>
      <th>Avantaj</th>
      <th>Risk</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Farklı fonksiyon adları</td>
      <td>Seçim tamamen açıktır</td>
      <td>Gereksiz isim kalabalığı</td>
    </tr>
    <tr>
      <td>Overloading</td>
      <td>Temiz ve doğal API</td>
      <td>Belirsiz çağrı ihtimali</td>
    </tr>
    <tr>
      <td>Şablonlar</td>
      <td>Çok sayıda türü destekler</td>
      <td>Hata mesajları karmaşıklaşabilir</td>
    </tr>
  </tbody>
</table>

<h2 id="ne-zaman-kullanmalıyız">Ne zaman kullanmalıyız?</h2>

<p>Aşırı yüklenen fonksiyonlar kavramsal olarak aynı işi yapmalıdır. <code class="language-plaintext highlighter-rouge">yazdir</code>, <code class="language-plaintext highlighter-rouge">hesapla</code> veya <code class="language-plaintext highlighter-rouge">ekle</code> gibi işlemler bunun için uygundur. Bir overload dosya silerken diğeri matematiksel hesap yapıyorsa ortak isim geliştiriciyi şaşırtır.</p>

<p>Kısacası function overloading, C++ arayüzlerini esnek ve okunabilir hâle getirir. Parametre listelerini belirgin tuttuğunuz, örtük dönüşümleri sınırladığınız ve her sürüme aynı kavramsal sorumluluğu verdiğiniz sürece tek bir isim gerçekten birçok yeteneği zarifçe taşıyabilir.</p>]]></content><author><name>Sonsuz Us</name></author><category term="Bilgi" /><category term="c++" /><category term="fonksiyonlar" /><category term="function-overloading" /><category term="oop" /><category term="programlama" /><summary type="html"><![CDATA[Bir hesap makinesindeki “topla” düğmesinin tam sayılar, ondalıklı sayılar ve hatta metinler için farklı davranabildiğini düşünün. C++ fonksiyon aşırı yükleme sayesinde benzer işlemleri yapan fonksiyonlara aynı ismi verebilir, kullanım sırasında hangi sürümün çalışacağını derleyiciye bırakabiliriz. Böylece toplaTamSayilari, toplaOndalikliSayilari gibi isimler üretmek yerine daha sade ve anlaşılır bir arayüz oluştururuz.]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://program.sonsuz.us/img/c-fonksiyon-asiri-87.png" /><media:content medium="image" url="https://program.sonsuz.us/img/c-fonksiyon-asiri-87.png" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">C++ İstisna Garantileri: Güçlü, Temel ve Zayıf Güvencenin Gerçek Etkisi</title><link href="https://program.sonsuz.us/posts/c-istisna-garantileri-guclu-temel-ve-zayif-guvencenin-gercek-etkisi/" rel="alternate" type="text/html" title="C++ İstisna Garantileri: Güçlü, Temel ve Zayıf Güvencenin Gerçek Etkisi" /><published>2026-10-18T00:00:00+00:00</published><updated>2026-10-18T00:00:00+00:00</updated><id>https://program.sonsuz.us/posts/c-istisna-garantileri-guclu-temel-ve-zayif-guvencenin-gercek-etkisi</id><content type="html" xml:base="https://program.sonsuz.us/posts/c-istisna-garantileri-guclu-temel-ve-zayif-guvencenin-gercek-etkisi/"><![CDATA[<p><img src="/img/c-istisna-garantileri-83.svg" alt="c-istisna-garantileri-83" /></p>

<p>Bir C++ fonksiyonunun istisna fırlatabilmesi tek başına korkutucu değildir; asıl mesele, istisna sonrasında programın hangi durumda kaldığıdır. Sepete ürün eklerken bellek tahsisi başarısız olursa eski sepet hâlâ kullanılabilir mi, yoksa nesne yarı güncellenmiş bir zombiye mi dönüşür? İstisna garantileri tam olarak bu soruya cevap verir.</p>

<p>``</p>

<h2 id="önce-terminolojiyi-netleştirelim">Önce terminolojiyi netleştirelim</h2>

<p>C++ literatüründe yaygın olarak <strong>no-throw</strong>, <strong>güçlü</strong>, <strong>temel</strong> ve <strong>garantisiz</strong> olmak üzere dört seviye bulunur. “Zayıf garanti” standartlaşmış ayrı bir seviye değildir. Bazı kaynaklar bu ifadeyi temel garantinin eş anlamlısı olarak, bazılarıysa hiçbir durum garantisi vermeyen kod için kullanır. Bu yazıda karışıklığı önlemek amacıyla <strong>zayıf/garantisiz</strong> ifadesini son anlamda kullanacağız.</p>

<table>
  <thead>
    <tr>
      <th>Seviye</th>
      <th>İstisna sonrasında durum</th>
      <th style="text-align: right">Veri kaybı</th>
      <th>Kullanılabilirlik</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Güçlü garanti</td>
      <td>İşlem hiç başlamamış gibi</td>
      <td style="text-align: right">Yok</td>
      <td>Tam</td>
    </tr>
    <tr>
      <td>Temel garanti</td>
      <td>Durum değişebilir fakat geçerlidir</td>
      <td style="text-align: right">Olabilir</td>
      <td>Nesne kullanılabilir</td>
    </tr>
    <tr>
      <td>Zayıf/garantisiz</td>
      <td>Durum hakkında söz verilmez</td>
      <td style="text-align: right">Muhtemel</td>
      <td>Belirsiz</td>
    </tr>
  </tbody>
</table>

<p>Güçlü garantiyi bir işlem dönüşümüyle ifade edebiliriz. Başlangıç durumu $S$, işlem $f$ ise:</p>

\[f(S) = S' \quad \text{veya istisna durumunda} \quad S\]

<p>Yani sonuç ya tamamen yeni durumdur ya da tamamen eski durumdur. Bu yaklaşım veritabanlarındaki atomik işlemlere benzer.</p>

<h2 id="güçlü-garanti-ya-hep-ya-hiç">Güçlü garanti: Ya hep ya hiç</h2>

<p>Aşağıdaki sınıf, yeni değeri önce geçici nesnede hazırlar. Riskli işlemler tamamlanmadan mevcut veriye dokunulmaz:</p>

<div class="language-cpp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="cp">#include</span> <span class="cpf">&lt;string&gt;</span><span class="cp">
#include</span> <span class="cpf">&lt;utility&gt;</span><span class="cp">
</span>
<span class="k">class</span> <span class="nc">Profile</span> <span class="p">{</span>
    <span class="n">std</span><span class="o">::</span><span class="n">string</span> <span class="n">name</span><span class="p">;</span>

<span class="nl">public:</span>
    <span class="kt">void</span> <span class="n">rename</span><span class="p">(</span><span class="k">const</span> <span class="n">std</span><span class="o">::</span><span class="n">string</span><span class="o">&amp;</span> <span class="n">newName</span><span class="p">)</span> <span class="p">{</span>
        <span class="n">std</span><span class="o">::</span><span class="n">string</span> <span class="n">temporary</span> <span class="o">=</span> <span class="n">newName</span><span class="p">;</span> <span class="c1">// Bellek ayırırken fırlatabilir</span>
        <span class="n">name</span><span class="p">.</span><span class="n">swap</span><span class="p">(</span><span class="n">temporary</span><span class="p">);</span>            <span class="c1">// noexcept</span>
    <span class="p">}</span>
<span class="p">};</span>
</code></pre></div></div>

<p>Kopyalama sırasında <code class="language-plaintext highlighter-rouge">std::bad_alloc</code> oluşursa <code class="language-plaintext highlighter-rouge">name</code> değişmez. Başarılı olursa <code class="language-plaintext highlighter-rouge">swap</code> ile yeni değer devreye alınır. Bu desen <strong>copy-and-swap</strong> veya daha genel anlamıyla “önce hazırla, sonra taahhüt et” yaklaşımıdır.</p>

<p>Güçlü garanti; finansal işlemler, yapılandırma güncellemeleri ve birden fazla adımın tek işlem gibi görünmesi gereken yerlerde değerlidir. Bedeli ise geçici kopyalar, ek bellek ve bazen daha karmaşık tasarımdır.</p>

<h2 id="temel-garanti-dağınık-ama-hayatta">Temel garanti: Dağınık ama hayatta</h2>

<p>Temel garanti, istisna sonrasında nesnenin kurallarını koruduğunu ve kaynak sızdırmadığını söyler. Ancak eski değerlerin korunacağını söylemez:</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">std</span><span class="o">::</span><span class="n">vector</span><span class="o">&lt;</span><span class="kt">int</span><span class="o">&gt;&amp;</span> <span class="n">values</span><span class="p">)</span> <span class="p">{</span>
    <span class="n">values</span><span class="p">.</span><span class="n">clear</span><span class="p">();</span>
    <span class="n">values</span><span class="p">.</span><span class="n">push_back</span><span class="p">(</span><span class="mi">0</span><span class="p">);</span> <span class="c1">// Bellek tahsisi başarısız olabilir</span>
<span class="p">}</span>
</code></pre></div></div>

<p><code class="language-plaintext highlighter-rouge">push_back</code> başarısız olursa vektör boş kalabilir. Eski elemanlar kaybedilmiştir fakat <code class="language-plaintext highlighter-rouge">values</code> hâlâ geçerli bir vektördür; yeniden doldurulabilir, taşınabilir veya yok edilebilir. Bu, temel garantinin pratik özüdür.</p>

<p>RAII burada kritik rol oynar. <code class="language-plaintext highlighter-rouge">std::vector</code>, <code class="language-plaintext highlighter-rouge">std::string</code>, akıllı işaretçiler ve kilit sınıfları kaynaklarını yıkıcılarında bıraktığı için istisna sırasında bellek ve kilit sızıntılarını önler.</p>

<h2 id="zayıf-veya-garantisiz-kod-sürpriz-kutusu">Zayıf veya garantisiz kod: Sürpriz kutusu</h2>

<p>Ham kaynaklar ve sıralı güncellemeler tehlikeli bir kombinasyondur:</p>

<div class="language-cpp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">account</span><span class="p">.</span><span class="n">balance</span> <span class="o">-=</span> <span class="n">amount</span><span class="p">;</span>
<span class="n">ledger</span><span class="p">.</span><span class="n">add</span><span class="p">(</span><span class="n">account</span><span class="p">.</span><span class="n">id</span><span class="p">,</span> <span class="n">amount</span><span class="p">);</span> <span class="c1">// Fırlatabilir</span>
<span class="n">account</span><span class="p">.</span><span class="n">lastTransfer</span> <span class="o">=</span> <span class="n">now</span><span class="p">();</span>
</code></pre></div></div>

<p><code class="language-plaintext highlighter-rouge">ledger.add</code> fırlatırsa bakiye azalmış, kayıt eklenmemiş ve zaman damgası değişmemiş olabilir. Nesneler tek tek geçerli görünse bile sistemin iş kuralı bozulmuştur. Böyle bir fonksiyon tekrar çağrılırsa para ikinci kez düşülebilir.</p>

<p>Çözüm; değişiklikleri geçici bir yapıda toplamak, geri alma işlemi tasarlamak veya fırlatabilen adımları mutasyondan önce tamamlamaktır.</p>

<h2 id="hangi-seviyeyi-seçmeliyiz">Hangi seviyeyi seçmeliyiz?</h2>

<p>Her fonksiyona güçlü garanti vermek gereksiz olabilir. Salt hesaplamalarda ve kritik güncellemelerde güçlü garanti hedeflenebilir; büyük koleksiyonları dönüştüren performans odaklı işlemlerde temel garanti yeterli olabilir. Yıkıcılar, kaynak bırakma fonksiyonları ve <code class="language-plaintext highlighter-rouge">swap</code> gibi altyapı işlemleri ise mümkünse <code class="language-plaintext highlighter-rouge">noexcept</code> olmalıdır.</p>

<p>Pratik kontrol sorusu şudur: “Bu satır fırlatırsa hangi değişiklikler yapılmış olacak?” Cevap belirsizse yalnızca bir istisna probleminiz değil, aynı zamanda bir tasarım probleminiz vardır.</p>]]></content><author><name>Sonsuz Us</name></author><category term="Bilgi" /><category term="c++" /><category term="istisna yönetimi" /><category term="exception safety" /><category term="raii" /><category term="yazılım tasarımı" /><summary type="html"><![CDATA[Bir C++ fonksiyonunun istisna fırlatabilmesi tek başına korkutucu değildir; asıl mesele, istisna sonrasında programın hangi durumda kaldığıdır. Sepete ürün eklerken bellek tahsisi başarısız olursa eski sepet hâlâ kullanılabilir mi, yoksa nesne yarı güncellenmiş bir zombiye mi dönüşür? İstisna garantileri tam olarak bu soruya cevap verir.]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://program.sonsuz.us/img/c-istisna-garantileri-83.png" /><media:content medium="image" url="https://program.sonsuz.us/img/c-istisna-garantileri-83.png" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">C++ İstisna Yönetimi: Hataları Güvenle Yakalamak</title><link href="https://program.sonsuz.us/posts/c-istisna-yonetimi-hatalari-guvenle-yakalamak/" rel="alternate" type="text/html" title="C++ İstisna Yönetimi: Hataları Güvenle Yakalamak" /><published>2026-10-18T00:00:00+00:00</published><updated>2026-10-18T00:00:00+00:00</updated><id>https://program.sonsuz.us/posts/c-istisna-yonetimi-hatalari-guvenle-yakalamak</id><content type="html" xml:base="https://program.sonsuz.us/posts/c-istisna-yonetimi-hatalari-guvenle-yakalamak/"><![CDATA[<p>Bir C++ programı derlenmiş olsa bile çalışma sırasında dosya bulunamaması, belleğin ayrılamaması veya geçersiz veriyle karşılaşılması gibi sorunlar yaşayabilir. İstisna yönetimi, bu beklenmedik durumları programı aniden sonlandırmadan uygun bir noktaya bildirmemizi sağlar. Kısacası <code class="language-plaintext highlighter-rouge">throw</code> alarmı çalıştırır, <code class="language-plaintext highlighter-rouge">try</code> riskli bölgeyi gözetler, <code class="language-plaintext highlighter-rouge">catch</code> ise olaya müdahale eder.
``</p>
<h2 id="i̇stisna-yönetiminin-temel-mantığı">İstisna yönetiminin temel mantığı</h2>

<p>Normal koşullarda fonksiyonlar sonuçlarını <code class="language-plaintext highlighter-rouge">return</code> ile döndürür. Ancak bir fonksiyon görevini tamamlayamıyorsa sıradan bir sonuç döndürmek yanıltıcı olabilir. Örneğin pozitif sayı bekleyen bir karekök fonksiyonuna negatif değer verilmesi ayrı bir kontrol akışı gerektirir.</p>

<p>İstisna oluştuğunda program, uygun bir <code class="language-plaintext highlighter-rouge">catch</code> bloğu bulana kadar çağrı zincirinde geriye ilerler. Bu sürece <strong>stack unwinding</strong> denir. Matematiksel olarak bir fonksiyonun geçerli kümesini şöyle gösterebiliriz:</p>

\[f(x) = \sqrt{x}, \qquad x \in [0, \infty)\]

<p>Burada $x &lt; 0$ olması, fonksiyon sözleşmesinin ihlal edildiğini belirtir.</p>

<table>
  <thead>
    <tr>
      <th>Araç</th>
      <th>Görevi</th>
      <th>Benzetme</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">try</code></td>
      <td>Hata oluşturabilecek kodu çalıştırır</td>
      <td>Güvenlik kamerası</td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">throw</code></td>
      <td>İstisna üretir</td>
      <td>Alarm düğmesi</td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">catch</code></td>
      <td>Belirli istisnayı yakalar</td>
      <td>Müdahale ekibi</td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">noexcept</code></td>
      <td>Fonksiyonun istisna fırlatmayacağını bildirir</td>
      <td>Güvenlik garantisi</td>
    </tr>
  </tbody>
</table>

<h2 id="temel-try-throw-ve-catch-kullanımı">Temel <code class="language-plaintext highlighter-rouge">try</code>, <code class="language-plaintext highlighter-rouge">throw</code> ve <code class="language-plaintext highlighter-rouge">catch</code> kullanımı</h2>

<p>Aşağıdaki örnek, bölme işleminden önce paydayı denetler. Sıfıra bölme tespit edildiğinde <code class="language-plaintext highlighter-rouge">std::runtime_error</code> nesnesi fırlatılır:</p>

<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;stdexcept&gt;</span><span class="cp">
</span>
<span class="kt">double</span> <span class="nf">bol</span><span class="p">(</span><span class="kt">double</span> <span class="n">pay</span><span class="p">,</span> <span class="kt">double</span> <span class="n">payda</span><span class="p">)</span> <span class="p">{</span>
    <span class="k">if</span> <span class="p">(</span><span class="n">payda</span> <span class="o">==</span> <span class="mf">0.0</span><span class="p">)</span> <span class="p">{</span>
        <span class="k">throw</span> <span class="n">std</span><span class="o">::</span><span class="n">runtime_error</span><span class="p">(</span><span class="s">"Sıfıra bölme girişimi!"</span><span class="p">);</span>
    <span class="p">}</span>
    <span class="k">return</span> <span class="n">pay</span> <span class="o">/</span> <span class="n">payda</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="k">try</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">bol</span><span class="p">(</span><span class="mi">42</span><span class="p">,</span> <span class="mi">0</span><span class="p">)</span> <span class="o">&lt;&lt;</span> <span class="sc">'\n'</span><span class="p">;</span>
    <span class="p">}</span> <span class="k">catch</span> <span class="p">(</span><span class="k">const</span> <span class="n">std</span><span class="o">::</span><span class="n">runtime_error</span><span class="o">&amp;</span> <span class="n">hata</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">"Hata: "</span> <span class="o">&lt;&lt;</span> <span class="n">hata</span><span class="p">.</span><span class="n">what</span><span class="p">()</span> <span class="o">&lt;&lt;</span> <span class="sc">'\n'</span><span class="p">;</span>
    <span class="p">}</span>
<span class="p">}</span>
</code></pre></div></div>

<p>İstisnanın <code class="language-plaintext highlighter-rouge">const</code> referansla yakalanması gereksiz kopyalamayı engeller ve çok biçimliliği korur. <code class="language-plaintext highlighter-rouge">what()</code> metodu ise hatanın açıklamasını verir. Program kontrolsüz biçimde çökmek yerine kullanıcıya anlamlı bir mesaj sunar.</p>

<h2 id="standart-mı-özel-istisna-mı">Standart mı, özel istisna mı?</h2>

<p>C++ standart kütüphanesi <code class="language-plaintext highlighter-rouge">std::exception</code> tabanlı birçok hata türü sağlar.</p>

<table>
  <thead>
    <tr>
      <th>İstisna</th>
      <th>Uygun kullanım</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">std::invalid_argument</code></td>
      <td>Geçersiz fonksiyon argümanı</td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">std::out_of_range</code></td>
      <td>Aralık dışı indeks</td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">std::runtime_error</code></td>
      <td>Genel çalışma zamanı sorunu</td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">std::bad_alloc</code></td>
      <td>Bellek ayırma başarısızlığı</td>
    </tr>
  </tbody>
</table>

<p>Uygulamaya özgü hatalar için özel bir sınıf da tanımlanabilir:</p>

<div class="language-cpp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="cp">#include</span> <span class="cpf">&lt;stdexcept&gt;</span><span class="cp">
#include</span> <span class="cpf">&lt;string&gt;</span><span class="cp">
</span>
<span class="k">class</span> <span class="nc">BakiyeHatasi</span> <span class="o">:</span> <span class="k">public</span> <span class="n">std</span><span class="o">::</span><span class="n">runtime_error</span> <span class="p">{</span>
<span class="nl">public:</span>
    <span class="k">explicit</span> <span class="n">BakiyeHatasi</span><span class="p">(</span><span class="k">const</span> <span class="n">std</span><span class="o">::</span><span class="n">string</span><span class="o">&amp;</span> <span class="n">mesaj</span><span class="p">)</span>
        <span class="o">:</span> <span class="n">std</span><span class="o">::</span><span class="n">runtime_error</span><span class="p">(</span><span class="n">mesaj</span><span class="p">)</span> <span class="p">{}</span>
<span class="p">};</span>

<span class="kt">void</span> <span class="nf">paraCek</span><span class="p">(</span><span class="kt">double</span> <span class="n">bakiye</span><span class="p">,</span> <span class="kt">double</span> <span class="n">miktar</span><span class="p">)</span> <span class="p">{</span>
    <span class="k">if</span> <span class="p">(</span><span class="n">miktar</span> <span class="o">&gt;</span> <span class="n">bakiye</span><span class="p">)</span> <span class="p">{</span>
        <span class="k">throw</span> <span class="n">BakiyeHatasi</span><span class="p">(</span><span class="s">"Yetersiz bakiye"</span><span class="p">);</span>
    <span class="p">}</span>
<span class="p">}</span>
</code></pre></div></div>

<p>Bu yaklaşım, çağıran kodun banka işlemlerine özgü problemi diğer çalışma zamanı hatalarından ayırmasını sağlar.</p>

<h2 id="yakalama-sırası-ve-yeniden-fırlatma">Yakalama sırası ve yeniden fırlatma</h2>

<p><code class="language-plaintext highlighter-rouge">catch</code> blokları özel türden genel türe doğru sıralanmalıdır. Aksi hâlde <code class="language-plaintext highlighter-rouge">std::exception</code> gibi genel bir blok, türetilmiş bütün istisnaları önce yakalayabilir.</p>

<div class="language-cpp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">try</span> <span class="p">{</span>
    <span class="n">paraCek</span><span class="p">(</span><span class="mi">100</span><span class="p">,</span> <span class="mi">250</span><span class="p">);</span>
<span class="p">}</span> <span class="k">catch</span> <span class="p">(</span><span class="k">const</span> <span class="n">BakiyeHatasi</span><span class="o">&amp;</span> <span class="n">hata</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="n">hata</span><span class="p">.</span><span class="n">what</span><span class="p">()</span> <span class="o">&lt;&lt;</span> <span class="sc">'\n'</span><span class="p">;</span>
    <span class="k">throw</span><span class="p">;</span> <span class="c1">// Aynı istisnayı üst seviyeye iletir</span>
<span class="p">}</span> <span class="k">catch</span> <span class="p">(</span><span class="k">const</span> <span class="n">std</span><span class="o">::</span><span class="n">exception</span><span class="o">&amp;</span> <span class="n">hata</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">"Genel hata: "</span> <span class="o">&lt;&lt;</span> <span class="n">hata</span><span class="p">.</span><span class="n">what</span><span class="p">()</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>Parametresiz <code class="language-plaintext highlighter-rouge">throw;</code>, mevcut istisnayı türünü kaybetmeden yeniden fırlatır. Bu yöntem, alt seviyede kayıt tutup üst seviyede kullanıcıya cevap vermek için kullanışlıdır.</p>

<h2 id="güvenli-tasarım-için-kısa-kurallar">Güvenli tasarım için kısa kurallar</h2>

<p>İstisnaları sıradan döngü kontrolü amacıyla değil, gerçekten olağan dışı durumlar için kullanın. Kaynak yönetiminde RAII yaklaşımını tercih edin; <code class="language-plaintext highlighter-rouge">std::vector</code>, <code class="language-plaintext highlighter-rouge">std::string</code> ve akıllı işaretçiler stack unwinding sırasında otomatik olarak temizlenir. Yıkıcılar mümkünse istisna fırlatmamalıdır. Ayrıca yalnızca gerçekten garanti verebildiğiniz fonksiyonları <code class="language-plaintext highlighter-rouge">noexcept</code> olarak işaretleyin.</p>

<p>Doğru tasarlanmış istisna yönetimi hataları yok etmez; onları görünür, sınıflandırılabilir ve güvenli biçimde yönetilebilir hâle getirir. Böylece programınız ilk beklenmedik durumda havlu atmak yerine kontrollü bir iniş yapar.</p>

<p><img src="/img/c-istisna-yonetimi-33.svg" alt="c-istisna-yonetimi-33" /></p>]]></content><author><name>Sonsuz Us</name></author><category term="Bilgi" /><category term="c++" /><category term="istisna yönetimi" /><category term="exception handling" /><category term="try-catch" /><category term="hata yönetimi" /><summary type="html"><![CDATA[Bir C++ programı derlenmiş olsa bile çalışma sırasında dosya bulunamaması, belleğin ayrılamaması veya geçersiz veriyle karşılaşılması gibi sorunlar yaşayabilir. İstisna yönetimi, bu beklenmedik durumları programı aniden sonlandırmadan uygun bir noktaya bildirmemizi sağlar. Kısacası throw alarmı çalıştırır, try riskli bölgeyi gözetler, catch ise olaya müdahale eder.]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://program.sonsuz.us/img/c-istisna-yonetimi-33.png" /><media:content medium="image" url="https://program.sonsuz.us/img/c-istisna-yonetimi-33.png" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">C Karakter Dizileri: Null Karakterinden Güvenli Metin İşlemeye</title><link href="https://program.sonsuz.us/posts/c-karakter-dizileri-null-karakterinden-guvenli-metin-islemeye/" rel="alternate" type="text/html" title="C Karakter Dizileri: Null Karakterinden Güvenli Metin İşlemeye" /><published>2026-10-18T00:00:00+00:00</published><updated>2026-10-18T00:00:00+00:00</updated><id>https://program.sonsuz.us/posts/c-karakter-dizileri-null-karakterinden-guvenli-metin-islemeye</id><content type="html" xml:base="https://program.sonsuz.us/posts/c-karakter-dizileri-null-karakterinden-guvenli-metin-islemeye/"><![CDATA[<p>C dilinde metinlerle çalışmak ilk bakışta birkaç kelimeyi bir değişkende saklamak kadar basit görünür. Fakat C, hazır ve bağımsız bir <code class="language-plaintext highlighter-rouge">string</code> veri türü sunmaz. Bunun yerine metinleri, bellekte art arda bulunan karakterlerden oluşan ve özel bir null karakteriyle sonlandırılan diziler şeklinde işler. Bu yaklaşım hem yüksek performans hem de etkileyici bir kontrol sağlar; ancak sınırlar unutulduğunda programı küçük bir bellek mayın tarlasına çevirebilir.</p>

<p><img src="/img/c-karakter-dizileri-59.svg" alt="c-karakter-dizileri-59" /></p>

<p>``</p>

<h2 id="c-stringinin-temel-yapısı">C string’inin temel yapısı</h2>

<p>Bir C karakter dizisinin her elemanı <code class="language-plaintext highlighter-rouge">char</code> türündedir. Metnin bittiği yer, sayısal değeri sıfır olan <code class="language-plaintext highlighter-rouge">\0</code> karakteriyle belirtilir. Örneğin <code class="language-plaintext highlighter-rouge">"Kod"</code> metni bellekte şu şekilde tutulur:</p>

<table>
  <thead>
    <tr>
      <th style="text-align: right">İndis</th>
      <th style="text-align: center">Karakter</th>
      <th style="text-align: right">Sayısal değer</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td style="text-align: right">0</td>
      <td style="text-align: center"><code class="language-plaintext highlighter-rouge">K</code></td>
      <td style="text-align: right">75</td>
    </tr>
    <tr>
      <td style="text-align: right">1</td>
      <td style="text-align: center"><code class="language-plaintext highlighter-rouge">o</code></td>
      <td style="text-align: right">111</td>
    </tr>
    <tr>
      <td style="text-align: right">2</td>
      <td style="text-align: center"><code class="language-plaintext highlighter-rouge">d</code></td>
      <td style="text-align: right">100</td>
    </tr>
    <tr>
      <td style="text-align: right">3</td>
      <td style="text-align: center"><code class="language-plaintext highlighter-rouge">\0</code></td>
      <td style="text-align: right">0</td>
    </tr>
  </tbody>
</table>

<p>Görünen karakter sayısı $n$ ise gereken en düşük bellek miktarı yaklaşık olarak şöyledir:</p>

\[B = (n + 1) \times sizeof(char)\]

<p>C standardında <code class="language-plaintext highlighter-rouge">sizeof(char)</code> her zaman 1 olduğundan, üç karakterli <code class="language-plaintext highlighter-rouge">"Kod"</code> için dört baytlık alan gerekir. Fazladan bayt, null karakterinin koltuğudur; görünmez ama yolculuk onsuz tamamlanmaz.</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">char</span> <span class="n">metin</span><span class="p">[]</span> <span class="o">=</span> <span class="s">"Kod"</span><span class="p">;</span>

    <span class="n">printf</span><span class="p">(</span><span class="s">"%s</span><span class="se">\n</span><span class="s">"</span><span class="p">,</span> <span class="n">metin</span><span class="p">);</span>
    <span class="n">printf</span><span class="p">(</span><span class="s">"Ilk karakter: %c</span><span class="se">\n</span><span class="s">"</span><span class="p">,</span> <span class="n">metin</span><span class="p">[</span><span class="mi">0</span><span class="p">]);</span>
    <span class="n">printf</span><span class="p">(</span><span class="s">"Sonlandirici deger: %d</span><span class="se">\n</span><span class="s">"</span><span class="p">,</span> <span class="n">metin</span><span class="p">[</span><span class="mi">3</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>Derleyici burada dizinin boyutunu otomatik olarak dört seçer ve sona <code class="language-plaintext highlighter-rouge">\0</code> ekler. <code class="language-plaintext highlighter-rouge">%s</code>, karakterleri null sonlandırıcıya ulaşıncaya kadar ekrana yazar.</p>

<h2 id="dizi-mi-işaretçi-mi">Dizi mi, işaretçi mi?</h2>

<p>Aşağıdaki iki tanım benzer görünse de aynı davranışı garanti etmez:</p>

<table>
  <thead>
    <tr>
      <th>Tanım</th>
      <th>Veri konumu</th>
      <th>Değiştirilebilir mi?</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">char ad[] = "Ada";</code></td>
      <td>Yazılabilir dizi</td>
      <td>Evet</td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">const char *ad = "Ada";</code></td>
      <td>String sabitini gösterir</td>
      <td>Hayır</td>
    </tr>
  </tbody>
</table>

<div class="language-c highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kt">char</span> <span class="n">dil</span><span class="p">[]</span> <span class="o">=</span> <span class="s">"C dili"</span><span class="p">;</span>
<span class="n">dil</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">=</span> <span class="sc">'c'</span><span class="p">;</span>  <span class="cm">/* Gecerli: dizi degistirilebilir. */</span>

<span class="k">const</span> <span class="kt">char</span> <span class="o">*</span><span class="n">mesaj</span> <span class="o">=</span> <span class="s">"Merhaba"</span><span class="p">;</span>
<span class="cm">/* mesaj[0] = 'm';  Hatali: string sabiti degistirilmemeli. */</span>
</code></pre></div></div>

<p>İkinci kullanımda <code class="language-plaintext highlighter-rouge">const</code>, yanlışlıkla salt okunur veriyi değiştirmeye çalışmamızı engeller. Yalın <code class="language-plaintext highlighter-rouge">char *mesaj = "Merhaba";</code> bazı derleyicilerde kabul edilse bile karakterleri değiştirmek tanımsız davranıştır.</p>

<h2 id="uzunluk-ve-kapasite-aynı-şey-değildir">Uzunluk ve kapasite aynı şey değildir</h2>

<p><code class="language-plaintext highlighter-rouge">strlen()</code> yalnızca <code class="language-plaintext highlighter-rouge">\0</code> öncesindeki karakterleri sayar. <code class="language-plaintext highlighter-rouge">sizeof()</code> ise erişilebilen dizi nesnesinin toplam boyutunu verir.</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">
#include</span> <span class="cpf">&lt;string.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">char</span> <span class="n">kutu</span><span class="p">[</span><span class="mi">20</span><span class="p">]</span> <span class="o">=</span> <span class="s">"Merhaba"</span><span class="p">;</span>

    <span class="n">printf</span><span class="p">(</span><span class="s">"Uzunluk: %zu</span><span class="se">\n</span><span class="s">"</span><span class="p">,</span> <span class="n">strlen</span><span class="p">(</span><span class="n">kutu</span><span class="p">));</span> <span class="cm">/* 7 */</span>
    <span class="n">printf</span><span class="p">(</span><span class="s">"Kapasite: %zu</span><span class="se">\n</span><span class="s">"</span><span class="p">,</span> <span class="k">sizeof</span><span class="p">(</span><span class="n">kutu</span><span class="p">));</span> <span class="cm">/* 20 */</span>
    <span class="k">return</span> <span class="mi">0</span><span class="p">;</span>
<span class="p">}</span>
</code></pre></div></div>

<p>Bu örnekte metin uzunluğu $L=7$, dizinin kapasitesi $C=20$ bayttır. Güvenli bir string için temel koşul $L &lt; C$ olmalıdır; çünkü bir hücre <code class="language-plaintext highlighter-rouge">\0</code> için ayrılır. İşaretçi bir fonksiyona gönderildiğinde <code class="language-plaintext highlighter-rouge">sizeof()</code> artık dizinin kapasitesini değil, işaretçinin boyutunu verebilir. Bu nedenle kapasiteyi fonksiyona ayrıca göndermek iyi bir alışkanlıktır.</p>

<h2 id="güvenli-girdi-alma">Güvenli girdi alma</h2>

<p><code class="language-plaintext highlighter-rouge">scanf("%s", ...)</code> boşlukta okumayı keser ve sınır belirtilmezse taşmaya yol açabilir. <code class="language-plaintext highlighter-rouge">fgets()</code> ise kapasiteyi bildiği için daha güvenli bir seçenektir.</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">
#include</span> <span class="cpf">&lt;string.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">char</span> <span class="n">ad</span><span class="p">[</span><span class="mi">32</span><span class="p">];</span>

    <span class="n">printf</span><span class="p">(</span><span class="s">"Adinizi girin: "</span><span class="p">);</span>
    <span class="k">if</span> <span class="p">(</span><span class="n">fgets</span><span class="p">(</span><span class="n">ad</span><span class="p">,</span> <span class="k">sizeof</span> <span class="n">ad</span><span class="p">,</span> <span class="n">stdin</span><span class="p">)</span> <span class="o">!=</span> <span class="nb">NULL</span><span class="p">)</span> <span class="p">{</span>
        <span class="n">ad</span><span class="p">[</span><span class="n">strcspn</span><span class="p">(</span><span class="n">ad</span><span class="p">,</span> <span class="s">"</span><span class="se">\n</span><span class="s">"</span><span class="p">)]</span> <span class="o">=</span> <span class="sc">'\0'</span><span class="p">;</span>
        <span class="n">printf</span><span class="p">(</span><span class="s">"Merhaba, %s!</span><span class="se">\n</span><span class="s">"</span><span class="p">,</span> <span class="n">ad</span><span class="p">);</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><code class="language-plaintext highlighter-rouge">fgets()</code> satır sonunu diziye ekleyebilir. <code class="language-plaintext highlighter-rouge">strcspn()</code> ilk <code class="language-plaintext highlighter-rouge">\n</code> karakterinin konumunu bulur ve bu karakter null sonlandırıcıyla değiştirilir.</p>

<h2 id="akılda-tutulacaklar">Akılda tutulacaklar</h2>

<p>C string’leri, null karakteriyle sonlanan <code class="language-plaintext highlighter-rouge">char</code> dizileridir. Her zaman kapasiteyi hesaba katın, sonlandırıcı için yer bırakın ve sınır kontrollü fonksiyonları tercih edin. <code class="language-plaintext highlighter-rouge">strlen</code>, <code class="language-plaintext highlighter-rouge">strcmp</code>, <code class="language-plaintext highlighter-rouge">strchr</code> ve dikkatli kullanıldığında <code class="language-plaintext highlighter-rouge">snprintf</code>, metin işlemlerinde güçlü yardımcılarınızdır. C size emniyet kemerini zorla takmaz; fakat kemerin nerede olduğunu bilmek programınızı çöküşlerden korur.</p>]]></content><author><name>Sonsuz Us</name></author><category term="Bilgi" /><category term="c" /><category term="string" /><category term="karakter-dizileri" /><category term="bellek" /><category term="pointer" /><category term="programlama" /><summary type="html"><![CDATA[C dilinde metinlerle çalışmak ilk bakışta birkaç kelimeyi bir değişkende saklamak kadar basit görünür. Fakat C, hazır ve bağımsız bir string veri türü sunmaz. Bunun yerine metinleri, bellekte art arda bulunan karakterlerden oluşan ve özel bir null karakteriyle sonlandırılan diziler şeklinde işler. Bu yaklaşım hem yüksek performans hem de etkileyici bir kontrol sağlar; ancak sınırlar unutulduğunda programı küçük bir bellek mayın tarlasına çevirebilir.]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://program.sonsuz.us/img/c-karakter-dizileri-59.png" /><media:content medium="image" url="https://program.sonsuz.us/img/c-karakter-dizileri-59.png" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">C# Operatörler ve Program Kontrolü: Kararlardan Döngülere</title><link href="https://program.sonsuz.us/posts/c-operatorler-ve-program-kontrolu-kararlardan-dongulere/" rel="alternate" type="text/html" title="C# Operatörler ve Program Kontrolü: Kararlardan Döngülere" /><published>2026-10-18T00:00:00+00:00</published><updated>2026-10-18T00:00:00+00:00</updated><id>https://program.sonsuz.us/posts/c-operatorler-ve-program-kontrolu-kararlardan-dongulere</id><content type="html" xml:base="https://program.sonsuz.us/posts/c-operatorler-ve-program-kontrolu-kararlardan-dongulere/"><![CDATA[<p>Bir C# programı yalnızca yukarıdan aşağıya çalışan komutlardan oluşmaz. Değerleri karşılaştırır, koşullara göre karar verir ve gerektiğinde aynı işlemi tekrarlar. Operatörler bu kararların kelimeleri, kontrol blokları ise programın trafik ışıklarıdır. Gelin C# kodunun nasıl düşündüğünü adım adım inceleyelim.</p>

<p>``</p>

<h2 id="operatörlerin-temel-mantığı">Operatörlerin temel mantığı</h2>

<p>Operatör, bir veya daha fazla değer üzerinde işlem yapan semboldür. Örneğin <code class="language-plaintext highlighter-rouge">+</code> iki sayıyı toplarken <code class="language-plaintext highlighter-rouge">&gt;=</code> değerleri karşılaştırır. <code class="language-plaintext highlighter-rouge">=</code> ile <code class="language-plaintext highlighter-rouge">==</code> arasındaki fark özellikle önemlidir: İlki atama, ikincisi eşitlik kontrolüdür.</p>

<div class="language-csharp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kt">int</span> <span class="n">puan</span> <span class="p">=</span> <span class="m">75</span><span class="p">;</span>              <span class="c1">// Atama</span>
<span class="kt">bool</span> <span class="n">gectiMi</span> <span class="p">=</span> <span class="n">puan</span> <span class="p">&gt;=</span> <span class="m">50</span><span class="p">;</span>  <span class="c1">// Karşılaştırma</span>
<span class="kt">int</span> <span class="n">bonusluPuan</span> <span class="p">=</span> <span class="n">puan</span> <span class="p">+</span> <span class="m">10</span><span class="p">;</span>
</code></pre></div></div>

<p>Aritmetik operatörler matematiksel işlemleri gerçekleştirir. İki sayı $a$ ve $b$ olmak üzere kalan işlemi $a \bmod b$ biçiminde düşünülebilir. C# dilinde bunun karşılığı <code class="language-plaintext highlighter-rouge">%</code> operatörüdür.</p>

<table>
  <thead>
    <tr>
      <th>Grup</th>
      <th>Operatörler</th>
      <th>Örnek kullanım</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Aritmetik</td>
      <td><code class="language-plaintext highlighter-rouge">+</code>, <code class="language-plaintext highlighter-rouge">-</code>, <code class="language-plaintext highlighter-rouge">*</code>, <code class="language-plaintext highlighter-rouge">/</code>, <code class="language-plaintext highlighter-rouge">%</code></td>
      <td><code class="language-plaintext highlighter-rouge">sayi % 2</code></td>
    </tr>
    <tr>
      <td>Karşılaştırma</td>
      <td><code class="language-plaintext highlighter-rouge">==</code>, <code class="language-plaintext highlighter-rouge">!=</code>, <code class="language-plaintext highlighter-rouge">&lt;</code>, <code class="language-plaintext highlighter-rouge">&gt;</code>, <code class="language-plaintext highlighter-rouge">&lt;=</code>, <code class="language-plaintext highlighter-rouge">&gt;=</code></td>
      <td><code class="language-plaintext highlighter-rouge">yas &gt;= 18</code></td>
    </tr>
    <tr>
      <td>Mantıksal</td>
      <td><code class="language-plaintext highlighter-rouge">&amp;&amp;</code>, <code class="language-plaintext highlighter-rouge">||</code>, <code class="language-plaintext highlighter-rouge">!</code></td>
      <td><code class="language-plaintext highlighter-rouge">aktif &amp;&amp; yetkili</code></td>
    </tr>
    <tr>
      <td>Atama</td>
      <td><code class="language-plaintext highlighter-rouge">=</code>, <code class="language-plaintext highlighter-rouge">+=</code>, <code class="language-plaintext highlighter-rouge">-=</code>, <code class="language-plaintext highlighter-rouge">*=</code>, <code class="language-plaintext highlighter-rouge">/=</code></td>
      <td><code class="language-plaintext highlighter-rouge">puan += 5</code></td>
    </tr>
    <tr>
      <td>Artırma/Azaltma</td>
      <td><code class="language-plaintext highlighter-rouge">++</code>, <code class="language-plaintext highlighter-rouge">--</code></td>
      <td><code class="language-plaintext highlighter-rouge">sayac++</code></td>
    </tr>
  </tbody>
</table>

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

<p>Mantıksal operatörler Boolean cebirine dayanır. <code class="language-plaintext highlighter-rouge">&amp;&amp;</code> için sonuç yalnızca iki ifade de doğruysa doğrudur:</p>

\[A \land B = true \quad \text{yalnızca A ve B doğruysa}\]

<p><code class="language-plaintext highlighter-rouge">||</code> operatöründe ise koşullardan birinin doğru olması yeterlidir. C# kısa devre değerlendirmesi uygular; <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. Bu davranış hem performans sağlar hem de bazı null hatalarını engeller.</p>

<h2 id="ca-özgü-kullanışlı-işleçler">C#’a özgü kullanışlı işleçler</h2>

<p>C#, null değerlerle güvenli çalışmayı kolaylaştıran operatörler sunar. <code class="language-plaintext highlighter-rouge">?.</code> yalnızca nesne null değilse üyeye erişir; <code class="language-plaintext highlighter-rouge">??</code> ise sol taraf null olduğunda yedek değer üretir.</p>

<div class="language-csharp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kt">string</span><span class="p">?</span> <span class="n">kullaniciAdi</span> <span class="p">=</span> <span class="k">null</span><span class="p">;</span>
<span class="kt">int</span><span class="p">?</span> <span class="n">uzunluk</span> <span class="p">=</span> <span class="n">kullaniciAdi</span><span class="p">?.</span><span class="n">Length</span><span class="p">;</span>
<span class="kt">string</span> <span class="n">gorunenAd</span> <span class="p">=</span> <span class="n">kullaniciAdi</span> <span class="p">??</span> <span class="s">"Misafir"</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">gorunenAd</span><span class="p">);</span> <span class="c1">// Misafir</span>
</code></pre></div></div>

<p><code class="language-plaintext highlighter-rouge">is</code> tür denetimi ve örüntü eşleştirme için, <code class="language-plaintext highlighter-rouge">as</code> ise güvenli tür dönüşümü için kullanılır. Ayrıca <code class="language-plaintext highlighter-rouge">nameof(degisken)</code> değişkenin adını metin olarak verir; böylece yeniden adlandırmalara dayanıklı hata mesajları oluşturulur.</p>

<table>
  <thead>
    <tr>
      <th>İşleç</th>
      <th>Amaç</th>
      <th>Başarısızlık davranışı</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">?.</code></td>
      <td>Güvenli üye erişimi</td>
      <td>Null üretir</td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">??</code></td>
      <td>Varsayılan değer seçimi</td>
      <td>Sağ tarafı kullanır</td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">is</code></td>
      <td>Tür veya örüntü kontrolü</td>
      <td><code class="language-plaintext highlighter-rouge">false</code> üretir</td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">as</code></td>
      <td>Referans türü dönüşümü</td>
      <td>Null üretir</td>
    </tr>
  </tbody>
</table>

<h2 id="if-else-ile-karar-vermek">if-else ile karar vermek</h2>

<p><code class="language-plaintext highlighter-rouge">if</code> bloğu koşul doğru olduğunda çalışır. Alternatif yollar <code class="language-plaintext highlighter-rouge">else if</code> ve <code class="language-plaintext highlighter-rouge">else</code> ile tanımlanır.</p>

<div class="language-csharp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kt">int</span> <span class="n">not</span> <span class="p">=</span> <span class="m">82</span><span class="p">;</span>

<span class="k">if</span> <span class="p">(</span><span class="n">not</span> <span class="p">&gt;=</span> <span class="m">85</span><span class="p">)</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="s">"Pek iyi"</span><span class="p">);</span>
<span class="p">}</span>
<span class="k">else</span> <span class="k">if</span> <span class="p">(</span><span class="n">not</span> <span class="p">&gt;=</span> <span class="m">50</span><span class="p">)</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="s">"Geçti"</span><span class="p">);</span>
<span class="p">}</span>
<span class="k">else</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="s">"Tekrar dene"</span><span class="p">);</span>
<span class="p">}</span>
</code></pre></div></div>

<p>Basit seçimlerde üçlü koşul operatörü kullanılabilir: <code class="language-plaintext highlighter-rouge">sonuc = kosul ? dogruDeger : yanlisDeger;</code>. Ancak iç içe üçlü ifadeler kodu bulmacaya çevirebilir; okunabilirlik her zaman kısalıktan değerlidir.</p>

<h2 id="döngüsel-iterasyon-mekanizmaları">Döngüsel iterasyon mekanizmaları</h2>

<p>Döngüler tekrar eden işleri otomatikleştirir. Hangi döngünün seçileceği, tekrar sayısının bilinip bilinmemesine bağlıdır.</p>

<table>
  <thead>
    <tr>
      <th>Döngü</th>
      <th>Ne zaman tercih edilir?</th>
      <th>Özellik</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">for</code></td>
      <td>Tekrar sayısı biliniyorsa</td>
      <td>Sayaç kontrolü sunar</td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">while</code></td>
      <td>Devam koşulu önemliyse</td>
      <td>Koşulu başta sınar</td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">do-while</code></td>
      <td>İşlem en az bir kez yapılacaksa</td>
      <td>Koşulu sonda sınar</td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">foreach</code></td>
      <td>Koleksiyon gezilecekse</td>
      <td>İndeks yönetimi gerektirmez</td>
    </tr>
  </tbody>
</table>

<div class="language-csharp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kt">string</span><span class="p">[]</span> <span class="n">diller</span> <span class="p">=</span> <span class="p">{</span> <span class="s">"C#"</span><span class="p">,</span> <span class="s">"Java"</span><span class="p">,</span> <span class="s">"Python"</span> <span class="p">};</span>

<span class="k">foreach</span> <span class="p">(</span><span class="kt">string</span> <span class="n">dil</span> <span class="k">in</span> <span class="n">diller</span><span class="p">)</span>
<span class="p">{</span>
    <span class="k">if</span> <span class="p">(</span><span class="n">dil</span> <span class="p">==</span> <span class="s">"Java"</span><span class="p">)</span>
        <span class="k">continue</span><span class="p">;</span> <span class="c1">// Bu turu atlar</span>

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

<p><code class="language-plaintext highlighter-rouge">continue</code> mevcut turu atlatırken <code class="language-plaintext highlighter-rouge">break</code> döngüyü tamamen bitirir. Sonsuz döngülerden kaçınmak için <code class="language-plaintext highlighter-rouge">while</code> koşulunu etkileyen değerin gerçekten değiştiğinden emin olun. Özetle operatörler veriyi işler, koşullar yolu seçer, döngüler ise işi tekrarlar; bu üçlü, neredeyse bütün C# uygulamalarının kontrol merkezidir.</p>]]></content><author><name>Sonsuz Us</name></author><category term="Bilgi" /><category term="c#" /><category term="operatörler" /><category term="if-else" /><category term="döngüler" /><category term="programlama" /><category term="kontrol-akışı" /><summary type="html"><![CDATA[Bir C# programı yalnızca yukarıdan aşağıya çalışan komutlardan oluşmaz. Değerleri karşılaştırır, koşullara göre karar verir ve gerektiğinde aynı işlemi tekrarlar. Operatörler bu kararların kelimeleri, kontrol blokları ise programın trafik ışıklarıdır. Gelin C# kodunun nasıl düşündüğünü adım adım inceleyelim.]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://program.sonsuz.us/img/c-operatorler-ve-81.png" /><media:content medium="image" url="https://program.sonsuz.us/img/c-operatorler-ve-81.png" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">C++ Şablonlarında Specialization ve Overloading: Derleyicinin İnce Seçim Oyunu</title><link href="https://program.sonsuz.us/posts/c-sablonlarinda-specialization-ve-overloading-derleyicinin-ince-secim-oyunu/" rel="alternate" type="text/html" title="C++ Şablonlarında Specialization ve Overloading: Derleyicinin İnce Seçim Oyunu" /><published>2026-10-18T00:00:00+00:00</published><updated>2026-10-18T00:00:00+00:00</updated><id>https://program.sonsuz.us/posts/c-sablonlarinda-specialization-ve-overloading-derleyicinin-ince-secim-oyunu</id><content type="html" xml:base="https://program.sonsuz.us/posts/c-sablonlarinda-specialization-ve-overloading-derleyicinin-ince-secim-oyunu/"><![CDATA[<p><img src="/img/c-sablonlarinda-specialization-82.svg" alt="c-sablonlarinda-specialization-82" /></p>

<p>C++ şablonlarında özelleştirme ve aşırı yükleme aynı hedefe gidiyormuş gibi görünür: belirli türlerde farklı davranmak. Fakat derleyicinin gözünde bunlar iki ayrı mekanizmadır. Overloading adaylar arasındaki yarışı belirlerken specialization, yarışı kazanan şablonun özel bir sürümünün bulunup bulunmadığına bakar. Küçük görünen bu sıra farkı, şaşırtıcı sonuçların kaynağıdır.</p>

<p>``</p>

<h2 id="i̇ki-mekanizmanın-temel-anlamı">İki mekanizmanın temel anlamı</h2>

<p>Bir fonksiyon şablonunu aşırı yüklediğimizde derleyicinin aday listesine yeni bir fonksiyon şablonu ekleriz. Açık özelleştirme ise yeni ve bağımsız bir aday oluşturmaz; mevcut birincil şablonun belirli argümanlar için alternatif uygulamasını tanımlar.</p>

<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">
</span>
<span class="k">template</span><span class="o">&lt;</span><span class="k">typename</span> <span class="nc">T</span><span class="p">&gt;</span>
<span class="kt">void</span> <span class="nf">goster</span><span class="p">(</span><span class="n">T</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="s">"Genel sürüm</span><span class="se">\n</span><span class="s">"</span><span class="p">;</span>
<span class="p">}</span>

<span class="k">template</span><span class="o">&lt;</span><span class="p">&gt;</span>
<span class="kt">void</span> <span class="n">goster</span><span class="o">&lt;</span><span class="kt">int</span><span class="o">&gt;</span><span class="p">(</span><span class="kt">int</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="s">"int özelleştirmesi</span><span class="se">\n</span><span class="s">"</span><span class="p">;</span>
<span class="p">}</span>

<span class="k">template</span><span class="o">&lt;</span><span class="k">typename</span> <span class="nc">T</span><span class="p">&gt;</span>
<span class="kt">void</span> <span class="nf">goster</span><span class="p">(</span><span class="n">T</span><span class="o">*</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="s">"İşaretçi overload'u</span><span class="se">\n</span><span class="s">"</span><span class="p">;</span>
<span class="p">}</span>
</code></pre></div></div>

<p>Burada üç bildirim varmış gibi görünse de overload çözümlemesinde yalnızca <code class="language-plaintext highlighter-rouge">goster(T)</code> ve <code class="language-plaintext highlighter-rouge">goster(T*)</code> yarışır. <code class="language-plaintext highlighter-rouge">goster&lt;int&gt;</code> ise ilk şablona bağlı bir açık özelleştirmedir.</p>

<table>
  <thead>
    <tr>
      <th>Özellik</th>
      <th>Overloading</th>
      <th>Specialization</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Yeni aday oluşturur mu?</td>
      <td>Evet</td>
      <td>Hayır</td>
    </tr>
    <tr>
      <td>Fonksiyonlarda kısmi biçimi var mı?</td>
      <td>Overload ile benzetilebilir</td>
      <td>Hayır</td>
    </tr>
    <tr>
      <td>Seçim zamanı</td>
      <td>Overload çözümlemesi sırasında</td>
      <td>Birincil şablon seçildikten sonra</td>
    </tr>
    <tr>
      <td>Kapsam</td>
      <td>Fonksiyon ve normal fonksiyonlar</td>
      <td>Birincil şablona bağlı</td>
    </tr>
    <tr>
      <td>Temel amaç</td>
      <td>Farklı parametre biçimleri</td>
      <td>Belirli argüman için özel uygulama</td>
    </tr>
  </tbody>
</table>

<h2 id="derleyicinin-seçim-sırası">Derleyicinin seçim sırası</h2>

<p>Basitleştirilmiş süreç şöyledir:</p>

<ol>
  <li>Görünür fonksiyonlar ve fonksiyon şablonları aday kümeye alınır.</li>
  <li>Şablon argüman çıkarımı yapılır.</li>
  <li>Dönüşüm kalitesi ve şablonların kısmi sıralaması değerlendirilir.</li>
  <li>En iyi overload seçilir.</li>
  <li>Kazanan bir fonksiyon şablonuysa ona ait açık özelleştirme aranır.</li>
</ol>

<p>Bunu kabaca</p>

\[\text{çağrılacak fonksiyon} = \operatorname{specialization}(\operatorname{bestOverload}(C))\]

<p>şeklinde düşünebiliriz. Buradaki $C$, uygun adaylar kümesidir. İşlemlerin sırası ters değildir; specialization önce yarışıp overload’u yenemez.</p>

<h2 id="klasik-işaretçi-sürprizi">Klasik işaretçi sürprizi</h2>

<div class="language-cpp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kt">int</span><span class="o">*</span> <span class="n">p</span> <span class="o">=</span> <span class="nb">nullptr</span><span class="p">;</span>
<span class="n">goster</span><span class="p">(</span><span class="n">p</span><span class="p">);</span>
</code></pre></div></div>

<p>İlk bakışta <code class="language-plaintext highlighter-rouge">T = int*</code> olduğundan genel şablonun <code class="language-plaintext highlighter-rouge">int*</code> özelleştirmesinin aranacağı düşünülebilir. Ancak <code class="language-plaintext highlighter-rouge">goster(T*)</code>, <code class="language-plaintext highlighter-rouge">int*</code> argümanı için <code class="language-plaintext highlighter-rouge">goster(T)</code> şablonundan daha özeldir. Dolayısıyla pointer overload’u yarışı kazanır. Derleyici artık yalnızca bu kazanan şablona bağlı bir explicit specialization olup olmadığına bakar; diğer birincil şablonun özelleştirmesine geri dönmez.</p>

<p>Bu nedenle bir specialization’ın hangi birincil şablona bağlı olduğu kritik önemdedir. Bildirim sırası ve specialization bildiriminin çağrıdan önce görünür olması da ayrı derleme birimlerinde ciddi farklar yaratabilir. Açık özelleştirme, örtük örneklemeye yol açan ilk kullanımdan önce bildirilmelidir.</p>

<h2 id="neden-fonksiyon-şablonları-kısmen-özelleştirilemez">Neden fonksiyon şablonları kısmen özelleştirilemez?</h2>

<p>Sınıf şablonlarında kısmi özelleştirme geçerlidir:</p>

<div class="language-cpp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">template</span><span class="o">&lt;</span><span class="k">typename</span> <span class="nc">T</span><span class="p">&gt;</span>
<span class="k">struct</span> <span class="nc">Bilgi</span><span class="p">;</span>

<span class="k">template</span><span class="o">&lt;</span><span class="k">typename</span> <span class="nc">T</span><span class="p">&gt;</span>
<span class="k">struct</span> <span class="nc">Bilgi</span><span class="o">&lt;</span><span class="n">T</span><span class="o">*&gt;</span> <span class="p">{</span>
    <span class="k">static</span> <span class="k">constexpr</span> <span class="kt">bool</span> <span class="n">pointer</span> <span class="o">=</span> <span class="nb">true</span><span class="p">;</span>
<span class="p">};</span>
</code></pre></div></div>

<p>Fakat aşağıdaki fonksiyon biçimi geçersizdir:</p>

<div class="language-cpp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">template</span><span class="o">&lt;</span><span class="k">typename</span> <span class="nc">T</span><span class="p">&gt;</span>
<span class="kt">void</span> <span class="n">isle</span><span class="o">&lt;</span><span class="n">T</span><span class="o">*&gt;</span><span class="p">(</span><span class="n">T</span><span class="o">*</span><span class="p">);</span> <span class="c1">// Geçersiz kısmi specialization</span>
</code></pre></div></div>

<p>Fonksiyonlarda aynı niyet overload ile ifade edilir:</p>

<div class="language-cpp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">template</span><span class="o">&lt;</span><span class="k">typename</span> <span class="nc">T</span><span class="p">&gt;</span>
<span class="kt">void</span> <span class="nf">isle</span><span class="p">(</span><span class="n">T</span><span class="o">*</span><span class="p">)</span> <span class="p">{</span>
    <span class="c1">// Türetilen her işaretçi türü için ortak davranış</span>
<span class="p">}</span>
</code></pre></div></div>

<p>Bunun önemli nedeni, fonksiyonlarda zaten overload çözümlemesi bulunmasıdır. Kısmi specialization da eklenseydi iki ayrı sıralama sistemi birbiriyle çakışabilirdi.</p>

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

<p>Bir tür ailesini yakalamak istiyorsanız overload kullanın. Yalnızca tek ve kesin bir şablon argümanı kombinasyonunda davranışı değiştirecekseniz explicit specialization düşünülebilir. Bununla birlikte fonksiyonlarda overload çoğu zaman daha okunabilir ve öngörülebilirdir.</p>

<p>Modern C++ kodunda <code class="language-plaintext highlighter-rouge">if constexpr</code>, kavramlar ve <code class="language-plaintext highlighter-rouge">requires</code> ifadeleri de güçlü alternatiflerdir. Özellikle kısıtlı overload’lar, niyeti doğrudan tür sistemi üzerinden anlatır. Altın kural şudur: specialization’ı bağımsız yarışmacı sanmayın; o, ancak bağlı olduğu şablon yarışı kazandığında sahneye çıkan yedek oyuncudur.</p>]]></content><author><name>Sonsuz Us</name></author><category term="Bilgi" /><category term="c++" /><category term="templates" /><category term="specialization" /><category term="overloading" /><category term="derleyici" /><category term="generic-programming" /><summary type="html"><![CDATA[C++ şablonlarında özelleştirme ve aşırı yükleme aynı hedefe gidiyormuş gibi görünür: belirli türlerde farklı davranmak. Fakat derleyicinin gözünde bunlar iki ayrı mekanizmadır. Overloading adaylar arasındaki yarışı belirlerken specialization, yarışı kazanan şablonun özel bir sürümünün bulunup bulunmadığına bakar. Küçük görünen bu sıra farkı, şaşırtıcı sonuçların kaynağıdır.]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://program.sonsuz.us/img/c-sablonlarinda-specialization-82.png" /><media:content medium="image" url="https://program.sonsuz.us/img/c-sablonlarinda-specialization-82.png" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">Fazladan Eklem, Fazladan Kaçış: Redundant Robot Kollarda Engel Atlama</title><link href="https://program.sonsuz.us/posts/fazladan-eklem-fazladan-kacis-redundant-robot-kollarda-engel-atlama/" rel="alternate" type="text/html" title="Fazladan Eklem, Fazladan Kaçış: Redundant Robot Kollarda Engel Atlama" /><published>2026-10-18T00:00:00+00:00</published><updated>2026-10-18T00:00:00+00:00</updated><id>https://program.sonsuz.us/posts/fazladan-eklem-fazladan-kacis-redundant-robot-kollarda-engel-atlama</id><content type="html" xml:base="https://program.sonsuz.us/posts/fazladan-eklem-fazladan-kacis-redundant-robot-kollarda-engel-atlama/"><![CDATA[<p>Bir robot kolunun görevi yalnızca hedefe ulaşmak değildir; bunu masaya, duvara veya merakla yaklaşan başka bir robota çarpmadan yapması gerekir. Redundant, yani artıklıklı çok eklemli kollar tam bu noktada avantaj sağlar. Uç efektörün konumu değişmeden dirseklerini ve diğer eklemlerini hareket ettirebilen bu robotlar, engeller karşısında adeta “hedefe bakarken belini büken” mekanik akrobatlara dönüşür.
``</p>
<h2 id="artıklılık-ne-anlama-gelir">Artıklılık ne anlama gelir?</h2>

<p>Bir manipülatörün eklem değişkenlerini $q \in R^n$, uç efektör görevini ise $x \in R^m$ ile gösterelim. İleri kinematik ilişki</p>

\[x = f(q)\]

<p>şeklindedir. Eğer eklem sayısı görev uzayının boyutundan büyükse, yani $n &gt; m$ ise sistem redundant kabul edilir. Örneğin üç boyutlu uzayda yalnızca uç noktanın konumunu kontrol etmek için üç bağımsız değişken yeterliyken yedi eklemli bir kol dört adet fazladan serbestlik derecesine sahiptir.</p>

<p>Bu fazlalık gereksiz değildir. Aynı uç efektör konumunu üreten birden fazla eklem yapılandırması bulunabilir. Robot böylece ana görevi bozmadan dirseğini bir engelden uzaklaştırabilir, eklem sınırlarından kaçabilir veya daha rahat bir duruş seçebilir.</p>

<table>
  <thead>
    <tr>
      <th>Özellik</th>
      <th>Minimum serbestlikli kol</th>
      <th>Redundant kol</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Aynı hedef için çözüm</td>
      <td>Genellikle sınırlı</td>
      <td>Çok sayıda</td>
    </tr>
    <tr>
      <td>Engel çevresinde hareket</td>
      <td>Kısıtlı</td>
      <td>Esnek</td>
    </tr>
    <tr>
      <td>Eklem sınırlarından kaçış</td>
      <td>Zor</td>
      <td>İkincil görevle mümkün</td>
    </tr>
    <tr>
      <td>Hesaplama maliyeti</td>
      <td>Daha düşük</td>
      <td>Daha yüksek</td>
    </tr>
    <tr>
      <td>Arıza toleransı</td>
      <td>Düşük</td>
      <td>Görece yüksek</td>
    </tr>
  </tbody>
</table>

<p><img src="/img/fazladan-eklem-fazladan-66.svg" alt="fazladan-eklem-fazladan-66" /></p>

<h2 id="jacobian-ve-sıfır-uzayı">Jacobian ve sıfır uzayı</h2>

<p>Eklem hızları ile uç efektör hızı arasındaki ilişki Jacobian matrisiyle kurulur:</p>

\[\dot{x} = J(q)\dot{q}\]

<p>Redundant bir sistemde ters çözüm tek değildir. Yaygın hız çözümü şöyledir:</p>

\[\dot{q} = J^+\dot{x} + (I-J^+J)z\]

<p>Burada $J^+$ Jacobian’ın sözde tersidir. İlk terim uç efektörü hedeflenen yönde hareket ettirir. İkinci terim ise Jacobian’ın sıfır uzayında kalır; başka bir deyişle uç efektör hareketini değiştirmeden eklemleri oynatır. Engel kaçınma sihrinin büyük bölümü bu ikinci terimdedir.</p>

<p>$z$ vektörü, robotu engelden uzaklaştıran bir maliyet fonksiyonunun negatif gradyanı olarak seçilebilir:</p>

\[z = -k \nabla H(q)\]

<p>$H(q)$ robot ile engel arasındaki mesafe azaldıkça büyüyen bir ceza fonksiyonu olabilir. Böylece robot bir eliyle hedefe ilerlerken “dirseğini içeri çekebilir.”</p>

<h2 id="basit-bir-hesaplama-örneği">Basit bir hesaplama örneği</h2>

<p>Aşağıdaki Python kodu, ana uç efektör hızına sıfır uzayı üzerinden ikincil bir kaçınma hareketi ekler:</p>

<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kn">import</span> <span class="n">numpy</span> <span class="k">as</span> <span class="n">np</span>

<span class="k">def</span> <span class="nf">redundant_velocity</span><span class="p">(</span><span class="n">J</span><span class="p">,</span> <span class="n">target_velocity</span><span class="p">,</span> <span class="n">avoidance_gradient</span><span class="p">,</span> <span class="n">gain</span><span class="o">=</span><span class="mf">0.4</span><span class="p">):</span>
    <span class="n">J_pinv</span> <span class="o">=</span> <span class="n">np</span><span class="p">.</span><span class="n">linalg</span><span class="p">.</span><span class="nf">pinv</span><span class="p">(</span><span class="n">J</span><span class="p">)</span>
    <span class="n">identity</span> <span class="o">=</span> <span class="n">np</span><span class="p">.</span><span class="nf">eye</span><span class="p">(</span><span class="n">J</span><span class="p">.</span><span class="n">shape</span><span class="p">[</span><span class="mi">1</span><span class="p">])</span>

    <span class="n">primary</span> <span class="o">=</span> <span class="n">J_pinv</span> <span class="o">@</span> <span class="n">target_velocity</span>
    <span class="n">null_space</span> <span class="o">=</span> <span class="n">identity</span> <span class="o">-</span> <span class="n">J_pinv</span> <span class="o">@</span> <span class="n">J</span>
    <span class="n">secondary</span> <span class="o">=</span> <span class="n">null_space</span> <span class="o">@</span> <span class="p">(</span><span class="o">-</span><span class="n">gain</span> <span class="o">*</span> <span class="n">avoidance_gradient</span><span class="p">)</span>

    <span class="k">return</span> <span class="n">primary</span> <span class="o">+</span> <span class="n">secondary</span>
</code></pre></div></div>

<p><code class="language-plaintext highlighter-rouge">primary</code> hedefe ulaşma görevini gerçekleştirir. <code class="language-plaintext highlighter-rouge">secondary</code> ise engel maliyetini azaltmaya çalışır. <code class="language-plaintext highlighter-rouge">null_space</code> izdüşümü sayesinde ikincil hareket, ideal matematiksel koşullarda uç efektörün istenen hızını bozmaz.</p>

<h2 id="potansiyel-alan-yaklaşımı">Potansiyel alan yaklaşımı</h2>

<p>Engeller çoğu zaman itici potansiyel alanlarla modellenir. Engel ile robot noktası arasındaki mesafe $d$, etkinin başladığı güvenli mesafe $d_0$ olsun:</p>

\[U(d) = \frac{1}{2}\eta\left(\frac{1}{d}-\frac{1}{d_0}\right)^2, \quad d &lt; d_0\]

<p>Robot engelden uzaktaysa ceza sıfırdır; yaklaştıkça hızla büyür. Bu yöntem sezgiseldir fakat yerel minimumlara takılabilir. Ayrıca yalnızca uç efektörü değil, dirsek ve bağlantılar üzerindeki örnek noktaları da kontrol etmek gerekir.</p>

<table>
  <thead>
    <tr>
      <th>Yaklaşım</th>
      <th>Avantaj</th>
      <th>Dezavantaj</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Potansiyel alan</td>
      <td>Hızlı ve sezgisel</td>
      <td>Yerel minimum oluşturabilir</td>
    </tr>
    <tr>
      <td>Sıfır uzayı kontrolü</td>
      <td>Ana görevi korur</td>
      <td>Tekilliklere duyarlıdır</td>
    </tr>
    <tr>
      <td>Optimizasyon tabanlı kontrol</td>
      <td>Kısıtları birlikte işler</td>
      <td>Daha fazla hesaplama ister</td>
    </tr>
  </tbody>
</table>

<p>Sonuç olarak fazladan serbestlik derecesi, robota yalnızca daha fazla hareket değil, aynı hedefe giderken daha iyi hareket seçme özgürlüğü verir. Doğru kontrol algoritmasıyla redundant kol; engellerden kaçınabilir, eklem sınırlarını koruyabilir ve çalışma alanında çok daha güvenli davranabilir.</p>]]></content><author><name>Sonsuz Us</name></author><category term="Bilgi" /><category term="robotik" /><category term="redundant manipülatör" /><category term="engel kaçınma" /><category term="ters kinematik" /><category term="jacobian" /><category term="optimizasyon" /><summary type="html"><![CDATA[Bir robot kolunun görevi yalnızca hedefe ulaşmak değildir; bunu masaya, duvara veya merakla yaklaşan başka bir robota çarpmadan yapması gerekir. Redundant, yani artıklıklı çok eklemli kollar tam bu noktada avantaj sağlar. Uç efektörün konumu değişmeden dirseklerini ve diğer eklemlerini hareket ettirebilen bu robotlar, engeller karşısında adeta “hedefe bakarken belini büken” mekanik akrobatlara dönüşür.]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://program.sonsuz.us/img/fazladan-eklem-fazladan-66.png" /><media:content medium="image" url="https://program.sonsuz.us/img/fazladan-eklem-fazladan-66.png" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">Java Dize İşlemleri: String, StringBuilder ve StringBuffer Rehberi</title><link href="https://program.sonsuz.us/posts/java-dize-islemleri-string-stringbuilder-ve-stringbuffer-rehberi/" rel="alternate" type="text/html" title="Java Dize İşlemleri: String, StringBuilder ve StringBuffer Rehberi" /><published>2026-10-18T00:00:00+00:00</published><updated>2026-10-18T00:00:00+00:00</updated><id>https://program.sonsuz.us/posts/java-dize-islemleri-string-stringbuilder-ve-stringbuffer-rehberi</id><content type="html" xml:base="https://program.sonsuz.us/posts/java-dize-islemleri-string-stringbuilder-ve-stringbuffer-rehberi/"><![CDATA[<p>Java’da metinlerle çalışmak ilk bakışta oldukça basittir: Bir <code class="language-plaintext highlighter-rouge">String</code> tanımlar, birkaç kelimeyi birleştirir ve sonucu ekrana yazdırırız. Ancak perde arkasında nesne üretimi, bellek kullanımı, eşzamanlılık ve performans gibi önemli ayrıntılar bulunur. Özellikle döngü içinde binlerce metni birleştiriyorsanız doğru sınıfı seçmek, programınızı kaplumbağadan yarış arabasına dönüştürebilir.</p>

<p>``</p>

<h2 id="string-neden-değiştirilemez">String neden değiştirilemez?</h2>

<p>Java’daki <code class="language-plaintext highlighter-rouge">String</code> nesneleri <strong>immutable</strong>, yani değiştirilemez yapıdadır. Bir <code class="language-plaintext highlighter-rouge">String</code> oluşturulduktan sonra içindeki karakter dizisi aynı nesne üzerinde değiştirilemez. Yapılan her değişiklik yeni bir <code class="language-plaintext highlighter-rouge">String</code> nesnesi üretir.</p>

<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nc">String</span> <span class="n">mesaj</span> <span class="o">=</span> <span class="s">"Merhaba"</span><span class="o">;</span>
<span class="n">mesaj</span> <span class="o">=</span> <span class="n">mesaj</span> <span class="o">+</span> <span class="s">" Java"</span><span class="o">;</span>

<span class="nc">System</span><span class="o">.</span><span class="na">out</span><span class="o">.</span><span class="na">println</span><span class="o">(</span><span class="n">mesaj</span><span class="o">);</span> <span class="c1">// Merhaba Java</span>
</code></pre></div></div>

<p>Burada ilk nesne büyütülmez. <code class="language-plaintext highlighter-rouge">"Merhaba Java"</code> değerini taşıyan yeni bir nesne oluşturulur ve <code class="language-plaintext highlighter-rouge">mesaj</code> değişkeni artık onu gösterir. Eski nesneye başka bir referans yoksa nesne daha sonra çöp toplayıcı tarafından temizlenebilir.</p>

<p>Değiştirilemezlik; güvenlik, çok iş parçacıklı kullanım ve hash kodunun önbelleğe alınması açısından avantaj sağlar. Ayrıca Java, aynı sabit metinleri <strong>String Pool</strong> içinde paylaşabilir:</p>

<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nc">String</span> <span class="n">a</span> <span class="o">=</span> <span class="s">"kahve"</span><span class="o">;</span>
<span class="nc">String</span> <span class="n">b</span> <span class="o">=</span> <span class="s">"kahve"</span><span class="o">;</span>

<span class="nc">System</span><span class="o">.</span><span class="na">out</span><span class="o">.</span><span class="na">println</span><span class="o">(</span><span class="n">a</span> <span class="o">==</span> <span class="n">b</span><span class="o">);</span> <span class="c1">// Genellikle true</span>
<span class="nc">System</span><span class="o">.</span><span class="na">out</span><span class="o">.</span><span class="na">println</span><span class="o">(</span><span class="n">a</span><span class="o">.</span><span class="na">equals</span><span class="o">(</span><span class="n">b</span><span class="o">));</span> <span class="c1">// true</span>
</code></pre></div></div>

<p><code class="language-plaintext highlighter-rouge">==</code> referansları, <code class="language-plaintext highlighter-rouge">equals()</code> ise metinsel içeriği karşılaştırır. İçerik karşılaştırmalarında doğru tercih çoğunlukla <code class="language-plaintext highlighter-rouge">equals()</code> metodudur.</p>

<h2 id="birleştirme-maliyeti">Birleştirme maliyeti</h2>

<p>Tek tük birleştirmelerde <code class="language-plaintext highlighter-rouge">+</code> kullanmak okunaklı ve uygundur. Fakat bir döngüde sürekli kullanıldığında çok sayıda geçici nesne oluşturabilir. Her adımda büyüyen metnin yeniden kopyalandığını düşünürsek yaklaşık maliyet şu toplamla ifade edilebilir:</p>

\[1 + 2 + 3 + \dots + n = \frac{n(n+1)}{2} = O(n^2)\]

<p>Derleyici basit ifadeleri optimize edebilse de dinamik döngülerde <code class="language-plaintext highlighter-rouge">StringBuilder</code> daha güvenilir bir performans seçeneğidir.</p>

<h2 id="stringbuilder-hızlı-ve-dinamik">StringBuilder: Hızlı ve dinamik</h2>

<p><code class="language-plaintext highlighter-rouge">StringBuilder</code>, değiştirilebilir bir karakter tamponu tutar. <code class="language-plaintext highlighter-rouge">append()</code>, <code class="language-plaintext highlighter-rouge">insert()</code>, <code class="language-plaintext highlighter-rouge">delete()</code> ve <code class="language-plaintext highlighter-rouge">reverse()</code> gibi metotlar çoğunlukla aynı nesne üzerinde çalışır.</p>

<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nc">StringBuilder</span> <span class="n">sonuc</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">StringBuilder</span><span class="o">();</span>

<span class="k">for</span> <span class="o">(</span><span class="kt">int</span> <span class="n">i</span> <span class="o">=</span> <span class="mi">1</span><span class="o">;</span> <span class="n">i</span> <span class="o">&lt;=</span> <span class="mi">5</span><span class="o">;</span> <span class="n">i</span><span class="o">++)</span> <span class="o">{</span>
    <span class="n">sonuc</span><span class="o">.</span><span class="na">append</span><span class="o">(</span><span class="s">"Ürün "</span><span class="o">)</span>
         <span class="o">.</span><span class="na">append</span><span class="o">(</span><span class="n">i</span><span class="o">)</span>
         <span class="o">.</span><span class="na">append</span><span class="o">(</span><span class="s">"\n"</span><span class="o">);</span>
<span class="o">}</span>

<span class="nc">String</span> <span class="n">metin</span> <span class="o">=</span> <span class="n">sonuc</span><span class="o">.</span><span class="na">toString</span><span class="o">();</span>
<span class="nc">System</span><span class="o">.</span><span class="na">out</span><span class="o">.</span><span class="na">println</span><span class="o">(</span><span class="n">metin</span><span class="o">);</span>
</code></pre></div></div>

<p>Bu kod, ürün satırlarını tek bir dinamik tamponda biriktirir. İşlem tamamlandığında <code class="language-plaintext highlighter-rouge">toString()</code> ile normal bir <code class="language-plaintext highlighter-rouge">String</code> elde edilir. Başlangıç boyutu biliniyorsa kapasite vermek yeniden boyutlandırma sayısını azaltabilir:</p>

<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nc">StringBuilder</span> <span class="n">rapor</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">StringBuilder</span><span class="o">(</span><span class="mi">1024</span><span class="o">);</span>
<span class="n">rapor</span><span class="o">.</span><span class="na">append</span><span class="o">(</span><span class="s">"Aylık rapor: "</span><span class="o">).</span><span class="na">append</span><span class="o">(</span><span class="mi">2026</span><span class="o">);</span>
</code></pre></div></div>

<p>Kapasite, metnin gerçek uzunluğundan farklıdır. Uzunluk kullanılan karakter sayısını, kapasite ise yeni bellek ayrılmadan tutulabilecek yaklaşık karakter miktarını belirtir.</p>

<h2 id="stringbuffer-kilitli-ama-güvenli">StringBuffer: Kilitli ama güvenli</h2>

<p><code class="language-plaintext highlighter-rouge">StringBuffer</code>, kullanım biçimi bakımından <code class="language-plaintext highlighter-rouge">StringBuilder</code> ile neredeyse aynıdır. Temel fark, metotlarının eşzamanlı erişime karşı senkronize edilmesidir. Birden fazla iş parçacığı aynı tamponu değiştiriyorsa bu koruma faydalı olabilir. Buna karşılık kilitleme maliyeti nedeniyle tek iş parçacıklı kodlarda genellikle daha yavaştır.</p>

<table>
  <thead>
    <tr>
      <th>Özellik</th>
      <th>String</th>
      <th>StringBuilder</th>
      <th>StringBuffer</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Değiştirilebilir mi?</td>
      <td>Hayır</td>
      <td>Evet</td>
      <td>Evet</td>
    </tr>
    <tr>
      <td>Thread-safe mi?</td>
      <td>Değişmezliği sayesinde güvenli</td>
      <td>Hayır</td>
      <td>Evet</td>
    </tr>
    <tr>
      <td>Birleştirme performansı</td>
      <td>Yoğun işlemlerde düşük</td>
      <td>Genellikle en hızlı</td>
      <td>Kilit nedeniyle daha yavaş</td>
    </tr>
    <tr>
      <td>Tipik kullanım</td>
      <td>Sabit metinler</td>
      <td>Döngüler ve metin üretimi</td>
      <td>Paylaşılan eşzamanlı tampon</td>
    </tr>
  </tbody>
</table>

<p><img src="/img/java-dize-islemleri-82.svg" alt="java-dize-islemleri-82" /></p>

<h2 id="hangisini-seçmeliyiz">Hangisini seçmeliyiz?</h2>

<p>Metin değişmeyecekse veya yalnızca birkaç basit işlem yapılacaksa <code class="language-plaintext highlighter-rouge">String</code> tercih edilmelidir. Döngü içinde JSON, SQL, rapor ya da dosya içeriği üretiliyorsa <code class="language-plaintext highlighter-rouge">StringBuilder</code> daha uygundur. Aynı değiştirilebilir tampon gerçekten birden fazla iş parçacığı tarafından paylaşılıyorsa <code class="language-plaintext highlighter-rouge">StringBuffer</code> düşünülebilir.</p>

<p>Kısacası, <code class="language-plaintext highlighter-rouge">String</code> güvenli ve sade bir kasa; <code class="language-plaintext highlighter-rouge">StringBuilder</code> hızlı çalışan bir atölye; <code class="language-plaintext highlighter-rouge">StringBuffer</code> ise kapısında güvenlik görevlisi bulunan bir atölyedir. Doğru araç, metnin ne kadar değişeceğine ve kimler tarafından kullanılacağına bağlıdır.</p>]]></content><author><name>Sonsuz Us</name></author><category term="Bilgi" /><category term="java" /><category term="string" /><category term="stringbuilder" /><category term="stringbuffer" /><category term="bellek" /><category term="performans" /><summary type="html"><![CDATA[Java’da metinlerle çalışmak ilk bakışta oldukça basittir: Bir String tanımlar, birkaç kelimeyi birleştirir ve sonucu ekrana yazdırırız. Ancak perde arkasında nesne üretimi, bellek kullanımı, eşzamanlılık ve performans gibi önemli ayrıntılar bulunur. Özellikle döngü içinde binlerce metni birleştiriyorsanız doğru sınıfı seçmek, programınızı kaplumbağadan yarış arabasına dönüştürebilir.]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://program.sonsuz.us/img/java-dize-islemleri-82.png" /><media:content medium="image" url="https://program.sonsuz.us/img/java-dize-islemleri-82.png" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">Java Operatörleri ve Kontrol İfadeleriyle Program Akışını Yönetmek</title><link href="https://program.sonsuz.us/posts/java-operatorleri-ve-kontrol-ifadeleriyle-program-akisini-yonetmek/" rel="alternate" type="text/html" title="Java Operatörleri ve Kontrol İfadeleriyle Program Akışını Yönetmek" /><published>2026-10-18T00:00:00+00:00</published><updated>2026-10-18T00:00:00+00:00</updated><id>https://program.sonsuz.us/posts/java-operatorleri-ve-kontrol-ifadeleriyle-program-akisini-yonetmek</id><content type="html" xml:base="https://program.sonsuz.us/posts/java-operatorleri-ve-kontrol-ifadeleriyle-program-akisini-yonetmek/"><![CDATA[<p>Bir Java programı yalnızca yukarıdan aşağıya çalışan komutlardan oluşsaydı, hesap makinesinden biraz daha heyecanlı uygulamalar geliştirmek zor olurdu. Operatörler verileri işlerken kontrol ifadeleri programın hangi yolu izleyeceğine karar verir. Başka bir deyişle operatörler soruları hazırlar, karar yapıları cevapları değerlendirir, döngüler ise gerekli işleri sabırla tekrarlar.
``</p>
<h2 id="operatörler-programın-hesaplama-araçları">Operatörler: Programın hesaplama araçları</h2>

<p>Operatörler, bir veya daha fazla değer üzerinde işlem yapan sembollerdir. Örneğin <code class="language-plaintext highlighter-rouge">+</code> toplama yaparken <code class="language-plaintext highlighter-rouge">&gt;</code> iki değeri karşılaştırır. Bir ifadenin sonucu başka bir operatörün girdisi olabilir. Bu nedenle işlem önceliğini anlamak önemlidir.</p>

<p>Örneğin aşağıdaki matematiksel ifade Java’da da aynı öncelik mantığıyla değerlendirilir:</p>

\[sonuc = 10 + 4 \times 2 = 18\]

<p>Çarpma önce çalışır. Sonucun <code class="language-plaintext highlighter-rouge">28</code> olması isteniyorsa parantez kullanılmalıdır: <code class="language-plaintext highlighter-rouge">(10 + 4) * 2</code>.</p>

<table>
  <thead>
    <tr>
      <th>Operatör grubu</th>
      <th>Örnekler</th>
      <th>Görevi</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Aritmetik</td>
      <td><code class="language-plaintext highlighter-rouge">+</code>, <code class="language-plaintext highlighter-rouge">-</code>, <code class="language-plaintext highlighter-rouge">*</code>, <code class="language-plaintext highlighter-rouge">/</code>, <code class="language-plaintext highlighter-rouge">%</code></td>
      <td>Matematiksel işlem yapar</td>
    </tr>
    <tr>
      <td>Karşılaştırma</td>
      <td><code class="language-plaintext highlighter-rouge">==</code>, <code class="language-plaintext highlighter-rouge">!=</code>, <code class="language-plaintext highlighter-rouge">&lt;</code>, <code class="language-plaintext highlighter-rouge">&gt;=</code></td>
      <td><code class="language-plaintext highlighter-rouge">boolean</code> sonuç üretir</td>
    </tr>
    <tr>
      <td>Mantıksal</td>
      <td><code class="language-plaintext highlighter-rouge">&amp;&amp;</code>, <code class="language-plaintext highlighter-rouge">||</code>, <code class="language-plaintext highlighter-rouge">!</code></td>
      <td>Koşulları birleştirir veya tersine çevirir</td>
    </tr>
    <tr>
      <td>Atama</td>
      <td><code class="language-plaintext highlighter-rouge">=</code>, <code class="language-plaintext highlighter-rouge">+=</code>, <code class="language-plaintext highlighter-rouge">-=</code></td>
      <td>Değişkene değer atar veya günceller</td>
    </tr>
    <tr>
      <td>Artırma-azaltma</td>
      <td><code class="language-plaintext highlighter-rouge">++</code>, <code class="language-plaintext highlighter-rouge">--</code></td>
      <td>Sayıyı bir artırır veya azaltır</td>
    </tr>
  </tbody>
</table>

<p><img src="/img/java-operatorleri-ve-60.svg" alt="java-operatorleri-ve-60" /></p>

<p>Mod alma operatörü <code class="language-plaintext highlighter-rouge">%</code>, özellikle çift-tek kontrolünde kullanışlıdır. Bir $n$ sayısı için $n \bmod 2 = 0$ ise sayı çifttir.</p>

<h2 id="karar-yapıları-yol-ayrımındaki-java">Karar yapıları: Yol ayrımındaki Java</h2>

<p><code class="language-plaintext highlighter-rouge">if</code>, <code class="language-plaintext highlighter-rouge">else if</code> ve <code class="language-plaintext highlighter-rouge">else</code>, koşullara göre farklı kod blokları çalıştırır. Koşulun sonucu mutlaka <code class="language-plaintext highlighter-rouge">true</code> veya <code class="language-plaintext highlighter-rouge">false</code> olmalıdır.</p>

<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kt">int</span> <span class="n">puan</span> <span class="o">=</span> <span class="mi">78</span><span class="o">;</span>

<span class="k">if</span> <span class="o">(</span><span class="n">puan</span> <span class="o">&gt;=</span> <span class="mi">85</span><span class="o">)</span> <span class="o">{</span>
    <span class="nc">System</span><span class="o">.</span><span class="na">out</span><span class="o">.</span><span class="na">println</span><span class="o">(</span><span class="s">"Pekiyi"</span><span class="o">);</span>
<span class="o">}</span> <span class="k">else</span> <span class="k">if</span> <span class="o">(</span><span class="n">puan</span> <span class="o">&gt;=</span> <span class="mi">50</span><span class="o">)</span> <span class="o">{</span>
    <span class="nc">System</span><span class="o">.</span><span class="na">out</span><span class="o">.</span><span class="na">println</span><span class="o">(</span><span class="s">"Geçti"</span><span class="o">);</span>
<span class="o">}</span> <span class="k">else</span> <span class="o">{</span>
    <span class="nc">System</span><span class="o">.</span><span class="na">out</span><span class="o">.</span><span class="na">println</span><span class="o">(</span><span class="s">"Kaldı"</span><span class="o">);</span>
<span class="o">}</span>
</code></pre></div></div>

<p>Bu kod, karşılaştırma operatörleriyle puanı sınıflandırır. Koşullar yukarıdan aşağıya sınanır ve ilk doğru bloğun ardından yapı sona erer. Dolayısıyla daha özel veya yüksek eşikli koşulların önce yazılması önemlidir.</p>

<p>Sabit seçeneklerin bulunduğu durumlarda <code class="language-plaintext highlighter-rouge">switch</code> daha okunaklı olabilir:</p>

<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nc">String</span> <span class="n">rol</span> <span class="o">=</span> <span class="s">"editor"</span><span class="o">;</span>

<span class="k">switch</span> <span class="o">(</span><span class="n">rol</span><span class="o">)</span> <span class="o">{</span>
    <span class="k">case</span> <span class="s">"admin"</span> <span class="o">-&gt;</span> <span class="nc">System</span><span class="o">.</span><span class="na">out</span><span class="o">.</span><span class="na">println</span><span class="o">(</span><span class="s">"Tam yetki"</span><span class="o">);</span>
    <span class="k">case</span> <span class="s">"editor"</span> <span class="o">-&gt;</span> <span class="nc">System</span><span class="o">.</span><span class="na">out</span><span class="o">.</span><span class="na">println</span><span class="o">(</span><span class="s">"İçerik düzenleme yetkisi"</span><span class="o">);</span>
    <span class="k">default</span> <span class="o">-&gt;</span> <span class="nc">System</span><span class="o">.</span><span class="na">out</span><span class="o">.</span><span class="na">println</span><span class="o">(</span><span class="s">"Sınırlı yetki"</span><span class="o">);</span>
<span class="o">}</span>
</code></pre></div></div>

<table>
  <thead>
    <tr>
      <th>Yapı</th>
      <th>En uygun kullanım</th>
      <th>Güçlü yönü</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">if-else</code></td>
      <td>Aralıklar ve karmaşık koşullar</td>
      <td>Esneklik</td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">switch</code></td>
      <td>Belirli, ayrık seçenekler</td>
      <td>Okunabilirlik</td>
    </tr>
    <tr>
      <td>Üçlü operatör</td>
      <td>Kısa değer seçimi</td>
      <td>Az kod</td>
    </tr>
  </tbody>
</table>

<p>Üçlü operatörün biçimi <code class="language-plaintext highlighter-rouge">koşul ? doğruDeğer : yanlışDeğer</code> şeklindedir. Örneğin <code class="language-plaintext highlighter-rouge">yas &gt;= 18 ? "Yetişkin" : "Çocuk"</code> ifadesi kısa bir karar üretir; ancak iç içe kullanılırsa okunabilirliği hızla düşürür.</p>

<h2 id="döngüler-tekrarın-kontrollü-hâli">Döngüler: Tekrarın kontrollü hâli</h2>

<p>Döngüler, aynı işlemi belirli bir koşul sağlandığı sürece tekrarlar. <code class="language-plaintext highlighter-rouge">for</code> tekrar sayısı bilindiğinde, <code class="language-plaintext highlighter-rouge">while</code> koşul ön planda olduğunda, <code class="language-plaintext highlighter-rouge">do-while</code> ise bloğun en az bir kez çalışması gerektiğinde tercih edilir.</p>

<div class="language-java 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="o">;</span>

<span class="k">for</span> <span class="o">(</span><span class="kt">int</span> <span class="n">i</span> <span class="o">=</span> <span class="mi">1</span><span class="o">;</span> <span class="n">i</span> <span class="o">&lt;=</span> <span class="mi">5</span><span class="o">;</span> <span class="n">i</span><span class="o">++)</span> <span class="o">{</span>
    <span class="n">toplam</span> <span class="o">+=</span> <span class="n">i</span><span class="o">;</span>
<span class="o">}</span>

<span class="nc">System</span><span class="o">.</span><span class="na">out</span><span class="o">.</span><span class="na">println</span><span class="o">(</span><span class="n">toplam</span><span class="o">);</span> <span class="c1">// 15</span>
</code></pre></div></div>

<p>Bu döngü $1+2+3+4+5=15$ toplamını hesaplar. Başlangıç değeri, devam koşulu ve artış işlemi aynı satırda görüldüğü için akış kolayca izlenebilir.</p>

<p><code class="language-plaintext highlighter-rouge">break</code> döngüyü tamamen sonlandırırken <code class="language-plaintext highlighter-rouge">continue</code> yalnızca mevcut turu atlar. Bunlar güçlü araçlardır; gereğinden fazla kullanılmaları akışı takip etmeyi zorlaştırabilir.</p>

<h2 id="kısa-devre-değerlendirmesi">Kısa devre değerlendirmesi</h2>

<p>Mantıksal <code class="language-plaintext highlighter-rouge">&amp;&amp;</code> operatörü ilk koşul yanlışsa ikinci koşulu çalıştırmaz. <code class="language-plaintext highlighter-rouge">||</code> ise ilk koşul doğruysa devamını değerlendirmez:</p>

<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">if</span> <span class="o">(</span><span class="n">kullanici</span> <span class="o">!=</span> <span class="kc">null</span> <span class="o">&amp;&amp;</span> <span class="n">kullanici</span><span class="o">.</span><span class="na">isActive</span><span class="o">())</span> <span class="o">{</span>
    <span class="nc">System</span><span class="o">.</span><span class="na">out</span><span class="o">.</span><span class="na">println</span><span class="o">(</span><span class="s">"Giriş başarılı"</span><span class="o">);</span>
<span class="o">}</span>
</code></pre></div></div>

<p>Burada önce <code class="language-plaintext highlighter-rouge">null</code> kontrolü yapılır. Böylece var olmayan bir nesne üzerinde metot çağrılması ve <code class="language-plaintext highlighter-rouge">NullPointerException</code> oluşması engellenir.</p>

<p>Sonuç olarak operatörler veriyi dönüştürür, karar ifadeleri uygun yolu seçer ve döngüler tekrarları yönetir. Sağlam bir Java programında bu üçlü birlikte çalışır: doğru koşul kurulur, akış bilinçli biçimde yönlendirilir ve her tekrarın ne zaman biteceği açıkça tanımlanır.</p>]]></content><author><name>Sonsuz Us</name></author><category term="Bilgi" /><category term="java" /><category term="operatörler" /><category term="kontrol-akışı" /><category term="döngüler" /><category term="karar-yapıları" /><category term="programlama" /><summary type="html"><![CDATA[Bir Java programı yalnızca yukarıdan aşağıya çalışan komutlardan oluşsaydı, hesap makinesinden biraz daha heyecanlı uygulamalar geliştirmek zor olurdu. Operatörler verileri işlerken kontrol ifadeleri programın hangi yolu izleyeceğine karar verir. Başka bir deyişle operatörler soruları hazırlar, karar yapıları cevapları değerlendirir, döngüler ise gerekli işleri sabırla tekrarlar.]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://program.sonsuz.us/img/java-operatorleri-ve-60.png" /><media:content medium="image" url="https://program.sonsuz.us/img/java-operatorleri-ve-60.png" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">Java Tarihçesi ve Evrimi: Oak Ağacından JVM Dünyasına</title><link href="https://program.sonsuz.us/posts/java-tarihcesi-ve-evrimi-oak-agacindan-jvm-dunyasina/" rel="alternate" type="text/html" title="Java Tarihçesi ve Evrimi: Oak Ağacından JVM Dünyasına" /><published>2026-10-18T00:00:00+00:00</published><updated>2026-10-18T00:00:00+00:00</updated><id>https://program.sonsuz.us/posts/java-tarihcesi-ve-evrimi-oak-agacindan-jvm-dunyasina</id><content type="html" xml:base="https://program.sonsuz.us/posts/java-tarihcesi-ve-evrimi-oak-agacindan-jvm-dunyasina/"><![CDATA[<p>Java, bugün kurumsal uygulamalardan Android ekosistemine kadar pek çok alanda karşımıza çıksa da yolculuğuna web için değil, etkileşimli elektronik cihazlar için başladı. Dilin asıl başarısı yalnızca sözdiziminden kaynaklanmadı; farklı donanımlarda aynı programı çalıştırmayı hedefleyen taşınabilir mimarisi, yazılım dünyasının önemli problemlerinden birine güçlü bir cevap verdi.</p>

<p>``</p>

<h2 id="green-project-ve-oakın-doğuşu">Green Project ve Oak’ın Doğuşu</h2>

<p>Java’nın hikâyesi 1991 yılında Sun Microsystems bünyesindeki <strong>Green Project</strong> ile başladı. James Gosling, Mike Sheridan ve Patrick Naughton gibi mühendisler, televizyon kutuları ve ev cihazları için güvenilir bir yazılım platformu geliştirmeye çalışıyordu. C ve C++ güçlüydü; ancak donanıma bağımlılık, elle bellek yönetimi ve işaretçi hataları bu cihazlar için ciddi risk oluşturuyordu.</p>

<p>Gosling tarafından geliştirilen dil önce, ofisinin önündeki ağaçtan esinlenilerek <strong>Oak</strong> adını aldı. Oak isminin başka bir şirket tarafından tescillenmiş olması nedeniyle dilin adı daha sonra Java olarak değiştirildi. Projenin cihaz pazarı beklenen hızda büyümese de internetin yükselişi, taşınabilir kod fikrine yeni bir sahne hazırladı. Java, 1995 yılında resmen tanıtıldı.</p>

<p>Java’nın temel felsefesi şu sloganla özetlendi: <strong>Write Once, Run Anywhere</strong> — bir kez yaz, her yerde çalıştır.</p>

<table>
  <thead>
    <tr>
      <th>Özellik</th>
      <th>C/C++ yaklaşımı</th>
      <th>Java yaklaşımı</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Derleme hedefi</td>
      <td>Belirli işlemci ve işletim sistemi</td>
      <td>JVM üzerinde çalışan bayt kod</td>
    </tr>
    <tr>
      <td>Bellek yönetimi</td>
      <td>Çoğunlukla geliştiriciye ait</td>
      <td>Garbage Collector tarafından yönetilir</td>
    </tr>
    <tr>
      <td>İşaretçiler</td>
      <td>Doğrudan kullanılabilir</td>
      <td>Güvenli referans modeli kullanılır</td>
    </tr>
    <tr>
      <td>Taşınabilirlik</td>
      <td>Yeniden derleme gerekebilir</td>
      <td>Uygun JVM yeterlidir</td>
    </tr>
    <tr>
      <td>Güvenlik</td>
      <td>Ortama ve koda bağlıdır</td>
      <td>Doğrulama ve çalışma zamanı kontrolleri vardır</td>
    </tr>
  </tbody>
</table>

<p><img src="/img/java-tarihcesi-ve-53.svg" alt="java-tarihcesi-ve-53" /></p>

<h2 id="kaynak-koddan-bayt-koda">Kaynak Koddan Bayt Koda</h2>

<p>Java derleyicisi, kaynak kodunu doğrudan belirli bir işlemcinin makine diline dönüştürmez. Bunun yerine JVM’nin anlayabileceği ara temsil olan <strong>bayt kodu</strong> üretir.</p>

<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">public</span> <span class="kd">class</span> <span class="nc">MerhabaJVM</span> <span class="o">{</span>
    <span class="kd">public</span> <span class="kd">static</span> <span class="kt">void</span> <span class="nf">main</span><span class="o">(</span><span class="nc">String</span><span class="o">[]</span> <span class="n">args</span><span class="o">)</span> <span class="o">{</span>
        <span class="kt">int</span> <span class="n">javaYasi</span> <span class="o">=</span> <span class="mi">2026</span> <span class="o">-</span> <span class="mi">1995</span><span class="o">;</span>
        <span class="nc">System</span><span class="o">.</span><span class="na">out</span><span class="o">.</span><span class="na">println</span><span class="o">(</span><span class="s">"Java yaklaşık "</span> <span class="o">+</span> <span class="n">javaYasi</span> <span class="o">+</span> <span class="s">" yaşında!"</span><span class="o">);</span>
    <span class="o">}</span>
<span class="o">}</span>
</code></pre></div></div>

<p>Bu sınıf şu komutla derlenir:</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>javac MerhabaJVM.java
java MerhabaJVM
</code></pre></div></div>

<p><code class="language-plaintext highlighter-rouge">javac</code> komutu kaynak dosyadan <code class="language-plaintext highlighter-rouge">MerhabaJVM.class</code> dosyasını üretir. Bu dosya işlemciye özel makine kodu değil, JVM komutları içerir. <code class="language-plaintext highlighter-rouge">javap -c MerhabaJVM</code> komutu kullanılarak bayt kod talimatları incelenebilir.</p>

<p>Süreci matematiksel bir dönüşüm gibi gösterebiliriz:</p>

\[Kaynak\ Kod \xrightarrow{javac} Bayt\ Kod \xrightarrow{JVM} Makine\ Kodu\]

<p>Aynı <code class="language-plaintext highlighter-rouge">.class</code> dosyasının farklı sistemlerde çalışabilmesinin koşulu, her sistem için uygun bir JVM bulunmasıdır. Dolayısıyla taşınabilir olan JVM’nin kendisi değil, JVM üzerinde çalışacak şekilde üretilen bayt koddur.</p>

<h2 id="jvm-tam-olarak-ne-yapar">JVM Tam Olarak Ne Yapar?</h2>

<p><strong>Java Virtual Machine</strong>, fiziksel işlemci ile Java programı arasında soyut bir bilgisayar gibi davranır. Sınıfları yükler, bayt kodunu doğrular, belleği düzenler ve kodu çalıştırır. JVM’nin başlıca bileşenleri şunlardır:</p>

<ul>
  <li><strong>Class Loader:</strong> Gerekli sınıfları çalışma anında yükler.</li>
  <li><strong>Bytecode Verifier:</strong> Talimatların güvenli ve kurallara uygun olduğunu denetler.</li>
  <li><strong>Execution Engine:</strong> Bayt kodu yorumlar veya makine koduna dönüştürür.</li>
  <li><strong>Garbage Collector:</strong> Kullanılmayan nesnelerin belleğini otomatik olarak geri kazanır.</li>
  <li><strong>Runtime Data Areas:</strong> Heap, stack ve metot alanı gibi bellek bölgelerini yönetir.</li>
</ul>

<p>İlk JVM’ler bayt kodu çoğunlukla yorumluyordu. Modern JVM’lerdeki <strong>JIT derleyici</strong>, sık çalışan kod bölümlerini çalışma sırasında yerel makine koduna çevirir. Basitleştirilmiş performans fikri şöyle ifade edilebilir:</p>

\[T_{toplam} = T_{yükleme} + T_{JIT} + n \cdot T_{çalıştırma}\]

<p>Başlangıçta JIT maliyeti oluşsa da tekrar sayısı $n$ büyüdükçe optimize edilmiş kod önemli hız kazandırır.</p>

<h2 id="javanın-evrimi">Java’nın Evrimi</h2>

<p>Java zaman içinde yalnızca bir dil olmaktan çıkıp büyük bir platforma dönüştü. Java 5 generics ve annotation özelliklerini, Java 8 lambda ifadelerini ve Stream API’yi getirdi. Java 9 modül sistemini tanıttı; sonraki sürümler record, sealed class, pattern matching ve virtual thread gibi modern yetenekler ekledi.</p>

<p>Bugün Java’nın gücü; olgun kütüphane ekosistemi, geriye dönük uyumluluk yaklaşımı ve JVM’nin gelişmiş optimizasyonlarında yatıyor. Üstelik Kotlin, Scala ve Clojure gibi diller de JVM üzerinde çalışabiliyor. Kısacası Oak’ın küçük cihazlar için filizlenen fikri, milyonlarca uygulamayı taşıyan oldukça büyük bir ormana dönüştü.</p>]]></content><author><name>Sonsuz Us</name></author><category term="Bilgi" /><category term="java" /><category term="jvm" /><category term="bayt-kod" /><category term="programlama-tarihi" /><category term="sanal-makine" /><category term="nesne-yönelimli-programlama" /><summary type="html"><![CDATA[Java, bugün kurumsal uygulamalardan Android ekosistemine kadar pek çok alanda karşımıza çıksa da yolculuğuna web için değil, etkileşimli elektronik cihazlar için başladı. Dilin asıl başarısı yalnızca sözdiziminden kaynaklanmadı; farklı donanımlarda aynı programı çalıştırmayı hedefleyen taşınabilir mimarisi, yazılım dünyasının önemli problemlerinden birine güçlü bir cevap verdi.]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://program.sonsuz.us/img/java-tarihcesi-ve-53.png" /><media:content medium="image" url="https://program.sonsuz.us/img/java-tarihcesi-ve-53.png" xmlns:media="http://search.yahoo.com/mrss/" /></entry></feed>