C Data Types: Primary, Modifiers, sizeof, Format Specifiers & Type Casting
Welcome to Phase 2 (Part 2): C Data Types, Modifiers, sizeof, Format Specifiers & Type Casting Masterclass! C is a statically typed language, meaning the compiler must know the exact data type and memory byte size of every variable at compile time. In this comprehensive guide, you will master the 5 primary C data types (int, float, double, char, _Bool), size & sign modifiers (short, long, signed, unsigned), bit-level integer ranges, measuring memory with the sizeof operator, the universal Format Specifiers reference guide, and explicit type casting.
C provides 5 fundamental primary types and 4 type modifiers to customize size and sign representations:
| Data Type | Typical Size in RAM | Range of Values (Typical 64-bit OS) | Common Format Specifier |
|---|---|---|---|
char | 1 Byte (8 bits) | -128 to +127 (or 0 to 255 if unsigned) | %c |
int | 4 Bytes (32 bits) | -2,147,483,648 to +2,147,483,647 | %d or %i |
unsigned int | 4 Bytes (32 bits) | 0 to 4,294,967,295 (Zero negatives, 2x positive!) | %u |
short int | 2 Bytes (16 bits) | -32,768 to +32,767 | %hd |
long long int | 8 Bytes (64 bits) | $-2^{63}$ to $+2^{63}-1$ ($approx pm 9.22 imes 10^{18}$) | %lld |
float | 4 Bytes (32 bits) | $approx pm 3.4 imes 10^{38}$ (6-7 decimal precision digits) | %f |
double | 8 Bytes (64 bits) | $approx pm 1.7 imes 10^{308}$ (15-17 decimal precision digits) | %lf (in scanf) / %f (printf) |
_Bool (C99+) | 1 Byte | 0 (false) or 1 (true) (<stdbool.h>) | %d |
๐ก signed vs unsigned Explained
โข signed (Default): Most significant bit (MSB) is the sign bit ($0 = +ve$, $1 = -ve$). Allows both positive and negative values.
โข unsigned: Disallows negative numbers entirely. The MSB is used for magnitude, doubling the maximum positive range (e.g. unsigned char is 0 to 255 instead of -128 to 127)!
The sizeof operator is evaluated at compile time. It returns the exact size in bytes occupied by a data type or variable in memory as a size_t integer (printed with %zu or %lu):
#include <stdio.h>
#include <stdbool.h>
int main(void) {
printf("sizeof(char): %zu byte\n", sizeof(char));
printf("sizeof(short): %zu bytes\n", sizeof(short));
printf("sizeof(int): %zu bytes\n", sizeof(int));
printf("sizeof(long long): %zu bytes\n", sizeof(long long));
printf("sizeof(float): %zu bytes\n", sizeof(float));
printf("sizeof(double): %zu bytes\n", sizeof(double));
printf("sizeof(bool): %zu byte\n", sizeof(bool));
return 0;
}
In C, printf() and scanf() functions need Format Specifiers (starting with %) to interpret binary bytes in memory correctly:
| Format Specifier | Data Type Targeted | Example Usage | Output Produced |
|---|---|---|---|
%d or %i | signed int | printf("%d", 42); | 42 |
%u | unsigned int | printf("%u", 4000000000U); | 4000000000 |
%c | single char | printf("%c", 'A'); | A |
%s | String (character array) | printf("%s", "Hello"); | Hello |
%f | float (or double in printf) | printf("%.2f", 5.857f); | 5.86 (Rounded to 2 decimals) |
%lf | double (Compulsory in scanf) | scanf("%lf", &price); | Reads 64-bit double |
%p | Pointer / Memory Address | printf("%p", (void*)&age); | 0x7ffee4b1a8 (Hex address) |
%x / %X | Hexadecimal integer | printf("%X", 255); | FF |
%% | Literal percent sign % | printf("100%%"); | 100% |
#include <stdio.h>
int main(void) {
char grade = 'A';
int age = 21;
float height = 5.8f;
double price = 99.99;
printf("Grade: %c\n", grade);
printf("Age: %d\n", age);
printf("Height: %.1f\n", height);
printf("Price: %.2f\n", price);
return 0;
}
1. Implicit Type Conversion (Automatic Type Promotion)
Compiler different types unna expression lo chinna type ni pedda type ga automatic ga promote chesthundhi (Widening):
int a = 5; double b = 2.5; double result = a + b; // 'a' is automatically promoted to 5.0 (result = 7.5)
2. Explicit Type Casting (Manual Operator: (type)value)
Developer explicitly data type ni force chesi convert cheyyadam:
โ ๏ธ Integer Division Trap: int a = 5, b = 2; float div = a / b; produces 2.0 (because integer / integer discards decimals!).
โ
Fixed with Cast: float div = (float)a / b; correctly produces 2.5!
#include <stdio.h>
int main(void) {
int totalMarks = 475;
int totalSubjects = 5;
// Integer division trap vs Explicit Casting
double wrongAvg = totalMarks / totalSubjects; // 95.0
double exactAvg = (double)totalMarks / totalSubjects; // 95.0
int num1 = 7, num2 = 2;
printf("7 / 2 without cast (Integer division): %d\n", num1 / num2); // 3
printf("7 / 2 WITH cast ((float)7 / 2): %.2f\n", (float)num1 / num2); // 3.50
return 0;
}
Run this complete data types and format specifiers program in our live GCC compiler:
#include <stdio.h>
int main(void) {
char grade = 'A';
int age = 21;
float height = 5.8f;
double price = 99.99;
printf("Grade: %c\n", grade);
printf("Age: %d\n", age);
printf("Height: %.1f\n", height);
printf("Price: %.2f\n", price);
return 0;
}