liveBook · Manning

Chapter 5: Basic values and data

What you will learn in chapter 5 of Modern C, Third Edition

The chapter introduces the distinction between C values and their representations, and presents the abstract state machine as a platform-independent way to reason about program state.

After this chapter you will be able to

What it builds on

Section by section

Introduction

The chapter introduces the distinction between C values and their representations, and presents the abstract state machine as a platform-independent way to reason about program state.

Key terms: values, representations, portable code, abstract state machine, objects, type, value

5.1 The abstract state machine

The section uses a small C computation to introduce observable program state and explain why compilers may optimize away steps that do not affect it.

Key terms: values, variables, expressions, observable states, addressable memory, output device, optimization, abstract state machine

5.1.1 Values

The section presents C values as abstract, number-like entities and relates program data and execution state to the goal of platform-independent results.

Key terms: value, representation, control expression, values, numbers, truth values, data, state, executable, outside intervention

5.1.2 Types

This subsection establishes that every C value has a statically determined type that governs its operations and their results.

Key terms: type, value, statically determined

5.1.3 Binary representation and the abstract state machine

The section explains how platform-specific binary representations help determine operation results, how programs can observe those representations, and how these facts define C’s abstract state machine.

Key terms: binary representation, operands, type, platform, observable, C library headers, SIZE_MAX, SIZE_WIDTH, object representation, abstract state machine

5.1.4 Optimization

This section explains why a compiler may change how a C program executes while preserving observable behavior, and why types can limit those optimizations.

Key terms: abstract state machine, observable states, optimization, overflow, unsigned type, signed integer types, floating-point types

5.2 Basic types

The section classifies C’s basic numeric types, explains narrow-integer promotion and platform-dependent ranges, and gives purpose-based guidance for choosing types.

Key terms: basic types, unsigned integers, signed integers, real floating-point numbers, complex floating-point numbers, precision, narrow types, promoted, signed int, char

5.3 Specifying values

This section explains how C literals specify values and how their spelling affects their type and, for floating-point literals, their effective value.

Key terms: decimal integer literal, octal integer literal, hexadecimal integer literal, binary integer literal, decimal floating-point literal, hexadecimal floating-point literal, string literals, numerical literals, negation operator, first fit rule

5.3.1 Complex constants

This section explains how to specify complex values in C using standard macros and why nonstandard imaginary-suffix literals are not portable.

Key terms: __STDC_NO_COMPLEX__, <complex.h>, <tgmath.h>, CMPLX, CMPLXF, CMPLXL, real part, imaginary part, I, imaginary unit

5.4 Implicit conversions

This section shows how implicit conversions affect C values and expression results, and why arithmetic types should be chosen to make those conversions harmless.

Key terms: unary -, unary +, promoted operand, unsigned int, implicit conversions, implementation defined, narrowing conversions, modulus, INT_MAX, float

5.5 Initializers

This section explains why objects should be initialized and how scalar, array, designated, and empty initializers work.

Key terms: initializer, defined state, abstract machine, scalar types, array initializers, incomplete type, designated initializers, aggregate data types, default initializer, { }

5.6 Named constants

This section explains why programs should name meaningful constants and keep constants with different meanings distinct, even when their values happen to match.

Key terms: named constants, constants with different meanings

5.6.1 Read-only objects

This section distinguishes C constants from read-only objects and explains the different guarantees of const-qualified objects, string literals, and constexpr objects.

Key terms: constant, const-qualified objects, read-only, string literals, char const[], bird, constexpr, const-qualified, compile time

5.6.2 Enumerations

This section explains how enumeration constants name integer values, when they qualify as integer constant expressions, and how C23 determines or explicitly specifies an enumeration’s underlying type.

Key terms: enumeration constants, positional value, explicit value, enumeration type, signed int, tag, integer constant expression, ICE, const-qualified, constexpr

5.6.3 Macros

This section explains how #define macros provide textual replacements for constant values and gives a naming convention for them.

Key terms: macro, textual replacement, preprocessor, #define, replacement text, macro names, all caps

5.6.4 Compound literals

This section explains how compound literals can be used in macros to provide values of a chosen type, while warning that they define objects rather than true constants and require care in macro definitions.

Key terms: compound literal, object, ICE, initializer, const-qualified, macro replacement, function-like macro, continuation markers

5.6.5 The constexpr construct

This section introduces C23’s constexpr for named constant expressions, explains its exact-fit initializer rule, and illustrates its use with compound literals.

Key terms: constexpr, constant expression, file scope, compound literals, initializer, conversion, unsigned, compound literal, const qualification, CORVID_NAMES

5.7 Binary representations

Distinguishes a type’s binary representation from the in-memory representation of its objects and notes that one value can have multiple binary representations.

Key terms: binary representation, in-memory object representation, value, type

5.7.1 Unsigned integers

This section explains how the precision and binary representation of unsigned integers determine their range and arithmetic.

Key terms: unsigned integer types, ring, integers modulo, _MAX, UINT_MAX, ULONG_MAX, bits, precision, width, least-significant bit

5.7.2 Bit sets and bitwise operators

The section explains how unsigned values can represent sets of bits, how bitwise operators manipulate those sets, and how programs use them for flags.

Key terms: bit set, unsigned value, base set, precision, union, intersection, symmetric difference, complement, flags, power of 2

5.7.3 Shift operators

This section explains how shift operators move bits in unsigned values, how those shifts relate to powers of two, and why shift counts must be limited.

Key terms: left-shift operator, <<, powers of 2, bit sets, precision, second operand, shift operation, right-shift operation, >>, less-significant bits

5.7.4 Boolean values

This section explains C’s Boolean values, their special assignment behavior, and when to use bool or include <stdbool.h>.

Key terms: bool, false, true, unsigned type, modulus rule, bool variables, C23, <stdbool.h>

5.7.5 Signed integers

Explains how signed integers are represented in C and why signed overflow makes arithmetic, negation, and bit operations hazardous.

Key terms: signed types, unsigned types, sign bit, twos’ complement, signed overflow, undefined behavior, as-if rule, abstract state machine, INT_MIN, INT_MAX

5.7.6 Fixed-width integer types

This section explains when fixed-width integer types are useful, what their names guarantee, and how to use their associated macros and C23 format specifiers.

Key terms: <limits.h>, <stdint.h>, width, precision, uint(N)_t, int(N)_t, _WIDTH, _MIN, _MAX, _C

5.7.7 Bit-precise integer types

Introduces C23 bit-precise integers, their literals, width limits, and arithmetic behavior.

Key terms: _BitInt, bit-precise integer types, BITINT_MAXWIDTH, wb, u, unsigned _BitInt, signed _BitInt, maximal width of the operands, unsigned _BitInt(3), wraps around

5.7.8 Floating-point data

This section explains the limits and simplified binary representation of floating-point values, the consequences for arithmetic and comparison, and how complex values are represented and accessed.

Key terms: floating-point types, DBL_MIN, DBL_MAX, sign, exponent, mantissa bits, precision, DBL_MANT_DIG, DBL_MIN_EXP, intermediate computations

5.8 Summary

Where this is used later

Concepts explained in this chapter

← Chapter 4: Expressing computations Chapter 6: Derived data types →

These guides are generated from the text of Manning books by Manning's knowledge graph and link to the sections they draw on. The full books are available on liveBook and at manning.com.