Exercise 3-17 (Unions size and simple use in C/C++)
Chapter_3 Exercise_3-16 Union | SimpleArrays Exercise_3-18 |
Exercise 3-17 TCP1, p. 228
Exercise 3-17. Experiment with Union.cpp (see ch3-Union) by removing various union elements to see the effects on the size of the resulting union. Try assigning to one element (thus one type) of the union and printing out via a different element (thus a different type) to see what happens.
CONTENTS: unions.c Unions.cpp
unions.c download
#include <stdio.h> // for printf(), putchar()
typedef union Union1 // type `union Union1' defined in C
{
char c1;
char c2;
} Union1; // type `Union1' defined in C
typedef union Union2
{
char c;
short sh;
} Union2;
typedef union Union3
{
int i;
long l;
long long ll;
} Union3;
typedef union Union4
{
float f;
double d;
long double ld;
} Union4;
int main()
{
printf("sizeof(char) = %lu\n", sizeof(char));
printf("sizeof(Union1) = %lu\n", sizeof(union Union1)); // sizeof(Union1)
union Union1 u1; // Union1 u1;
printf("c1 = %c (%d), c2 = %c (%d)\n", u1.c1, u1.c1, u1.c2, u1.c2);
u1.c1 = 'a'; // ASCII value 97
printf("c1 = %c (%d), c2 = %c (%d)\n", u1.c1, u1.c1, u1.c2, u1.c2);
u1.c2 = 'b'; // ASCII value 98
printf("c1 = %c (%d), c2 = %c (%d)\n", u1.c1, u1.c1, u1.c2, u1.c2);
putchar('\n');
printf("sizeof(char) = %lu\n", sizeof(char));
printf("sizeof(short) = %lu\n", sizeof(short));
printf("sizeof(Union2) = %lu\n", sizeof(Union2));
Union2 u2;
printf("c = %c (%d), sh = %d\n", u2.c, u2.c, u2.sh);
u2.c = 'c'; // ASCII value 99
printf("c = %c (%d), sh = %d\n", u2.c, u2.c, u2.sh);
u2.sh = 100; // ASCII value for 'd'
printf("c = %c (%d), sh = %d\n", u2.c, u2.c, u2.sh);
putchar('\n');
printf("sizeof(int) = %lu\n", sizeof(int));
printf("sizeof(long) = %lu\n", sizeof(long));
printf("sizeof(long long) = %lu\n", sizeof(long long));
printf("sizeof(Union3) = %lu\n", sizeof(Union3));
Union3 u3;
printf("i = %d, l = %ld, ll = %lld\n", u3.i, u3.l, u3.ll); // decimal
printf("i = %x, l = %lx, ll = %llx\n", u3.i, u3.l, u3.ll); // hex
u3.i = 1;
printf("i = %d, l = %ld, ll = %Ld\n", u3.i, u3.l, u3.ll); // decimal
u3.l = 1000000;
printf("i = %d, l = %ld, ll = %Ld\n", u3.i, u3.l, u3.ll);
u3.ll = 1000000000;
printf("i = %d, l = %ld, ll = %Ld\n", u3.i, u3.l, u3.ll);
putchar('\n');
printf("sizeof(float) = %lu\n", sizeof(float));
printf("sizeof(double) = %lu\n", sizeof(double));
printf("sizeof(long double) = %lu\n", sizeof(long double));
printf("sizeof(Union4) = %lu\n", sizeof(Union4));
Union4 u4;
printf("f = %g, d = %g, ld = %Lg\n", u4.f, u4.d, u4.ld);
u4.f = 1000000000;
printf("f = %g, d = %g, ld = %Lg\n", u4.f, u4.d, u4.ld);
u4.d = 1000000000000;
printf("f = %g, d = %g, ld = %Lg\n", u4.f, u4.d, u4.ld);
u4.ld = 1000000000000000;
printf("f = %g, d = %g, ld = %Lg\n", u4.f, u4.d, u4.ld);
return 0;
}
/*
gcc unions.c -o unions
./unions
sizeof(char) = 1
sizeof(Union1) = 1
c1 = (0), c2 = (0)
c1 = a (97), c2 = a (97)
c1 = b (98), c2 = b (98)
sizeof(char) = 1
sizeof(short) = 2
sizeof(Union2) = 2
c = (0), sh = 0
c = c (99), sh = 99
c = d (100), sh = 100
sizeof(int) = 4
sizeof(long) = 8
sizeof(long long) = 8
sizeof(Union3) = 8
i = -1594085248, l = 94530636099712, ll = 94530636099712 // decimal
i = a0fc3080, l = 55f9a0fc3080, ll = 55f9a0fc3080 // hexadecimal
i = 1, l = 94527935217665, ll = 94527935217665 // decimal
i = 1000000, l = 1000000, ll = 1000000
i = 1000000000, l = 1000000000, ll = 1000000000
sizeof(float) = 4
sizeof(double) = 8
sizeof(long double) = 16
sizeof(Union4) = 16
f = 7.70068e-34, d = 6.95251e-310, ld = 5.12954e-4937
f = 1e+09, d = 6.95257e-310, ld = 5.12958e-4937
f = -1.73472e-18, d = 1e+12, ld = 1.74478e-4932
f = -1.0842e-19, d = -4.77948e+170, ld = 1e+15
*/
Note: For Union3, i = a0fc3080 has the last 8 hex digits (represented on 4 bytes, the size of int) of l = 55f9a0fc3080 (12 hex digits out of max 16 for 8 bytes, size of long). Check RapidTables for numeric_conversions: Hex_to_Decimal or Decimal_to_Hex.
Unions.cpp download
#include <iostream>
using std::cout;
using std::endl;
using std::dec; // decimal
using std::hex; // hexadecimal
union Union1 // types `union Union1', `Union1' defined in C++
{
char c1;
char c2;
};
union Union2
{
char c;
short sh;
};
union Union3
{
int i;
long l;
long long ll;
};
union Union4
{
float f;
double d;
long double ld;
};
int main()
{
cout << "sizeof(char) = " << sizeof(char) << endl;
cout << "sizeof(Union1) = " << sizeof(union Union1) << endl;
union Union1 u1; // Union1 u1;
cout << "c1 = " << u1.c1 << "(" << int(u1.c1) << "), c2 = " << u1.c2
<< "(" << int(u1.c2) << ")" << endl;
u1.c1 = 'a'; // ASCII value 97
cout << "c1 = " << u1.c1 << "(" << int(u1.c1) << "), c2 = " << u1.c2
<< "(" << int(u1.c2) << ")" << endl;
u1.c2 = 'b'; // ASCII value 98
cout << "c1 = " << u1.c1 << "(" << int(u1.c1) << "), c2 = " << u1.c2
<< "(" << int(u1.c2) << ")" << endl;
cout << endl;
cout << "sizeof(char) = " << sizeof(char) << endl;
cout << "sizeof(short) = " << sizeof(short) << endl;
cout << "sizeof(Union2) = " << sizeof(Union2) << endl;
Union2 u2;
cout << "c = " << u2.c << "(" << int(u2.c) << "), sh = " << u2.sh << endl;
u2.c = 'c'; // ASCII value 99
cout << "c = " << u2.c << "(" << int(u2.c) << "), sh = " << u2.sh << endl;
u2.sh = 100; // ASCII value for 'd'
cout << "c = " << u2.c << "(" << int(u2.c) << "), sh = " << u2.sh << endl;
cout << endl;
cout << "sizeof(int) = " << sizeof(int) << endl;
cout << "sizeof(long) = " << sizeof(long) << endl;
cout << "sizeof(long long) = " << sizeof(long long) << endl;
cout << "sizeof(Union3) = " << sizeof(Union3) << endl;
Union3 u3;
cout << "i = " << u3.i << ", l = " << u3.l << ", ll = " << u3.ll << endl; // decimal
cout << "i = " << hex << u3.i << ", l = " << u3.l // hex
<< ", ll = " << u3.ll << dec << endl; // at the end, revert to decimal
u3.i = 1;
cout << "i = " << u3.i << ", l = " << u3.l << ", ll = " << u3.ll << endl;
u3.l = 1000000; // decimal
cout << "i = " << u3.i << ", l = " << u3.l << ", ll = " << u3.ll << endl;
u3.ll = 1000000000;
cout << "i = " << u3.i << ", l = " << u3.l << ", ll = " << u3.ll << endl;
cout << endl;
cout << "sizeof(float) = " << sizeof(float) << endl;
cout << "sizeof(double) = " << sizeof(double) << endl;
cout << "sizeof(long double) = " << sizeof(long double) << endl;
cout << "sizeof(Union4) = " << sizeof(Union4) << endl;
Union4 u4;
cout << "f = " << u4.f << ", d = " << u4.d << ", ld = " << u4.ld << endl;
u4.f = 1000000000;
cout << "f = " << u4.f << ", d = " << u4.d << ", ld = " << u4.ld << endl;
u4.d = 1000000000000;
cout << "f = " << u4.f << ", d = " << u4.d << ", ld = " << u4.ld << endl;
u4.ld = 1000000000000000;
cout << "f = " << u4.f << ", d = " << u4.d << ", ld = " << u4.ld << endl;
return 0;
}
/*
g++ Unions.cpp -o Unions
./Unions
sizeof(char) = 1
sizeof(Union1) = 1
c1 = (0), c2 = (0)
c1 = a(97), c2 = a(97)
c1 = b(98), c2 = b(98)
sizeof(char) = 1
sizeof(short) = 2
sizeof(Union2) = 2
c = (0), sh = 0
c = c(99), sh = 99
c = d(100), sh = 100
sizeof(int) = 4
sizeof(long) = 8
sizeof(long long) = 8
sizeof(Union3) = 8
i = 328057344, l = 94596982751744, ll = 94596982751744 // decimal
i = 138dc200, l = 5609138dc200, ll = 5609138dc200 // hexadecimal
i = 1, l = 94596654694401, ll = 94596654694401 // decimal
i = 1000000, l = 1000000, ll = 1000000
i = 1000000000, l = 1000000000, ll = 1000000000
sizeof(float) = 4
sizeof(double) = 8
sizeof(long double) = 16
sizeof(Union4) = 16
f = -3.00175e+16, d = 6.95269e-310, ld = 5.12967e-4937
f = 1e+09, d = 6.95257e-310, ld = 5.12958e-4937
f = -1.73472e-18, d = 1e+12, ld = 1.74478e-4932
f = -1.0842e-19, d = -4.77948e+170, ld = 1e+15
*/
Note: After printing in hex for Union3, we must revert to decimal format (see print_hex_number on cplusplus). Otherwise, all integral numbers would later be printed in hexadecimal; in particular, the size of long double and Union4 would be displayed as 10 (16 in decimal).
Chapter_3 Exercise_3-16 Union | BACK_TO_TOP | SimpleArrays Exercise_3-18 |
Comments
Post a Comment