4バイトのintをchar配列に格納したい... char配列の最初の4つの場所がintの4バイトになるようにします。
次に、intを配列から引き出したい...
また、誰かがループでこれを行うためのコードを私に与えることができる場合のボーナスポイント... IE 32バイト配列に8 intのように書き込む。
int har = 0x01010101;
char a[4];
int har2;
// write har into char such that:
// a[0] == 0x01, a[1] == 0x01, a[2] == 0x01, a[3] == 0x01 etc.....
// then, pull the bytes out of the array such that:
// har2 == har
みんなありがとう!
編集:int
は4バイトであると想定します...
EDIT2:エンディアンについては気にしないでください...私はエンディアンについて心配します。 C/C++で上記を実現するさまざまな方法が欲しいだけです。ありがとう
EDIT3:わからない場合は、低レベルでシリアル化クラスを記述しようとしています...したがって、いくつかの一般的なデータ型をシリアル化するためのさまざまな戦略を探しています。
最適な方法ではありませんが、エンディアンセーフです。
int har = 0x01010101;
char a[4];
a[0] = har & 0xff;
a[1] = (har>>8) & 0xff;
a[2] = (har>>16) & 0xff;
a[3] = (har>>24) & 0xff;
バイトオーダーなどを気にしない限り、memcpy
がうまくいきます:
_memcpy(a, &har, sizeof(har));
...
memcpy(&har2, a, sizeof(har2));
_
もちろん、特定の実装でsizeof(int)==4
が保証されているわけではありません(実際には、これが実際にfalseである実装もあります)。
ループを書くことはここから簡単です。
int main() {
typedef union foo {
int x;
char a[4];
} foo;
foo p;
p.x = 0x01010101;
printf("%x ", p.a[0]);
printf("%x ", p.a[1]);
printf("%x ", p.a[2]);
printf("%x ", p.a[3]);
return 0;
}
リトルエンディアンマシンでは、a [0]がLSBを保持し、a [3]がMSBを保持することに注意してください。
#include <stdio.h>
int main(void) {
char a[sizeof(int)];
*((int *) a) = 0x01010101;
printf("%d\n", *((int *) a));
return 0;
}
覚えておいてください:
オブジェクトまたは不完全型へのポインタは、別のオブジェクトまたは不完全型へのポインタに変換される場合があります。結果のポインターが指す型に対して正しく配置されていない場合、動作は未定義です。
注:最後に割り当てられていない要素を介して共用体にアクセスすることは、未定義の動作です。 (文字が8ビットで整数が4バイトのプラットフォームを想定)0xFFのビットマスクは1文字をマスクするため、
char arr[4];
int a = 5;
arr[3] = a & 0xff;
arr[2] = (a & 0xff00) >>8;
arr[1] = (a & 0xff0000) >>16;
arr[0] = (a & 0xff000000)>>24;
arr [0]は最上位バイトを保持し、arr [3]は最下位バイトを保持します。
編集:ちょうど&&が論理的な「and」であるトリック&&is bit賢明な「and」を理解するだけです。忘れられていたシフトについてのコメントに感謝します。
ユニオンを使用しないでください、Pavelは明確にします:
C++は、最後に書き込まれたもの以外のユニオンメンバーへのアクセスを禁止しているため、これはUBです。特に、コンパイラーは、上記のコードを使用して
int
メンバーへの割り当てを完全に自由に最適化できます。これは、その値が後で使用されないためです(char[4]
メンバーの後続の読み取りのみを確認し、そこで意味のある価値を提供する義務はありません)。実際には、特にg ++はそのようなトリックを引くことで知られているため、これは単なる理論ではありません。一方、static_cast<void*>
に続けてstatic_cast<char*>
を使用しても、動作することが保証されています。
– Pavel Minaev
これには、新しい配置を使用することもできます。
void foo (int i) {
char * c = new (&i) char[sizeof(i)];
}
#include <stdint.h> int main(int argc、char * argv []){ /* 8 int inループ*/ int i; int * intPtr int intArr [8] = {1、2、3、4、5、6、7、8}; char * charArr = malloc(32); for(i = 0; i <8; i ++){ intPtr =(int *)&(charArr [i * 4]); /* ^ ^ ^ ^ */ /* |にポイント| | */ /* intとしてキャスト* | | */ /* |のアドレス*/ /* char配列内の場所*/ * intPtr = intArr [i];/* */ } を指す場所にintを書き込む/ * intを読み取る*/ for(i = 0; i <8; i ++) { intPtr =(int *)&(charArr [i * 4]); intArr [i] = * intPtr; } char * myArr = malloc(13); int myInt; uint8_t * p8;/*符号なし8ビット整数*/ uint16_t * p16;/*符号なし16ビット整数*/ uint32_t * p32;/*符号なし32ビット整数*/ /* 4バイト整数以外のサイズを使用して、*/ /* myArrのすべてのビットを1に設定*/ p8 =(uint8_t *)&(myArr [0]); p16 =(uint16_t *)&(myArr [1]); p32 =(uint32_t *)&(myArr [5]); * p8 = 255; * p16 = 65535; * p32 = 4294967295; /*値を取得しますバックアウト*/ p16 =(uint16_t *)&(myArr [1]); uint16_t my16 = * p16; /* 16ビットを置くintを通常のintに変換*/ myInt =(int)my16; }
char a[10];
int i=9;
a=boost::lexical_cast<char>(i)
これはcharをintに、そしてその逆に変換するための最良の方法であることがわかりました。
boost :: lexical_castの代替はsprintfです。
char temp[5];
temp[0]="h"
temp[1]="e"
temp[2]="l"
temp[3]="l"
temp[5]='\0'
sprintf(temp+4,%d",9)
cout<<temp;
出力は:hell9になります
union value {[.___。] int i; char bytes [sizeof(int)]; }; value v; vi = 2; char * bytes = v.bytes;