Lexical Elements: The Building Blocks
A C program is a sequence of Tokens. The compiler’s lexer breaks your source code into these basic units: Keywords, Identifiers, Constants, String Literals, and Punctuators.
- Case Sensitivity: C is strictly case-sensitive.
int MyVar;andint myvar;refer to two distinct memory locations. - Internal vs External Linkage: Identifiers have “linkage” which determines if the same name in a different file refers to the same object. We will explore this in the “Storage Classes” module.
Fundamental Data Types
C’s type system is designed to expose the underlying hardware’s capabilities. Unlike managed languages, C types often have implementation-defined sizes.
1. Integer Types
The size of int is typically the “natural” size of the processor’s word (32-bits on most modern systems). However, the standard only guarantees minimum ranges:
| Type | Minimum Size | Guaranteed Range |
|---|---|---|
char | 8 bits | -127 to 127 (or 0 to 255) |
short | 16 bits | -32,767 to 32,767 |
int | 16 bits | -32,767 to 32,767 |
long | 32 bits | -2,147,483,647 to 2,147,483,647 |
long long | 64 bits | -(2^63 - 1) to (2^63 - 1) |
2. Floating-Point Types
C uses the IEEE 754 Standard for floating-point arithmetic.
float: Single precision (usually 32-bit).double: Double precision (usually 64-bit).long double: Extended precision (often 80-bit or 128-bit).
The stdint.h Solution
Because primitive sizes vary by architecture, systems programming requires Fixed-Width Types. Since the C99 standard, <stdint.h> provides types that are guaranteed to be the same size everywhere.
#include <stdint.h>
int32_t fixed_int; // Exactly 32 bits
uint64_t large_unsig; // Exactly 64 bits, unsigned
intptr_t pointer_int; // Integer large enough to hold a pointer
Implicit Conversions and Promotion
C performs Integer Promotion: any type smaller than an int (like char or short) is converted to an int before arithmetic operations.
The “Usual Arithmetic Conversions” rule:
When mixing types (e.g., int + double), C promotes the “smaller” type to the “larger” one to prevent precision loss. However, converting a double to an int causes truncation, where the fractional part is simply discarded.
Type Promotion
int a = 5;
float b = 2.0;
// What is the resulting type of (a / b)?
// Answer: Limits and Overflow
What happens when you add 1 to the maximum possible value of a signed integer?
- Signed Overflow: This is Undefined Behavior. The compiler might assume it never happens and optimize away your checks.
- Unsigned Overflow: This is well-defined as Wrap-around (modulo arithmetic).
Interactive Lab
Waiting for signal...