2016-03-20 7 views
-4

Dies ist das Programm: -Warum folgen dem Wert des Arrays drei Nullen?

#include<stdio.h> 
int main() 
{ 
    int a[8]={1,2,3,4,5,6,7,8,9},i; 
    char* p; 
    p=(char*)a; 
    printf("%d",*p); 
    for(i=0;i<32;i++) 
    { 
     p=p+1; 
     printf("%d",*p); 
    } 
    return 0; 

} 

Ausgang: -

$ ./a.out 
100020003000400050006000700080000 

Warum die Ausgabe so ist?
Warum folgen dem Wert des Arrays drei Nullen?

char Zeiger wird um 1 Byte erhöht. Die binäre Darstellung von 1 im Speicher gespeichert ist 0000000 00000000 00000000 00000001. Ist das richtig? Also sollte die Ausgabe wie 0 0 0 1 sein. Wenn falsch, bitte erklären.

+0

Es ist der Wert der Ganzzahl gefolgt von drei Nullen, tatsächlich. –

+0

Ich frage mich, wie ein 32-Bit-Int Byte für Byte im Speicher aussieht? –

+2

Hinweis: Trotz der Besetzung in Zeile 6 enthält 'a' noch int-Werte, keine char- –

Antwort

5

Lösung

char sind in der Regel 1 Byte während int der Regel 4 Bytes sind. Im Speicher, wenn Sie eine char pointer 4-mal erhöhen müssen, um eine int vollständig zu inkrementieren.

ändern

char* p; 
p=(char*)a; 

zu:

int* p; 
p=(int*)a; 

Dies löscht alle Nullen

Auch

int a[8]={1,2,3,4,5,6,7,8,9},i; 

ändern:

int a[9]={1,2,3,4,5,6,7,8,9},i; 

wie Sie die Zuweisung nicht ausreichend Platz und ändern

printf("%d",*p); 
for(i=0;i<32;i++) 
{ 
    p=p+1; 
    printf("%d",*p); 
} 

zu:

for(i=0; i<9; i++) 
{ 
    printf("%d",*p); 
    p=p+1; 
} 

Memory Map Visualisierung Arrays in C und die meisten Sprachen sind nur Elemente in aufeinanderfolgenden Speicher abgelegt Standorte. int array[2] = {1,2} wird so in Erinnerung aussehen:

// Assuming array starts at location 0x000 (in hex) 
// Keep in mind a byte is 8 bits so a byte can contain values from 0x00 to 0xff 
location: value: 
0x00  = [0x01] // first byte of first int 
0x01  = [0x00] // second byte of first int 
0x02  = [0x00] // third byte of first int 
0x03  = [0x00] // fourth byte of first int 
0x04  = [0x02] // first byte of second int 
0x05  = [0x00] // second byte of second int 
0x06  = [0x00] // third byte of second int 
0x07  = [0x00] // fourth byte of second int 

Wie Sie sehen können, int belegt 4 Byte. int * erhöht um 4 Speicherplätze, die Sie zum nächsten ganzzahligen Wert bringen. In Ihrem Fall, nachdem Sie eine char * inkrementieren, erhöhen Sie nur ein Viertel dieser int und drucken die Nullen (3 von ihnen).

Wenn Sie int array[2] = {256, 2} versuchen und durchlaufen sie char * mit, ich bin sicher, dass Sie ausdrucken:

0 1 0 0 2 0 0 0

Dies liegt daran, 256 0x100 gleich in so kann es nicht in einem Byte gespeichert werden und muss das zweite Byte innerhalb der ersten int verwenden.Die Speicherzuordnung sieht wie folgt aus:

location: value: 
0x00  = [0x00] // first byte of first int 
0x01  = [0x01] // second byte of first int 
0x02  = [0x00] // third byte of first int 
0x03  = [0x00] // fourth byte of first int 
0x04  = [0x02] // first byte of second int 
0x05  = [0x00] // second byte of second int 
0x06  = [0x00] // third byte of second int 
0x07  = [0x00] // fourth byte of second int 
+0

warum der Compiler keine Warnung für solche Deklarationen gibt int a [8] = {1,2,3,4,5,6,7,8,9}, i ; '? – cmks

+0

Abhängig davon, welchen Compiler Sie verwenden und welche Flags Sie beim Kompilieren verwendet haben. Ich benutzte '-Werror' und diese Zeile gab mir einen Fehler. – PhotometricStereo

+0

Ich möchte wissen, warum gibt es Nullen nach int value.int Wert ist von 4 Bytes und das Zeichen ist von 1 Byte.Was ist die Speicher-Darstellung für sie. –

2

Ihre Schleife greift auf 32 Adressen zu n = 0; n < 32. Unter der Annahme, dass Integer 4 Byte auf Ihrem System belegen, greifen Sie nur auf Bytes zu, die das 4. Mal den Anfang von 4-Byte-Ganzzahlen bilden.

Dieser Code wird für jede Schleife um 4 erhöht.

#include<stdio.h> 
int main() 
{ 
    int a[8]={1,2,3,4,5,6,7,8}, i; 
    char* p; 
    p=(char*)a; 

    for(i = 0; i < 32; i += 4) { 
     printf("%d\t",*(p+i)); 
    } 

    printf("\n"); 
    return 0; 
} 

der Schleifensteuerung wäre stabiler Verwendung dieser

for(i = 0; i < 32; i += sizeof(int)) { 

da sie die Schrittweite, was Größe ‚Integer‘ ist auf der Maschine, auf es läuft gesetzt würde.

Es gibt andere Probleme, einschließlich Ihrer Array-Zuweisung ist mehr als die zugewiesene Array-Größe.

Gab es einen Grund für die nicht nur die Array-Elemente zugreifen:

#include<stdio.h> 
int main() 
{ 
    int a[8]={1,2,3,4,5,6,7,8}, i; 

    for(i = 0; i < sizeof(a)/sizeof(a[0]); i ++) { 
     printf("%d\t", a[i]); 
    } 
    printf("\n"); 
    return 0; 
} 

Dies kann Ihnen helfen, zu sehen, wie die ganze Zahl gespeichert ist. Da es sich um einen vorzeichenbehafteten Wert handelt, handelt es sich wahrscheinlich um eine Zweierkomplement-Notation.

#include<stdio.h> 
int main() 
{ 
    int a[8] = {1, -2147483647 ,3,4,5,6,7,8}, i; 
    char* p; 
    p=(char*)a; 
    for(i = 0; i < 32; i++) { 
     printf("%d\t",(*p)); 
     p++; 
     if (i%4 == 3) printf("\n"); 
    } 
    return 0; 

} 

führen Sie es erneut, nachdem die negative Zahl Erniedrigen (die größte negative Zahl für eine 32-Bit-Ganzzahl mit Vorzeichen) Die \ t und das zusätzlichen printf line-Hilfe-Format der Ausgabe, die es leichter zu folgen. Beachten Sie auch, dass p erst nach dem Drucken erhöht wird. In Ihrem ursprünglichen Code haben Sie über das Ende der im Array verwendeten Bytes hinaus zugegriffen.

Auch Ihre erste printf Linie entfernen, da es die Ausgabe verwirrt

+0

Char Zeiger wird um 1 Byte erhöht.Die binäre Darstellung von 1 im Speicher gespeichert ist 0000000 00000000 00000000 00000001 .Ist das richtig? also sollte die Ausgabe wie 0 0 0 1 sein. Wenn falsch, bitte erklären. –

+0

@KunalKakade Ich weiß nicht, wie Integer auf Ihrem Betriebssystem dargestellt werden. – anita2R

+0

sein Ubuntu 14.4. Sag mir in deinem OS? wenn du in meiner nicht weißt? –

1

Dies ist ein Endian-Problem.

Die Binärdarstellung von 1 im Speicher ist 0000000 00000000 00000000 00000001? Ist das richtig ?

Ja - aber betrachten Sie wo diese Bytes gespeichert sind.

so sollte die Ausgabe wie 0 0 0 1 sein falsch, wenn Sie

Nicht ganz und gar nicht so im Fall des OP zu erklären.

[Lassen Sie uns die Größe int ist 4 mal so groß wie der char annehmen und char 8 Bit]

warum ist der Ausgang dieses c-Programm wie ist das?

Die Reihenfolge im Speicher des 4 hängt von endian. In den Fällen von OP wird das niedrigstwertige Byte in der ersten Adresse gespeichert, gefolgt von den verbleibenden 3 wahrscheinlich mit jedem höherwertigen Byte im nächsten adressierten Byte. Dies ist Little Endian.

Auf einer anderen Maschine kann die Reihenfolge umgekehrt werden und in der Reihenfolge OP erwartet - das ist big Endian.

Andere Bestellungen sind möglich, obwohl jetzt selten.

Verwandte Themen