2016-07-01 25 views
5

Ho trovato questo programma durante un test online sulla programmazione c L'ho provato al mio livello ma non riesco a capire perché l'uscita di questo programma sia 64.Perché questo programma emette 64?

Qualcuno può spiegare il concetto alla base di questo?

#include <iostream> 
#include <stdio.h> 

using namespace std; 

int main() 
{ 
    int a = 320; 
    char *ptr; 
    ptr = (char *)&a; 
    printf("%d",*ptr); 
    return 0; 
} 

uscita:

Grazie.

+1

suggerimento: qual è la dimensione del carattere? sarebbe adatto ... – nayana

+1

'320' in esadecimale è' 0x140'. '0x40' in decimale è' 64'. Altre domande? –

+3

@MichaelWalz .. oh in questo modo non imparerà nulla: D – nayana

risposta

11

A char * punti a un solo byte. Supponendo che un byte sul sistema sia 8 bit, il numero 320 occupa 2 byte. Il byte inferiore di questi è 64, il byte superiore è 1, perché 320 = 256 * 1 + 64. Questo è il motivo per cui ottieni 64 sul tuo computer (un computer little-endian).

Ma nota che su altre piattaforme, così chiamato piattaforme big-endian, il risultato potrebbe benissimo essere 1 (byte più significativo di un valore di byte a 16 bit/2) o 0 (byte più significativo di un valore maggiore di 16 bit/2 byte).

Si noti che tutto ciò presuppone che la piattaforma abbia byte a 8 bit. Se avesse, diciamo byte a 10 bit, otterresti di nuovo un risultato diverso. Fortunatamente, la maggior parte dei computer ha byte a 8 bit al giorno d'oggi.

5

Non sarà in grado di capire questo a meno che non si sa su:

  1. hex/represenation binario, e
  2. endianess CPU.

Immettere il numero decimale 320 in esadecimale. Dividi in byte. Supponendo che int sia 4 byte, dovresti essere in grado di dire quali parti del numero vanno in byte.

Dopodiché, considera la endianità della CPU specificata e ordina i byte in tale ordine. (Prima il byte MS o il byte LS.)

Il codice accede al byte assegnato all'indirizzo più basso del numero intero. Ciò che contiene dipende dall'aspetto della CPU. Otterrai l'esadecimale 0x40 o l'esadecimale 0x00.


Nota: Si consiglia di non utilizzare char per questo tipo di cose, perché ha signedness implementazione definita. Nel caso in cui i byte di dati contengano valori maggiori di 0x7F, si potrebbero ottenere alcuni bug molto strani, che appaiono/scompaiono in modo incoerente tra più compilatori. Utilizzare sempre uint8_t* quando si esegue qualsiasi forma di manipolazione bit/byte.

È possibile esporre questo bug sostituendo 320 con 384. Il vostro sistema little endian può quindi stampare -128 o 128, otterrete risultati diversi su diversi compilatori.

+0

Il codice non accede al byte più significativo, ma quello dei quattro byte memorizzati in memoria con l'indirizzo più piccolo - che può essere il più o meno significativo. – Aconcagua

+0

@Aconcagua In effetti, risolto. – Lundin

0

Int è four byte di byte di byte mentre char è un byte di dati di un byte, il puntatore di char può mantenere l'indirizzo un byte alla volta. Il valore binario di 320 è 00000000 00000000 00000001 01000000.Quindi, char pointerptr punta solo a first byte. *ptr vale a dire il contenuto del primo byte è 01000000 e il suo valore decimale è 64.

+0

_Int è due byte_ ........... o.O – LPs

0

Ciò che @Lundin ha detto è sufficiente. BTW, forse alcune conoscenze di base sono utili. 320 = 0x0140. un int = 4 caratteri. Quindi, quando stampa il primo byte, emette 0x40 = 64 a causa di endianess della cpu.

+0

Ciò è tecnicamente errato; int è quattro caratteri solo sui processori più comuni in questi giorni. Ma soprattutto i microcontroller e DSP possono essere diversi, visto int = 16 bit = 2 caratteri e persino int = 16 bit = 1 carattere. – Aconcagua

+0

Grazie per il vostro consiglio! Colpa mia, voglio solo scrivere qualcosa di facile da capire. –

0

ptr è il puntatore char di a. Quindi * ptr darà il valore char di a. char occupa solo 1 byte, quindi ripete i suoi valori dopo 255. Quello è 256 diventa 0, 257 diventa 1 e così via. Quindi 320 diventa 64.