[C]convertire int in byte...
Ragazzi ma come faccio a convertire una variabile di tipo int nei corrispondenti 4 byte????
Non esiste una funzione in C in grado di fare questo????
Non esiste una funzione in C in grado di fare questo????

Risposte
Puoi fare qualcosa come il seguente.
In questo caso arr punterebbe direttamente all'intero, volendone fare una copia, il metodo più facile è quello di usare memcpy oppure usare una union. Per cosa ti serve?
int i; /* ... */ char *arr = (char *) &i;
In questo caso arr punterebbe direttamente all'intero, volendone fare una copia, il metodo più facile è quello di usare memcpy oppure usare una union. Per cosa ti serve?
Mi serve per svolgere il seguente esercizio:
Scrivere il codice di una funzione C che permetta di copiare in un vettore di 4 char i 4 byte di un numero intero
Scrivere il codice di una funzione C che permetta di copiare in un vettore di 4 char i 4 byte di un numero intero
Ciao
scusa ma perché non usi una union?
penso che sia più semplice no?
scusa ma perché non usi una union?
union myUnion { unsigned int ValInt; unsigned char ValByte[4]; }; int main (void) { union myUnion ValUnion; unsigned char Byte1; unsigned char Byte2; unsigned char Byte3; unsigned char Byte4; //scrivo il valore come int ValUnion.ValInt = 155; //leggo il valore in byte Byte1 = ValUnion.ValByte[0]; Byte2 = ValUnion.ValByte[1]; Byte3 = ValUnion.ValByte[2]; Byte4 = ValUnion.ValByte[3]; }
penso che sia più semplice no?
Solo per fare un confronto con l'uso di memcpy:
E' probabilmente meglio usare una union in questo caso (o il trucco dei puntatori se si vuole modificare il valore invece che copiarlo), m è comunque molto utile conoscere memcpy. E' infatti un metodo molto semplice ed efficiente per fare copie di oggetti "complessi" (come array) o di oggetti del quale non si conosce il tipo.
#include <string.h> int i; char b[sizeof(int)]; /* potrebbe non essere uguale a 4.. */ memcpy(b, &i, sizeof(int));
E' probabilmente meglio usare una union in questo caso (o il trucco dei puntatori se si vuole modificare il valore invece che copiarlo), m è comunque molto utile conoscere memcpy. E' infatti un metodo molto semplice ed efficiente per fare copie di oggetti "complessi" (come array) o di oggetti del quale non si conosce il tipo.
@apatriarca:
te ne intendi di PIC?
te ne intendi di PIC?
Non particolarmente, perché? Ti riferisci al "potrebbe non essere uguale a 4.."? Diciamo che nei sistemi a 32 e 64 bit gli interi sono in effetti quasi sempre a 32 bit, ma questo non è vero per i sistemi a 16bit (lo standard garantisce infatti solo una dimensione minima di 16bit). Altri tipi, come i long potrebbero invece variare tra i 32 e i 64 bit (se non ricordo male Microsoft nei suoi compilatori a 64 bit usa una dimensione per i long di 32 mentre gcc usa 64 bit).
Oppure ti riferisci all'uso di memcpy? Non sono al corrente di problemi di questa funzione con i PIC..
Oppure ti riferisci all'uso di memcpy? Non sono al corrente di problemi di questa funzione con i PIC..
no ho un problema con un PIC e cerco aiuto

"fk16":
Scrivere il codice di una funzione C che permetta di copiare in un vettore di 4 char i 4 byte di un numero intero
Dal testo dell'esercizio sembra che tu sia agli inizi con lo studio del C, o sbaglio? Se è così e non hai ancora imparato a usare le union o memcpy, come suggerito, forse puoi anche risolverlo con solo gli operatori & e shift (a sinistra e a destra) sui bit, per esempio con un ciclo for del tipo:
s = sizeof(int); for (i = 0; i < s; i++) { shift = i * 8; tuo_array[i] = (unsigned char)((numero_intero & (255 << shift)) >> shift); }
@anonymous_be1147: Il problema del tuo metodo è che il risultato dipende dall'endianess del sistema. Stai infatti dando per esempio per scontato che
Sul mio sistema funziona essendo little-endian ma, a meno di aver preso un abbaglio, non dovrebbe funzionare su un sistema big-endian. Il vantaggio delle soluzioni "più avanzate" (ma si può in realtà discutere se richiamare una funzione sia in effetti più complicato di scrivere un codice come il tuo) è che questo genere di problemi non si possono presentare.
(*(unsigned char *)&numero_intero) == (unsigned char) (numero_intero & 0xff)
Sul mio sistema funziona essendo little-endian ma, a meno di aver preso un abbaglio, non dovrebbe funzionare su un sistema big-endian. Il vantaggio delle soluzioni "più avanzate" (ma si può in realtà discutere se richiamare una funzione sia in effetti più complicato di scrivere un codice come il tuo) è che questo genere di problemi non si possono presentare.
Concordo con apatriarca.
l'approccio con l'uso dello shift mi ha causato seri bachi in passato per via di un big-endian che supponevo essere little-endian
l'approccio con l'uso dello shift mi ha causato seri bachi in passato per via di un big-endian che supponevo essere little-endian
"apatriarca":
@anonymous_be1147: Il problema del tuo metodo è che il risultato dipende dall'endianess del sistema.
Be', l'esercizio richiedeva semplicemente di "copiare in un vettore di 4 char i 4 byte di un numero intero", senza alcun riferimento all'ordine dei byte, cioè, per esempio, se il primo elemento dell'array dovesse contenere il byte meno/più significativo. In ogni caso, le operazioni sui bit sono indipendenti dall'architettura, purché eseguite con accortezza, come per altro in questo caso, usando degli unsigned.
Comunque, per dirimere la questione, ho fatto delle prove su un iMac (architettura i386 - little-endian), sfruttando l'emulatore PowerPC (big-endian) presente nel sistema. Ed ecco i risultati. Il numero testato è
0xDDCCBBAA, tutti i programmi sono stati compilati con i comandi:
gcc -Wall -arch i386 nome_programma.c -o nome_programma_i386 gcc -Wall -arch ppc nome_programma.c -o nome_programma_ppc
[*:1r0gukd1]Programma usando un puntatore a carattere
#include <stdio.h> int main(void) { unsigned int n = 0xDDCCBBAA; unsigned int i; unsigned char *cp; cp = (unsigned char*)&n; for (i = 0; i < sizeof(int); i++) { printf("0x%X ", *(cp++)); } printf("\n"); return 0; }
[table="puntatore-a-carattere"]
0xAA 0xBB 0xCC 0xDD
0xDD 0xCC 0xBB 0xAA
Quindi in questo caso l'ordine di memorizzazione è invertito (come peraltro ci si poteva aspettare).
[/*:m:1r0gukd1]
[*:1r0gukd1]Programma proposto da Summerwind78, usando le union
#include <stdio.h> union myUnion { unsigned int ValInt; unsigned char ValByte[4]; }; int main(void) { union myUnion ValUnion; unsigned char Byte1; unsigned char Byte2; unsigned char Byte3; unsigned char Byte4; /* scrivo il valore come int */ ValUnion. ValInt = 0xDDCCBBAA; /* leggo il valore in byte */ Byte1 = ValUnion.ValByte[0]; printf("0x%X ", Byte1); Byte2 = ValUnion.ValByte[1]; printf("0x%X ", Byte2); Byte3 = ValUnion.ValByte[2]; printf("0x%X ", Byte3); Byte4 = ValUnion.ValByte[3]; printf("0x%X ", Byte4); return 0; }
[table="uso-union"]
0xAA 0xBB 0xCC 0xDD
0xDD 0xCC 0xBB 0xAA
Anche in questo caso l'ordine è invertito.
[/*:m:1r0gukd1]
[*:1r0gukd1]Programma usando gli operatori bit a bit
#include <stdio.h> #define NUMBER 0xDDCCBBAA int main(void) { unsigned int i; unsigned int int_size = sizeof(int); unsigned int shift; unsigned int num = NUMBER; unsigned char A [int_size]; for (i = 0; i < int_size; i++) { shift = i * 0x08; A[i] = (unsigned char)((num & (0xFF << shift)) >> shift); printf("0x%X ", A[i]); } printf("\n"); return 0; }
[table="uso-bitwise"]
0xAA 0xBB 0xCC 0xDD
0xAA 0xBB 0xCC 0xDD
Qui l'ordine è invece rispettato. Ribadisco comunque che l'esercizio non richiedeva affatto di controllare l'ordine dei byte.[/*:m:1r0gukd1][/list:u:1r0gukd1]
Ovviamente, nel caso abbia preso un abbaglio clamoroso, "mi corrigerete".

(Se qualcun altro vuol verificare/confrontare i risultati, e non ha un iMac, può farlo su un sistema Linux/Gnu (architetture Linux x86 e Linux PowerPC) tramite qemu.)
Credo che tu abbia frainteso il mio commento
se apatriarca non giudica le mie soluzione quelle meno valide non riesce a dormire!!!

apatriarca scherzo. Mi fai divertire ogni volta che mi commenti



apatriarca scherzo. Mi fai divertire ogni volta che mi commenti

concordo
"apatriarca":
Credo che tu abbia frainteso il mio commento.[...]
Più che altro ho voluto controllare cosa succedeva su un'architettura big-endian, anche perché avevo guardato sul Deitel & Deitel, "C - Corso completo di programmazione", dopo aver letto il tuo messaggio, e lì si diceva testualmente: "I risultati delle manipolazioni dei dati dipendono dalla macchina" (ok, magari non è il massimo come riferimento, ma è quello che avevo a portata di mano in quel momento e non ricordavo più dove avevo messo il K&R), quindi una verifica sul campo si rendeva necessaria.

Personalmente penso che i problemi di portabilità si abbiano soltanto nel caso vengano usati dati signed con l'operatore di scorrimento a destra. Putroppo nemmeno una ricerca in Internet ha chiarito del tutto la questione (il link più attendibile trovato è quello riportato sopra). Magari sarebbe interessante sentire cosa ne pensa/sa in proposito anche qualche altro guru di questa sezione, tipo Rggb, hamming_burst, Sergio o Raptorista, tanto per fare qualche nome a caso.
P.S. Non pensavo che si potessero fare delle tabelle così..
Be', sono prodotte da BBCode personalizzati e quindi è difficile trovarli in altri forum.
