c
examples
examples.cš§c
/*
* ============================================================================
* TYPE CASTING IN C - EXAMPLES
* ============================================================================
* This file demonstrates implicit and explicit type conversions.
*
* Compile: gcc -Wall examples.c -o examples -lm
* Run: ./examples
* ============================================================================
*/
#include <stdio.h>
#include <stdint.h>
#include <math.h>
/*
* Example 1: Implicit Integer Promotion
* -------------------------------------
* Small integer types are promoted to int in expressions.
*/
void example_integer_promotion() {
printf("\n=== Example 1: Integer Promotion ===\n");
char a = 10;
char b = 20;
// Both chars promoted to int before addition
printf("sizeof(char) = %zu\n", sizeof(char));
printf("sizeof(a + b) = %zu (promoted to int)\n", sizeof(a + b));
// Result fits in char
char result = a + b;
printf("char + char: %d\n", result);
// Demonstration with short
short s1 = 100, s2 = 200;
printf("\nsizeof(short) = %zu\n", sizeof(short));
printf("sizeof(s1 + s2) = %zu (promoted to int)\n", sizeof(s1 + s2));
}
/*
* Example 2: Implicit Type Conversion in Expressions
* -------------------------------------------------
* Types are converted to the "higher" type in mixed expressions.
*/
void example_implicit_conversion() {
printf("\n=== Example 2: Implicit Conversion ===\n");
int i = 10;
float f = 3.5f;
double d = 2.5;
printf("int i = %d, float f = %.1f, double d = %.1f\n\n", i, f, d);
// int + float ā float
float result1 = i + f;
printf("int + float ā float: %d + %.1f = %.1f\n", i, f, result1);
// float + double ā double
double result2 = f + d;
printf("float + double ā double: %.1f + %.1f = %.1f\n", f, d, result2);
// int + double ā double
double result3 = i + d;
printf("int + double ā double: %d + %.1f = %.1f\n", i, d, result3);
// All together
double result4 = i + f + d;
printf("int + float + double = %.1f\n", result4);
}
/*
* Example 3: Integer Division Problem
* -----------------------------------
* Common pitfall: integer division truncates.
*/
void example_integer_division() {
printf("\n=== Example 3: Integer Division ===\n");
int a = 5, b = 2;
// Integer division - truncates!
int resultInt = a / b;
printf("Integer: %d / %d = %d (truncated!)\n", a, b, resultInt);
// Still truncates because division happens first
float wrong = a / b;
printf("Wrong: %d / %d = %.2f (still 2.0)\n", a, b, wrong);
// Cast one operand to float
float correct1 = (float)a / b;
printf("Correct: (float)%d / %d = %.2f\n", a, b, correct1);
float correct2 = a / (float)b;
printf("Correct: %d / (float)%d = %.2f\n", a, b, correct2);
// Cast result - too late!
float late = (float)(a / b);
printf("Too late: (float)(%d / %d) = %.2f (still 2.0)\n", a, b, late);
// Practical example: average calculation
int sum = 17;
int count = 3;
float average = (float)sum / count;
printf("\nAverage: %d / %d = %.2f\n", sum, count, average);
}
/*
* Example 4: Explicit Casting
* ---------------------------
* Using the cast operator.
*/
void example_explicit_casting() {
printf("\n=== Example 4: Explicit Casting ===\n");
// Float to int (truncation, not rounding)
float f = 3.7f;
int i = (int)f;
printf("(int)3.7 = %d (truncated, not rounded)\n", i);
f = -3.7f;
i = (int)f;
printf("(int)-3.7 = %d (truncated toward zero)\n", i);
// Rounding
f = 3.7f;
i = (int)(f + 0.5f);
printf("Rounded 3.7: (int)(3.7 + 0.5) = %d\n", i);
// Using math functions
printf("\nUsing math.h:\n");
double d = 3.7;
printf("floor(3.7) = %.0f\n", floor(d));
printf("ceil(3.7) = %.0f\n", ceil(d));
printf("round(3.7) = %.0f\n", round(d));
d = 3.3;
printf("floor(3.3) = %.0f\n", floor(d));
printf("ceil(3.3) = %.0f\n", ceil(d));
printf("round(3.3) = %.0f\n", round(d));
}
/*
* Example 5: Character and Integer
* --------------------------------
* Characters are small integers (ASCII values).
*/
void example_char_int() {
printf("\n=== Example 5: Character and Integer ===\n");
char c = 'A';
int ascii = (int)c;
printf("'%c' as int: %d\n", c, ascii);
// Integer to character
int num = 66;
char letter = (char)num;
printf("%d as char: '%c'\n", num, letter);
// Character arithmetic
printf("\nCharacter arithmetic:\n");
c = 'A';
printf("'A' + 1 = '%c' (ASCII %d)\n", c + 1, c + 1);
printf("'A' + 25 = '%c' (ASCII %d)\n", c + 25, c + 25);
// Convert lowercase to uppercase
char lower = 'g';
char upper = lower - 32; // or: lower - ('a' - 'A')
printf("'%c' to uppercase: '%c'\n", lower, upper);
// Digit character to number
char digit = '7';
int value = digit - '0';
printf("'%c' as number: %d\n", digit, value);
// Number to digit character
int n = 5;
char d = (char)(n + '0');
printf("%d as digit char: '%c'\n", n, d);
}
/*
* Example 6: Widening vs Narrowing
* --------------------------------
* Safe vs dangerous conversions.
*/
void example_widening_narrowing() {
printf("\n=== Example 6: Widening vs Narrowing ===\n");
// Widening (safe - no data loss)
printf("Widening (safe):\n");
char c = 127;
short s = c;
int i = s;
long l = i;
printf("char %d ā short %d ā int %d ā long %ld\n", c, s, i, l);
// Narrowing (dangerous - may lose data)
printf("\nNarrowing (dangerous):\n");
int big = 300;
char small = (char)big; // 300 doesn't fit in char!
printf("int %d ā char %d (data loss!)\n", big, small);
big = 127;
small = (char)big; // Fits in char
printf("int %d ā char %d (fits)\n", big, small);
// Long to int
long bigLong = 3000000000L;
int truncated = (int)bigLong;
printf("long %ld ā int %d (overflow!)\n", bigLong, truncated);
}
/*
* Example 7: Signed and Unsigned
* ------------------------------
* Dangerous conversions between signed and unsigned.
*/
void example_signed_unsigned() {
printf("\n=== Example 7: Signed and Unsigned ===\n");
// Negative to unsigned
int negative = -1;
unsigned int asUnsigned = (unsigned int)negative;
printf("signed -1 ā unsigned: %u\n", asUnsigned);
printf("Binary: -1 is all 1s, which is max unsigned\n");
// Large unsigned to signed
unsigned int bigUnsigned = 4000000000U;
int asSigned = (int)bigUnsigned;
printf("\nunsigned %u ā signed: %d\n", bigUnsigned, asSigned);
// The comparison trap!
printf("\nDangerous comparison:\n");
unsigned int u = 10;
int s = -1;
// This comparison gives unexpected results!
if (s < u) {
printf("-1 < 10: true (expected)\n");
} else {
printf("-1 < 10: false (WRONG! -1 becomes %u)\n", (unsigned int)s);
}
// Safe way to compare
if (s < 0 || (unsigned int)s < u) {
printf("Safe comparison: -1 is less\n");
}
}
/*
* Example 8: Pointer Casting
* --------------------------
* Converting between pointer types.
*/
void example_pointer_casting() {
printf("\n=== Example 8: Pointer Casting ===\n");
int x = 0x12345678;
printf("int x = 0x%08X\n\n", x);
// Cast to void* (generic pointer)
void *voidPtr = &x;
printf("void* can hold any pointer type\n");
// Cast back to int*
int *intPtr = (int*)voidPtr;
printf("Cast back to int*: %d\n", *intPtr);
// View as bytes (little-endian)
unsigned char *bytePtr = (unsigned char*)&x;
printf("\nAs bytes (little-endian): ");
for (int i = 0; i < sizeof(int); i++) {
printf("%02X ", bytePtr[i]);
}
printf("\n");
// Array element access with casting
int arr[] = {100, 200, 300};
void *basePtr = arr;
// Access second element through void pointer
int *element = (int*)basePtr + 1;
printf("\nSecond element: %d\n", *element);
}
/*
* Example 9: Fixed-Width Types
* ----------------------------
* Using stdint.h for predictable sizes.
*/
void example_fixed_width() {
printf("\n=== Example 9: Fixed-Width Types ===\n");
int8_t i8 = 127;
int16_t i16 = 32767;
int32_t i32 = 2147483647;
int64_t i64 = 9223372036854775807LL;
printf("int8_t: %d (size: %zu)\n", i8, sizeof(int8_t));
printf("int16_t: %d (size: %zu)\n", i16, sizeof(int16_t));
printf("int32_t: %d (size: %zu)\n", i32, sizeof(int32_t));
printf("int64_t: %lld (size: %zu)\n", (long long)i64, sizeof(int64_t));
// Explicit casting between fixed-width types
printf("\nCasting between fixed-width types:\n");
i32 = 1000;
i8 = (int8_t)i32; // Truncated!
printf("int32_t %d ā int8_t %d (overflow!)\n", 1000, i8);
i32 = 100;
i8 = (int8_t)i32; // Fits
printf("int32_t %d ā int8_t %d (fits)\n", 100, i8);
}
/*
* Example 10: Practical Applications
* ----------------------------------
* Real-world casting scenarios.
*/
void example_practical() {
printf("\n=== Example 10: Practical Applications ===\n");
// 1. Calculating percentage
int passed = 85;
int total = 100;
float percentage = (float)passed / total * 100;
printf("1. Percentage: %d/%d = %.1f%%\n", passed, total, percentage);
// 2. Temperature conversion
int fahrenheit = 98;
float celsius = (float)(fahrenheit - 32) * 5 / 9;
printf("2. Temperature: %d°F = %.1f°C\n", fahrenheit, celsius);
// 3. Color component extraction
unsigned int color = 0xFF5733; // RGB color
unsigned char red = (unsigned char)((color >> 16) & 0xFF);
unsigned char green = (unsigned char)((color >> 8) & 0xFF);
unsigned char blue = (unsigned char)(color & 0xFF);
printf("3. Color 0x%06X: R=%d, G=%d, B=%d\n", color, red, green, blue);
// 4. Scaling integer to percentage
int value = 75;
int maxValue = 255;
int percent = (int)((float)value / maxValue * 100);
printf("4. Scale: %d/%d = %d%%\n", value, maxValue, percent);
// 5. Rounding to nearest 10
int number = 47;
int rounded = ((number + 5) / 10) * 10;
printf("5. Round to nearest 10: %d ā %d\n", number, rounded);
// 6. Safe average
int a = 1000000000, b = 2000000000;
// int wrong = (a + b) / 2; // May overflow!
int safe = a / 2 + b / 2 + (a % 2 + b % 2) / 2;
printf("6. Safe average of %d and %d: %d\n", a, b, safe);
}
/*
* Example 11: Bit Representation
* ------------------------------
* Viewing bit patterns through casting.
*/
void example_bit_representation() {
printf("\n=== Example 11: Bit Representation ===\n");
// View float as integer bits
float f = 3.14f;
// Using union (safe, well-defined)
union {
float f;
unsigned int u;
} converter;
converter.f = f;
printf("float %.2f as bits: 0x%08X\n", f, converter.u);
// Break down IEEE 754 format
unsigned int bits = converter.u;
unsigned int sign = (bits >> 31) & 1;
unsigned int exponent = (bits >> 23) & 0xFF;
unsigned int mantissa = bits & 0x7FFFFF;
printf("Sign: %d, Exponent: %d, Mantissa: 0x%06X\n",
sign, exponent, mantissa);
// Show negative
converter.f = -3.14f;
printf("\nfloat %.2f as bits: 0x%08X\n", -3.14f, converter.u);
}
/*
* Main Function
*/
int main() {
printf("āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā\n");
printf("ā TYPE CASTING IN C - EXAMPLES ā\n");
printf("ā Understanding type conversions ā\n");
printf("āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā\n");
example_integer_promotion();
example_implicit_conversion();
example_integer_division();
example_explicit_casting();
example_char_int();
example_widening_narrowing();
example_signed_unsigned();
example_pointer_casting();
example_fixed_width();
example_practical();
example_bit_representation();
printf("\n=== All Examples Completed! ===\n");
return 0;
}