サーチ…
構造体と共用体の違い
これは、共用体メンバがメモリを共有し、構造体メンバがメモリを共有していないことを示しています。
#include <stdio.h>
#include <string.h>
union My_Union
{
int variable_1;
int variable_2;
};
struct My_Struct
{
int variable_1;
int variable_2;
};
int main (void)
{
union My_Union u;
struct My_Struct s;
u.variable_1 = 1;
u.variable_2 = 2;
s.variable_1 = 1;
s.variable_2 = 2;
printf ("u.variable_1: %i\n", u.variable_1);
printf ("u.variable_2: %i\n", u.variable_2);
printf ("s.variable_1: %i\n", s.variable_1);
printf ("s.variable_2: %i\n", s.variable_2);
printf ("sizeof (union My_Union): %i\n", sizeof (union My_Union));
printf ("sizeof (struct My_Struct): %i\n", sizeof (struct My_Struct));
return 0;
}
ユニオンを使用して値を再解釈する
いくつかのC実装では、コードがunion型の1つのメンバに書き込んだり、別の型から読み込んだりして再解析型キャストを実行することができます(古い型のビット表現として新しい型を解析する)。
しかし、これはCの標準の現在または過去では許可されていませんが、未定義の動作につながることに注意してください。コンパイラによって提供される非常に一般的な拡張は少なくありません(したがって、 。
この技術の実際の例としては、IEEE 754浮動小数点数の実装の詳細に依存して浮動小数点演算を使用するよりも速く逆平方根を実行する「高速逆平方根」アルゴリズムがあります。このアルゴリズムは、ポインタキャスティング(これは非常に危険であり、厳密なエイリアシング規則を破る)またはunion(これはまだ未定義の動作ですが、多くのコンパイラで動作します)
union floatToInt
{
int32_t intMember;
float floatMember; /* Float must be 32 bits IEEE 754 for this to work */
};
float inverseSquareRoot(float input)
{
union floatToInt x;
int32_t i;
float f;
x.floatMember = input; /* Assign to the float member */
i = x.intMember; /* Read back from the integer member */
i = 0x5f3759df - (i >> 1);
x.intMember = i; /* Assign to the integer member */
f = x.floatMember; /* Read back from the float member */
f = f * (1.5f - input * 0.5f * f * f);
return f * (1.5f - input * 0.5f * f * f);
}
この技術は、従来のコンピュータグラフィックスやゲームでは、浮動小数点演算の使用に比べてスピードが速かったため広く使用されていましたが、妥協であり、精度を失い、スピードと引き換えに非常にポータブルではありませんでした。
1人の組合員に書き込み、別の組合員から読む
組合のメンバーは、同じ空間を共有します。つまり、あるメンバーへの書き込みは他のすべてのメンバーのデータを上書きし、あるメンバーからの読み取り結果は他のすべてのメンバーからの読み取りと同じデータになります。しかし、ユニオンメンバーは異なるタイプとサイズを持つことができるため、読み込まれるデータは異なる解釈が可能です。http://www.riptutorial.com/c/example/9399/using-unions-to-reinterpret-values
以下の簡単な例は、同じタイプの2つのメンバーを持つ共用体を示しています。これは、メンバーへの書き込みをすることを示しているm_1
メンバーから読み出され書き込まれた値に結果m_2
とメンバーへの書き込みm_2
メンバーから読み出され書き込まれた値に結果m_1
。
#include <stdio.h>
union my_union /* Define union */
{
int m_1;
int m_2;
};
int main (void)
{
union my_union u; /* Declare union */
u.m_1 = 1; /* Write to m_1 */
printf("u.m_2: %i\n", u.m_2); /* Read from m_2 */
u.m_2 = 2; /* Write to m_2 */
printf("u.m_1: %i\n", u.m_1); /* Read from m_1 */
return 0;
}
結果
u.m_2: 1
u.m_1: 2