Cでの予期せぬ結果:私は131809282883593 int型8バイト長の長いを復号化するために割り当てを実装しましたビットフィールドと連合 - 私はCコースには、次の割り当てを与えてきた
次のように:
#include <stdio.h>
#include <string.h>
struct Message {
unsigned int hour : 5;
unsigned int minutes : 6;
unsigned int seconds : 6;
unsigned int day : 5;
unsigned int month : 4;
unsigned int year : 12;
unsigned long long int code : 26;
}; // 64 bit in total
union Msgdecode {
long long int datablob;
struct Message elems;
};
int main(void) {
long long int datablob = 131809282883593;
union Msgdecode m;
m.datablob = datablob;
printf("%d:%d:%d %d.%d.%d code:%lu\n", m.elems.hour, m.elems.minutes,
m.elems.seconds, m.elems.day, m.elems.month, m.elems.year,(long unsigned int) m.elems.code);
union Msgdecode m2;
m2.elems.hour = 9;
m2.elems.minutes = 0;
m2.elems.seconds = 0;
m2.elems.day = 30;
m2.elems.month = 5;
m2.elems.year = 2017;
m2.elems.code = 4195376;
printf("m2.datablob: should: 131809282883593 is: %lld\n", m2.datablob); //WHY does m2.datablob != m.datablob?!
printf("m.datablob: should: 131809282883593 is: %lld\n", m.datablob);
printf("%d:%d:%d %d.%d.%d code:%lu\n", m2.elems.hour, m2.elems.minutes,
m2.elems.seconds, m2.elems.day, m2.elems.month, m2.elems.year, (long unsigned int) m2.elems.code);
}
を私のハードを与える..what時間は出力です。これまでデコード/エンコーディングはうまくいきました。 9:0:0 2017年5月30日とコード4195376はを期待されているが、「datablob」の差は本当にない - そしてそれが由来どこ理由/私が把握することはできません。
9:0:0 30.5.2017 code:4195376
m2.datablob: should: 131809282883593 is: 131810088189961
m.datablob: should: 131809282883593 is: 131809282883593
9:0:0 30.5.2017 code:4195376
あなたが見ることができるように、データブロックはであり、元に戻ってになりますが、オリジナルはありません。私はこれについてCに慣れ親しんだ同僚に相談しましたが、この動作の理由を理解できませんでした。
Q:なぜブロブが異なるのですか?
ボーナス-Q:別のフィールドを含めるために労働組合Msgdecode
を操作すると、奇妙なことが起こります:
union Msgdecode {
long long int datablob;
struct Message elems;
char bytes[8]; // added this
};
結果:
9:0:0 30.5.2017 code:0
m2.datablob: should: 131809282883593 is: 8662973939721
m.datablob: should: 131809282883593 is: 131809282883593
9:0:0 30.5.2017 code:4195376
をPS:ビットフィールド+組合の質問についてはSOに読ん彼らがむしろ信頼できないという印象を与えました。これは一般的に言えますか?
これがあなたの割り当てであれば、それはひどいものです。ビットフィールド構造はレイアウトに関してほとんど保証しません。シフトとマスキングを使用してください!そして、 'int'、' unsigned int'、 '_Bool'ビットフリッド以外を使うことは保証されていません。脇役として:あなたが使用するタイプのどれも、spicifの表現や幅を保証しません!固定幅が必要な場合は、固定幅タイプを使用してください。 – Olaf
@Olafそれは私の割り当てです。最終的に私のPS-Questionは「はい」と答えることができますか? :) – Gewure
はい、私たちは個人指導のサービスではありません。その家庭教師と良いCの本を取得し、本の情報でコースの材料をフィルタリングします。脇役として:私は決して私の生徒にそのような課題を与えませんでした:コードで:あなたは私のコースで失敗するでしょう。いくつかの理由:上記を参照してください。 – Olaf