ProgramlamaGömülü C Mühendisi

C dilinde bit düzeyindeki operatörler (&, |, ^, ~, <<, >>) nasıl çalışır? Farklı uzunlukta ve işaretli tiplerle çalışırken bunların özelliği nedir ve geliştiricilerin kullanımında yaptığı yaygın hatalar nelerdir?

Hintsage yapay zeka asistanı ile mülakatları geçin

Cevap.

Bit düzeyindeki operatörler, tam sayısal tiplerin bireysel bitlerini yönetir:

  • & — bit düzeyinde VE
  • | — bit düzeyinde VEYA
  • ^ — bit düzeyinde özel VEYA
  • ~ — bit düzeyinde DEĞİL
  • << — sola kaydırma
  • >> — sağa kaydırma

Özellikler:

  • Operatörler yalnızca tam sayısal tiplerle (int, unsigned int, vb.) çalışır.
  • İşaretli sayılar (signed) sağa kaydırma (>>) işlemlerinde aritmetik veya mantıksal kaydırma üretebilir — bu derleyiciye bağlıdır.
  • Bir değişkenin bit sayısını aşan kaydırmalarda belirsiz bir davranış ortaya çıkar.
  • Güvenilir çalışma için genellikle unsigned tipleri tercih edilir, böylece işaret genişlemesinden kaçınılır.

Örnek:

unsigned int flags = 0; flags |= 0x1; // 0. biti ayarlamak flags &= ~0x2; // 1. biti sıfırlamak if ((flags & 0x4) != 0) { /* ... */ } // 2. biti kontrol etmek

Hileli Soru.

İşaretli signed int ve işareti olmayan unsigned int için sağa kaydırma (>>) işlemi nasıl farklılık gösterir?

Sıkça Yanlış Cevap: Sağa kaydırmanın her zaman solda sıfırlar eklediğini, işarete bakılmaksızın varsayıyorlar.

Doğru Cevap: unsigned int için sağa kaydırma (>>) her zaman sıfırlar ekler. signed int için ise ya işareti (negatif bir sayıysa birler), ya da sıfırlar eklenir — bu derleyici uygulamasına (mimari ve C standardı kuralları) bağlıdır.

Örnek:

signed int a = -8; unsigned int b = (unsigned int)a; printf("%d ", a >> 1); printf("%u ", b >> 1);

İlk durumda sonuç derleyiciye bağlıdır; ikinci durumda her zaman sıfırlarla mantıksal bir kaydırma olacaktır.

Konunun inceliklerini bilmemekten kaynaklanan gerçek hata örnekleri.


Hikaye

Protokol işleme kodunda, sinyal bayrakları char tipinde saklanıyordu. Programcı, 8 bit sağa kaydırmayı (flag << 8) uyguladı; bu, taşma ve tip yükseltme kuralları nedeniyle tüm verilerin kaybına sebep oldu — result her zaman sıfır kalıyordu.


Hikaye

Ağ protokolünden veri okuma (big-endian). Baytları birleştirmek için bit düzeyindeki işlemlerin kullanılmasında unsigned türüne dönüşüm yapılmamıştı, bu da bazen yapı alanının okunmasında beklenmedik negatif değerlere neden oluyordu.


Hikaye

~ (bit düzeyinde DEĞİL) kullanılarak int türünde bir değerdeki bitlerin sıfırlanması (örneğin, ~0x80) 0x7F olarak kabul edildi, ancak gerçekte negatif bir sayı olan -129 elde edildi; bu da sonraki hesaplamalarda ve mantıksal kontrollerde hatalara yol açtı.