2016-04-02 9 views
1

Ich habe eine Google auf das, und ich erkannte, dass einige sagen, es kann einige sagen, dass es nicht kann.Können wir die Adresse für Stringliteral ausdrucken?

Ich möchte nur überprüfen.

Zum Beispiel

char gchararr1i[] = "testing 123"; // global char array init 
char *gptr1i = "hello", *gptr2ui; // global char pointer init and un-init 
float gfloati = 123.4; // global float var init 
double gdoubleui; // global double var un-int 


int main(int argc, char *argv[]) { 

    printf("\n Address of string literals \"testing 123\" = %p and \"hello\" = %p \n", gchararr1i, gptr1i);// output the addresses of string literals "testing 123" and "hello" 

    f1(10, -20, 30.3, 'A', 45.67); 
    exit(0);    
} 
+1

Ja, Sie können das tun, obwohl Sie die Zeiger technisch auf 'void *' umstellen sollten. – user3386109

+0

was meinst du nur werfen die Zeiger auf void *? Wie auch immer, wenn es möglich ist, ist die Art, wie ich gedruckt habe, richtig? –

+1

Zum Beispiel 'printf (" adresse =% p \ n ", (void *) gchararr1i);' Die C-Spezifikation besagt, dass das Argument für '% p' * * ein' void * 'sein muss, obwohl es in den meisten Fällen keinen Unterschied macht . – user3386109

Antwort

4

Sind wir in der Lage wörtliche die Adresse für String auszudrucken?

Ja. Ein einfaches Beispiel, um die Adresse für ein String-Literal auszugeben.

printf("%p\n", (void *) "Hello Word!"); 

Output

0x100403055 

Folgende druckt die Adresse des ersten Elements der gchararr1i[]. Dies kann die Adresse des Zeichenfolgenliterals sein oder nicht. Das Zeichenfolgenliteral ist möglicherweise nicht einmal separat im Code vorhanden.

char gchararr1i[] = "testing 123"; 
printf("%p\n", (void *) gchararr1i); 

Output

0x22caa0 

Folgende druckt den Adreßwert des Zeigers gptr1i, die die Adresse des Stringliteral "hello" werden passiert.

char *gptr1i = "hello"; 
printf("%p\n", (void *) gptr1i); 

Ausgabe

0x100403060 

-

Detail: "%p nur mit Druck void* Zeiger definiert ist. Wenn andere Objektzeiger als void* gedruckt werden, zuerst auf void *. @user3386109. Hinweis: Zum Drucken von Funktionszeigern siehe this.

int x; 
// printf("%p\n", x); 
printf("%p\n", (void *)&x); 
+0

Ich denke immer, dass% p verwendet wird, um die Adresse des Zeigers auszudrucken. Nein? –

+0

'"% p "' dient nur zum Drucken von 'void *' Zeigern. Alle Zeiger, mit Ausnahme von Zeigern auf Funktionen, wandeln sich leicht in 'void *' um. Einen Zeiger auf "void *" zu setzen, ist der Ansatz des robusten Codes. Viele Implementierungen führen zu dem gleichen Ergebnis, wenn der Cast weggelassen wird, aber das ist kein robuster Code und _technisch ist ein undefiniertes Verhalten. – chux

+0

Warum * "technisch" * UB? Es ist nichts unklar. –

7

können Sie übernehmen die Adresse eines Stringliteral, aber man kann nicht sicher sein, dass zwei Zeichenketten mit den exakt gleichen Inhalt an derselben Adresse sein wird (oder dass sie nicht die gleiche Adresse haben). Die Compiler-Toolchain kann in dieser Hinsicht frei entscheiden.

Der Standard lässt sogar zu, dass ein Zeichenfolgenliteral den Speicher mit einem anderen gemeinsam nutzt. Zum Beispiel könnte die Adresse "world" in das Literal "hello world" "zeigen". Ich kenne keine Implementierung, die das tut, aber ich habe auch nicht danach gesucht.

Verwandte Themen