Trasmettere un personaggio a un corto senza segno: cosa succede dietro le quinte?

StackOverflow https://stackoverflow.com/questions/402616

  •  03-07-2019
  •  | 
  •  

Domanda

Dato questo campo:

char lookup_ext[8192] = {0}; // Gets filled later

E questa affermazione:

unsigned short *slt = (unsigned short*) lookup_ext;

Cosa succede dietro le quinte?

lookup_ext [1669] restituisce 67 = 0100 0011 (C), lookup_ext [1670] restituisce 78 = 0100 1110 (N) e lookup_ext [1671] restituisce 68 = 0100 0100 (D); slt [1670] restituisce 18273 = 0100 0111 0110 0001.

Sto provando a portarlo su C #, quindi oltre a una semplice via d'uscita, mi chiedo anche cosa succede davvero qui. È da un po 'che non uso C ++ regolarmente.

Grazie!

È stato utile?

Soluzione

L'affermazione che mostri non lancia un carattere su un corto senza segno, lancia un puntatore su un carattere su un puntatore su un corto senza segno. Ciò significa che le normali conversioni aritmetiche dei dati puntati non si verificheranno e che i dati dei caratteri sottostanti verranno semplicemente interpretati come short senza segno quando vi si accede attraverso la variabile slt.

Nota che sizeof(unsigned short) è improbabile che sia uno, quindi slt[1670] non corrisponderà necessariamente a lookup_ext[1670]. È più probabile - se, diciamo, lookup_ext[3340] è due - corrispondere a lookup_ext[3341] e <=>.

Sai perché il codice originale utilizza questo aliasing? Se non è necessario, potrebbe valere la pena provare a rendere il codice C ++ più pulito e verificare che il comportamento rimanga invariato prima del porting.

Altri suggerimenti

Se ho capito bene, la conversione del tipo convertirà un array di caratteri di dimensioni 8192 in un array int breve di dimensioni pari a metà di quello, che è 4096.

Quindi non capisco cosa stai confrontando nella tua domanda. slt [1670] dovrebbe corrispondere a lookup_ext [1670 * 2] e lookup_ext [1670 * 2 + 1].

Bene, questa affermazione

char lookup_ext[8192] = {0}; // Gets filled later

Crea un array localmente o non localmente, a seconda di dove si trova la definizione. Inizializzandolo in questo modo, con un inizializzatore aggregato inizializzeremo tutti i suoi elementi a zero (il primo esplicitamente, gli altri implicitamente). Pertanto mi chiedo perché il tuo programma abbia valori diversi da zero. A meno che il riempimento non avvenga prima della lettura, allora ha senso.

unsigned short *slt = (unsigned short*) lookup_ext;

Ciò interpreterà i byte che compongono l'array come oggetti corti non firmati quando si legge dalla destinazione di quel puntatore. A rigor di termini, quanto sopra è un comportamento indefinito, perché non puoi essere sicuro che l'array sia allineato in modo appropriato e leggeresti da un puntatore che non punta al tipo di tipo appuntito originale (carattere senza segno & Lt; - < !> gt; unsigned short). In C ++, l'unico modo portatile per leggere il valore da qualche altro pod (semplici vecchi dati. Sono tutte le strutture e i tipi semplici che sono possibili anche in C (come breve), in senso lato) è usando funzioni di libreria come memcpy o memmove.

Quindi, se leggi *slt sopra, interpreteresti i primi sizeof(*slt) byte dell'array e provi a leggerlo come short senza segno (che si chiama type pun).

Quando fai " unsigned short slt = (unsigned short ) lookup_ext; " ;, il no. di byte equivalenti alla dimensione di (unsigned short) vengono prelevati dalla posizione indicata da lookup_ext e memorizzati nella posizione indicata da slt. Dato che short senza segno sarebbe 2 byte, i primi due byte da lookup_ext sarebbero memorizzati nella posizione data da slt.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top