2017-08-12 3 views
-1

Was wird die Ausgabe des folgenden C-Codes sein. Angenommen, es läuft auf einer Little-Endian-Maschine, wobei short int 2 Bytes und char 1 Byte benötigt.Ausgabe des folgenden C-Codes

#include<stdio.h> 
int main() { 
    short int c[5]; 
    int i = 0; 
    for(i = 0; i < 5; i++) 
     c[i] = 400 + i; 
    char *b = (char *)c; 
    printf("%d", *(b+8)); 
    return 0; 
} 

In meiner Maschine gab es

-108 

Ich weiß nicht, ob meine Maschine Little-Endian oder Big-Endian ist. Ich fand irgendwo, dass es geben sollte

148 

als die Ausgabe. Weil niederwertige 8 Bits von 404 (d. H. Element c [4]) 148 ist. Aber ich denke, aufgrund von "% d" sollte es 2 Bytes aus dem Speicher lesen, beginnend mit der Adresse von c [4].

+1

Kompilierungsflag kann das Standardzeichen in signed/unsigned etc ändern –

Antwort

1

c[4] speichert 404. In einer Zwei-Byte-Little-Endian-Darstellung bedeutet dies zwei Bytes von 0x940x01, oder (in Dezimal) 1481.

b+8 adressiert den Speicher von c[4]. b ist ein Zeiger auf char, so dass die 8 bedeutet, 8 Byte (das ist 4 Zwei-Byte-Kurzschlüsse) hinzufügen. Mit anderen Worten, b+8 zeigt auf das erste Byte von c[4], das 148 enthält.

*(b+8) (die auch als b[8] geschrieben werden konnte) dereferenzieren den Zeiger und verschafft Ihnen somit den Wert 148 als char. Was dies tut, ist implementation-defined: Auf vielen gängigen Plattformen char ist ein signierter Typ (mit einem Bereich von -128 .. 127), so dass es nicht tatsächlich 148 sein kann. Aber wenn es ein vorzeichenloser Typ ist (mit einem Bereich von 0 .. 255), dann ist 148 in Ordnung.

Das Bitmuster für 148 im Binärformat ist 10010100. Wenn Sie dies als Zweierkomplementnummer interpretieren, erhalten Sie -108.

Dieser char Wert (entweder 148 oder -108) wird dann automatisch auf int umgewandelt, weil es in der Argumentliste einer Variablen-Argumentfunktion (printf) erscheint. Dies ändert den Wert nicht.

Schließlich teilt "%d"printf, das int Argument zu nehmen und es als eine Dezimalzahl zu formatieren.

So rekapitulieren: Vorausgesetzt Sie haben eine Maschine, wo

  • ein Byte 8 Bits ist
  • negative Zahlen verwenden Zweier-Komplement
  • short int 2 Byte

... dann gibt dieses Programm entweder -108 aus (wenn char ein signierter Typ ist) oder 148 (wenn char ein u nsigned Typ).

1

Um zu sehen, welche Arten in Ihrem System Größen haben:

printf("char = %u\n", sizeof(char));  
printf("short = %u\n", sizeof(short));  
printf("int = %u\n", sizeof(int));  
printf("long = %u\n", sizeof(long));  
printf("long long = %u\n", sizeof(long long)); 

ändern Sie die Zeilen in Ihrem Programm

unsigned char *b = (unsigned char *)c; 
printf("%d\n", *(b + 8)); 

Und einfacher Test (ich weiß, dass dies nicht der Fall garantiert, aber alle C-Compiler, die ich kenne, machen es so und mir sind alte CDC- oder UNISYS-Maschinen egal, die unterschiedliche Adressen und Zeiger auf verschiedene haben mieten Arten von Daten

printf(" endianes test: %s\n", (*b + (unsigned)*(b + 1) * 0x100) == 400? "little" : "big"); 

Noch eine Anmerkung: Es ist nur, weil in Ihrem Programm c [0] == 400

2

Der Code gibt verschiedene Ausgaben auf verschiedenen Computern, da auf einigen Plattformen der Typ char standardmäßig signiert ist und bei anderen standardmäßig nicht signiert ist. Das hat nichts mit Endianess zu tun. Versuchen Sie Folgendes:

char *b = (char *)c; 
    printf("%d\n", (unsigned char)*(b+8)); // always prints 148 
    printf("%d\n", (signed char)*(b+8)); // always prints -108 (=-256 +148) 

Der Standardwert hängt von den Plattform- und Compilereinstellungen ab. Sie können das Standardverhalten mit den GCC-Optionen -fsigned-char und -funsigned-char steuern.

Verwandte Themen