2015-05-13 20 views
7

Aşağıdaki program neden konsola "0x2ffee4" yazdırıyor?Niçin dize dizi çıkışı onaltılık yazdırıyor?

#include <string> 
#include <iostream> 

using namespace std; 

int main() { 
    string city1[] = "toronto"; 
    cout << city1; 
    return 0; 
} 
+3

[hatta derlemek gerekmiyor] (http://coliru.stacked-crooked.com/a/b4a620e2db97afae) – chris

+1

OMG değil GCC hata tekrar ... –

+0

@chris http://stackoverflow.com/sorular/21481462 /-ne-string-dizi-ortalama-niçin-does-it-iş; https://gcc.gnu.org/bugzilla/show_bug.cgi?id = 60009 –

cevap

2

T.C. Eğer herhangi bir diziyi başlatmak istediğiniz herhangi bir zaman

include <string> 
include <iostream> 

int main() { 
    using namespace std; 

    // string city1[] = "toronto"; // Compiler Error - Do Next Line Instead 
    string city1[] = { "toronto" }; 
    cout << city1[0]; 

    return 0; 
} 

: Doğru, ben de o zaman bunu yapmak isteyeyim cout kullanarak konsola "toronto" yazdırmak için bekliyordum eğer söz etmek istiyorum bildirim sırasında yazın = {}; Her dizinin elemanını virgülle ayırmak için. Bu kod örneğinde bak:

#include <string> 
#include <iostream> 

int main() { 
    using namespace std; 

    string cities[] = { "New York", "Philadelphia", "Chicago", "Boston" }; 

    // Same As Above Except Size Of Array Is Defined First Then The Elements 
    string cities[4]; 
    cities[0] = "New York"; 
    cities[1] = "Philadelphia"; 
    cities[2] = "Chicago"; 
    cities[3] = "Boston"; 

    unsigned index = 0; 
    for (; index < 4; index++) { 
     cout << cities[index] << endl; 
    } 

    return 0; 
} 

o zaman sen dizinin boyutu belirtmek gerekir bildirirken dizi başlatılıyor değilseniz. TC zaten belirttiği gibi

int main() { 
    int iArray[]; // Compiler Error 
    int iArray[] = { 4, 3, 2, 1, 6 }; // Okay and is the same as 

    int iArray[5]; // Okay 
    iArray[0] = 4; 
    iArray[1] = 3; 
    iArray[2] = 2; 
    iArray[3] = 1; 
    iArray[4] = 6; 

    return 0; 

}

konsol çıkış akışı std göndermek için bir endeks değeri ile braket operatörü kullanmıyorsanız :: cout o zaman alıyorsanız onaltılık değeri doğrudur ; İlk endeksin adresini döndürüyor. Bu yüzden c/C++ dizileri ve işaretçiler benzerdir (aynı değildirler, ancak neredeyse birbirlerine benzerler). Dizilerdeki ana fark, boyutlarının sabit olması, boyutunun derleme zamanında bilinmesi ve daha büyük boyutlu yeni bir dizi oluştururken, içeriğin temp değişkenine depolanmasına gerek kalmadan, boyut olarak dinamik olarak değiştirilememesidir. sonra tüm verileri yeni diziye kopyalayıp eski diziyi temizler. İşaretçiler bu şekilde davranmazlarsa, işaretçiler yeni kullanılarak yığın üzerinde dinamik olarak ayrılabilir, ancak bu değişkenin bellek sızıntılarını önlemek için daha fazla kullanımı olmadığında, işaretçi elden önce silinirse ve bir şey erişmeye çalıştığında silinmelidir. Bu bellek adresi artık geçerli değil ve arayan kişiye ait değil, normal olarak işlenmeyen özel durumlar, yığın bozulması vb. olarak görülür ve programınızı kilitler. Aynı şey onları sınırlarını geçmeye çalıştıkça diziler için de geçerlidir.

#include <iostream> 

int main() { 
    // Arrays Are 0 Indexed 
    int iArray[3] = { 1, 2, 3 }; 

    // If you try to do this to access the last element 
    std::cout << iArray[3] << std::endl; // Program Will Crash 

    // Since Arrays Are 0 Indexed And The Size Of The Array Is 3 
    // The 3rd Value Is Indexed At 2, And By Trying To Index Location Of Array 
    // At 3, This Memory Doesn't Belong To You, And It Is Undefined Behavior. 
    // This Memory Could Contain Nothing, Random Data, Or Even Data That Belongs To 
    // Something Else Which If Changed Can Even Cause System Failure   

    return 0; 
} 
+1

bu karışıklığı temizledi. teşekkürler ton! – wazeeer

18

ilk satır gerektiği "toronto" sonlandırıcı boş 8 karakter olduğu için değil derleme, ama bu derlemek ve

std::string city1[] = {"toronto", "toronto", "toronto", "toronto", 
         "toronto", "toronto", "toronto", "toronto"}; 

(8 gibi yüksek bir değere eşit davranmaya yapan bir GCC bug var Evet, yani "Chargoggagoggmanchauggagoggchaubunagungamaugg" kullandıysanız, her biri "Chargoggagoggmanchauggagoggchaubunagungamaugg" depolayan 46 diziden oluşan bir dizi oluşturacaktır.)

Gereksiz t der ki, derleyici bir hataya güvenmemelisin.

GCC'nin buggy davranışı altında, city1std::string s dizisi; Böyle bir şeyi basmayı destekleyen operatör << aşırı yük yok. Bunun yerine, std::cout << city1'da, dizi ilk öğeye bir gösterici ile bozulur ve bunun yerine işaretçide saklanan adres yazdırılır.

Muhtemelen std::string city1 = "toronto"; yazmayı kastediyorsunuz. Bir dizgi, bir dizi değil.

+0

açıklama için teşekkürler efendim. – wazeeer

+0

O alır, kudos @wazeeer, ancak TL için, DR kalabalık, T.C., bu bölüm cevap olduğundan, sorunun cevabın üstüne cevabın üstüne daha yakın bir şekilde yazılmasının nedenini not etmelisiniz. – user4581301

+1

@ user4581301 Bilmiyorum, bana göre cevap "derleme yapmayacağı için bir şey yazdırmamalı" ... –