c
exercises
exercises.cš§c
/*
* ============================================================================
* TYPE CASTING IN C - EXERCISES
* ============================================================================
* Complete these exercises to master type casting.
*
* Compile: gcc -Wall exercises.c -o exercises -lm
* Run: ./exercises
* ============================================================================
*/
#include <stdio.h>
#include <stdint.h>
#include <math.h>
/*
* ============================================================================
* EXERCISE 1: Integer Division Fix
* ============================================================================
* Difficulty: Easy
*
* Task: Fix the integer division problem to get accurate results.
*
* Expected Output:
* 7 / 3 = 2.33 (not 2.00!)
* 10 / 4 = 2.50 (not 2.00!)
*/
void exercise_1() {
printf("\n=== Exercise 1: Integer Division Fix ===\n");
int a = 7, b = 3;
int c = 10, d = 4;
// TODO: Fix these to get proper floating-point results
float result1 = a / b; // Currently gives 2.00
float result2 = c / d; // Currently gives 2.00
printf("%d / %d = %.2f\n", a, b, result1);
printf("%d / %d = %.2f\n", c, d, result2);
}
/*
* ============================================================================
* EXERCISE 2: ASCII Conversion
* ============================================================================
* Difficulty: Easy
*
* Task: Convert between characters and their ASCII values.
*
* Expected Output:
* 'A' ā 65
* 65 ā 'A'
* 'z' ā 122
* 97 ā 'a'
*/
void exercise_2() {
printf("\n=== Exercise 2: ASCII Conversion ===\n");
char c1 = 'A';
int n1 = 65;
char c2 = 'z';
int n2 = 97;
// TODO: Convert and print
// Char to ASCII
// ASCII to Char
}
/*
* ============================================================================
* EXERCISE 3: Temperature Conversion
* ============================================================================
* Difficulty: Easy
*
* Task: Convert Celsius to Fahrenheit and vice versa.
* Formula: F = C * 9/5 + 32
*
* Expected Output:
* 25°C = 77.00°F
* 100°F = 37.78°C
*/
void exercise_3() {
printf("\n=== Exercise 3: Temperature Conversion ===\n");
int celsius = 25;
int fahrenheit = 100;
// TODO: Convert celsius to fahrenheit (must use casting!)
float f_result; // Should be 77.00
// TODO: Convert fahrenheit to celsius (must use casting!)
float c_result; // Should be 37.78
printf("%d°C = %.2f°F\n", celsius, f_result);
printf("%d°F = %.2f°C\n", fahrenheit, c_result);
}
/*
* ============================================================================
* EXERCISE 4: Rounding Numbers
* ============================================================================
* Difficulty: Medium
*
* Task: Implement different rounding methods using casting.
*
* Expected Output:
* 3.7: truncate=3, round=4, floor=3, ceil=4
* 3.2: truncate=3, round=3, floor=3, ceil=4
* -3.7: truncate=-3, round=-4, floor=-4, ceil=-3
*/
void exercise_4() {
printf("\n=== Exercise 4: Rounding Numbers ===\n");
float values[] = {3.7f, 3.2f, -3.7f};
int count = sizeof(values) / sizeof(values[0]);
for (int i = 0; i < count; i++) {
float f = values[i];
// TODO: Implement each rounding method
int truncated; // Just cast to int
int rounded; // Use (int)(f + 0.5f) for positive, adjust for negative
int floored; // Use floor() from math.h
int ceiled; // Use ceil() from math.h
// Truncation
// Rounding (handle positive and negative)
// Floor
// Ceil
printf("%.1f: truncate=%d, round=%d, floor=%d, ceil=%d\n",
f, truncated, rounded, floored, ceiled);
}
}
/*
* ============================================================================
* EXERCISE 5: Percentage Calculation
* ============================================================================
* Difficulty: Easy
*
* Task: Calculate exam score as percentage.
*
* Expected Output:
* Score: 17/20 = 85.00%
* Score: 7/11 = 63.64%
* Score: 3/8 = 37.50%
*/
void exercise_5() {
printf("\n=== Exercise 5: Percentage Calculation ===\n");
int scores[][2] = {{17, 20}, {7, 11}, {3, 8}};
int count = sizeof(scores) / sizeof(scores[0]);
for (int i = 0; i < count; i++) {
int obtained = scores[i][0];
int total = scores[i][1];
// TODO: Calculate percentage with proper casting
float percentage;
printf("Score: %d/%d = %.2f%%\n", obtained, total, percentage);
}
}
/*
* ============================================================================
* EXERCISE 6: Signed/Unsigned Awareness
* ============================================================================
* Difficulty: Medium
*
* Task: Predict the output before running, then verify.
*
* Questions:
* 1. What happens when -1 is cast to unsigned?
* 2. What happens when a large unsigned is cast to signed?
* 3. Why does -1 < 10U give unexpected results?
*/
void exercise_6() {
printf("\n=== Exercise 6: Signed/Unsigned ===\n");
// TODO: Predict each result before running
// Question 1: -1 as unsigned
int neg = -1;
unsigned int asUnsigned = (unsigned int)neg;
printf("1. (unsigned int)(-1) = %u\n", asUnsigned);
printf(" Prediction: ?\n");
// Question 2: Large unsigned as signed
unsigned int big = 4000000000U;
int asSigned = (int)big;
printf("\n2. (int)(4000000000U) = %d\n", asSigned);
printf(" Prediction: ?\n");
// Question 3: Comparison trap
int a = -1;
unsigned int b = 10;
int comparison = (a < b); // What will this be?
printf("\n3. (-1 < 10U) = %d\n", comparison);
printf(" Prediction: ?\n");
printf(" Explanation: -1 becomes %u when compared to unsigned\n",
(unsigned int)a);
}
/*
* ============================================================================
* EXERCISE 7: Byte Extraction
* ============================================================================
* Difficulty: Medium
*
* Task: Extract individual bytes from a 32-bit integer.
*
* Expected Output:
* 0x12345678:
* Byte 0 (LSB): 0x78
* Byte 1: 0x56
* Byte 2: 0x34
* Byte 3 (MSB): 0x12
*/
void exercise_7() {
printf("\n=== Exercise 7: Byte Extraction ===\n");
unsigned int value = 0x12345678;
printf("0x%08X:\n", value);
// TODO: Extract each byte using bitwise ops and casting
unsigned char byte0; // LSB
unsigned char byte1;
unsigned char byte2;
unsigned char byte3; // MSB
printf("Byte 0 (LSB): 0x%02X\n", byte0);
printf("Byte 1: 0x%02X\n", byte1);
printf("Byte 2: 0x%02X\n", byte2);
printf("Byte 3 (MSB): 0x%02X\n", byte3);
}
/*
* ============================================================================
* EXERCISE 8: Color Manipulation
* ============================================================================
* Difficulty: Medium
*
* Task: Work with RGB colors represented as 32-bit integers.
*
* Expected Output:
* Color 0xFF5733: R=255, G=87, B=51
* Created color: 0x00FF00 (green)
*/
void exercise_8() {
printf("\n=== Exercise 8: Color Manipulation ===\n");
// Part 1: Extract RGB components
unsigned int color = 0xFF5733;
// TODO: Extract R, G, B values (8 bits each)
unsigned char r, g, b;
printf("Color 0x%06X: R=%d, G=%d, B=%d\n", color, r, g, b);
// Part 2: Create color from components
// TODO: Create a pure green color (R=0, G=255, B=0)
unsigned int green;
printf("Created color: 0x%06X (green)\n", green);
}
/*
* ============================================================================
* EXERCISE 9: Safe Average
* ============================================================================
* Difficulty: Hard
*
* Task: Calculate the average of two large integers without overflow.
*
* Naive approach (a + b) / 2 may overflow!
*
* Expected Output:
* a = 2000000000, b = 2000000000
* Unsafe average: (overflow!)
* Safe average: 2000000000
*/
void exercise_9() {
printf("\n=== Exercise 9: Safe Average ===\n");
int a = 2000000000;
int b = 2000000000;
printf("a = %d, b = %d\n", a, b);
// Unsafe: May overflow
int unsafe = (a + b) / 2;
printf("Unsafe average: %d (may be wrong!)\n", unsafe);
// TODO: Calculate safe average without overflow
// Hint 1: Use long long for intermediate calculation
// Hint 2: Or use: a/2 + b/2 + (a%2 + b%2)/2
int safe;
printf("Safe average: %d\n", safe);
}
/*
* ============================================================================
* EXERCISE 10: Fixed-Width Conversions
* ============================================================================
* Difficulty: Medium
*
* Task: Practice with fixed-width types from stdint.h
*
* Expected Output:
* int8_t max: 127
* int16_t max: 32767
* int32_t max: 2147483647
*
* Overflow test:
* int8_t 200 = -56 (overflow!)
* int16_t 40000 = -25536 (overflow!)
*/
void exercise_10() {
printf("\n=== Exercise 10: Fixed-Width Types ===\n");
// TODO: Find and print max values for each type
int8_t max8;
int16_t max16;
int32_t max32;
// Max values: 2^(n-1) - 1
printf("int8_t max: %d\n", max8);
printf("int16_t max: %d\n", max16);
printf("int32_t max: %d\n", max32);
printf("\nOverflow test:\n");
// TODO: Demonstrate overflow with casting
int16_t big16 = 200; // Fits in int16
int8_t small8 = (int8_t)big16; // May overflow!
printf("int8_t 200 = %d (overflow!)\n", small8);
int32_t big32 = 40000;
int16_t small16 = (int16_t)big32;
printf("int16_t 40000 = %d (overflow!)\n", small16);
}
/*
* ============================================================================
* BONUS: Type Punning with Union
* ============================================================================
* Difficulty: Hard
*
* Task: Use a union to view the bit representation of a float.
*/
void bonus_exercise() {
printf("\n=== BONUS: Type Punning ===\n");
// TODO: Create a union to view float as int
// union {
// float f;
// unsigned int i;
// } converter;
// TODO: Set float to 1.0, -1.0, and 0.0
// Print the integer representation in hexadecimal
// Expected insight:
// 1.0 = 0x3F800000
// -1.0 = 0xBF800000
// 0.0 = 0x00000000
}
/*
* ============================================================================
* MAIN FUNCTION
* ============================================================================
*/
int main() {
printf("āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā\n");
printf("ā TYPE CASTING - EXERCISES ā\n");
printf("ā Complete each exercise to practice ā\n");
printf("āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā\n");
// Uncomment each exercise as you complete it
// exercise_1();
// exercise_2();
// exercise_3();
// exercise_4();
// exercise_5();
// exercise_6();
// exercise_7();
// exercise_8();
// exercise_9();
// exercise_10();
// bonus_exercise();
printf("\n=== Uncomment exercises in main() to run them ===\n");
return 0;
}
/*
* ============================================================================
* ANSWER KEY
* ============================================================================
*
* Exercise 1:
* float result1 = (float)a / b;
* float result2 = (float)c / d;
*
* Exercise 2:
* printf("'%c' ā %d\n", c1, (int)c1);
* printf("%d ā '%c'\n", n1, (char)n1);
*
* Exercise 3:
* float f_result = (float)celsius * 9 / 5 + 32;
* float c_result = (float)(fahrenheit - 32) * 5 / 9;
*
* Exercise 4:
* truncated = (int)f;
* rounded = (f >= 0) ? (int)(f + 0.5f) : (int)(f - 0.5f);
* floored = (int)floor(f);
* ceiled = (int)ceil(f);
*
* Exercise 5:
* float percentage = (float)obtained / total * 100;
*
* Exercise 7:
* byte0 = (unsigned char)(value & 0xFF);
* byte1 = (unsigned char)((value >> 8) & 0xFF);
* byte2 = (unsigned char)((value >> 16) & 0xFF);
* byte3 = (unsigned char)((value >> 24) & 0xFF);
*
* Exercise 8:
* r = (unsigned char)((color >> 16) & 0xFF);
* g = (unsigned char)((color >> 8) & 0xFF);
* b = (unsigned char)(color & 0xFF);
* green = ((unsigned int)0 << 16) | ((unsigned int)255 << 8) | (unsigned int)0;
*
* Exercise 9:
* int safe = (int)((long long)a + (long long)b) / 2;
* // OR
* int safe = a/2 + b/2 + (a%2 + b%2)/2;
*
* Exercise 10:
* max8 = 127; // 2^7 - 1
* max16 = 32767; // 2^15 - 1
* max32 = 2147483647; // 2^31 - 1
*
* BONUS:
* union { float f; unsigned int i; } converter;
* converter.f = 1.0f;
* printf("1.0 = 0x%08X\n", converter.i);
*
* ============================================================================
*/