<?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-19T18:05:50+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 Göstericiler: Belleğin Adres Defterini Okumak</title><link href="https://program.sonsuz.us/posts/c-gostericiler-bellegin-adres-defterini-okumak/" rel="alternate" type="text/html" title="C Göstericiler: Belleğin Adres Defterini Okumak" /><published>2026-10-19T00:00:00+00:00</published><updated>2026-10-19T00:00:00+00:00</updated><id>https://program.sonsuz.us/posts/c-gostericiler-bellegin-adres-defterini-okumak</id><content type="html" xml:base="https://program.sonsuz.us/posts/c-gostericiler-bellegin-adres-defterini-okumak/"><![CDATA[<p>C dilinde göstericiler, ilk karşılaşmada belleğin karanlık sokaklarında dolaşmak gibi görünebilir. Oysa bir gösterici yalnızca başka bir nesnenin bellekteki adresini saklayan değişkendir. Bu mekanizmayı kavradığınızda dizilerin, dinamik belleğin, fonksiyon parametrelerinin ve veri yapılarının neden bu kadar verimli çalıştığını da anlamaya başlarsınız.</p>

<p>``</p>

<h2 id="değer-değil-adres-saklamak">Değer Değil, Adres Saklamak</h2>

<p>Normal bir değişken doğrudan veri taşır. Gösterici ise bu verinin bulunduğu konumu taşır. Örneğin <code class="language-plaintext highlighter-rouge">int sayi = 42;</code> ifadesi bellekte bir tamsayı oluşturur. <code class="language-plaintext highlighter-rouge">&amp;sayi</code>, bu değişkenin adresini verir; <code class="language-plaintext highlighter-rouge">*ptr</code> ise göstericinin tuttuğu adrese giderek oradaki değere erişir.</p>

<table>
  <thead>
    <tr>
      <th>İfade</th>
      <th>Anlamı</th>
      <th>Örnek sonuç</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">sayi</code></td>
      <td>Değişkenin değeri</td>
      <td><code class="language-plaintext highlighter-rouge">42</code></td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">&amp;sayi</code></td>
      <td>Değişkenin adresi</td>
      <td><code class="language-plaintext highlighter-rouge">0x7ffd...</code></td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">ptr</code></td>
      <td>Göstericide saklanan adres</td>
      <td><code class="language-plaintext highlighter-rouge">0x7ffd...</code></td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">*ptr</code></td>
      <td>Adresteki değer</td>
      <td><code class="language-plaintext highlighter-rouge">42</code></td>
    </tr>
  </tbody>
</table>

<p><img src="/img/c-gostericiler-bellegin-75.svg" alt="c-gostericiler-bellegin-75" /></p>

<div class="language-c highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="cp">#include</span> <span class="cpf">&lt;stdio.h&gt;</span><span class="cp">
</span>
<span class="kt">int</span> <span class="nf">main</span><span class="p">(</span><span class="kt">void</span><span class="p">)</span> <span class="p">{</span>
    <span class="kt">int</span> <span class="n">sayi</span> <span class="o">=</span> <span class="mi">42</span><span class="p">;</span>
    <span class="kt">int</span> <span class="o">*</span><span class="n">ptr</span> <span class="o">=</span> <span class="o">&amp;</span><span class="n">sayi</span><span class="p">;</span>

    <span class="n">printf</span><span class="p">(</span><span class="s">"Deger: %d</span><span class="se">\n</span><span class="s">"</span><span class="p">,</span> <span class="n">sayi</span><span class="p">);</span>
    <span class="n">printf</span><span class="p">(</span><span class="s">"Adres: %p</span><span class="se">\n</span><span class="s">"</span><span class="p">,</span> <span class="p">(</span><span class="kt">void</span> <span class="o">*</span><span class="p">)</span><span class="n">ptr</span><span class="p">);</span>
    <span class="n">printf</span><span class="p">(</span><span class="s">"Pointer uzerinden deger: %d</span><span class="se">\n</span><span class="s">"</span><span class="p">,</span> <span class="o">*</span><span class="n">ptr</span><span class="p">);</span>

    <span class="o">*</span><span class="n">ptr</span> <span class="o">=</span> <span class="mi">99</span><span class="p">;</span> <span class="cm">/* Adresteki gerçek değeri değiştirir. */</span>
    <span class="n">printf</span><span class="p">(</span><span class="s">"Yeni deger: %d</span><span class="se">\n</span><span class="s">"</span><span class="p">,</span> <span class="n">sayi</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>Burada <code class="language-plaintext highlighter-rouge">int *ptr</code>, <code class="language-plaintext highlighter-rouge">ptr</code> değişkeninin bir <code class="language-plaintext highlighter-rouge">int</code> adresi taşıyacağını belirtir. <code class="language-plaintext highlighter-rouge">*ptr = 99</code> işlemi kopyayı değil, doğrudan <code class="language-plaintext highlighter-rouge">sayi</code> değişkenini değiştirir. Göstericilerin fonksiyonlara “dışarıdaki” veriyi değiştirme gücü vermesi de bu mantığa dayanır.</p>

<h2 id="bellek-ve-tür-bilgisi">Bellek ve Tür Bilgisi</h2>

<p>Bir adresi yalnızca sayı gibi düşünmek eksik kalır. Göstericinin türü, derleyiciye o adreste kaç baytlık ve nasıl yorumlanacak bir veri bulunduğunu söyler. Tipik bir sistemde <code class="language-plaintext highlighter-rouge">char</code> 1 bayt, <code class="language-plaintext highlighter-rouge">int</code> 4 bayt olabilir; ancak kesin boyutlar platforma bağlıdır ve <code class="language-plaintext highlighter-rouge">sizeof</code> ile öğrenilmelidir.</p>

<p>Bir dizinin başlangıç adresi $A$, eleman boyutu $s$ ve erişilecek indis $i$ olsun. İlgili elemanın adresi şu şekilde hesaplanır:</p>

\[\operatorname{adres}(dizi[i]) = A + i \times s\]

<p>Bu nedenle işaretçi aritmetiği sıradan tam sayı aritmetiğinden farklıdır. <code class="language-plaintext highlighter-rouge">ptr + 1</code>, adresi bir bayt değil, gösterilen türün boyutu kadar ilerletir.</p>

<div class="language-c highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="cp">#include</span> <span class="cpf">&lt;stdio.h&gt;</span><span class="cp">
</span>
<span class="kt">int</span> <span class="nf">main</span><span class="p">(</span><span class="kt">void</span><span class="p">)</span> <span class="p">{</span>
    <span class="kt">int</span> <span class="n">sayilar</span><span class="p">[]</span> <span class="o">=</span> <span class="p">{</span><span class="mi">10</span><span class="p">,</span> <span class="mi">20</span><span class="p">,</span> <span class="mi">30</span><span class="p">,</span> <span class="mi">40</span><span class="p">};</span>
    <span class="kt">int</span> <span class="o">*</span><span class="n">ptr</span> <span class="o">=</span> <span class="n">sayilar</span><span class="p">;</span>

    <span class="k">for</span> <span class="p">(</span><span class="kt">size_t</span> <span class="n">i</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="n">i</span> <span class="o">&lt;</span> <span class="mi">4</span><span class="p">;</span> <span class="n">i</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span>
        <span class="n">printf</span><span class="p">(</span><span class="s">"%zu: %d</span><span class="se">\n</span><span class="s">"</span><span class="p">,</span> <span class="n">i</span><span class="p">,</span> <span class="o">*</span><span class="p">(</span><span class="n">ptr</span> <span class="o">+</span> <span class="n">i</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">*(ptr + i)</code> ile <code class="language-plaintext highlighter-rouge">ptr[i]</code> eşdeğerdir. Hatta <code class="language-plaintext highlighter-rouge">sayilar[i]</code> ifadesi de temelde başlangıç adresinden uygun miktarda ilerleyip değeri çözme işlemidir.</p>

<table>
  <thead>
    <tr>
      <th>İşlem</th>
      <th>Etki</th>
      <th>Güvenli kullanım</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">ptr++</code></td>
      <td>Sonraki elemana geçer</td>
      <td>Dizi sınırları içinde</td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">ptr--</code></td>
      <td>Önceki elemana geçer</td>
      <td>Başlangıcın gerisine gitmeden</td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">ptr2 - ptr1</code></td>
      <td>Eleman uzaklığını verir</td>
      <td>Aynı dizi üzerinde</td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">ptr + i</code></td>
      <td><code class="language-plaintext highlighter-rouge">i</code> eleman ilerler</td>
      <td>Geçerli aralıkta</td>
    </tr>
  </tbody>
</table>

<h2 id="null-ve-tehlikeli-göstericiler">NULL ve Tehlikeli Göstericiler</h2>

<p>Başlatılmamış bir gösterici rastgele bir adres taşıyabilir. <code class="language-plaintext highlighter-rouge">NULL</code>, göstericinin geçerli bir nesneyi göstermediğini açıkça belirtir. Ancak <code class="language-plaintext highlighter-rouge">NULL</code> göstericiyi çözmek, yani <code class="language-plaintext highlighter-rouge">*ptr</code> kullanmak tanımsız davranıştır.</p>

<div class="language-c highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kt">int</span> <span class="o">*</span><span class="n">ptr</span> <span class="o">=</span> <span class="nb">NULL</span><span class="p">;</span>

<span class="k">if</span> <span class="p">(</span><span class="n">ptr</span> <span class="o">!=</span> <span class="nb">NULL</span><span class="p">)</span> <span class="p">{</span>
    <span class="cm">/* Yalnızca geçerli adres varsa erişilir. */</span>
    <span class="o">*</span><span class="n">ptr</span> <span class="o">=</span> <span class="mi">5</span><span class="p">;</span>
<span class="p">}</span>
</code></pre></div></div>

<p>Benzer şekilde yaşam süresi bitmiş yerel değişkenlerin adresleri ve <code class="language-plaintext highlighter-rouge">free</code> ile serbest bırakılmış bölgeleri gösteren işaretçiler “sarkan gösterici” oluşturur. Dizi sınırını aşmak da komşunun posta kutusunu kendi kutunuz sanmaya benzer: Adres vardır, fakat erişim hakkınız yoktur.</p>

<h2 id="sonuç">Sonuç</h2>

<p>Göstericiler C’nin performans ve kontrol gücünün merkezindedir. <code class="language-plaintext highlighter-rouge">&amp;</code> adres alır, <code class="language-plaintext highlighter-rouge">*</code> adresteki veriyi çözer, tür bilgisi ise aritmetik adımların boyutunu belirler. Güvenli kullanım için göstericileri başlatmak, <code class="language-plaintext highlighter-rouge">NULL</code> kontrolü yapmak, nesnelerin yaşam süresini izlemek ve dizi sınırlarını korumak gerekir. Bu kurallar oturduğunda belleğin karanlık sokakları, tabelaları gayet okunaklı bir mahalleye dönüşür.</p>]]></content><author><name>Sonsuz Us</name></author><category term="Bilgi" /><category term="c" /><category term="göstericiler" /><category term="bellek" /><category term="pointer" /><category term="işaretçi-aritmetiği" /><category term="programlama" /><summary type="html"><![CDATA[C dilinde göstericiler, ilk karşılaşmada belleğin karanlık sokaklarında dolaşmak gibi görünebilir. Oysa bir gösterici yalnızca başka bir nesnenin bellekteki adresini saklayan değişkendir. Bu mekanizmayı kavradığınızda dizilerin, dinamik belleğin, fonksiyon parametrelerinin ve veri yapılarının neden bu kadar verimli çalıştığını da anlamaya başlarsınız.]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://program.sonsuz.us/img/c-gostericiler-bellegin-75.png" /><media:content medium="image" url="https://program.sonsuz.us/img/c-gostericiler-bellegin-75.png" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">C# ve .NET Mimarisinin Temelleri: Kaynak Koddan CLR’a Yolculuk</title><link href="https://program.sonsuz.us/posts/c-ve-net-mimarisinin-temelleri-kaynak-koddan-clra-yolculuk/" rel="alternate" type="text/html" title="C# ve .NET Mimarisinin Temelleri: Kaynak Koddan CLR’a Yolculuk" /><published>2026-10-19T00:00:00+00:00</published><updated>2026-10-19T00:00:00+00:00</updated><id>https://program.sonsuz.us/posts/c-ve-net-mimarisinin-temelleri-kaynak-koddan-clra-yolculuk</id><content type="html" xml:base="https://program.sonsuz.us/posts/c-ve-net-mimarisinin-temelleri-kaynak-koddan-clra-yolculuk/"><![CDATA[<p>Bir C# programında <code class="language-plaintext highlighter-rouge">Console.WriteLine</code> yazıp çalıştır düğmesine bastığımızda perde arkasında küçük bir teknoloji festivali başlar. Kaynak kod derlenir, ara dile çevrilir, çalışma zamanı tarafından incelenir ve makine koduna dönüştürülür. C# ile .NET arasındaki ilişkiyi anlamak; performans, hata ayıklama ve taşınabilirlik gibi konuları ezberden değil, sağlam bir mimari üzerinden değerlendirmeyi sağlar.</p>

<p>``</p>

<h2 id="c-nereden-geldi">C# nereden geldi?</h2>

<p>C#, Microsoft tarafından .NET platformunun temel dillerinden biri olarak geliştirildi. Dilin baş mimarı Anders Hejlsberg’dir; ilk sürüm 2000 yılında duyurulmuş, .NET Framework ile birlikte 2002 yılında yaygın kullanıma açılmıştır. C++, Java ve Delphi gibi dillerden fikirler taşısa da zamanla kendine özgü, modern bir kimlik kazanmıştır.</p>

<p>C# başlangıçta Windows uygulamalarıyla özdeşleşse de günümüzde açık kaynaklı ve platformlar arası .NET üzerinde çalışır. Web uygulamalarından oyunlara, masaüstü yazılımlarından bulut servislerine kadar geniş bir kullanım alanına sahiptir.</p>

<table>
  <thead>
    <tr>
      <th>Kavram</th>
      <th>C#</th>
      <th>.NET</th>
      <th>CLR</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Temel görevi</td>
      <td>Programlama dili sunmak</td>
      <td>Geliştirme platformu sağlamak</td>
      <td>Kodu çalıştırmak</td>
    </tr>
    <tr>
      <td>İçeriği</td>
      <td>Sözdizimi ve dil kuralları</td>
      <td>Kütüphaneler, araçlar ve çalışma zamanı</td>
      <td>JIT, GC ve tür güvenliği</td>
    </tr>
    <tr>
      <td>Benzetme</td>
      <td>Tarif</td>
      <td>Mutfak</td>
      <td>Aşçı</td>
    </tr>
  </tbody>
</table>

<p><img src="/img/c-ve-net-45.svg" alt="c-ve-net-45" /></p>

<p>Bu ayrım önemlidir: C# bir <strong>dildir</strong>, .NET bir <strong>platformdur</strong>, CLR ise bu platformun çalışma zamanı motorudur.</p>

<h2 id="derleme-süreci-nasıl-işler">Derleme süreci nasıl işler?</h2>

<p>C# kaynak kodu doğrudan işlemcinin anlayacağı makine koduna çevrilmez. Önce Roslyn derleyicisi tarafından <strong>Common Intermediate Language</strong> olarak bilinen CIL’e dönüştürülür. CIL, işlemciden büyük ölçüde bağımsız bir ara dildir. Derleme sonucunda <code class="language-plaintext highlighter-rouge">.dll</code> veya <code class="language-plaintext highlighter-rouge">.exe</code> uzantılı bir <strong>assembly</strong> oluşur.</p>

<p>Bir assembly yalnızca CIL komutlarını içermez. Türler, metotlar, sürüm bilgileri ve bağımlılıklar gibi <strong>metadata</strong> bilgilerini de taşır. Çalıştırma sırasında CLR içindeki Just-In-Time derleyicisi, ihtiyaç duyulan metotların CIL kodunu hedef işlemcinin makine koduna çevirir.</p>

<p>Süreci şöyle özetleyebiliriz:</p>

<div class="language-text highlighter-rouge"><div class="highlight"><pre class="highlight"><code>C# kaynak kodu
      ↓ Roslyn
CIL + metadata içeren assembly
      ↓ CLR ve JIT
Makine kodu
      ↓
İşlemci
</code></pre></div></div>

<p>Toplam çalışma maliyeti basitleştirilmiş biçimde şu şekilde düşünülebilir:</p>

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

<p>JIT maliyeti ilk çağrıda hissedilebilir; ancak üretilen yerel kod sonraki çağrılarda yeniden kullanılabilir. .NET ayrıca uygulamayı önceden yerel koda yaklaştıran ReadyToRun ve Native AOT gibi seçenekler de sunar.</p>

<h2 id="clr-hangi-işleri-üstlenir">CLR hangi işleri üstlenir?</h2>

<p>CLR, yalnızca kodu çalıştıran pasif bir katman değildir. Bellek yönetimi, hata işleme, güvenlik kontrolleri, iş parçacıkları ve tür güvenliği gibi sorumlulukları üstlenir. En bilinen bileşenlerinden biri <strong>Garbage Collector</strong>, yani çöp toplayıcıdır. Artık erişilemeyen nesnelerin belleğini otomatik olarak geri kazanır.</p>

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

<span class="k">public</span> <span class="k">sealed</span> <span class="k">class</span> <span class="nc">Urun</span>
<span class="p">{</span>
    <span class="k">public</span> <span class="kt">string</span> <span class="n">Ad</span> <span class="p">{</span> <span class="k">get</span><span class="p">;</span> <span class="p">}</span>
    <span class="k">public</span> <span class="kt">decimal</span> <span class="n">Fiyat</span> <span class="p">{</span> <span class="k">get</span><span class="p">;</span> <span class="p">}</span>

    <span class="k">public</span> <span class="nf">Urun</span><span class="p">(</span><span class="kt">string</span> <span class="n">ad</span><span class="p">,</span> <span class="kt">decimal</span> <span class="n">fiyat</span><span class="p">)</span>
    <span class="p">{</span>
        <span class="n">Ad</span> <span class="p">=</span> <span class="n">ad</span><span class="p">;</span>
        <span class="n">Fiyat</span> <span class="p">=</span> <span class="n">fiyat</span><span class="p">;</span>
    <span class="p">}</span>

    <span class="k">public</span> <span class="kt">decimal</span> <span class="nf">KdvliFiyat</span><span class="p">(</span><span class="kt">decimal</span> <span class="n">oran</span><span class="p">)</span> <span class="p">=&gt;</span> <span class="n">Fiyat</span> <span class="p">*</span> <span class="p">(</span><span class="m">1</span> <span class="p">+</span> <span class="n">oran</span><span class="p">);</span>
<span class="p">}</span>

<span class="kt">var</span> <span class="n">urun</span> <span class="p">=</span> <span class="k">new</span> <span class="nf">Urun</span><span class="p">(</span><span class="s">"Klavye"</span><span class="p">,</span> <span class="m">1200m</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">urun</span><span class="p">.</span><span class="nf">KdvliFiyat</span><span class="p">(</span><span class="m">0.20m</span><span class="p">));</span>
</code></pre></div></div>

<p>Bu örnekte <code class="language-plaintext highlighter-rouge">Urun</code> nesnesi yönetilen bellekte oluşturulur. CLR nesnenin yaşam döngüsünü izler; nesneye erişim kalmadığında ayrılan alan GC tarafından temizlenebilir. Geliştiricinin çoğu durumda belleği elle serbest bırakması gerekmez.</p>

<h2 id="cts-ve-cls-neden-önemlidir">CTS ve CLS neden önemlidir?</h2>

<p><strong>Common Type System</strong>, .NET dillerinin ortak tür modelini tanımlar. Örneğin C# dilindeki <code class="language-plaintext highlighter-rouge">int</code>, CLR düzeyinde <code class="language-plaintext highlighter-rouge">System.Int32</code> türüne karşılık gelir. <strong>Common Language Specification</strong> ise farklı .NET dillerinin birbiriyle uyumlu çalışabilmesi için takip etmesi gereken kuralları belirler.</p>

<table>
  <thead>
    <tr>
      <th>Bileşen</th>
      <th>Sağladığı avantaj</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>CIL</td>
      <td>İşlemci bağımsız ara temsil</td>
    </tr>
    <tr>
      <td>Metadata</td>
      <td>Tür ve bağımlılık bilgilerinin taşınması</td>
    </tr>
    <tr>
      <td>JIT</td>
      <td>Hedef sisteme uygun makine kodu</td>
    </tr>
    <tr>
      <td>GC</td>
      <td>Otomatik bellek yönetimi</td>
    </tr>
    <tr>
      <td>CTS ve CLS</td>
      <td>Diller arası uyumluluk</td>
    </tr>
  </tbody>
</table>

<p>Sonuç olarak C# kodu tek başına yolculuk etmez. Roslyn, CIL, assembly, JIT ve CLR katmanları birlikte çalışarak taşınabilir, güvenli ve yönetilebilir bir yürütme ortamı oluşturur. Bu mimariyi bilmek, yalnızca kod yazmayı değil, kodun gerçekte nasıl hayata geçtiğini de anlamaktır.</p>]]></content><author><name>Sonsuz Us</name></author><category term="Bilgi" /><category term="csharp" /><category term="dotnet" /><category term="clr" /><category term="derleme" /><category term="jit" /><category term="programlama" /><summary type="html"><![CDATA[Bir C# programında Console.WriteLine yazıp çalıştır düğmesine bastığımızda perde arkasında küçük bir teknoloji festivali başlar. Kaynak kod derlenir, ara dile çevrilir, çalışma zamanı tarafından incelenir ve makine koduna dönüştürülür. C# ile .NET arasındaki ilişkiyi anlamak; performans, hata ayıklama ve taşınabilirlik gibi konuları ezberden değil, sağlam bir mimari üzerinden değerlendirmeyi sağlar.]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://program.sonsuz.us/img/c-ve-net-45.png" /><media:content medium="image" url="https://program.sonsuz.us/img/c-ve-net-45.png" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">C++’ta Const Borcu: İhmal Edilen const Doğruluğu Arayüzleri Nasıl Yaşlandırır?</title><link href="https://program.sonsuz.us/posts/cta-const-borcu-ihmal-edilen-const-dogrulugu-arayuzleri-nasil-yaslandirir/" rel="alternate" type="text/html" title="C++’ta Const Borcu: İhmal Edilen const Doğruluğu Arayüzleri Nasıl Yaşlandırır?" /><published>2026-10-19T00:00:00+00:00</published><updated>2026-10-19T00:00:00+00:00</updated><id>https://program.sonsuz.us/posts/cta-const-borcu-ihmal-edilen-const-dogrulugu-arayuzleri-nasil-yaslandirir</id><content type="html" xml:base="https://program.sonsuz.us/posts/cta-const-borcu-ihmal-edilen-const-dogrulugu-arayuzleri-nasil-yaslandirir/"><![CDATA[<p>C++’ta <code class="language-plaintext highlighter-rouge">const</code>, yalnızca derleyiciyi memnun eden küçük bir anahtar kelime değildir; bir arayüzün hangi işlemleri garanti ettiğini anlatan sözleşmedir. Bugün atlanan bir <code class="language-plaintext highlighter-rouge">const</code>, kodu hemen bozmayabilir. Ancak proje büyüdükçe yeniden kullanım, eşzamanlılık ve geriye dönük uyumluluk gibi alanlarda faiz işleyen bir tasarım borcuna dönüşür.
``</p>
<h2 id="const-doğruluğu-gerçekte-ne-söyler">Const doğruluğu gerçekte ne söyler?</h2>

<p>Bir nesneye <code class="language-plaintext highlighter-rouge">const</code> erişim, gözlemlenebilir durumunun değiştirilmeyeceği sözünü verir. Üye fonksiyonun sonundaki <code class="language-plaintext highlighter-rouge">const</code> ise bu sözün fonksiyon arayüzündeki karşılığıdır:</p>

<div class="language-cpp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">class</span> <span class="nc">User</span> <span class="p">{</span>
<span class="nl">public:</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">name</span><span class="p">()</span> <span class="k">const</span> <span class="p">{</span>
        <span class="k">return</span> <span class="n">name_</span><span class="p">;</span>
    <span class="p">}</span>

<span class="k">private</span><span class="o">:</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="p">};</span>
</code></pre></div></div>

<p>Burada ilk <code class="language-plaintext highlighter-rouge">const</code>, döndürülen referans üzerinden metnin değiştirilemeyeceğini; ikinci <code class="language-plaintext highlighter-rouge">const</code> ise <code class="language-plaintext highlighter-rouge">name()</code> çağrısının <code class="language-plaintext highlighter-rouge">User</code> nesnesini değiştirmediğini belirtir. İki kullanım farklı soruları yanıtlar: “Sonuç değiştirilebilir mi?” ve “İşlem nesneyi değiştiriyor mu?”</p>

<p>Bunu kabaca bir durum geçişiyle ifade edebiliriz. Salt okunur işlem için beklenen ilişki:</p>

\[f(S) = (R, S)\]

<p>Burada $S$ nesnenin başlangıç durumu, $R$ sonuçtur. Değiştirici bir işlemdeyse yeni durum $S’$ oluşabilir:</p>

\[g(S) = (R, S'), \quad S' \neq S\]

<p><code class="language-plaintext highlighter-rouge">const</code>, ilk davranışı tür sistemi seviyesinde ilan eder ve derleyicinin bu sözleşmeyi denetlemesini sağlar.</p>

<h2 id="küçük-ihmal-büyük-arayüz-problemi">Küçük ihmal, büyük arayüz problemi</h2>

<p>Aşağıdaki fonksiyon nesneyi değiştirmese bile <code class="language-plaintext highlighter-rouge">const</code> olarak işaretlenmemiştir:</p>

<div class="language-cpp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">class</span> <span class="nc">Report</span> <span class="p">{</span>
<span class="nl">public:</span>
    <span class="n">std</span><span class="o">::</span><span class="n">string</span> <span class="n">summary</span><span class="p">()</span> <span class="p">{</span> <span class="c1">// Aslında değişiklik yapmıyor</span>
        <span class="k">return</span> <span class="n">title_</span> <span class="o">+</span> <span class="s">": "</span> <span class="o">+</span> <span class="n">body_</span><span class="p">;</span>
    <span class="p">}</span>

<span class="k">private</span><span class="o">:</span>
    <span class="n">std</span><span class="o">::</span><span class="n">string</span> <span class="n">title_</span><span class="p">;</span>
    <span class="n">std</span><span class="o">::</span><span class="n">string</span> <span class="n">body_</span><span class="p">;</span>
<span class="p">};</span>
</code></pre></div></div>

<p>Bu eksiklik yüzünden <code class="language-plaintext highlighter-rouge">const Report&amp;</code> alan kodlar <code class="language-plaintext highlighter-rouge">summary()</code> metodunu çağıramaz. Sorunu geçici olarak aşmak isteyen geliştiriciler nesneleri gereksiz yere kopyalayabilir, parametrelerden <code class="language-plaintext highlighter-rouge">const</code> niteliğini kaldırabilir veya daha kötüsü <code class="language-plaintext highlighter-rouge">const_cast</code> kullanabilir. Böylece yerel bir ihmal, çağrı zinciri boyunca yayılır.</p>

<table>
  <thead>
    <tr>
      <th>Tasarım tercihi</th>
      <th>Kısa vadeli sonuç</th>
      <th>Uzun vadeli etki</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Doğru <code class="language-plaintext highlighter-rouge">const</code> kullanımı</td>
      <td>Biraz daha dikkat gerektirir</td>
      <td>Açık sözleşme ve geniş kullanım alanı</td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">const</code> kullanımını ertelemek</td>
      <td>Kod hızlı yazılır</td>
      <td>API esnekliği azalır</td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">const_cast</code> ile aşmak</td>
      <td>Derleme hatası susturulur</td>
      <td>Tanımsız davranış ve bakım riski</td>
    </tr>
    <tr>
      <td>Her şeyi değiştirilebilir bırakmak</td>
      <td>Basit görünür</td>
      <td>Eşzamanlılık analizi zorlaşır</td>
    </tr>
  </tbody>
</table>

<h2 id="sonradan-eklemek-neden-pahalıdır">Sonradan eklemek neden pahalıdır?</h2>

<p>Bir metoda sonradan <code class="language-plaintext highlighter-rouge">const</code> eklemek kaynak kod düzeyinde küçük görünür:</p>

<div class="language-cpp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">std</span><span class="o">::</span><span class="n">string</span> <span class="n">summary</span><span class="p">()</span> <span class="k">const</span><span class="p">;</span>
</code></pre></div></div>

<p>Fakat gerçek projede bu değişiklik; çağrılan yardımcı metotların, kullanılan işaretçilerin ve önbelleklerin de incelenmesini gerektirir. Ayrıca üye fonksiyonun <code class="language-plaintext highlighter-rouge">const</code> niteliği türünün parçasıdır. Sanal fonksiyonlarda taban ve türetilmiş sınıfların imzaları eşleşmelidir:</p>

<div class="language-cpp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">struct</span> <span class="nc">Document</span> <span class="p">{</span>
    <span class="k">virtual</span> <span class="n">std</span><span class="o">::</span><span class="n">string</span> <span class="n">title</span><span class="p">()</span> <span class="k">const</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
<span class="p">};</span>

<span class="k">struct</span> <span class="nc">Invoice</span> <span class="o">:</span> <span class="n">Document</span> <span class="p">{</span>
    <span class="n">std</span><span class="o">::</span><span class="n">string</span> <span class="n">title</span><span class="p">()</span> <span class="k">const</span> <span class="k">override</span> <span class="p">{</span>
        <span class="k">return</span> <span class="s">"Fatura"</span><span class="p">;</span>
    <span class="p">}</span>
<span class="p">};</span>
</code></pre></div></div>

<p>Taban sınıfa sonradan <code class="language-plaintext highlighter-rouge">const</code> eklemek, bütün türetilmiş sınıfları değiştirebilir. Paylaşılan kütüphanelerde bu durum kaynak ve ikili uyumluluk planlarını da etkiler.</p>

<h2 id="mantıksal-const-ve-önbellekleme">Mantıksal const ve önbellekleme</h2>

<p>Bazen bir sorgu sonucu önbelleğe alınır. Kullanıcının gözünde nesne değişmezken içeride teknik bir güncelleme gerekir. Bunun için <code class="language-plaintext highlighter-rouge">mutable</code> bilinçli biçimde kullanılabilir:</p>

<div class="language-cpp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">class</span> <span class="nc">Calculator</span> <span class="p">{</span>
<span class="nl">public:</span>
    <span class="kt">int</span> <span class="n">result</span><span class="p">()</span> <span class="k">const</span> <span class="p">{</span>
        <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="n">cached_</span><span class="p">)</span> <span class="p">{</span>
            <span class="n">cache_</span> <span class="o">=</span> <span class="n">expensiveCalculation</span><span class="p">();</span>
            <span class="n">cached_</span> <span class="o">=</span> <span class="nb">true</span><span class="p">;</span>
        <span class="p">}</span>
        <span class="k">return</span> <span class="n">cache_</span><span class="p">;</span>
    <span class="p">}</span>

<span class="k">private</span><span class="o">:</span>
    <span class="kt">int</span> <span class="n">expensiveCalculation</span><span class="p">()</span> <span class="k">const</span> <span class="p">{</span> <span class="k">return</span> <span class="mi">42</span><span class="p">;</span> <span class="p">}</span>
    <span class="k">mutable</span> <span class="kt">bool</span> <span class="n">cached_</span> <span class="o">=</span> <span class="nb">false</span><span class="p">;</span>
    <span class="k">mutable</span> <span class="kt">int</span> <span class="n">cache_</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
<span class="p">};</span>
</code></pre></div></div>

<p>Bu yaklaşım fiziksel değil, mantıksal değişmezliği temsil eder. Yine de <code class="language-plaintext highlighter-rouge">mutable</code>, eşzamanlı erişimi otomatik olarak güvenli yapmaz; gerekirse kilit veya atomik tür kullanılmalıdır.</p>

<h2 id="sağlam-arayüz-için-pratik-ölçüt">Sağlam arayüz için pratik ölçüt</h2>

<p>Bir metot tasarlarken önce “Bu işlem nesnenin kullanıcı tarafından gözlemlenen anlamını değiştiriyor mu?” diye sorun. Yanıt hayırsa metodu <code class="language-plaintext highlighter-rouge">const</code> yapın. Parametrelerde mümkün olduğunda <code class="language-plaintext highlighter-rouge">const T&amp;</code>, sahiplik aktarılmıyorsa salt okunur işaretçi veya görünüm türleri kullanın. <code class="language-plaintext highlighter-rouge">const</code> doğruluğunu baştan kurmak birkaç saniye; yıllar sonra bütün API ağında düzeltmek ise pahalı bir mimari operasyondur. Kısacası <code class="language-plaintext highlighter-rouge">const</code>, kısıtlama değil, gelecekteki kullanım biçimlerine açılan güvenli bir kapıdır.</p>

<p><img src="/img/cta-const-borcu-47.svg" alt="cta-const-borcu-47" /></p>]]></content><author><name>Sonsuz Us</name></author><category term="Bilgi" /><category term="c++" /><category term="const-correctness" /><category term="api-tasarımı" /><category term="yazılım-mimarisi" /><category term="teknik-borç" /><summary type="html"><![CDATA[C++’ta const, yalnızca derleyiciyi memnun eden küçük bir anahtar kelime değildir; bir arayüzün hangi işlemleri garanti ettiğini anlatan sözleşmedir. Bugün atlanan bir const, kodu hemen bozmayabilir. Ancak proje büyüdükçe yeniden kullanım, eşzamanlılık ve geriye dönük uyumluluk gibi alanlarda faiz işleyen bir tasarım borcuna dönüşür.]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://program.sonsuz.us/img/cta-const-borcu-47.png" /><media:content medium="image" url="https://program.sonsuz.us/img/cta-const-borcu-47.png" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">C++’ta const Referanslar ve Geçici Nesne Ömrü: Sessiz Tuzaklar</title><link href="https://program.sonsuz.us/posts/cta-const-referanslar-ve-gecici-nesne-omru-sessiz-tuzaklar/" rel="alternate" type="text/html" title="C++’ta const Referanslar ve Geçici Nesne Ömrü: Sessiz Tuzaklar" /><published>2026-10-19T00:00:00+00:00</published><updated>2026-10-19T00:00:00+00:00</updated><id>https://program.sonsuz.us/posts/cta-const-referanslar-ve-gecici-nesne-omru-sessiz-tuzaklar</id><content type="html" xml:base="https://program.sonsuz.us/posts/cta-const-referanslar-ve-gecici-nesne-omru-sessiz-tuzaklar/"><![CDATA[<p><img src="/img/cta-const-referanslar-21.svg" alt="cta-const-referanslar-21" /></p>

<p>C++’ta <code class="language-plaintext highlighter-rouge">const T&amp;</code> gördüğümüzde genellikle “güvenli, değiştirilemez referans” diye düşünürüz. Ancak geçici nesneler devreye girdiğinde konu yalnızca değiştirilebilirlikten ibaret değildir. Referansın neye, nerede ve nasıl bağlandığı; geçici nesnenin hemen yok edilmesini de kapsam sonuna kadar yaşamasını da sağlayabilir. Kısacası <code class="language-plaintext highlighter-rouge">const</code>, bazen nesneye adeta fazladan can verir.</p>

<p>``</p>

<h2 id="geçici-nesne-nedir">Geçici nesne nedir?</h2>

<p>Bir ifadenin sonucunu taşımak için oluşturulan, genellikle adı olmayan nesneye geçici nesne denir. Örneğin <code class="language-plaintext highlighter-rouge">std::string("merhaba")</code> bir geçici nesne üretir. Normal koşullarda bu nesne, içinde oluşturulduğu <strong>tam ifadenin</strong> sonunda yok edilir. Çoğu zaman bu nokta noktalı virgüldür.</p>

<div class="language-cpp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">std</span><span class="o">::</span><span class="n">string</span><span class="p">(</span><span class="s">"merhaba"</span><span class="p">);</span> <span class="c1">// Nesne bu satırın sonunda yok edilir.</span>
</code></pre></div></div>

<p>Basitleştirilmiş biçimde geçici nesnenin olağan ömrünü şöyle düşünebiliriz:</p>

\[L_{geçici} = t_{ifade\ sonu} - t_{oluşturma}\]

<p>Fakat uygun bir yerel referansa doğrudan bağlama yapılırsa ömür, referansın kapsamına kadar uzatılabilir:</p>

\[L_{uzatılmış} = t_{kapsam\ sonu} - t_{oluşturma}\]

<h2 id="const-referans-neden-özel"><code class="language-plaintext highlighter-rouge">const</code> referans neden özel?</h2>

<p>Lvalue referansları normalde geçici nesnelere bağlanamaz:</p>

<div class="language-cpp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">std</span><span class="o">::</span><span class="n">string</span><span class="o">&amp;</span> <span class="n">a</span> <span class="o">=</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="c1">// Hata</span>
</code></pre></div></div>

<p>Bunun nedeni, kısa ömürlü ve isimsiz bir değerin değiştirilebilir bir lvalue referansı üzerinden kullanılmasının riskli kabul edilmesidir. Buna karşılık <code class="language-plaintext highlighter-rouge">const</code> lvalue referansı bağlanabilir:</p>

<div class="language-cpp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><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="o">=</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="n">std</span><span class="o">::</span><span class="n">cout</span> <span class="o">&lt;&lt;</span> <span class="n">a</span><span class="p">;</span> <span class="c1">// Güvenli: geçicinin ömrü a'nın kapsamına uzatıldı.</span>
</code></pre></div></div>

<table>
  <thead>
    <tr>
      <th>Bağlama biçimi</th>
      <th style="text-align: right">Geçiciye bağlanır mı?</th>
      <th style="text-align: right">Ömür uzar mı?</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">T&amp;</code></td>
      <td style="text-align: right">Hayır</td>
      <td style="text-align: right">Hayır</td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">const T&amp;</code></td>
      <td style="text-align: right">Evet</td>
      <td style="text-align: right">Genellikle evet</td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">T&amp;&amp;</code></td>
      <td style="text-align: right">Evet</td>
      <td style="text-align: right">Yerel değişkense evet</td>
    </tr>
    <tr>
      <td>Fonksiyon parametresi <code class="language-plaintext highlighter-rouge">const T&amp;</code></td>
      <td style="text-align: right">Evet</td>
      <td style="text-align: right">Yalnızca çağrının tam ifadesinin sonuna kadar</td>
    </tr>
  </tbody>
</table>

<p>Son satır kritik bir ayrıntıdır. Bir fonksiyon parametresine bağlanan geçici, fonksiyon çağrısı bittikten sonra saklanamaz.</p>

<div class="language-cpp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">const</span> <span class="n">std</span><span class="o">::</span><span class="n">string</span><span class="o">*</span> <span class="n">adres</span><span class="p">;</span>

<span class="kt">void</span> <span class="nf">sakla</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> <span class="p">{</span>
    <span class="n">adres</span> <span class="o">=</span> <span class="o">&amp;</span><span class="n">metin</span><span class="p">;</span>
<span class="p">}</span>

<span class="n">sakla</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">"kaybolacak"</span><span class="p">));</span>
<span class="c1">// Bu noktadan sonra adres dangling pointer!</span>
</code></pre></div></div>

<p><code class="language-plaintext highlighter-rouge">metin</code>, fonksiyon içinde geçerlidir; fakat çağrının bulunduğu tam ifade sona erince geçici nesne yok edilir.</p>

<h2 id="referansı-döndürmek-ömrü-uzatmaz">Referansı döndürmek ömrü uzatmaz</h2>

<p>En tehlikeli sürprizlerden biri, fonksiyondan <code class="language-plaintext highlighter-rouge">const</code> referans döndürmektir:</p>

<div class="language-cpp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><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="err">ü</span><span class="n">ret</span><span class="p">()</span> <span class="p">{</span>
    <span class="k">return</span> <span class="n">std</span><span class="o">::</span><span class="n">string</span><span class="p">(</span><span class="s">"geçici"</span><span class="p">);</span> <span class="c1">// Hatalı: yok edilecek nesneye referans</span>
<span class="p">}</span>
</code></pre></div></div>

<p><code class="language-plaintext highlighter-rouge">const</code> burada koruyucu kalkan değildir. Fonksiyon sona erdiğinde geçici nesne yok edilir ve dönen referans boşa çıkar. Doğru yaklaşım değeri döndürmektir:</p>

<div class="language-cpp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">std</span><span class="o">::</span><span class="n">string</span> <span class="err">ü</span><span class="n">ret</span><span class="p">()</span> <span class="p">{</span>
    <span class="k">return</span> <span class="n">std</span><span class="o">::</span><span class="n">string</span><span class="p">(</span><span class="s">"güvenli"</span><span class="p">);</span>
<span class="p">}</span>
</code></pre></div></div>

<p>Modern C++, kopya eleme ve taşıma sayesinde bu kodu çoğunlukla ek maliyet oluşturmadan çalıştırır.</p>

<h2 id="i̇kinci-referans-ikinci-bir-ömür-vermez">İkinci referans ikinci bir ömür vermez</h2>

<p>Ömür uzatma aktarılabilir bir özellik değildir:</p>

<div class="language-cpp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><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">ilk</span> <span class="o">=</span> <span class="n">std</span><span class="o">::</span><span class="n">string</span><span class="p">(</span><span class="s">"örnek"</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">ikinci</span> <span class="o">=</span> <span class="n">ilk</span><span class="p">;</span>
</code></pre></div></div>

<p>Nesnenin ömrü <code class="language-plaintext highlighter-rouge">ilk</code> nedeniyle uzatılmıştır. <code class="language-plaintext highlighter-rouge">ikinci</code>, aynı nesneye başka bir takma ad verir; ömrü yeniden başlatmaz veya kendi kapsamına göre genişletmez. Eğer <code class="language-plaintext highlighter-rouge">ikinci</code>, <code class="language-plaintext highlighter-rouge">ilk</code>ten daha uzun yaşarsa dangling referansa dönüşebilir.</p>

<h2 id="const-dönüş-değeri-her-zaman-yararlı-değildir"><code class="language-plaintext highlighter-rouge">const</code> dönüş değeri her zaman yararlı değildir</h2>

<p>Eski kodlarda <code class="language-plaintext highlighter-rouge">const T</code> döndüren fonksiyonlar görülebilir:</p>

<div class="language-cpp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">const</span> <span class="n">std</span><span class="o">::</span><span class="n">string</span> <span class="n">olu</span><span class="err">ş</span><span class="n">tur</span><span class="p">();</span>
</code></pre></div></div>

<p>Bu kullanım, modern C++’ta taşıma işlemlerini engelleyebilir; çünkü taşıma kurucuları çoğunlukla <code class="language-plaintext highlighter-rouge">T&amp;&amp;</code> bekler, <code class="language-plaintext highlighter-rouge">const T&amp;&amp;</code> değil. Değer döndüren fonksiyonlarda genellikle yalnızca <code class="language-plaintext highlighter-rouge">T</code> tercih edilmelidir.</p>

<p>Özet kural şudur: Yerel <code class="language-plaintext highlighter-rouge">const T&amp;</code> ve <code class="language-plaintext highlighter-rouge">T&amp;&amp;</code>, doğrudan bağlandıkları geçicinin ömrünü uzatabilir. Parametreler, döndürülen referanslar ve başka bir referans üzerinden yapılan bağlamalar için aynı güvenceyi varsaymayın. <code class="language-plaintext highlighter-rouge">const</code>, değişikliği sınırlar; her durumda ömür yönetmez.</p>]]></content><author><name>Sonsuz Us</name></author><category term="Bilgi" /><category term="c++" /><category term="const" /><category term="referanslar" /><category term="nesne-ömrü" /><category term="geçici-nesneler" /><category term="modern-c++" /><summary type="html"><![CDATA[C++’ta const T&amp; gördüğümüzde genellikle “güvenli, değiştirilemez referans” diye düşünürüz. Ancak geçici nesneler devreye girdiğinde konu yalnızca değiştirilebilirlikten ibaret değildir. Referansın neye, nerede ve nasıl bağlandığı; geçici nesnenin hemen yok edilmesini de kapsam sonuna kadar yaşamasını da sağlayabilir. Kısacası const, bazen nesneye adeta fazladan can verir.]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://program.sonsuz.us/img/cta-const-referanslar-21.png" /><media:content medium="image" url="https://program.sonsuz.us/img/cta-const-referanslar-21.png" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">C++’ta delete ve delete[] Farkı: Tek Bir Köşeli Parantezin Bedeli</title><link href="https://program.sonsuz.us/posts/cta-delete-ve-delete-farki-tek-bir-koseli-parantezin-bedeli/" rel="alternate" type="text/html" title="C++’ta delete ve delete[] Farkı: Tek Bir Köşeli Parantezin Bedeli" /><published>2026-10-19T00:00:00+00:00</published><updated>2026-10-19T00:00:00+00:00</updated><id>https://program.sonsuz.us/posts/cta-delete-ve-delete-farki-tek-bir-koseli-parantezin-bedeli</id><content type="html" xml:base="https://program.sonsuz.us/posts/cta-delete-ve-delete-farki-tek-bir-koseli-parantezin-bedeli/"><![CDATA[<p><img src="/img/cta-delete-ve-81.svg" alt="cta-delete-ve-81" /></p>

<p>C++’ta dinamik bellek yönetirken <code class="language-plaintext highlighter-rouge">delete</code> ile <code class="language-plaintext highlighter-rouge">delete[]</code> arasındaki iki köşeli parantez küçük görünebilir. Ancak yanlış silme ifadesini kullanmak; bellek sızıntısı, eksik yıkıcı çağrıları, heap bozulması ve yalnızca üretim ortamında ortaya çıkan gizemli çökmeler gibi ciddi sonuçlara yol açabilir.
``</p>
<h2 id="temel-eşleştirme-kuralı">Temel eşleştirme kuralı</h2>

<p>C++’ta bellek ayırma ve serbest bırakma işlemleri doğru biçimde eşleştirilmelidir:</p>

<table>
  <thead>
    <tr>
      <th>Bellek ayırma</th>
      <th>Belleği serbest bırakma</th>
      <th>Kullanım amacı</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">new T</code></td>
      <td><code class="language-plaintext highlighter-rouge">delete</code></td>
      <td>Tek bir nesne</td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">new T[n]</code></td>
      <td><code class="language-plaintext highlighter-rouge">delete[]</code></td>
      <td>Nesne dizisi</td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">malloc</code> / <code class="language-plaintext highlighter-rouge">calloc</code></td>
      <td><code class="language-plaintext highlighter-rouge">free</code></td>
      <td>C tarzı ham bellek</td>
    </tr>
  </tbody>
</table>

<p>Başka bir ifadeyle şu eşitlik korunmalıdır:</p>

\[new\ T \longleftrightarrow delete\]

\[new\ T[n] \longleftrightarrow delete[]\]

<p><code class="language-plaintext highlighter-rouge">new[]</code> ile oluşturulan bir diziyi normal <code class="language-plaintext highlighter-rouge">delete</code> ile silmek <strong>tanımsız davranıştır</strong>. Tanımsız davranış, programın mutlaka anında çökeceği anlamına gelmez. Program düzgün çalışıyor gibi görünebilir, rastgele sonuç üretebilir veya başka bir noktada çökebilir. Tehlikeli olan da budur.</p>

<h2 id="neden-iki-farklı-silme-işlemi-var">Neden iki farklı silme işlemi var?</h2>

<p>Tek bir nesne oluşturulduğunda çalışma zamanı yalnızca o nesnenin yıkıcısını çağırır ve belleği serbest bırakır. Dizilerde ise her elemanın ayrı ayrı yok edilmesi gerekir.</p>

<p>Bir dizi $n$ elemandan oluşuyorsa beklenen yıkıcı çağrısı sayısı şöyledir:</p>

\[D(n) = n\]

<p>Bazı C++ çalışma zamanı uygulamaları, ayrılan bloğun başında eleman sayısını saklayan ve halk arasında <strong>array cookie</strong> denilen ek bilgiler tutar. <code class="language-plaintext highlighter-rouge">delete[]</code>, bu bilgiyi kullanarak kaç yıkıcı çağrılması gerektiğini belirleyebilir. Standart, bu mekanizmanın nasıl uygulanacağını zorunlu kılmaz; fakat programcıya doğru silme ifadesini kullanma sorumluluğunu verir.</p>

<div class="language-cpp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">class</span> <span class="nc">Sensor</span> <span class="p">{</span>
<span class="nl">public:</span>
    <span class="n">Sensor</span><span class="p">()</span> <span class="o">=</span> <span class="k">default</span><span class="p">;</span>

    <span class="o">~</span><span class="n">Sensor</span><span class="p">()</span> <span class="p">{</span>
        <span class="c1">// Dosya, soket veya başka bir kaynak burada kapatılabilir.</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">Sensor</span><span class="o">*</span> <span class="n">sensors</span> <span class="o">=</span> <span class="k">new</span> <span class="n">Sensor</span><span class="p">[</span><span class="mi">4</span><span class="p">];</span>

    <span class="c1">// Dört elemanın da yıkıcısını çalıştırır.</span>
    <span class="k">delete</span><span class="p">[]</span> <span class="n">sensors</span><span class="p">;</span>
<span class="p">}</span>
</code></pre></div></div>

<p>Burada <code class="language-plaintext highlighter-rouge">delete sensors;</code> kullanılsaydı sonuç tanımsız olurdu. Yalnızca ilk elemanın yıkıcısının çağrılacağını varsaymak bile güvenli değildir; standart böyle bir garanti sunmaz.</p>

<h2 id="i̇lkel-türlerde-sorun-yok-mu">İlkel türlerde sorun yok mu?</h2>

<p><code class="language-plaintext highlighter-rouge">int</code> veya <code class="language-plaintext highlighter-rouge">double</code> gibi türlerin yıkıcısı olmadığı için yanlış kullanımın zararsız olduğu düşünülebilir:</p>

<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">scores</span> <span class="o">=</span> <span class="k">new</span> <span class="kt">int</span><span class="p">[</span><span class="mi">100</span><span class="p">];</span>
<span class="k">delete</span> <span class="n">scores</span><span class="p">;</span> <span class="c1">// Hatalı: delete[] kullanılmalıydı.</span>
</code></pre></div></div>

<p>Bu kod yine tanımsız davranıştır. Bellek yöneticisi dizi tahsisini farklı biçimde izleyebilir. Hata hemen görünmese bile heap yapısı bozulabilir. Doğru kullanım şöyledir:</p>

<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">scores</span> <span class="o">=</span> <span class="k">new</span> <span class="kt">int</span><span class="p">[</span><span class="mi">100</span><span class="p">];</span>
<span class="k">delete</span><span class="p">[]</span> <span class="n">scores</span><span class="p">;</span>
<span class="n">scores</span> <span class="o">=</span> <span class="nb">nullptr</span><span class="p">;</span>
</code></pre></div></div>

<p>İşaretçiyi <code class="language-plaintext highlighter-rouge">nullptr</code> yapmak, aynı işaretçinin yanlışlıkla tekrar silinmesi riskini azaltabilir. Ayrıca <code class="language-plaintext highlighter-rouge">delete nullptr</code> ve <code class="language-plaintext highlighter-rouge">delete[] nullptr</code> güvenlidir; ikisi de işlem yapmaz.</p>

<h2 id="hataları-nasıl-yakalarız">Hataları nasıl yakalarız?</h2>

<p>AddressSanitizer, Valgrind ve benzeri araçlar tahsis-silme uyumsuzluklarını bulabilir. GCC veya Clang ile örnek bir kontrol derlemesi şöyledir:</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>g++ <span class="nt">-std</span><span class="o">=</span>c++20 <span class="nt">-Wall</span> <span class="nt">-Wextra</span> <span class="nt">-fsanitize</span><span class="o">=</span>address main.cpp
./a.out
</code></pre></div></div>

<p>Derleyici uyarıları yardımcı olsa da işaretçi farklı fonksiyonlara taşındığında hatayı her zaman yakalayamaz.</p>

<h2 id="modern-c-çözümü">Modern C++ çözümü</h2>

<p>En güvenli yaklaşım, çıplak <code class="language-plaintext highlighter-rouge">new[]</code> kullanmaktan kaçınmaktır. Boyutu çalışma zamanında belirlenen diziler için <code class="language-plaintext highlighter-rouge">std::vector</code>, sabit boyutlular için <code class="language-plaintext highlighter-rouge">std::array</code> tercih edilmelidir:</p>

<div class="language-cpp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="cp">#include</span> <span class="cpf">&lt;vector&gt;</span><span class="cp">
</span>
<span class="kt">int</span> <span class="nf">main</span><span class="p">()</span> <span class="p">{</span>
    <span class="n">std</span><span class="o">::</span><span class="n">vector</span><span class="o">&lt;</span><span class="kt">int</span><span class="o">&gt;</span> <span class="n">scores</span><span class="p">(</span><span class="mi">100</span><span class="p">);</span>
    <span class="n">scores</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">=</span> <span class="mi">42</span><span class="p">;</span>
<span class="p">}</span> <span class="c1">// Bellek otomatik olarak temizlenir.</span>
</code></pre></div></div>

<p>Dinamik bir diziye gerçekten ihtiyaç varsa <code class="language-plaintext highlighter-rouge">std::unique_ptr&lt;T[]&gt;</code> kullanılabilir. Böylece doğru <code class="language-plaintext highlighter-rouge">delete[]</code> otomatik olarak çağrılır. Kısacası, <code class="language-plaintext highlighter-rouge">new</code> gördüğünüzde <code class="language-plaintext highlighter-rouge">delete</code>, <code class="language-plaintext highlighter-rouge">new[]</code> gördüğünüzde <code class="language-plaintext highlighter-rouge">delete[]</code> düşünün; daha iyisi, bu işi RAII kapsayıcılarına bırakın.</p>]]></content><author><name>Sonsuz Us</name></author><category term="Bilgi" /><category term="c++" /><category term="bellek yönetimi" /><category term="delete" /><category term="delete[]" /><category term="tanımsız davranış" /><category term="modern c++" /><summary type="html"><![CDATA[C++’ta dinamik bellek yönetirken delete ile delete[] arasındaki iki köşeli parantez küçük görünebilir. Ancak yanlış silme ifadesini kullanmak; bellek sızıntısı, eksik yıkıcı çağrıları, heap bozulması ve yalnızca üretim ortamında ortaya çıkan gizemli çökmeler gibi ciddi sonuçlara yol açabilir.]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://program.sonsuz.us/img/cta-delete-ve-81.png" /><media:content medium="image" url="https://program.sonsuz.us/img/cta-delete-ve-81.png" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">Diferansiyel Sürüşlü Robotlar Tekerlek Hızı Farkıyla Nasıl Döner?</title><link href="https://program.sonsuz.us/posts/diferansiyel-suruslu-robotlar-tekerlek-hizi-farkiyla-nasil-doner/" rel="alternate" type="text/html" title="Diferansiyel Sürüşlü Robotlar Tekerlek Hızı Farkıyla Nasıl Döner?" /><published>2026-10-19T00:00:00+00:00</published><updated>2026-10-19T00:00:00+00:00</updated><id>https://program.sonsuz.us/posts/diferansiyel-suruslu-robotlar-tekerlek-hizi-farkiyla-nasil-doner</id><content type="html" xml:base="https://program.sonsuz.us/posts/diferansiyel-suruslu-robotlar-tekerlek-hizi-farkiyla-nasil-doner/"><![CDATA[<p>Diferansiyel sürüşlü bir robotun direksiyonu yoktur; buna rağmen kıvrak biçimde dönebilir, hatta olduğu yerde kendi ekseni etrafında dans edebilir. Bu yeteneğin sırrı, sağ ve sol tekerleklerin farklı hızlarda döndürülmesidir. Alışveriş arabasını tek taraftan daha güçlü ittiğinizi düşünün: hız farkı, aracın yönünü değiştirir.</p>

<p><img src="/img/diferansiyel-suruslu-robotlar-65.svg" alt="diferansiyel-suruslu-robotlar-65" /></p>

<p>``</p>
<h2 id="temel-mekanik-düzen">Temel mekanik düzen</h2>

<p>Bu robotlarda aynı eksen üzerinde bulunan iki bağımsız tahrik tekerleği vardır. Tekerlekler arasındaki mesafeye <strong>iz genişliği</strong> veya dingil uzunluğu denir ve genellikle $L$ ile gösterilir. Sol tekerleğin doğrusal hızı $v_l$, sağ tekerleğinki ise $v_r$ olsun.</p>

<p>Robotun merkezinin ileri yönlü doğrusal hızı iki tekerlek hızının ortalamasıdır:</p>

\[v = (v_r + v_l) / 2\]

<p>Açısal hız ise tekerlekler arasındaki hız farkıyla belirlenir:</p>

\[ω = (v_r - v_l) / L\]

<p>Bu ikinci denklem robotun dönüş mantığını özetler. Hız farkı büyüdükçe robot daha hızlı döner. Tekerlekler arası mesafe büyüdükçe aynı hız farkıyla elde edilen açısal hız azalır; çünkü geniş bir robotu çevirmek daha zordur.</p>

<table>
  <thead>
    <tr>
      <th>Sol ve sağ hız ilişkisi</th>
      <th>Robotun davranışı</th>
      <th style="text-align: right">Açısal hız</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>$v_l = v_r &gt; 0$</td>
      <td>Düz ileri gider</td>
      <td style="text-align: right">$0$</td>
    </tr>
    <tr>
      <td>$v_l &lt; v_r$</td>
      <td>Sola döner</td>
      <td style="text-align: right">Pozitif</td>
    </tr>
    <tr>
      <td>$v_l &gt; v_r$</td>
      <td>Sağa döner</td>
      <td style="text-align: right">Negatif</td>
    </tr>
    <tr>
      <td>$v_l = -v_r$</td>
      <td>Olduğu yerde döner</td>
      <td style="text-align: right">En yüksek</td>
    </tr>
    <tr>
      <td>$v_l = v_r = 0$</td>
      <td>Durur</td>
      <td style="text-align: right">$0$</td>
    </tr>
  </tbody>
</table>

<p>Buradaki sağ ve sol yön işaretleri, kullanılan koordinat sistemine göre ters tanımlanabilir. Önemli olan yazılımın ve matematiksel modelin aynı işaret kuralını kullanmasıdır.</p>

<h2 id="görünmez-dönüş-merkezi-icc">Görünmez dönüş merkezi: ICC</h2>

<p>Robot viraj alırken iki tekerlek aynı merkez çevresinde fakat farklı yarıçaplarda yay çizer. Bu ortak noktaya <strong>Anlık Dönüş Merkezi</strong> ya da ICC denir. İç taraftaki tekerlek daha kısa, dış taraftaki tekerlek daha uzun yol aldığı için dış tekerlek daha hızlı dönmelidir.</p>

<p>Robot merkezinin dönüş yarıçapı $R$, açısal hız sıfır değilken şöyle bulunabilir:</p>

\[R = v / ω = L(v_r + v_l) / (2(v_r - v_l))\]

<p>Tekerlek hızları birbirine yaklaştığında paydadaki fark küçülür ve $R$ büyür; robot geniş bir yay çizer. Hızlar eşit olduğunda yarıçap teorik olarak sonsuza gider, yani hareket düz bir çizgiye dönüşür. Hızlar eşit büyüklükte ve zıt yönlü olduğundaysa $v=0$ olur; dönüş merkezi robotun tam ortasına gelir.</p>

<h2 id="basit-bir-hız-hesabı">Basit bir hız hesabı</h2>

<p>Aşağıdaki Python fonksiyonu, tekerlek hızlarından robotun doğrusal ve açısal hızını hesaplar:</p>

<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">def</span> <span class="nf">robot_hizi</span><span class="p">(</span><span class="n">sol_hiz</span><span class="p">,</span> <span class="n">sag_hiz</span><span class="p">,</span> <span class="n">tekerlek_araligi</span><span class="p">):</span>
    <span class="n">dogrusal_hiz</span> <span class="o">=</span> <span class="p">(</span><span class="n">sag_hiz</span> <span class="o">+</span> <span class="n">sol_hiz</span><span class="p">)</span> <span class="o">/</span> <span class="mi">2</span>
    <span class="n">acisal_hiz</span> <span class="o">=</span> <span class="p">(</span><span class="n">sag_hiz</span> <span class="o">-</span> <span class="n">sol_hiz</span><span class="p">)</span> <span class="o">/</span> <span class="n">tekerlek_araligi</span>
    <span class="k">return</span> <span class="n">dogrusal_hiz</span><span class="p">,</span> <span class="n">acisal_hiz</span>

<span class="n">v</span><span class="p">,</span> <span class="n">omega</span> <span class="o">=</span> <span class="nf">robot_hizi</span><span class="p">(</span><span class="mf">0.20</span><span class="p">,</span> <span class="mf">0.40</span><span class="p">,</span> <span class="mf">0.30</span><span class="p">)</span>
<span class="nf">print</span><span class="p">(</span><span class="n">v</span><span class="p">,</span> <span class="n">omega</span><span class="p">)</span>
</code></pre></div></div>

<p>Bu örnekte robotun doğrusal hızı $0.30\ m/s$, açısal hızı yaklaşık $0.67\ rad/s$ olur. Sağ tekerlek daha hızlı olduğu için robot sola yönelir.</p>

<p>Motorlar genellikle doğrusal hız yerine açısal tekerlek hızıyla kontrol edilir. Tekerlek yarıçapı $r$ ve motor açısal hızı $ω_w$ ise doğrusal hız:</p>

\[v_w = rω_w\]

<p>bağıntısıyla bulunur. Böylece enkoderden ölçülen dönüş hızı, robot kinematiğinde kullanılabilir.</p>

<h2 id="gerçek-dünya-neden-formüllerden-daha-huysuzdur">Gerçek dünya neden formüllerden daha huysuzdur?</h2>

<p>Teorik model tekerleklerin kaymadığını varsayar. Gerçekte zemin sürtünmesi, motor farklılıkları, pil gerilimi ve ağırlık dağılımı dönüşü etkiler. Aynı PWM değeri iki motorda aynı hızı üretmeyebilir. Bu nedenle enkoder geri bildirimi ve PID kontrolü kullanılarak her tekerleğin hedef hızı ayrı ayrı korunur.</p>

<p>Kısacası diferansiyel sürüş, mekanik olarak sade fakat matematiksel olarak güçlüdür: ortalama hız robotu ilerletir, hız farkı ise döndürür. İki motorun uyumlu anlaşmazlığı, robotun tüm yön kabiliyetini oluşturur.</p>]]></content><author><name>Sonsuz Us</name></author><category term="Bilgi" /><category term="robotik" /><category term="diferansiyel sürüş" /><category term="kinematik" /><category term="tekerlek hızı" /><category term="python" /><category term="mobil robotlar" /><summary type="html"><![CDATA[Diferansiyel sürüşlü bir robotun direksiyonu yoktur; buna rağmen kıvrak biçimde dönebilir, hatta olduğu yerde kendi ekseni etrafında dans edebilir. Bu yeteneğin sırrı, sağ ve sol tekerleklerin farklı hızlarda döndürülmesidir. Alışveriş arabasını tek taraftan daha güçlü ittiğinizi düşünün: hız farkı, aracın yönünü değiştirir.]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://program.sonsuz.us/img/diferansiyel-suruslu-robotlar-65.png" /><media:content medium="image" url="https://program.sonsuz.us/img/diferansiyel-suruslu-robotlar-65.png" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">Fırtınada Bile Gören Robotlar: Otonom Araçlarda Sensör Füzyonu</title><link href="https://program.sonsuz.us/posts/firtinada-bile-goren-robotlar-otonom-araclarda-sensor-fuzyonu/" rel="alternate" type="text/html" title="Fırtınada Bile Gören Robotlar: Otonom Araçlarda Sensör Füzyonu" /><published>2026-10-19T00:00:00+00:00</published><updated>2026-10-19T00:00:00+00:00</updated><id>https://program.sonsuz.us/posts/firtinada-bile-goren-robotlar-otonom-araclarda-sensor-fuzyonu</id><content type="html" xml:base="https://program.sonsuz.us/posts/firtinada-bile-goren-robotlar-otonom-araclarda-sensor-fuzyonu/"><![CDATA[<p>Güneşli bir günde yolu algılamak otonom araçlar için görece kolaydır. Ancak sis çöktüğünde, yağmur kamera görüntüsünü bozduğunda veya kar taneleri LiDAR ölçümlerinde hayalet noktalar oluşturduğunda işler değişir. Sensör füzyonu, farklı sensörlerin güçlü yanlarını birleştirerek aracın tek bir ölçüme körü körüne güvenmesini önler. Kısacası ekip çalışması yapar: Kamera renkleri söyler, radar mesafeyi ölçer, LiDAR çevrenin üç boyutlu haritasını çıkarır.</p>

<p><img src="/img/firtinada-bile-goren-83.svg" alt="firtinada-bile-goren-83" /></p>

<p>``</p>

<h2 id="tek-bir-sensör-neden-yetmez">Tek Bir Sensör Neden Yetmez?</h2>

<p>Her sensör çevreyi farklı bir fiziksel ilkeye göre gözlemler. Kameralar görünür ışığı, radar elektromanyetik dalgaların yansımasını, LiDAR ise lazer darbelerinin dönüş süresini kullanır. Bu çeşitlilik aynı zamanda hata çeşitliliği demektir. Kamera sisi yoğun bir duvar gibi görebilirken radar sisin içinden çalışmayı sürdürebilir. Buna karşılık radar, nesnenin bisiklet mi yoksa trafik levhası mı olduğunu kamera kadar başarılı sınıflandıramaz.</p>

<table>
  <thead>
    <tr>
      <th>Sensör</th>
      <th>Güçlü yönü</th>
      <th>Kötü havadaki sorunu</th>
      <th>Füzyondaki rolü</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Kamera</td>
      <td>Renk, şerit ve nesne sınıfı</td>
      <td>Sis, karanlık ve su damlaları</td>
      <td>Anlamsal bilgi sağlar</td>
    </tr>
    <tr>
      <td>LiDAR</td>
      <td>Hassas 3B geometri</td>
      <td>Yağmur ve karda sahte yansımalar</td>
      <td>Şekil ve konum üretir</td>
    </tr>
    <tr>
      <td>Radar</td>
      <td>Hız ve mesafe ölçümü</td>
      <td>Düşük açısal çözünürlük</td>
      <td>Zorlu havada kararlı ölçüm sağlar</td>
    </tr>
    <tr>
      <td>Ultrasonik</td>
      <td>Yakın mesafede ekonomiktir</td>
      <td>Rüzgâr ve yüzey yapısından etkilenir</td>
      <td>Park ve düşük hız desteği verir</td>
    </tr>
    <tr>
      <td>GNSS/IMU</td>
      <td>Araç konumu ve hareketi</td>
      <td>Tünel, yansıma ve sürüklenme</td>
      <td>Küresel ve göreli hareketi izler</td>
    </tr>
  </tbody>
</table>

<h2 id="güven-ağırlık-ve-olasılık">Güven, Ağırlık ve Olasılık</h2>

<p>Füzyonun temel fikri, bütün sensörlere eşit oy hakkı vermek değildir. Sistem, mevcut koşullara göre her ölçümün güvenilirliğini değerlendirir. Bir sensörün ölçümü $z_i$, güven ağırlığı $w_i$ ise basit bir birleşik tahmin şöyle yazılabilir:</p>

\[x = (w_1z_1 + w_2z_2 + ... + w_nz_n) / (w_1 + w_2 + ... + w_n)\]

<p>Yoğun siste kameranın $w$ değeri azaltılırken radarın ağırlığı artırılabilir. Daha gelişmiş sistemlerde Kalman filtresi, genişletilmiş Kalman filtresi, parçacık filtresi veya Bayesçi çıkarım kullanılır. Bayes yaklaşımı, yeni bir ölçüm geldiğinde önceki inancı günceller:</p>

\[P(x\vert z) = P(z\vert x)P(x) / P(z)\]

<p>Burada $P(x)$ önceki tahmini, $P(z\vert x)$ ölçümün bu tahmin altında görülme olasılığını, $P(x\vert z)$ ise güncellenmiş sonucu temsil eder. Böylece araç, “Radar önümde bir şey olduğunu söylüyor ama kamera emin değil” durumunu matematiksel olarak çözebilir.</p>

<h2 id="basit-bir-uyarlanabilir-füzyon-örneği">Basit Bir Uyarlanabilir Füzyon Örneği</h2>

<p>Aşağıdaki Python kodu, hava durumuna göre kamera ve radar ölçümlerinin ağırlıklarını değiştirir. Gerçek araçlarda belirsizlik kovaryans matrisleri ve zaman senkronizasyonu kullanılır; bu örnek temel mantığı görünür kılar.</p>

<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">def</span> <span class="nf">fuse_distance</span><span class="p">(</span><span class="n">camera</span><span class="p">,</span> <span class="n">radar</span><span class="p">,</span> <span class="n">weather</span><span class="p">):</span>
    <span class="c1"># Açık havada kamera daha güvenilirken siste radar öne çıkar.
</span>    <span class="n">weights</span> <span class="o">=</span> <span class="p">{</span>
        <span class="sh">"</span><span class="s">clear</span><span class="sh">"</span><span class="p">:</span> <span class="p">(</span><span class="mf">0.6</span><span class="p">,</span> <span class="mf">0.4</span><span class="p">),</span>
        <span class="sh">"</span><span class="s">rain</span><span class="sh">"</span><span class="p">:</span>  <span class="p">(</span><span class="mf">0.3</span><span class="p">,</span> <span class="mf">0.7</span><span class="p">),</span>
        <span class="sh">"</span><span class="s">fog</span><span class="sh">"</span><span class="p">:</span>   <span class="p">(</span><span class="mf">0.15</span><span class="p">,</span> <span class="mf">0.85</span><span class="p">)</span>
    <span class="p">}</span>

    <span class="n">camera_w</span><span class="p">,</span> <span class="n">radar_w</span> <span class="o">=</span> <span class="n">weights</span><span class="p">.</span><span class="nf">get</span><span class="p">(</span><span class="n">weather</span><span class="p">,</span> <span class="p">(</span><span class="mf">0.5</span><span class="p">,</span> <span class="mf">0.5</span><span class="p">))</span>
    <span class="k">return</span> <span class="n">camera</span> <span class="o">*</span> <span class="n">camera_w</span> <span class="o">+</span> <span class="n">radar</span> <span class="o">*</span> <span class="n">radar_w</span>

<span class="n">result</span> <span class="o">=</span> <span class="nf">fuse_distance</span><span class="p">(</span><span class="n">camera</span><span class="o">=</span><span class="mf">24.0</span><span class="p">,</span> <span class="n">radar</span><span class="o">=</span><span class="mf">21.5</span><span class="p">,</span> <span class="n">weather</span><span class="o">=</span><span class="sh">"</span><span class="s">fog</span><span class="sh">"</span><span class="p">)</span>
<span class="nf">print</span><span class="p">(</span><span class="sa">f</span><span class="sh">"</span><span class="s">Tahmini mesafe: </span><span class="si">{</span><span class="n">result</span><span class="si">:</span><span class="p">.</span><span class="mi">2</span><span class="n">f</span><span class="si">}</span><span class="s"> metre</span><span class="sh">"</span><span class="p">)</span>
</code></pre></div></div>

<p>Burada sisli havada radar ölçümü sonuca daha fazla yön verir. Fakat yalnızca hava etiketi kullanmak yeterli değildir. Kamera kontrastı, LiDAR dönüş yoğunluğu, radar sinyal-gürültü oranı ve sensör sıcaklığı gibi anlık kalite göstergeleri de ağırlıkları dinamik biçimde değiştirmelidir.</p>

<h2 id="füzyonun-gizli-kahramanları">Füzyonun Gizli Kahramanları</h2>

<p>Başarılı bir sistem için sensörlerin kalibrasyonu ve zaman eşlemesi kritiktir. Milisaniyelik gecikme, hızlı hareket eden bir aracın farklı konumlarda algılanmasına yol açabilir. Ayrıca sensörler ortak koordinat sistemine dönüştürülmelidir. Aksi hâlde radarın “ön sağ” dediği nesne, kamera görüntüsünde yanlış piksele bağlanır.</p>

<p>Sonuç olarak sensör füzyonu kötü havayı ortadan kaldırmaz; belirsizliği yönetilebilir hâle getirir. Güvenilir otonomi, en parlak sensöre sahip olmak değil, hangi sensöre ne zaman güvenileceğini bilmektir. Robotik aracın süper gücü kusursuz görmek değil, şüphe etmeyi matematikle öğrenmektir.</p>]]></content><author><name>Sonsuz Us</name></author><category term="Bilgi" /><category term="robotik" /><category term="otonom araçlar" /><category term="sensör füzyonu" /><category term="lidar" /><category term="radar" /><category term="bilgisayarlı görü" /><category term="yapay zeka" /><summary type="html"><![CDATA[Güneşli bir günde yolu algılamak otonom araçlar için görece kolaydır. Ancak sis çöktüğünde, yağmur kamera görüntüsünü bozduğunda veya kar taneleri LiDAR ölçümlerinde hayalet noktalar oluşturduğunda işler değişir. Sensör füzyonu, farklı sensörlerin güçlü yanlarını birleştirerek aracın tek bir ölçüme körü körüne güvenmesini önler. Kısacası ekip çalışması yapar: Kamera renkleri söyler, radar mesafeyi ölçer, LiDAR çevrenin üç boyutlu haritasını çıkarır.]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://program.sonsuz.us/img/firtinada-bile-goren-83.png" /><media:content medium="image" url="https://program.sonsuz.us/img/firtinada-bile-goren-83.png" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">HRI Güvenliği: Robotlarla Teması Nasıl Daha Az Riskli Hâle Getiriyoruz?</title><link href="https://program.sonsuz.us/posts/hri-guvenligi-robotlarla-temasi-nasil-daha-az-riskli-hale-getiriyoruz/" rel="alternate" type="text/html" title="HRI Güvenliği: Robotlarla Teması Nasıl Daha Az Riskli Hâle Getiriyoruz?" /><published>2026-10-19T00:00:00+00:00</published><updated>2026-10-19T00:00:00+00:00</updated><id>https://program.sonsuz.us/posts/hri-guvenligi-robotlarla-temasi-nasil-daha-az-riskli-hale-getiriyoruz</id><content type="html" xml:base="https://program.sonsuz.us/posts/hri-guvenligi-robotlarla-temasi-nasil-daha-az-riskli-hale-getiriyoruz/"><![CDATA[<p>İnsanlarla aynı çalışma alanını paylaşan robotlar artık yalnızca bilim kurgu filmlerinde değil; fabrikalarda, hastanelerde ve laboratuvarlarda karşımıza çıkıyor. Ancak bir robotun nazikçe kahve uzatmasıyla kontrolsüz biçimde kolumuza çarpması arasında ciddi bir güvenlik farkı var. İnsan-robot etkileşimi, yani HRI güvenlik standartları, bu farkı şansa bırakmak yerine temas olasılığını, çarpışma enerjisini ve uygulanabilecek kuvveti sistematik olarak sınırlandırır.
``</p>

<h2 id="standartlar-neden-gereklidir">Standartlar neden gereklidir?</h2>

<p>Robot güvenliğinde temel yaklaşım, “Çarpışma olursa dururuz” demek değildir. Öncelikle tehlike belirlenir, risk tahmin edilir ve tasarım yoluyla azaltılır. ISO 12100 bu genel risk değerlendirme mantığını sunarken ISO 10218 endüstriyel robot sistemlerine ilişkin güvenlik şartlarını tanımlar. İş birliğine dayalı uygulamalarda kullanılan ISO/TS 15066 ise insan vücudunun farklı bölgeleri için temas, basınç ve kuvvet değerlendirmelerine rehberlik eder.</p>

<p>Standartların izlediği hiyerarşi kabaca şöyledir:</p>

<ol>
  <li>Tehlikeyi mümkünse tasarımdan kaldırmak.</li>
  <li>Hızı, kuvveti ve hareket alanını sınırlandırmak.</li>
  <li>Sensörler ve güvenlik fonksiyonları kullanmak.</li>
  <li>Kalan riskleri kullanıcıya bildirmek ve eğitim sağlamak.</li>
</ol>

<p>Buradaki önemli ayrıntı şudur: Üzerinde “cobot” etiketi bulunan bir robot kendiliğinden güvenli değildir. Robot, uç efektör, taşınan parça, çalışma hızı ve çevredeki yüzeyler birlikte değerlendirilmelidir. Yumuşak robot kolu sivri bir metal parça taşıyorsa güvenlik hikâyesinin kötü karakteri o parça olabilir.</p>

<h2 id="dört-temel-iş-birliği-yaklaşımı">Dört temel iş birliği yaklaşımı</h2>

<table>
  <thead>
    <tr>
      <th>Yaklaşım</th>
      <th>Çalışma mantığı</th>
      <th>Temas riskini azaltma yöntemi</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Güvenlik dereceli izlemeli duruş</td>
      <td>İnsan ortak alana girdiğinde robot durur</td>
      <td>Hareketli robotla teması önler</td>
    </tr>
    <tr>
      <td>Elle yönlendirme</td>
      <td>Kullanıcı robotu kontrollü biçimde hareket ettirir</td>
      <td>Hız ve hareket yetkisini sınırlar</td>
    </tr>
    <tr>
      <td>Hız ve mesafe izleme</td>
      <td>İnsan yaklaştıkça robot yavaşlar</td>
      <td>Çarpışmadan önce güvenli duruş sağlar</td>
    </tr>
    <tr>
      <td>Güç ve kuvvet sınırlama</td>
      <td>Temas algılandığında kuvvet sınırlandırılır</td>
      <td>Yaralanma şiddetini azaltır</td>
    </tr>
  </tbody>
</table>

<p><img src="/img/hri-guvenligi-robotlarla-97.svg" alt="hri-guvenligi-robotlarla-97" /></p>

<p>Hız ve mesafe izleme yaklaşımında robotun yalnızca mevcut konumu değil, durmak için ihtiyaç duyduğu alan da önemlidir. Basitleştirilmiş durma mesafesi şöyle düşünülebilir:</p>

\[S = vT + \frac{v^2}{2a} + C\]

<p>Burada $v$ robot hızı, $T$ algılama ve kontrol gecikmesi, $a$ frenleme ivmesi, $C$ ise sensör belirsizliği ve güvenlik payıdır. Hız iki katına çıktığında frenleme bölümünün dört kat büyümesi, hızlı robotların neden daha geniş güvenlik mesafesine ihtiyaç duyduğunu açıklar.</p>

<p>Çarpışmada taşınan enerji de önemlidir:</p>

\[E_k = \frac{1}{2}mv^2\]

<p>Etkili kütle $m$ aynı kalsa bile hızdaki küçük artışlar temas enerjisini belirgin biçimde yükseltir. Bu nedenle güvenlik sistemleri çoğu zaman insan yaklaştıkça hızı kademeli azaltır.</p>

<h2 id="basit-bir-hız-sınırlandırma-mantığı">Basit bir hız sınırlandırma mantığı</h2>

<p>Aşağıdaki örnek, ölçülen insan-robot mesafesine göre hız komutu üretir:</p>

<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">def</span> <span class="nf">guvenli_hiz</span><span class="p">(</span><span class="n">mesafe</span><span class="p">,</span> <span class="n">azami_hiz</span><span class="o">=</span><span class="mf">1.0</span><span class="p">):</span>
    <span class="k">if</span> <span class="n">mesafe</span> <span class="o">&lt;</span> <span class="mf">0.4</span><span class="p">:</span>
        <span class="k">return</span> <span class="mf">0.0</span>       <span class="c1"># Tehlikeli yakınlık: dur
</span>    <span class="k">if</span> <span class="n">mesafe</span> <span class="o">&lt;</span> <span class="mf">1.0</span><span class="p">:</span>
        <span class="k">return</span> <span class="n">azami_hiz</span> <span class="o">*</span> <span class="p">(</span><span class="n">mesafe</span> <span class="o">-</span> <span class="mf">0.4</span><span class="p">)</span> <span class="o">/</span> <span class="mf">0.6</span>
    <span class="k">return</span> <span class="n">azami_hiz</span>

<span class="n">robot_hizi</span> <span class="o">=</span> <span class="nf">guvenli_hiz</span><span class="p">(</span><span class="n">sensor_mesafesi</span><span class="p">)</span>
</code></pre></div></div>

<p>Bu kod öğretici bir modeldir; gerçek bir güvenlik fonksiyonu değildir. Endüstriyel uygulamalarda sıradan kamera, işletim sistemi veya Python betiği tek başına yeterli kabul edilmez. Güvenlik dereceli sensörler, yedekli kontrol kanalları, hata teşhisi ve ISO 13849 gibi standartlara göre doğrulanmış performans seviyeleri gerekir.</p>

<h2 id="temasın-türü-de-sonucu-değiştirir">Temasın türü de sonucu değiştirir</h2>

<p>Standartlar geçici temas ile sıkışmalı teması ayırır. Robotun çarpıp geri çekildiği geçici temas kısa sürebilir; insanın robot ile duvar arasında sıkıştığı yarı statik temas ise daha tehlikelidir. Ayrıca baş, boyun ve göğüs gibi bölgelerin toleransı kol veya elden farklıdır. Bu nedenle tek bir evrensel kuvvet sınırı kullanmak yerine vücut bölgesi, temas alanı, süre ve basınç birlikte incelenir.</p>

<p>Sonuç olarak HRI güvenliği, robota dev bir acil durdurma düğmesi takmaktan ibaret değildir. Güvenli tasarım; mekanik yapı, sensörler, yazılım, doğrulama testleri ve insan davranışının ortak ürünüdür. İyi uygulanmış standartlar teması tamamen yok etmeyebilir, fakat temasın oluşma ihtimalini ve gerçekleştiğinde vereceği zararı ölçülebilir biçimde azaltır.</p>]]></content><author><name>Sonsuz Us</name></author><category term="Bilgi" /><category term="robotik" /><category term="hri" /><category term="iş güvenliği" /><category term="iso standartları" /><category term="cobot" /><category term="risk analizi" /><summary type="html"><![CDATA[İnsanlarla aynı çalışma alanını paylaşan robotlar artık yalnızca bilim kurgu filmlerinde değil; fabrikalarda, hastanelerde ve laboratuvarlarda karşımıza çıkıyor. Ancak bir robotun nazikçe kahve uzatmasıyla kontrolsüz biçimde kolumuza çarpması arasında ciddi bir güvenlik farkı var. İnsan-robot etkileşimi, yani HRI güvenlik standartları, bu farkı şansa bırakmak yerine temas olasılığını, çarpışma enerjisini ve uygulanabilecek kuvveti sistematik olarak sınırlandırır.]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://program.sonsuz.us/img/hri-guvenligi-robotlarla-97.png" /><media:content medium="image" url="https://program.sonsuz.us/img/hri-guvenligi-robotlarla-97.png" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">İki Teker Üstünde Dans: Ters Sarkaçla Kendi Kendini Dengeleyen Robot</title><link href="https://program.sonsuz.us/posts/iki-teker-ustunde-dans-ters-sarkacla-kendi-kendini-dengeleyen-robot/" rel="alternate" type="text/html" title="İki Teker Üstünde Dans: Ters Sarkaçla Kendi Kendini Dengeleyen Robot" /><published>2026-10-19T00:00:00+00:00</published><updated>2026-10-19T00:00:00+00:00</updated><id>https://program.sonsuz.us/posts/iki-teker-ustunde-dans-ters-sarkacla-kendi-kendini-dengeleyen-robot</id><content type="html" xml:base="https://program.sonsuz.us/posts/iki-teker-ustunde-dans-ters-sarkacla-kendi-kendini-dengeleyen-robot/"><![CDATA[<p><img src="/img/iki-teker-ustunde-21.svg" alt="iki-teker-ustunde-21" /></p>

<p>İki tekerlekli bir robotun devrilmeden ayakta kalması ilk bakışta sihir gibi görünür. Oysa robotun yaptığı şey, düşmeye başladığı yönü sürekli ölçmek ve tekerleklerini aynı yöne sürerek gövdesini yeniden ağırlık merkezinin altına taşımaktır. Bu hızlı geri besleme döngüsü; mekanik, sensör füzyonu ve kontrol teorisinin eğlenceli bir birleşimidir.
``</p>
<h2 id="ters-sarkaç-mantığı">Ters sarkaç mantığı</h2>

<p>Normal bir sarkaç aşağı doğru asılıyken kararlıdır. Ters sarkaçta ise kütle, dönme noktasının üzerinde bulunur. Robotun gövdesi dik konumdan çok az uzaklaştığında yer çekimi onu daha da fazla yatırır. Bu nedenle sistem <strong>doğal olarak kararsızdır</strong>.</p>

<p>Robotun eğim açısını $theta$, dik konumu da $theta = 0$ kabul edelim. Basitleştirilmiş açısal hareket yaklaşık olarak şöyle düşünülebilir:</p>

\[I theta'' = m g l sin(theta) - u\]

<p>Burada $I$ eylemsizlik momenti, $m$ gövde kütlesi, $g$ yer çekimi ivmesi, $l$ ağırlık merkezinin tekerlek eksenine uzaklığı ve $u$ motorların oluşturduğu düzeltici etkidir. Küçük açılarda $sin(theta) yaklaşık theta$ olduğundan model doğrusal hâle getirilebilir. Kontrolcünün görevi, uygun $u$ değerini üreterek açıyı sıfıra yaklaştırmaktır.</p>

<h2 id="robot-eğildiğini-nasıl-anlar">Robot eğildiğini nasıl anlar?</h2>

<p>MPU6050 gibi bir IMU, ivmeölçer ve jiroskop içerir. İvmeölçer uzun vadede güvenilir bir açı tahmini sunar fakat titreşimlerden etkilenir. Jiroskop hızlı hareketleri iyi ölçer ancak zamanla sürüklenir. İki ölçüm tamamlayıcı filtreyle birleştirilebilir:</p>

\[theta = alpha(theta_{eski} + omega Delta t) + (1-alpha)theta_{ivme}\]

<table>
  <thead>
    <tr>
      <th>Sensör</th>
      <th>Güçlü yanı</th>
      <th>Zayıf yanı</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>İvmeölçer</td>
      <td>Mutlak eğimi tahmin eder</td>
      <td>Motor titreşimlerine duyarlıdır</td>
    </tr>
    <tr>
      <td>Jiroskop</td>
      <td>Hızlı değişimleri yakalar</td>
      <td>Zamanla sürüklenir</td>
    </tr>
    <tr>
      <td>Birleşik tahmin</td>
      <td>Daha kararlı sonuç verir</td>
      <td>Doğru örnekleme süresi ister</td>
    </tr>
  </tbody>
</table>

<p>$alpha$ çoğunlukla 0,95 ile 0,99 arasında seçilir. Böylece kısa vadede jiroskopa, uzun vadede ivmeölçere güvenilir.</p>

<h2 id="pid-kontrolü">PID kontrolü</h2>

<p>En yaygın yaklaşım PID kontrolcüdür. Hata, hedef açı ile ölçülen açı arasındaki farktır:</p>

\[e(t) = theta_{hedef} - theta(t)\]

<p>Kontrol çıkışı ise üç davranışı birleştirir:</p>

\[u(t) = K_p e(t) + K_i integral(e(t)) + K_d de(t)/dt\]

<table>
  <thead>
    <tr>
      <th>Terim</th>
      <th>Görevi</th>
      <th>Fazla olursa</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>P</td>
      <td>Eğime anında karşı koyar</td>
      <td>Robot sallanır</td>
    </tr>
    <tr>
      <td>I</td>
      <td>Kalıcı açı hatasını giderir</td>
      <td>Yavaş salınım ve taşma oluşur</td>
    </tr>
    <tr>
      <td>D</td>
      <td>Hızlı değişimi frenler</td>
      <td>Gürültü büyütülür</td>
    </tr>
  </tbody>
</table>

<p>Aşağıdaki Arduino tarzı örnek, filtrelenmiş açı üzerinden temel kontrol çıkışını hesaplar:</p>

<div class="language-cpp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kt">float</span> <span class="n">kp</span> <span class="o">=</span> <span class="mf">28.0</span><span class="p">,</span> <span class="n">ki</span> <span class="o">=</span> <span class="mf">0.8</span><span class="p">,</span> <span class="n">kd</span> <span class="o">=</span> <span class="mf">1.4</span><span class="p">;</span>
<span class="kt">float</span> <span class="n">integral</span> <span class="o">=</span> <span class="mi">0</span><span class="p">,</span> <span class="n">previousError</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>

<span class="kt">float</span> <span class="nf">updateController</span><span class="p">(</span><span class="kt">float</span> <span class="n">angle</span><span class="p">,</span> <span class="kt">float</span> <span class="n">dt</span><span class="p">)</span> <span class="p">{</span>
  <span class="kt">float</span> <span class="n">targetAngle</span> <span class="o">=</span> <span class="mf">0.0</span><span class="p">;</span>
  <span class="kt">float</span> <span class="n">error</span> <span class="o">=</span> <span class="n">targetAngle</span> <span class="o">-</span> <span class="n">angle</span><span class="p">;</span>

  <span class="n">integral</span> <span class="o">+=</span> <span class="n">error</span> <span class="o">*</span> <span class="n">dt</span><span class="p">;</span>
  <span class="n">integral</span> <span class="o">=</span> <span class="n">constrain</span><span class="p">(</span><span class="n">integral</span><span class="p">,</span> <span class="o">-</span><span class="mf">20.0</span><span class="p">,</span> <span class="mf">20.0</span><span class="p">);</span>

  <span class="kt">float</span> <span class="n">derivative</span> <span class="o">=</span> <span class="p">(</span><span class="n">error</span> <span class="o">-</span> <span class="n">previousError</span><span class="p">)</span> <span class="o">/</span> <span class="n">dt</span><span class="p">;</span>
  <span class="n">previousError</span> <span class="o">=</span> <span class="n">error</span><span class="p">;</span>

  <span class="kt">float</span> <span class="n">output</span> <span class="o">=</span> <span class="n">kp</span> <span class="o">*</span> <span class="n">error</span> <span class="o">+</span> <span class="n">ki</span> <span class="o">*</span> <span class="n">integral</span> <span class="o">+</span> <span class="n">kd</span> <span class="o">*</span> <span class="n">derivative</span><span class="p">;</span>
  <span class="k">return</span> <span class="n">constrain</span><span class="p">(</span><span class="n">output</span><span class="p">,</span> <span class="o">-</span><span class="mf">255.0</span><span class="p">,</span> <span class="mf">255.0</span><span class="p">);</span>
<span class="p">}</span>
</code></pre></div></div>

<p>Fonksiyon, motor sürücüsüne gönderilecek yönlü PWM değerini üretir. İntegral sınırı, motorlar doygundayken hatanın kontrolsüz birikmesini önleyen <strong>anti-windup</strong> yöntemidir. Robot güvenlik açısını, örneğin 35 dereceyi aşarsa motorlar kapatılmalıdır.</p>

<h2 id="ayar-yaparken-izlenecek-yol">Ayar yaparken izlenecek yol</h2>

<p>Önce $K_i$ ve $K_d$ sıfırlanır. $K_p$, robot tepki verene kadar artırılır. Sürekli sallanma başladığında biraz azaltılır. Ardından $K_d$ eklenerek hareket sönümlenir. Son olarak küçük bir $K_i$, ağırlık dağılımından kaynaklanan kalıcı hatayı temizler.</p>

<p>Kontrol döngüsünün sabit aralıklarla, tercihen 200–500 Hz civarında çalışması önemlidir. Gevşek şasi, boşluklu dişliler, düşük torklu motorlar veya gecikmeli yazılım en iyi PID ayarını bile bozabilir. Başarılı bir dengeleme robotu yalnızca iyi kod değil; sağlam mekanik, temiz sensör verisi ve düzenli zamanlama ister. Kısacası robot düşmeyi engellemez; düşüşü saniyede yüzlerce kez ustaca yakalar.</p>]]></content><author><name>Sonsuz Us</name></author><category term="Proje" /><category term="robotik" /><category term="ters sarkaç" /><category term="pid kontrol" /><category term="arduino" /><category term="imu" /><category term="kontrol sistemleri" /><summary type="html"><![CDATA[İki tekerlekli bir robotun devrilmeden ayakta kalması ilk bakışta sihir gibi görünür. Oysa robotun yaptığı şey, düşmeye başladığı yönü sürekli ölçmek ve tekerleklerini aynı yöne sürerek gövdesini yeniden ağırlık merkezinin altına taşımaktır. Bu hızlı geri besleme döngüsü; mekanik, sensör füzyonu ve kontrol teorisinin eğlenceli bir birleşimidir.]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://program.sonsuz.us/img/iki-teker-ustunde-21.png" /><media:content medium="image" url="https://program.sonsuz.us/img/iki-teker-ustunde-21.png" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">Java Veri Tipleri, Değişkenler ve Diziler: Tip Güvenliğine Sağlam Bir Başlangıç</title><link href="https://program.sonsuz.us/posts/java-veri-tipleri-degiskenler-ve-diziler-tip-guvenligine-saglam-bir-baslangic/" rel="alternate" type="text/html" title="Java Veri Tipleri, Değişkenler ve Diziler: Tip Güvenliğine Sağlam Bir Başlangıç" /><published>2026-10-19T00:00:00+00:00</published><updated>2026-10-19T00:00:00+00:00</updated><id>https://program.sonsuz.us/posts/java-veri-tipleri-degiskenler-ve-diziler-tip-guvenligine-saglam-bir-baslangic</id><content type="html" xml:base="https://program.sonsuz.us/posts/java-veri-tipleri-degiskenler-ve-diziler-tip-guvenligine-saglam-bir-baslangic/"><![CDATA[<p>Java’da her verinin bir kimliği vardır: tipi! Bir değişkenin sayı mı, karakter mi yoksa mantıksal değer mi taşıyacağı önceden belirtilir. Bu yaklaşım başlangıçta biraz katı görünse de hataların daha kod çalışmadan yakalanmasını sağlar. Gelin Java’nın tip güvenliği dünyasına, değişkenlerine ve aynı türden verileri düzenleyen dizilerine yakından bakalım.
``</p>

<h2 id="java-neden-katı-tipli-bir-dildir">Java Neden Katı Tipli Bir Dildir?</h2>

<p>Java, <strong>statik ve güçlü tipli</strong> bir programlama dilidir. Statik tipleme, değişken tiplerinin derleme aşamasında bilinmesi anlamına gelir. Güçlü tipleme ise uyumsuz tipler arasında kontrolsüz işlem yapılmasını engeller.</p>

<p>Örneğin aşağıdaki kod derlenemez:</p>

<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kt">int</span> <span class="n">yas</span> <span class="o">=</span> <span class="mi">25</span><span class="o">;</span>
<span class="n">yas</span> <span class="o">=</span> <span class="s">"yirmi beş"</span><span class="o">;</span> <span class="c1">// Hata: String, int değişkenine atanamaz</span>
</code></pre></div></div>

<p>Derleyicinin bu itirazı aslında dostça bir uyarıdır. Aksi hâlde program, çalışma sırasında beklenmedik sonuçlarla karşılaşabilirdi. Tip güvenliği sayesinde bir değişkenin hangi değerleri taşıyabileceği ve üzerinde hangi işlemlerin uygulanabileceği bellidir.</p>

<h2 id="i̇lkel-veri-tipleri">İlkel Veri Tipleri</h2>

<p>Java’da doğrudan değer saklayan sekiz adet <strong>primitive</strong>, yani ilkel veri tipi bulunur. Bunlar nesne değildir ve genellikle hızlı, düşük maliyetli veri işlemleri için kullanılır.</p>

<table>
  <thead>
    <tr>
      <th>Tip</th>
      <th style="text-align: right">Boyut</th>
      <th>Örnek</th>
      <th>Kullanım amacı</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">byte</code></td>
      <td style="text-align: right">8 bit</td>
      <td><code class="language-plaintext highlighter-rouge">120</code></td>
      <td>Küçük tam sayılar</td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">short</code></td>
      <td style="text-align: right">16 bit</td>
      <td><code class="language-plaintext highlighter-rouge">30000</code></td>
      <td>Orta aralıklı tam sayılar</td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">int</code></td>
      <td style="text-align: right">32 bit</td>
      <td><code class="language-plaintext highlighter-rouge">42</code></td>
      <td>Genel tam sayı işlemleri</td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">long</code></td>
      <td style="text-align: right">64 bit</td>
      <td><code class="language-plaintext highlighter-rouge">9000L</code></td>
      <td>Büyük tam sayılar</td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">float</code></td>
      <td style="text-align: right">32 bit</td>
      <td><code class="language-plaintext highlighter-rouge">3.14F</code></td>
      <td>Düşük hassasiyetli ondalık sayılar</td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">double</code></td>
      <td style="text-align: right">64 bit</td>
      <td><code class="language-plaintext highlighter-rouge">3.14159</code></td>
      <td>Yüksek hassasiyetli ondalık sayılar</td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">char</code></td>
      <td style="text-align: right">16 bit</td>
      <td><code class="language-plaintext highlighter-rouge">'A'</code></td>
      <td>Tek bir Unicode karakteri</td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">boolean</code></td>
      <td style="text-align: right">JVM’e bağlı</td>
      <td><code class="language-plaintext highlighter-rouge">true</code></td>
      <td>Doğru veya yanlış durumu</td>
    </tr>
  </tbody>
</table>

<p><img src="/img/java-veri-tipleri-59.svg" alt="java-veri-tipleri-59" /></p>

<p>$n$ bitlik işaretli bir tam sayının teorik değer aralığı şu şekilde hesaplanır:</p>

\[-2^{n-1} \leq x \leq 2^{n-1}-1\]

<p>Dolayısıyla 8 bitlik <code class="language-plaintext highlighter-rouge">byte</code>, $-128$ ile $127$ arasında değer alabilir. Daha büyük bir değer atamaya çalışmak derleme hatasına neden olur.</p>

<h2 id="değişken-tanımlama-ve-tür-dönüşümü">Değişken Tanımlama ve Tür Dönüşümü</h2>

<p>Bir değişken; tip, isim ve isteğe bağlı başlangıç değerinden oluşur:</p>

<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kt">int</span> <span class="n">ogrenciSayisi</span> <span class="o">=</span> <span class="mi">24</span><span class="o">;</span>
<span class="kt">double</span> <span class="n">sicaklik</span> <span class="o">=</span> <span class="mf">21.5</span><span class="o">;</span>
<span class="kt">char</span> <span class="n">seviye</span> <span class="o">=</span> <span class="sc">'A'</span><span class="o">;</span>
<span class="kt">boolean</span> <span class="n">aktifMi</span> <span class="o">=</span> <span class="kc">true</span><span class="o">;</span>
</code></pre></div></div>

<p>Küçük kapsamlı bir tipten daha geniş kapsamlı tipe geçiş çoğunlukla otomatik yapılır. Buna <strong>widening conversion</strong> denir. Tersi yönde ise veri kaybı oluşabileceği için açık dönüşüm gerekir.</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">95</span><span class="o">;</span>
<span class="kt">double</span> <span class="n">ondalikliPuan</span> <span class="o">=</span> <span class="n">puan</span><span class="o">;</span> <span class="c1">// Otomatik dönüşüm</span>

<span class="kt">double</span> <span class="n">fiyat</span> <span class="o">=</span> <span class="mf">49.99</span><span class="o">;</span>
<span class="kt">int</span> <span class="n">tamFiyat</span> <span class="o">=</span> <span class="o">(</span><span class="kt">int</span><span class="o">)</span> <span class="n">fiyat</span><span class="o">;</span>   <span class="c1">// Açık dönüşüm: sonuç 49</span>
</code></pre></div></div>

<table>
  <thead>
    <tr>
      <th>Dönüşüm</th>
      <th>Örnek</th>
      <th>Risk</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Genişletme</td>
      <td><code class="language-plaintext highlighter-rouge">int</code> → <code class="language-plaintext highlighter-rouge">double</code></td>
      <td>Genellikle güvenli</td>
    </tr>
    <tr>
      <td>Daraltma</td>
      <td><code class="language-plaintext highlighter-rouge">double</code> → <code class="language-plaintext highlighter-rouge">int</code></td>
      <td>Hassasiyet veya veri kaybı</td>
    </tr>
  </tbody>
</table>

<h2 id="diziler-aynı-tipten-verilerin-takımı">Diziler: Aynı Tipten Verilerin Takımı</h2>

<p>Dizi, aynı veri tipindeki birden fazla değeri sabit uzunlukta saklar. Java dizileri nesnedir; ancak içlerinde ilkel değerler veya nesne referansları bulunabilir.</p>

<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kt">int</span><span class="o">[]</span> <span class="n">notlar</span> <span class="o">=</span> <span class="o">{</span><span class="mi">85</span><span class="o">,</span> <span class="mi">90</span><span class="o">,</span> <span class="mi">72</span><span class="o">,</span> <span class="mi">100</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">notlar</span><span class="o">[</span><span class="mi">0</span><span class="o">]);</span> <span class="c1">// 85</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">notlar</span><span class="o">.</span><span class="na">length</span><span class="o">);</span> <span class="c1">// 4</span>
</code></pre></div></div>

<p>Dizi indeksleri sıfırdan başlar. Uzunluğu $n$ olan bir dizinin geçerli indeks aralığı $0$ ile $n-1$ arasındadır. Bu sınırın dışına çıkılması <code class="language-plaintext highlighter-rouge">ArrayIndexOutOfBoundsException</code> üretir.</p>

<p>Diziler sonradan da oluşturulabilir:</p>

<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nc">String</span><span class="o">[]</span> <span class="n">diller</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">String</span><span class="o">[</span><span class="mi">3</span><span class="o">];</span>
<span class="n">diller</span><span class="o">[</span><span class="mi">0</span><span class="o">]</span> <span class="o">=</span> <span class="s">"Java"</span><span class="o">;</span>
<span class="n">diller</span><span class="o">[</span><span class="mi">1</span><span class="o">]</span> <span class="o">=</span> <span class="s">"Kotlin"</span><span class="o">;</span>
<span class="n">diller</span><span class="o">[</span><span class="mi">2</span><span class="o">]</span> <span class="o">=</span> <span class="s">"Python"</span><span class="o">;</span>

<span class="k">for</span> <span class="o">(</span><span class="nc">String</span> <span class="n">dil</span> <span class="o">:</span> <span class="n">diller</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">dil</span><span class="o">);</span>
<span class="o">}</span>
</code></pre></div></div>

<p>Buradaki geliştirilmiş <code class="language-plaintext highlighter-rouge">for</code> döngüsü, indeks yönetmeden her elemanı sırayla okur. Dizinin uzunluğu oluşturulduktan sonra değişmez; dinamik boyut gerekiyorsa <code class="language-plaintext highlighter-rouge">ArrayList</code> tercih edilir.</p>

<p>Sonuç olarak Java’nın katı tip sistemi, programcıyı kısıtlamak için değil güvenilir kod üretmeye yönlendirmek için vardır. Doğru veri tipini seçmek belleği ve niyeti netleştirirken diziler, benzer verileri düzenli biçimde yönetmenin temelini oluşturur.</p>]]></content><author><name>Sonsuz Us</name></author><category term="Bilgi" /><category term="java" /><category term="veri tipleri" /><category term="değişkenler" /><category term="diziler" /><category term="tip güvenliği" /><category term="programlama" /><summary type="html"><![CDATA[Java’da her verinin bir kimliği vardır: tipi! Bir değişkenin sayı mı, karakter mi yoksa mantıksal değer mi taşıyacağı önceden belirtilir. Bu yaklaşım başlangıçta biraz katı görünse de hataların daha kod çalışmadan yakalanmasını sağlar. Gelin Java’nın tip güvenliği dünyasına, değişkenlerine ve aynı türden verileri düzenleyen dizilerine yakından bakalım.]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://program.sonsuz.us/img/java-veri-tipleri-59.png" /><media:content medium="image" url="https://program.sonsuz.us/img/java-veri-tipleri-59.png" xmlns:media="http://search.yahoo.com/mrss/" /></entry></feed>