Diziler ve Vektörler: Tanıtıcı Benzerlikler ve Farklılıklar [kapalı]


111

C ++ 'da bir dizi ve vektör arasındaki farklar nelerdir? Farklılıkların bir örneği kitaplıklar, sembolizm, yetenekler vb. Olabilir.

Dizi

Diziler, belirli bir türden belirli sayıda öğe içerir. Derleyicinin program derlendiğinde gerekli miktarda alanı ayırabilmesi için, dizinin tanımlandığında içereceği öğelerin türünü ve sayısını belirtmeniz gerekir. Derleyici, program derlendiğinde bu değeri belirleyebilmelidir. Bir dizi tanımlandıktan sonra, dizinin belirli öğelerine erişmek için dizinin tanımlayıcısını bir dizinle birlikte kullanırsınız. [...] diziler sıfır dizinlidir; yani, ilk eleman 0 dizinindedir. Bu indeksleme şeması, C ++ 'da işaretçiler ve diziler arasındaki yakın ilişkinin ve dilin işaretçi aritmetiği için tanımladığı kuralların göstergesidir.

- C ++ Cep Referansı

Vektör

Bir vektör, dizi tarzı operator[]rastgele erişim sağlayan dinamik boyutlu bir nesne dizisidir . Üye işlevi push_back, bağımsız değişkenlerini copy yapıcısı aracılığıyla kopyalar, bu kopyayı vektördeki son öğe olarak ekler ve boyutunu birer birer artırır.pop_back son öğeyi kaldırarak tam tersini . Bir vektörün sonundan öğeleri eklemek veya silmek, amortize edilmiş sabit zaman alır ve başka bir konumdan ekleme veya silme işlemi doğrusal zaman alır. Bunlar vektörlerin temelleridir. Onlardan çok daha fazlası var. Çoğu durumda, bir vektör, C tarzı bir dizi üzerinde ilk tercihiniz olmalıdır. Her şeyden önce, dinamik olarak boyutlandırılırlar, bu da gerektiğinde büyüyebilecekleri anlamına gelir. C dizilerinde olduğu gibi, optimal bir statik boyutu bulmak için her türlü araştırma yapmanız gerekmez; bir vektör gerektiği gibi büyür ve gerekirse manuel olarak daha büyük veya daha küçük boyutlandırılabilir. İkinci olarak, vektörler,at üye işleviyle (ancakoperator[]), böylece sadece programınızın çökmesini veya daha kötüsünü izlemek yerine var olmayan bir dizine başvurursanız, bozuk verilerle yürütmeye devam ederseniz bir şeyler yapabilirsiniz.

- C ++ Yemek Kitabı


En temel fark: vektörün iyi bir seçim olduğu amaçlar vardır.
Jerry Coffin

1
"kapsamlı" ve "uygunluk" ortogonaldir. Olduğunu, sadece bir tane yok değil diğer ima ancak onlar bile aynı ölçekte değildir.
Orbit'te Hafiflik Yarışları

2
Tam olarak aradığım bilgi olan sorulara yakın olan insanlara gerçekten üzülüyorum. Bu çok sık oluyor.
Robert Tamlyn

Yanıtlar:


142

diziler:

  • yerleşik bir dil yapısıdır;
  • C89'dan neredeyse hiç değiştirilmemiş gelir;
  • sadece bitişik, indekslenebilir bir eleman dizisi sağlar ; çan ve ıslık yok;
  • sabit boyuttadır; C ++ 'da bir diziyi yeniden boyutlandıramazsınız (bir POD dizisi olmadığı ve ile ayrılmadığı sürece malloc);
  • dinamik olarak ayrılmadıkları sürece boyutları bir derleme zamanı sabiti olmalıdır;
  • beyan ettiğiniz kapsama bağlı olarak depolama alanlarını alırlar;
  • dinamik olarak tahsis edilmişse, bunları açıkça serbest bırakmanız gerekir;
  • dinamik olarak tahsis edilmişlerse, sadece bir işaretçi alırsınız ve boyutlarını belirleyemezsiniz; aksi takdirde, kullanabilirsiniz sizeof(bu nedenle, sizeof(arr)/sizeof(*arr)bir işaretçi üzerinde yanlışlıkla kullanıldığında sessizce başarısız olan yaygın deyim );
  • çoğu durumda otomatik olarak bir işaretleyiciye dönüşür; özellikle, bu, genellikle boyutları için ayrı bir parametrenin geçirilmesini gerektiren bir işleve geçirilirken olur;
  • bir işlevden döndürülemez;
  • doğrudan kopyalanamaz / atanamaz;
  • dinamik nesne dizileri, tüm öğelerinin ilk önce oluşturulması gerektiğinden varsayılan bir kurucu gerektirir;

std::vector:

  • bir şablon sınıfıdır;
  • yalnızca bir C ++ yapısıdır;
  • dinamik bir dizi olarak uygulanır ;
  • dinamik olarak büyür ve küçülür;
  • otomatik olarak imha edildiklerinde serbest kalan hafızalarını yönetir;
  • işlevlere geçirilebilir / işlevlerden döndürülebilir (değere göre);
  • kopyalanabilir / atanabilir (bu, depolanan tüm öğelerin derin bir kopyasını oluşturur);
  • işaretçileri çürümez, ama sen yapabilirsiniz açıkça onların veri (bir gösterici olsun &vec[0]beklendiği gibi çalışması garanti edilmiştir);
  • her zaman dahili dinamik diziyle birlikte boyutunu (şu anda kaç öğenin depolandığını) ve kapasiteyi ( şu anda ayrılmış blokta kaç öğenin saklanabileceğini ) getirir;
  • dahili dinamik dizi, nesnenin kendi içinde tahsis edilmez (sadece birkaç "defter tutma" alanı içerir), ancak ilgili şablon parametresinde belirtilen ayırıcı tarafından dinamik olarak tahsis edilir; varsayılan olan, gerçek nesnenin nereye tahsis edildiğinden bağımsız olarak, belleği serbest depodan (sözde yığın) alır;
  • bu nedenle, küçük, kısa ömürlü yerel diziler için "normal" dizilerden daha az verimli olabilirler;
  • yeniden tahsis edilirken nesneler kopyalanır (C ++ 11'de taşınır);
  • saklanan nesneler için varsayılan bir kurucu gerektirmez;
  • sözde STL'nin geri kalanıyla daha iyi entegre edilmiştir ( begin()/ end()yöntemlerini, olağan STL'leri typedef, ... sağlar)

Ayrıca dizilere "modern alternatif" i de göz önünde bulundurun - std::array; Zaten açıklanan başka bir yanıt arasındaki farkı std::vectorve std::arraysen ona bir göz atmak istersin.


1
Teşekkürler @ MatteoItalia. Bir veya iki referans iyi olurdu.
Trancot

1
@Trancot: Herhangi bir iyi C ++ kitabı işe yarar.
Matteo Italia

6
@Trancot: Size gerçekten çok daha iyi referanslar veremem - bu yazıda vurgulanan farklılıklar Standardın birçok farklı bölümünden gelir ve iyi bir C ++ kılavuzunun yardımıyla daha iyi anlaşılır.
Matteo Italia

Böylesine kapsamlı bir açıklama örneği harika olur!
carloswm85

26

Dizilerin C ++ 'da çok düşük seviyeli yapılar olduğunu ekleyeceğim ve "ipleri öğrenirken" onlardan mümkün olduğunca uzak durmaya çalışmalısınız - Bjarne Stroustrup bile bunu tavsiye ediyor (o C ++' ın tasarımcısı).

Vektörler, dizilerle aynı performansa çok yakındır, ancak birçok kolaylık ve güvenlik özelliği ile birlikte gelir. Ham dizilerle ilgilenen API'lerle arabirim oluştururken veya kendi koleksiyonlarınızı oluştururken muhtemelen dizileri kullanmaya başlayacaksınız.


1
Uygulama Programı Arayüzü: ( en.wikipedia.org/wiki/API ). Bir yazılım varlığına (paket, kitaplık, işletim sistemi) giriş noktalarının bir koleksiyonudur. Bazı API'ler, strcat (char * dst, char * src) gibi giriş noktalarına sahip olacaktır; burada dst ve src, karakter dizileri olarak değerlendirilir (işlev imzası karakterlere işaretçi ima etse bile).
John Källén

11

Bu referans, sorunuzu oldukça cevapladı. Basitçe ifade etmek gerekirse, vektörlerin uzunlukları dinamik iken dizilerin boyutu sabittir. bir dizi kullanırken, bildirim üzerine onun boyutunu belirtirsiniz:

int myArray[100];
myArray[0]=1;
myArray[1]=2;
myArray[2]=3;

vektörler için, sadece beyan edersiniz ve öğeler eklersiniz

vector<int> myVector;
myVector.push_back(1);
myVector.push_back(2);
myVector.push_back(3);
...

Bazen ihtiyaç duyulan eleman sayısını bilemeyeceğiniz için böyle bir durum için bir vektör ideal olacaktır.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.