Bence bir şey diğer cevaplar tarafından kaçırılıyor.
Evet, p[i]
tanım gereği eşdeğerdir *(p+i)
(eklenme değişmeli olduğu için) eşdeğerdir *(i+p)
, (yine []
operatörün tanımı ile ) eşdeğerdiri[p]
.
(Ve array[i]
, dizi adı örtük olarak dizinin ilk öğesine bir işaretçi olarak dönüştürülür.)
Ancak, eklemenin değişebilirliği bu durumda çok açık değildir.
Her iki işlenen de aynı türdeyse veya ortak bir türe yükseltilen farklı sayısal türlerde olduğunda, değişebilirlik tam anlamıyla mantıklıdır: x + y == y + x
.
Ancak bu durumda, özellikle bir işlenenin bir işaretçi ve diğerinin bir tam sayı olduğu işaretçi aritmetiğinden bahsediyoruz. (Tamsayı + tamsayı farklı bir işlemdir ve işaretçi + işaretçi saçmalıktır.)
C standardının +
operatörün tanımı ( N1570 6.5.6):
Ek olarak, her iki işlenen de aritmetik tipe sahip olmalı ya da bir işlenen tam bir nesne tipine işaretçi ve diğeri de tamsayı tipine sahip olmalıdır.
Kolayca söyleyebileceği gibi:
Ek olarak, her iki işlenen de aritmetik tipe veya sol
işlenen tam nesne tipine bir işaretçi ve sağ işlenen
tamsayı tipine sahip olmalıdır.
bu durumda hem i + p
ve i[p]
yasadışı olurdu.
C ++ terimleriyle, +
gevşek bir şekilde şu şekilde tanımlanabilecek iki aşırı yüklenmiş işleç setimiz var:
pointer operator+(pointer p, integer i);
ve
pointer operator+(integer i, pointer p);
sadece birincisi gerçekten gerekli.
Öyleyse neden bu şekilde?
C ++, bu tanımı B'den alan (dizi indekslemesinin değişebilirliği açıkça 1972 Kullanıcı Referansı B'de belirtilmiştir ) C'den devralmıştır , bu da onu BCPL'den (1967 tarihli manuel) almıştır; önceki diller (CPL? Algol?).
Bu nedenle dizi indekslemesinin toplama açısından tanımlandığı ve eklemenin, bir işaretçi ve bir tamsayı bile, değişmeli olduğu fikri, C'nin ata dillerine onlarca yıl öncesine dayanır.
Bu diller, modern C'den çok daha az güçlü yazılmıştır. Özellikle, işaretçiler ve tamsayılar arasındaki ayrım genellikle göz ardı edildi. (Erken C programcıları, bazen unsigned
anahtar sözcük dile eklenmeden önce işaretçileri işaretsiz tamsayılar olarak kullandılar .) Bu nedenle, ekleri değişmez yapma fikri, çünkü işlenenlerin farklı türlerde olması, muhtemelen bu dillerin tasarımcılarına gerçekleşmezdi. Bir kullanıcı iki "şey" eklemek isterse, bu "şeyler" tamsayı, işaretçi veya başka bir şey olsun, bunu önlemek dile bağlı değildir.
Yıllar geçtikçe, bu kuraldaki herhangi bir değişiklik mevcut kodu ihlal ederdi (1989 ANSI C standardı iyi bir fırsat olabilir).
İşaretçiyi sola ve sağa tamsayıyı koymayı gerektirecek şekilde C ve / veya C ++ 'ı değiştirmek varolan bazı kodları kırabilir, ancak gerçek ifade gücü kaybı olmaz.
Şimdi de aynı şeye sahibiz arr[3]
ve 3[arr]
anlamıyoruz, ancak ikinci form asla IOCCC dışında görünmemelidir .