2013-09-26 15 views
14

Ho 2 domande ... (sto imparando C e questo potrebbe essere domande stupide. Scuse)E 'valida per stampare l'indirizzo della stringa in C

  • Come per How to declare strings in C e nella maggior parte del libri, dicono sempre che dichiara una stringa anche se si assegnano memoria dicendo

    char p2[] = "String"; 
    

la mia domanda è, esiste un modo per dichiarare una stringa?

sono posti in lettura solo area e poi copiato matrice. È valido in C stampare l'indirizzo della stringa in questo modo?

printf("%p\n", &"Hello There"); // I tried, it prints some address 

e facendo questo

printf("%p\n", &"Hello There"); 
printf("%p\n", &"Hello There"); 

si sta stampando lo stesso indirizzo. ciò che è tatto è, dovrebbe stampare un indirizzo diverso. Il compilatore sta facendo qualche ottimizzazione qui?

risposta

14

C standard, §6.4.5 stringhe letterali, dice:

Non è specificato se questi array sono distinti purché i loro elementi abbiano i valori appropriati .

Quindi i valori letterali a due stringhe con lo stesso contenuto possono denotare lo stesso array e la stampa dei loro indirizzi fornisce lo stesso valore di puntatore due volte. Spetta al compilatore e al linker decidere questo; quando compilo il seguente programma come due moduli separati ...

// main.c 
#include <stdio.h> 

extern void print_foo_addr(void); 

int main() 
{ 
    printf("%p\n", &"foo"); 
    print_foo_addr(); 
    return 0; 
} 

e

// printfoo.c 
#include <stdio.h> 

void print_foo_addr() 
{ 
    printf("%p\n", &"foo"); 
} 

... poi ho due differenti valori di puntatore (GCC 4.7.3 su Linux), ma quando ho inserire la definizione per print_foo_addr in main.c, ottengo lo stesso valore due volte. Quindi sì, si tratta di un'ottimizzazione che è esplicitamente consentita dallo Standard, ma GCC almeno esegue questa ottimizzazione solo per modulo.

+0

Esiste comunque una variabile stringa? – StackIT

+0

Non penso sia possibile dichiarare una variabile stringa. Una variabile stringa è sempre definita. Ho ragione? – StackIT

+1

@Patil: cosa intendi per "variabile stringa"? Puoi avere una matrice di caratteri o un puntatore a un carattere. Questi possono essere dichiarati. Se la matrice contiene un carattere nullo e tutti i valori che precedono tale null sono valori in qualche particolare set di caratteri (o se lo stesso vale per il valore indicato dal char *), allora puoi chiamare la variabile "stringa". –

3

Questo è specificamente consentito dallo standard C.

6.4.5p5-6:

In fase di traduzione 7, un byte o codice di valore zero è allegato a ciascuna sequenza di caratteri multibyte che deriva da una stringa letterale o letterali. La sequenza di caratteri multibyte viene quindi utilizzata per inizializzare un array di durata e durata di memorizzazione statica sufficiente per contenere la sequenza. ...

Non è specificato se questi array siano distinti purché i loro elementi abbiano i valori appropriati.

+3

questa domanda riguarda C – moooeeeep

+0

Puoi spiegare in merito a C? – StackIT

+0

Whoops, si. Fisso. – aschepler

0

Il "Hello There" è stringa letterale e sarà disponibile in tabella di stringhe (Il motivo dietro ottenere stesso indirizzo per "Hello There" in printf).

Quando si esegue

char p2[] = "String"; 

memoria sarà assegnato e "String" verrà copiato nella memoria appena creato. Ma

char * p3 = "String"; punterà alla sezione di sola lettura. la tabella delle stringhe.

In questo caso, se si stampa p3 e &"String" sarà stesso.

Se si stampa p2 e &"String", verrà stampato un indirizzo diverso. Perché p2 è l'indirizzo di stack.

0

Le stringhe letterali sono posizionate in una sezione speciale, che deve essere di sola lettura. Inoltre, se si utilizza la stessa stringa letterale in più posizioni, in genere il compilatore può creare solo un'istanza di tale stringa. Questo è il motivo per cui si vede lo stesso indirizzo in questo esempio:

printf("%p\n", &"Hello There"); 
printf("%p\n", &"Hello There"); 

Tuttavia, non si può fare affidamento su questo, perché si tratta di un'ottimizzazione del compilatore, che può o non può accadere.

+0

BSS viene normalmente utilizzato per dati statici inizializzati a zero. I dati costanti spesso si trovano nella sezione di testo con il codice. – Dipstick

+0

@Dipstick, sì hai ragione, l'ho rimosso. – Devolus

Problemi correlati