C'de pointer aritmetiği nasıl çalışır? ptr + 1 ifadesi adresi kaç byte ilerletir?
Cevap
Pointer'a bir tamsayı eklemek adresi byte olarak değil, işaret ettiği tipin boyutu kadar ilerletir: ptr + n adresi n * sizeof(*ptr) byte kaydırır.
uint8_t a8[4];
uint32_t a32[4];
uint8_t *p8 = a8; /* 0x2000 varsayalım */
uint32_t *p32 = a32; /* 0x3000 varsayalım */
p8 + 1; /* 0x2001 */
p32 + 1; /* 0x3004 */
/* Dizi erişimi aslında pointer aritmetiğidir */
a32[2] == *(a32 + 2);
/* İki pointer farkı eleman sayısını verir (ptrdiff_t) */
ptrdiff_t n = &a32[3] - &a32[0]; /* 3 */Gömülü sistemlerde tipik kullanım
/* Bellek eşlemeli register erişimi */
#define GPIOA_BASE 0x40020000UL
#define GPIOA_ODR (*(volatile uint32_t *)(GPIOA_BASE + 0x14))
GPIOA_ODR |= (1U << 5); /* PA5 = 1 */Burada önce sayıya offset eklenir, sonra pointer'a cast edilir. Sırayı ters yapmak ((uint32_t *)GPIOA_BASE + 0x14) adresi 0x14 * 4 byte kaydırır; klasik bir hatadır.
Dikkat edilmesi gerekenler
void *üzerinde aritmetik standart C'de tanımsızdır (GCC uzantı olarak 1 byte kabul eder).- Dizi sınırının dışına çıkan pointer (sondan bir sonrası hariç) undefined behavior'dır.
- Farklı tipe cast edip okumak strict aliasing kuralını ihlal edebilir; byte bazlı erişim için
uint8_t *veyamemcpykullanın. - Hizalanmamış adresten
uint32_tokumak Cortex-M0 gibi çekirdeklerde HardFault üretir. - Donanım register'ları için pointer mutlaka
volatileolmalıdır.
İlgili C Programlama soruları
- C dilinde volatile anahtar kelimesi ne işe yarar?
- Bir yazmaçtaki belirli bir biti set, clear ve toggle eden C kodunu yazın.
- Stack ile heap arasındaki fark nedir? Gömülü sistemlerde dinamik bellek kullanımından neden kaçınılır?
- Endianness nedir? Little-endian ile big-endian farkı nedir?
- Bit field nedir? Donanım register'larına erişimde bit field mi yoksa bit maskesi mi kullanılmalı?
- Fonksiyon pointer'ları ve callback tabloları gömülü sistemlerde nasıl kullanılır? Bir state machine örneği verin.
Bu konuda başka bir soru biliyor musun?
Mülakatta karşılaştığın soruları ekle, onaylandıktan sonra yayına alınsın.