2015-05-13 18 views
7

Perché il seguente programma stampa "0x2ffee4" sulla console?Perché la stampa di una serie di stringhe è esadecimale?

#include <string> 
#include <iostream> 

using namespace std; 

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

[Non dovrebbe anche compilare] (http://coliru.stacked-crooked.com/a/b4a620e2db97afae) – chris

+1

non OMG che GCC bug di nuovo ... –

+0

@ Chris http://stackoverflow.com/domande/21481462/cosa-fa-string-array-media-e-perché-fa-da-lavoro; https://gcc.gnu.org/bugzilla/show_bug.cgi?id = 60009 –

risposta

2

La risposta data da T.C. è corretto, vorrei anche ricordare che se aspettavo di stampare "Toronto" alla console utilizzando cout allora si vorrebbe fare questo:

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; 
} 

Ogni volta che si desidera inizializzare un array di qualsiasi digita durante la dichiarazione che devi usare = {}; Per impostare l'elemento di ciascun array separato da virgole. Guardate questo esempio di codice:

#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; 
} 

Se non si inizializzare l'array quando dichiara allora è necessario specificare la dimensione della matrice.

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; 

}

Se non si utilizza l'operatore staffa con un valore di indice per inviare l'uscita della console flusso std :: cout quindi il valore esadecimale che si stanno ottenendo è corretto come TC aveva già affermato ; sta restituendo l'indirizzo del primo indice. Questo è il motivo per cui gli array e i puntatori di c/C++ sono simili (non sono uguali, ma si comportano quasi come un altro). La principale differenza con gli array è che sono di dimensioni costanti, che la dimensione deve essere nota al momento della compilazione e che non possono essere modificati in modo dinamico nelle dimensioni senza dover memorizzare il contenuto in una variabile temporanea durante la creazione di un nuovo array con dimensioni maggiori quindi copia tutti i dati nel nuovo array e quindi ripulisci il vecchio array. Con i puntatori non si comportano in questo modo, i puntatori possono essere allocati dinamicamente nell'heap usando new, ma devono anche essere cancellati quando quella variabile non ha più utilità per prevenire perdite di memoria, se il puntatore viene eliminato prima della mano e qualcosa tenta di accedervi quell'indirizzo di memoria non è più valido e non appartiene al chiamante, queste sono normalmente viste come eccezioni non gestite, danneggiamento dell'heap, ecc. e causeranno il crash del programma. Lo stesso vale per gli array quando si tenta di indicizzarli oltre i propri limiti.

#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

che ha chiarito la confusione. grazie mille! – wazeeer

18

La prima riga non dovrebbe di compilazione, ma c'è una GCC bug che lo rende la compilazione e si comportano in modo equivalente a qualcosa come

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

(8, perché "toronto" è di 8 caratteri, incluso il nulla di terminazione Sì, ciò significa che se si utilizza "Chargoggagoggmanchauggagoggchaubunagungamaugg", si creerebbe un array di 46 stringhe, ciascuna memorizzata "Chargoggagoggmanchauggagoggchaubunagungamaugg".)

Inutile t o dici, non dovresti fare affidamento su un bug del compilatore.

In base al comportamento del passeggino GCC, city1 sarebbe un array di std::string s; non c'è un sovraccarico dell'operatore << che supporta la stampa di una cosa del genere. Invece, in std::cout << city1, l'array decade in un puntatore al suo primo elemento e al suo posto viene stampato l'indirizzo memorizzato nel puntatore.

Probabilmente intendevi scrivere std::string city1 = "toronto";. Una stringa, non una matrice.

+0

grazie per la spiegazione, signore. – wazeeer

+0

Lo ottiene, complimenti @wazeeer, ma per la folla TL, DR, T.C., dovresti spostare la nota sul motivo per cui ha stampato l'indirizzo anziché la stringa più vicina alla parte superiore della risposta poiché quella sezione è la risposta. – user4581301

+1

@ user4581301 Non so, per me la risposta è "non dovrebbe essere stampato nulla perché non verrà compilato" ... –

Problemi correlati