Miten tekisin seuraavan:
int a = muunna_luvuksi("1234",sizeof(int));
Eli a:n arvo ei olisi 1234 vaan muistipaikassa a:n tavujen arvot olisi 41,42,43 ja 44? Ja toisaalta miten sen voi tehdä toisin päin?
Mikäli käytät C:tä, niin silloinhan arvot ovat juuri siten taulukossa, kuten yrität tehdä.
Kyseessä vaan tulostetaan numeroina eikä merkkeinä.
int i; char a[]="1234"; printf ("%s",a); for(i=0,i<strlen(a);i++) { printf ("%i ",a[i]); } printf("\n");
Koodi on viitteellinen, eikä testattu. Eikä ehkä ole puhdasta C:tä.
peran, varmaan tarkoitus oli kuitenkin saada ne tavut sijoitettua yhteen int-muuttujaan.
Tässä on kolme tapaa muunnokseen molempiin suuntiin.
#include <algorithm> #include <string.h> #include <stdio.h> int main() { // esimerkkidata typedef char int_str_t[sizeof(int)]; int_str_t s = {'1', '2', '3', '4'}, sa, sb, sc; int i = 0x34333231, ia, ib, ic; // memcpy memcpy(&ia, s, sizeof(int)); memcpy(sa, &i, sizeof(int)); // std::copy_n std::copy_n(s, sizeof(int), (char*)&ib); std::copy_n((const char*)&i, sizeof(int), sb); // sijoitus ic = *(const int*)s; *(int*)sc = 0x34333231; // malliksi vielä tulostus printf("%#10x %#10x %#10x\n", ia, ib, ic); printf("%.4s %.4s %.4s\n", sa, sb, sc); }
Muista, että joissain koneissa on eri tavujärjestys ja eri määrä tavuja int-muuttujassa.
Metabolix kirjoitti:
peran, varmaan tarkoitus oli kuitenkin saada ne tavut sijoitettua yhteen int-muuttujaan.
Joo, varmaan ymmärsin väärin.
Tukeeko C unionia? Itse jättäisin laskemisen ja tavujärjestyksestä huolehtimisen kääntäjälle.
Esim PL/I:llä kävisi huomattavasti Metabolixin esimerkkiä yksinkertaisemmin:
dcl 1 char_byte union, 2 chars char(4), 2 bytes (0:3) fixed bin(8) unsigned, 2 dword fixed bin(32) unsigned; chars = '1234'; put skip list (chars, hex(dword));
jalski kirjoitti:
Tukeeko C unionia? Itse jättäisin laskemisen ja tavujärjestyksestä huolehtimisen kääntäjälle.
Millä tavalla tämä vaikuttaa sen paremmin laskemiseen kuin tavujärjestykseenkään verrattuna yllä näyttämääni sijoitukseen? Pystytkö PL/I:n unionissa itse vaikuttamaan siihen, tuleeko tavuista '1234' luku 0x31323334 (big endian) vai 0x34333231 (little endian)? C:ssä tämä ei ainakaan onnistu, vaan luvut ovat järjestelmäriippuvaisessa muodossa.
Ja kyllä, C tukee myös unioneja. Niistä ei ole tässä hyötyä. C:ssä tavujen kopiointi muuttujasta toiseen (ilman lopettavaa nollatavua) on niin hankalaa, että siinä aukeaa taas paikka monelle uudelle virheelle kopioitavan määrän suhteen.
Metabolix kirjoitti:
Pystytkö PL/I:n unionissa itse vaikuttamaan siihen, tuleeko tavuista '1234' luku 0x31323334 (big endian) vai 0x34333231 (little endian)? C:ssä tämä ei ainakaan onnistu, vaan luvut ovat järjestelmäriippuvaisessa muodossa.
Itse asiassa kyllä, lisäämällä muuttujan perään "littleendian" tai "bigendian" attribuutti. Tässä laittamalla ykköstason union määrittelyn jälkeen attribuutti, vaikuttaa se koko unioniin.
Aihe on jo aika vanha, joten et voi enää vastata siihen.