Skip to content

Chapter 2 of 7

Data Types, Variables, and User-Defined Aggregates

C's basic data types are intentionally minimal: char (at least 8 bits), int (the natural integer size for the platform), float, double, and long double for floating-point values, plus _Bool for booleans. Modifiers like signed, unsigned, short, long, and long long adjust width and signedness. Because int is platform-dependent, <stdint.h> provides fixed-width types such as int32_t and uint64_t, while <inttypes.h> adds portable printf and scanf format macros like PRId32. The <stddef.h> header defines size_t (the unsigned type for sizes and counts) and ptrdiff_t (the signed type for pointer differences). Integer promotion converts small types like char and short to int or unsigned int before most operations, which is why sizeof('A') typically returns sizeof(int) rather than 1. The usual arithmetic conversions then resolve mixed-type expressions by promoting to the larger or higher-ranked type. For floating-point, float is typically IEEE-754 single precision, double is double precision and is the default for floating literals, and long double provides extended precision.

Programmers build richer types by combining the basic ones. A struct groups related variables of different types under one name, and members are accessed with the dot operator for values or the arrow operator for pointers, since p->field is equivalent to (*p).field. Dynamically allocated structs use malloc with sizeof and the arrow operator, and the original must be freed when done. A union is similar to a struct but all members share the same memory, so its size equals its largest member and only one member holds a meaningful value at a time. An enum defines named integer constants that start at 0 by default but can be assigned custom values. The typedef keyword creates an alias for an existing type, improving readability so you can write Point p; instead of struct Point p;.

C99 introduced designated initializers for setting specific struct or array members by name and compound literals like (struct Point){.x = 1, .y = 2} for unnamed objects. C99 also allows flexible array members, where a struct's final element is an unsized array that shares its allocation with the header. Bit-fields let you specify the exact number of bits a struct member occupies, which is useful for compact storage or matching hardware registers, though you cannot take their address. Each type has an alignment requirement, and compilers insert padding bytes so members start at properly aligned addresses; _Alignas overrides this to enforce stronger alignment, while #pragma pack controls padding globally. Endianness determines whether multibyte values are stored least-significant byte first (little-endian, common on x86 and ARM) or most-significant first (big-endian, used in network byte order). The volatile qualifier tells the compiler that a variable's value may change unexpectedly, such as from hardware or another thread, preventing the compiler from optimizing away reads, and the register keyword is a now-largely-ignored hint to keep a variable in a CPU register.

All chapters
  1. 1Pointers and Dynamic Memory
  2. 2Data Types, Variables, and User-Defined Aggregates
  3. 3Arrays, Strings, and Memory Operations
  4. 4Functions and Control Flow
  5. 5File I/O and Program Termination
  6. 6The Preprocessor and Macros
  7. 7Compilation, Linking, and Program Structure

Drill it

Reading is not remembering. These come from the C Programming deck:

Q

What is a pointer in C?

A pointer is a variable that stores the memory address of another variable.Declared using the * operator: int *ptr;The address-of operator &amp; retrieves a var...

Q

How do you dereference a pointer?

Dereferencing means accessing the value stored at the address a pointer holds.Use the * operator: int val = *ptr;This retrieves the value at the memory location...

Q

What is a NULL pointer?

A NULL pointer is a pointer that does not point to any valid memory location.Assigned with: int *ptr = NULL;Always check for NULL before dereferencing to avoid...

Q

What does malloc() do in C?

malloc() allocates a block of memory on the heap and returns a pointer to it.Syntax: int *p = (int *)malloc(n * sizeof(int));Returns NULL if allocation fails. M...