Variables and Data Types in C
C’s type system is small but precise. Understanding storage size, signedness, and promotion rules prevents subtle bugs.
Integer Types
| Type | Typical Size | Range (approx.) |
|---|---|---|
char |
1 byte | -128 to 127 or 0–255 |
short |
2 bytes | ±32K |
int |
4 bytes | ±2B |
long |
4 or 8 bytes | platform-dependent |
long long |
8 bytes | ±9×10¹⁸ |
Use <stdint.h> for portable fixed-width types:
#include <stdint.h>
uint8_t byte;
int32_t count;
uint64_t big;
Floating Point
float f = 3.14f; /* suffix f for float literal */
double d = 3.14; /* default type for decimals */
long double ld = 3.14L;
Never compare floats with ==. Use epsilon tolerance:
#include <math.h>
if (fabs(a - b) < 1e-9) { /* equal enough */ }
Variables and Constants
int count = 0; /* mutable */
const int MAX = 100; /* read-only */
#define BUFFER_SIZE 256 /* preprocessor constant */
enum Color { RED, GREEN, BLUE };
enum Color c = GREEN; /* c == 1 */
Input with scanf
#include <stdio.h>
int main(void) {
int age;
char name[64];
printf("Name: ");
scanf("%63s", name); /* width limit prevents overflow */
printf("Age: ");
scanf("%d", &age); /* & required — address of variable */
printf("Hello %s, age %d\n", name, age);
return 0;
}
Prefer fgets for line input — scanf("%s") stops at whitespace.
Type Conversions
int i = 42;
double d = i; /* implicit promotion */
int truncated = (int)3.99; /* explicit cast → 3 */
/* Integer promotion: char/short → int in expressions */
unsigned char a = 255, b = 1;
/* a + b promotes to int before addition */
Common Pitfalls
- Treating compiler warnings as optional rather than actionable feedback.
- Skipping error checks on library and system calls.
- Copy-pasting examples without adapting to your project’s conventions.
Best Practices
- Enable strict compiler warnings and fix them before merging.
- Write small, testable units with clear input/output contracts.
- Document non-obvious invariants and preconditions.
- Use version control and code review for every change.
Memory and Performance Notes
int is typically 32 bits. Use size_t for sizes. On LP64 systems, pointers are 64 bits.
Exercise
Write a program that reads two integers and prints their sum, product, and whether the second divides the first evenly.
Hint: Check division by zero before computing remainder with %.
Summary
Apply these concepts in small programs before moving to larger projects. Combine with adjacent topics in the learning path for deeper mastery.
Real-World Application
These concepts appear in production codebases — from operating system kernels to embedded firmware. Study open-source projects that use this topic extensively to see idiomatic patterns at scale.
Debugging Checklist
- Reproduce the issue with the smallest possible input.
- Enable compiler warnings and sanitizers.
- Use a debugger to inspect state at the failure point.
- Verify assumptions about types, sizes, and return values.
- Compare working and broken code paths side by side.
- Write a regression test once the bug is fixed.
Further Reading
Consult the ISO C standard, Effective C by Robert C. Seacord, and your compiler documentation for platform-specific behavior.
Quick Reference
Review the code examples on this page before starting the exercise. Type them manually to build muscle memory.
Additional Examples
Consider how this topic applies in a larger project:
// Break the problem into smaller functions
// Test each function independently
// Integrate incrementally
Working through variations of the examples above builds deeper understanding than reading alone.