SORU
13 Kasım 2012, Salı


Neden oku (->) C operatör var mı?

Nokta (.) operatörü için bir üye bir yapı, sırasında ok operatörü (->) (C) için bir üye bir yapı olan tarafından başvurulan bir işaretçi soru.

İşaretçi, kendisi nokta operatörü ile erişilebilir olabilir herhangi bir üye (aslında bir numara, herhangi bir üyesi değil o yüzden sanal bellek bir yeri tarif sadece) yok. Yani, orada olurdu hiçbir belirsizlik eğer biz sadece tanımlı nokta operatörü otomatik olarak inceleyebilirsiniz işaretçi ise kullanılan bir işaretçi (bir bilgi olduğu bilinen derleyici derleme zamanında afaık).

Neden dil yaratıcıları işler daha da karmaşık görünüşte gereksiz bu operatör ekleyerek yapmaya karar verdi? Büyük tasarım kararı nedir?

CEVAP
13 Kasım 2012, Salı


. otomatik olarak işaretçi çözümlemesi var. iki soru olarak sorunuzu yorumlamak istiyorum: 1) neden -> varsa bile, ve 2) Hem soruların yanıtlarını tarihsel kökleri var.

Neden -> diye biri var mı?

Bir çok ilk sürümleri C dil (bunları size olarak bakın CRM için "C Referans El Kitabı"), operatör -> çok özel anlam, eş anlamlı değildir * . kombinasyonu

Dennis M. Ritchie - C Reference Manual

C dili CRM tarafından açıklanan pek çok bakımdan modern C den çok farklı olduğunu. CRM yapı üyeleri genel konsepti uygulanmaktadırofsetyani tüm isimleri tüm yapı üyeleri bağımsız küresel bir anlamı vardı (ve, bu nedenle, benzersiz olması gerekiyordu). Örneğin bildirebilirsiniz

struct S {
  int a;
  int b;
};

ve Adı a b ofset 2 etmez adı ise 0, (boyutu 2 int yazın ve hiçbir doldurma varsayarak) mahsup etmez. Dil çeviri birimindeki tüm yapılar tüm üyeleri ya da benzersiz adları veya aynı uzaklık değeri için durmak gerekli. E. g. aynı çeviri biriminde ayrıca bildirebilirsiniz

struct X {
  int a;
  int x;
};

ve o 20* *adını sürekli 0 ofset etmez beri TAMAM olurdu. Ama bu ek Bildirge

struct Y {
  int b;
  int a;
};

""22* *uzaklığı (0 ve 2 b ofset olarak. tanımlamak için çalıştı beri resmi olarak geçersiz olacaktır

Ve bu -> operatör devreye giriyor. Her yapı üye adı kendi kendine yeten kendi genel anlamı olduğu için, dili bu gibi ifadeler destekledi

int i = 5;
i->b = 42;  /* Write 42 into `int` at address 7 */
100->a = 0; /* Write 0 into `int` at address 100 */

İlk atama derleyici tarafından yorumlandı "5 ofset 2 Ekle ve sonuç bu adreste int değerine 42 ata adresi al" gibi. I. e. yukarıdaki 7 adrese int değer 42 atayın. -> Bu sol tarafındaki ifadenin türü umurunda bile değildir unutmayın. Sol tarafta rvalue sayısal bir adres, bir işaretçi veya bir tamsayı () olarak yorumlandı.

Hile bu tür * . kombinasyonu ile mümkün değildi. Yapabilirsin

(*i).b = 42;

*i zaten geçersiz bir ifadesi olduğu. ., işlenen üzerinde daha sıkı tür gereksinimlerini etkiler ayrı olduğu için * operatör,. Bu sınırlama, CRM çözüm için bir yeteneği sağlamak için tanıttı sol işlenen türünden bağımsız olarak -> operatör,.

Keith "" 7.1.8: . şartı rahatlama olarak yorumlar, -> * . kombinasyon arasındaki fark CRM atıfta ne olduğunu belirtildiği gibi ^em>E1 işaretçi türü olması şartı rahatlamanın dışında, 45 ** tam olarak ifade (*E1).MOS eşdeğerdir

Daha sonra,&C K R pek çok özellik aslında CRM açıklanan önemli ölçüde yaşanmıştır. Fikri "global ofset tanımlayıcı olarak yapı üyesi" tamamen kaldırıldı. Ve -> operatör işlevi * . karma işlevselliğini tam olarak aynı oldu.

Neden mi . işaretçiyi otomatik olarak başvuru yapabilir?

Tekrar, dil CRM sürüm . operatörün sol işlenen bir olması gerekiyordulvalue. O olduğunusadecebu gereksinimi işlenen ve yukarıda açıklandığı gibi -> farklı yapan da buydu) uyguladı. CRM unutmayındeğil. sol işlenen bir yapı türü olması gerekir. Sadece bir lvalue olmak gerekliherhangi birlvalue. Bu C CRM sürümü bu gibi bir kod yazabilirsin anlamına gelir

struct S { int a, b; };
struct T { float x, y, z; };

struct T c;
c.b = 55;

Bu durumda derleyici ki yazmak 55 bir int değer konumlandırılmış at bayt uzaklığı 2'de sürekli hafıza bloğu olarak bilinen c bile olsa yazın struct T yoktu alan adında b. Derleyici c gerçek türü hakkında hiç umurumda olmaz. Bu konuda tek şey c bir lvalue olmasıdır: yazılabilir bir çeşit bellek bloğu.

Şimdi Eğer bunu sen yaptıysan unutmayın

S *s;
...
s.b = 42;

kod geçerli kabul edilecek s da bir lvalue olduğundan) ve derleyici sadece veri yazma girişimiişaretçi s kendisibayt ofset 2. Söylemeye gerek yok, bu gibi şeyler kolayca bellek taşması neden olabilir, ama dili böyle şeylerle, kendisini ilgilendirmeyen.

I. e. bu sürümü dil önerilen fikir hakkında aşırı operatör . işaretçi türleri işe yaramaz: operatör . zaten çok özel anlamı ile kullanıldığında işaretçiler (lvalue işaretçileri veya herhangi bir lvalues). Çok garip bir işlevi oldu, hiç şüphesiz. Ama orada o anda oldu.

Elbette, bu garip işlevi olmayan çok güçlü bir nedeni karşı aşırı tanıtılması . operatör için işaretçiler (önerilen) yenilenmiş versiyonu C - K&R C Ama olmadı bitti. Belki o zaman desteklenmesi gerektiğini bazı eski kodu C CRM sürüm yazılmıştır

Bunu Paylaş:
  • Google+
  • E-Posta
Etiketler:

YORUMLAR

SPONSOR VİDEO

Rastgele Yazarlar

  • androidandme

    androidandme

    10 Mart 2009
  • BlackmillMusic

    BlackmillMus

    3 Kasım 2010
  • natescamp

    natescamp

    30 NİSAN 2009