2013-02-05 13 views
24

Ho iniziato di recente la programmazione in C, proveniente da Java e Python. Ora, nel mio libro ho notato che per fare un programma di "Ciao Mondo", la sintassi è qualcosa di simile:C ha un tipo di stringa?

char message[10] 
strcpy(message, "Hello, world!") 
printf("%s\n", message); 

Ora, questo esempio utilizza un array di caratteri e mi chiedevo - cosa è successo a stringhe? Perché non posso semplicemente usare uno di quelli? Forse c'è un modo diverso per farlo?

+7

C non ha stringhe. – sashoalm

+4

è necessario un messaggio di carattere [14]; – acraig5075

+3

Il tuo strcpy traboccherà il tuo array di caratteri. è necessario almeno un array di caratteri di lunghezza 14 (13 caratteri + terminatore nul) – wich

risposta

50

C non ha e non ha mai avuto un tipo di stringa nativo. Per convenzione, la lingua utilizza le matrici di char terminate con un carattere null, ovvero con '\0'. Le funzioni e le macro nelle librerie standard del linguaggio forniscono il supporto per gli array di caratteri con terminazione nulla, ad esempio strlen itera su un array di char finché non incontra un carattere '\0' e strcpy copie dalla stringa di origine finché non incontra uno '\0'.

L'uso di stringhe con terminazione null in C riflette il fatto che C era destinato ad essere solo un po 'più di alto livello rispetto al linguaggio assembly. Le stringhe a terminazione zero erano già supportate direttamente in quel momento in assembly language for the PDP-10 and PDP-11.

Vale la pena notare che questa proprietà di stringhe C causa alcuni bug di sovraccarico del buffer, inclusi gravi errori di sicurezza. Ad esempio, se si dimentica di terminare con null la stringa di caratteri passata come argomento sorgente a strcpy, la funzione manterrà copia dei byte sequenziali da qualsiasi cosa si trovi in ​​memoria oltre la fine della stringa di origine finché non si verificherà un 0, potenzialmente sovrascrivendo qualsiasi informazione preziosa segue la posizione della stringa di destinazione in memoria.

Nell'esempio di codice, la stringa letterale "Hello, world!" sarà compilato in un array lungo 14 byte di char. I primi 13 byte contengono le lettere, la virgola, lo spazio e il punto esclamativo e il byte finale conterrà il carattere con terminatore nullo '\0', automaticamente aggiunto per te dal compilatore. Se si dovesse accedere all'ultimo elemento dell'array, lo si troverà uguale a 0. Es .:

const char foo[] = "Hello, world!"; 
assert(foo[12] == '!'); 
assert(foo[13] == '\0'); 

Tuttavia, nel tuo esempio, message è lungo solo 10 bytes. strcpy scrive tutti i 14 byte, incluso il null-terminator, in memoria a partire dall'indirizzo message. I primi 10 byte verranno scritti nella memoria allocata nello stack per message ei restanti quattro byte verranno semplicemente scritti alla fine dello stack. La conseguenza di scrivere quei quattro byte in più nello stack è difficile da prevedere in questo caso (in questo semplice esempio, potrebbe non ferire una cosa), ma nel codice reale porta di solito a dati corrotti o errori di violazione di accesso alla memoria.

+1

Questa è stata la risposta più utile, grazie :) – arielschon12

3

C non supporta un tipo di stringa di prima classe.

C++ è std :: string

11

Non v'è alcun tipo string in C. Devi usare array di carbone.

Il vostro codice non funzionerà, perché la dimensione dell'array dovrebbe consentire l'adattamento dell'intero array più un carattere di terminazione zero aggiuntivo.

7

In C, una stringa è semplicemente una matrice di caratteri, che termina con un byte null. Quindi uno char* è spesso pronunciato "stringa", quando stai leggendo il codice C.

1

C non ha il proprio tipo di dati String come Java.

Solo possiamo dichiarare stringa tipo di dati in C usando array di caratteri o un carattere puntatore Ad esempio:

char message[10]; 
or 
char *message; 

Ma è necessario dichiarare almeno:

char message[14]; 

per copiare "Ciao, mondo !" nella variabile del messaggio.

  • 13: lunghezza del "Ciao mondo!"
  • 1: per il carattere '\ 0' nulla che identifica fine della stringa
0

primo luogo, non c'è bisogno di fare tutto questo. In particolare, lo strcpy è ridondante: non è necessario copiare una stringa solo su printf. Il tuo message può essere definito con quella stringa in posizione.

In secondo luogo, non hai concesso spazio sufficiente per "Hello, World!" stringa (message deve avere almeno 14 caratteri, consentendo l'ulteriore per il terminatore null).

Sul perché, però, è storia. Nell'assembler, non ci sono stringhe, solo byte, parole ecc. Pascal aveva delle stringhe, ma a causa di ciò c'erano problemi di digitazione statica - string[20] era un tipo diverso da string[40]. C'erano lingue anche nei primi tempi che evitavano questo problema, ma questo causava problemi di allocazione indiretta e allocazione dinamica che erano molto più un problema di efficienza a quei tempi.

C semplicemente scelto per evitare i costi generali e mantenere un livello molto basso. Le stringhe sono matrici di caratteri. Gli array sono strettamente correlati ai puntatori che puntano al loro primo oggetto. Quando i tipi di array "decadono" ai tipi di puntatore, le informazioni sulla dimensione del buffer vengono perse dal tipo statico, quindi non si ottengono i vecchi problemi della stringa Pascal.

In C++, c'è la classe std::string che evita molti di questi problemi e ha i costi generali di allocazione dinamica, ma di questi tempi di solito non ci interessa. E in ogni caso, std::string è una classe di libreria - c'è la gestione dell'array di caratteri in stile C sotto.

4

notare nelle lingue che hai menzionato:

Java:

String str = new String("Hello"); 

Python:

str = "Hello" 

Sia Java e Python hanno il concetto di una "stringa", C non non ha il concetto di una "stringa". C ha matrici di caratteri che possono entrare in "sola lettura" o manipolabili.

C:

char * str = "Hello"; // the string "Hello\0" is pointed to by the character pointer 
         // str. This "string" can not be modified (read only) 

o

char str[] = "Hello"; // the characters: 'H''e''l''l''o''\0' have been copied to the 
         // array str. You can change them via: str[x] = 't' 

Un array di caratteri è una sequenza di caratteri contigui con un carattere sentinella unico alla fine (normalmente un terminatore NULL '\0'). Nota che il carattere sentinella viene automaticamente aggiunto automaticamente nei casi sopra indicati.

Problemi correlati