Data Types in C ๐
Mentor's Note: Data types are like egg cartons of different sizes. An egg carton of size 6 cannot hold 12 eggs, and you wouldn't use a 30-egg tray to store 2 eggs. Choosing the right data type saves computer memory! ๐ก
๐ Educational Content: This tutorial is designed to align with GSEB Std 10/12, CBSE Computer Science, and BCA Sem 1 syllabus standards.
By the end of this tutorial, you'll know:
- The 4 primary data types in C (
char,int,float,double). - How to determine the exact size of any data type using
sizeof(). - How type qualifiers (
short,long,signed,unsigned) modify data types. - The memory sizes, ranges, and format specifiers for each modified data type.
- How memory overflow works when you exceed a data type's range.
๐ The Scenario: The Warehouse Storage Cratesโ
Imagine you run a shipping warehouse. To organize items, you use specific storage crates:
- Small jewelry drawer: Stores exactly one character tag (like 'A' or 'B'). Takes up very little space.
- Medium file drawer: Stores whole numbers (like invoice IDs). Can hold numbers up to millions.
- Graduated cylinder: Stores precise quantities with decimal points (like liters of oil).
- Giant secure vault: Stores long, ultra-precise scientific decimal measurements.
If you try to store a giant machine in the jewelry drawer, the drawer breaks. If you store a single jewelry ring in the giant vault, you waste an enormous amount of vault space and money.
In C programming:
- The Jewelry Drawer is the
chartype (1 byte). - The File Drawer is the
inttype (4 bytes). - The Graduated Cylinder is the
floattype (4 bytes). - The Giant Vault is the
doubletype (8 bytes).
๐ Concept Explanationโ
In C, every variable must have a data type. The data type tells the compiler how much memory (how many bytes) to allocate for the variable and how to interpret the binary bits stored inside it.
The 4 Primary Data Typesโ
-
char(Character):- Stores a single character (like
'A','z', or'$'). - Size: 1 byte (8 bits).
- Under the hood, C actually stores the ASCII numeric value of the character (e.g.,
'A'is stored as65).
- Stores a single character (like
-
int(Integer):- Stores whole numbers without decimals (like
10,-450,0). - Size: Typically 4 bytes (32 bits) on modern computers.
- Stores whole numbers without decimals (like
-
float(Single-precision Floating Point):- Stores numbers with fractional decimal points (like
3.14,-0.005). - Size: 4 bytes (32 bits). Accurate up to 6 decimal places.
- Stores numbers with fractional decimal points (like
-
double(Double-precision Floating Point):- Stores large, highly precise decimal numbers.
- Size: 8 bytes (64 bits). Accurate up to 15 decimal places.
๐ Type Qualifiers: Modifying Primary Typesโ
You can modify the size or range of primary data types using type qualifiers:
- Size Qualifiers:
short(reduces size) andlong(increases size). - Sign Qualifiers:
signed(allows both positive and negative values) andunsigned(allows only positive values, which doubles the positive range).
Primary Data Types Sizes, Ranges & Format Specifiersโ
Below is the complete reference table for standard 32-bit/64-bit systems:
| Data Type | Size (Bytes) | Range | Format Specifier |
|---|---|---|---|
char / signed char | 1 | -128 to 127 | %c or %d (for ASCII value) |
unsigned char | 1 | 0 to 255 | %c or %d |
int / signed int | 4 | -2,147,483,648 to 2,147,483,647 | %d |
unsigned int | 4 | 0 to 4,294,967,295 | %u |
short int | 2 | -32,768 to 32,767 | %hd |
unsigned short int | 2 | 0 to 65,535 | %hu |
long int | 8 (or 4 on 32-bit) | -9.22 ร 10^18 to 9.22 ร 10^18 | %ld |
unsigned long int | 8 (or 4 on 32-bit) | 0 to 1.84 ร 10^19 | %lu |
float | 4 | 1.2E-38 to 3.4E+38 | %f |
double | 8 | 2.3E-308 to 1.7E+308 | %lf |
long double | 10 to 16 | 3.4E-4932 to 1.1E+4932 | %Lf |
๐ป The sizeof() Operator: Inspecting Memoryโ
The sizeof() operator is a built-in unary operator in C that returns the size of a variable or a data type in bytes.
#include <stdio.h>
// ๐ Scenario: Check variable crate sizes in memory
// ๐ Action: Prints size of types in bytes using sizeof()
int main() {
char sampleChar = 'K';
int sampleInt = 1500;
float sampleFloat = 4.5f;
double sampleDouble = 99.987;
// sizeof returns a size_t type (unsigned integer), printed using %zu
printf("Size of char variable : %zu byte\n", sizeof(sampleChar));
printf("Size of int variable : %zu bytes\n", sizeof(sampleInt));
printf("Size of float variable : %zu bytes\n", sizeof(sampleFloat));
printf("Size of double variable : %zu bytes\n", sizeof(sampleDouble));
// You can also pass types directly
printf("Size of unsigned int : %zu bytes\n", sizeof(unsigned int));
printf("Size of long int : %zu bytes\n", sizeof(long int));
return 0;
}
// Output:
// Size of char variable : 1 byte
// Size of int variable : 4 bytes
// Size of float variable : 4 bytes
// Size of double variable : 8 bytes
// Size of unsigned int : 4 bytes
// Size of long int : 8 bytes
๐ Sample Dry Runโ
Let's trace what happens when we check sizeof values:
| Step | Statement Executed | Target of sizeof | Evaluated Value | Description |
|---|---|---|---|---|
| 1 | sizeof(sampleChar) | sampleChar (char) | 1 | Char occupies exactly 1 byte. |
| 2 | sizeof(sampleInt) | sampleInt (int) | 4 | 32-bit integer occupies 4 bytes. |
| 3 | sizeof(sampleFloat) | sampleFloat (float) | 4 | Single-precision float occupies 4 bytes. |
| 4 | sizeof(sampleDouble) | sampleDouble (double) | 8 | Double-precision float occupies 8 bytes. |
๐งช Interactive Elementsโ
Try It Yourselfโ
Task: Predict what happens if you assign 128 to a variable declared as signed char (which has a max range of 127). Run this code to verify:
#include <stdio.h>
int main() {
signed char num = 127;
num = num + 1;
printf("Value: %d\n", num);
return 0;
}
Hint: When a signed number overflows its maximum limit, it wraps around to the lowest negative number.
Quick Quizโ
If you assign a character value like 'A' to an integer variable in C, does it compile?
- A) No, it throws a type mismatch error.
- B) Yes, it compiles and stores the ASCII value 65.
- C) Yes, but it crashes at runtime.
- D) No, C does not support implicit casting of char to int.
Explanation: In C, characters are treated as small integers under the hood. Assigning 'A' to an int compiles perfectly and stores the integer value 65 (its ASCII representation).
๐ Complexity Analysisโ
- Time Complexity:
sizeofevaluation: $O(1)$ constant time. Note:sizeofis evaluated at compile-time by the compiler, not during program execution, so it takes zero runtime.
- Space Complexity:
- Memory footprint: Varies based on selected type (1 byte to 16 bytes).
๐ฏ Practice Problemsโ
Easy Level ๐ขโ
- Write a C program to print the sizes of
short int,long int,long double, andunsigned charusingsizeof(). - Find the error in this code:
int main() {unsigned int score = -500;printf("%u", score);return 0;}
Medium Level ๐กโ
- Write a program to read a character from the user and display both the character and its numeric ASCII value.
Hard Level ๐ดโ
- Write a program that demonstrates integer underflow. Assign the minimum possible value to a
signed short intand subtract 1 from it. Print the resulting value and explain the output.
โ Frequently Asked Questionsโ
Details
Q: Why is the size of int 4 bytes on some machines and 2 bytes on others?
The size of int is platform-dependent. In old 16-bit DOS operating systems (like those running Turbo C++), an integer was 2 bytes. In modern 32-bit and 64-bit operating systems, an integer is 4 bytes. The C standard only mandates that sizeof(short int) <= sizeof(int) <= sizeof(long int).Details
Q: What is the difference between float and double?
float is a single-precision type occupying 4 bytes (6 decimal accuracy), while double is a double-precision type occupying 8 bytes (15 decimal accuracy). By default, any decimal constant (like 3.14) in C is treated as a double. To make it a float, you must add an 'f' suffix (like 3.14f).Details
Q: What is a void data type?
void means "no value" or "empty." It is used to specify that a function does not return any value (e.g., void display()) or that a function takes no arguments (e.g., int main(void)). You cannot declare a variable of type void.๐ Best Practices & Common Mistakesโ
โ Best Practicesโ
- Use
doublefor precision: Unless you are working on resource-constrained embedded systems, preferdoubleoverfloatto avoid decimal rounding errors. - Use
unsignedfor counts: If a variable will never be negative (like array indices, student count, age), declare it asunsignedto protect against negative logic bugs and double the positive limit. - Use
%zufor sizeof: Always print the return value ofsizeof()with the%zuformat specifier, which is standard forsize_t.
โ Common Mistakes โ ๏ธโ
- Decimal constant mismatch: Declaring
float x = 3.14;instead of3.14f. Without the 'f', the compiler warns you about converting a double to a float. - Overflowing variables: Storing a number like
100000in ashort int(max limit32767). - Wrong format specifier: Printing a float variable using
%dor an integer using%f. This prints garbage values.
โ Summaryโ
In this tutorial, you've learned:
- โ
C has 4 primary data types:
char,int,float, anddouble. - โ Data types determine the size of memory allocation and range of values.
- โ
Qualifiers like
short,long,signed, andunsignedadjust size and sign. - โ
The
sizeof()operator is evaluated at compile-time to return byte sizes. - โ Exceeding a type's limits triggers overflow/underflow, wrapping values.
๐ก Pro Tip: Use
#include <limits.h>to access constants likeINT_MAX,INT_MIN, andCHAR_MAXto check variables limits directly in your C program!
๐ Further Readingโ
Continue your learning path:
Go deeper:
---