Chapter 2: The principal structure of a program
The introduction connects earlier C examples to larger programs and distinguishes a program’s syntax from its semantic parts.
After this chapter you will be able to
- Syntax and semantic roles. Distinguish syntactical aspects, which specify a program so the compiler understands it, from semantic aspects, which specify what the program should do. Describe declarative parts as saying what things are, object definitions as saying where things are, and statements as saying what things are supposed to do.
- Grammar and punctuation roles. Explain that C programs are assembled from different kinds of text elements, including fixed special words and punctuation, and that the same punctuation can serve different purposes.
- Identifiers and their roles. Explain that identifiers are names for program entities and give examples of the different roles they can have, such as objects, type aliases, functions, and constants.
- Function definition and main. Describe how the example defines main with a declaration followed by a body, and state why main has a special role.
- Declarations and identifier use. Explain why an identifier needs a declaration before use, how this differs from a keyword, and why consistent declarations may be repeated.
- Information in declaration forms. Describe what the illustrated declarations say about main, A, argv, and the other named items, without relying on later details of their types.
- Variables as named objects. Distinguish a variable’s identifier, object, type, and value using the section’s box analogy.
- Visibility across nested scopes. Trace where the example identifiers are visible and distinguish block scope from file scope.
- Declarations and object definitions. Distinguish a declaration that specifies an identifier from a definition that provides an object, and explain how an initializer defines a variable in the simplified examples used here.
- Function definitions and uniqueness. Describe what distinguishes a function definition from a declaration and why each used object or function needs exactly one definition.
- Statements in the main function. Explain that the second part of the main function consists primarily of statements, which tell the compiler what to do with identifiers declared so far.
- For Loop Execution. Trace the four parts of a for statement and explain how the example repeats its body with i taking the values 0 through 4.
- Function call control transfer. Describe how a function call suspends execution of the current function and hands control to the named function, such as printf.
- Argument values in calls. Explain that a call passes the values of its arguments to the called function, so printf can use the value of i but cannot change i itself through that argument. Distinguish this call-by-value behavior from pass by reference, which C does not implement.
- Main return value. Explain that main’s return passes control to its caller and, because main is declared with int, sends back an int value; in this example, the value is EXIT_SUCCESS.
- Call and return control flow. Trace how execution moves from the platform’s startup routine to main, then to printf, and returns in the opposite direction; explain that main pauses during the printf call and resumes where it stopped afterward.
What it builds on
- Imperative programming (chapter 1) · The earlier C example identified as Listing 1.1.
Section by section
Introduction
The introduction connects earlier C examples to larger programs and distinguishes a program’s syntax from its semantic parts.
- Syntax and semantic roles: Distinguish syntactical aspects, which specify a program so the compiler understands it, from semantic aspects, which specify what the program should do. Describe declarative parts as saying what things are, object definitions as saying where things are, and statements as saying what things are supposed to do.
Why it matters: This distinction gives you a way to place the constructs discussed in the rest of the chapter. - Continuity of program structure: Explain why the earlier small examples remain useful when considering real C programs: real programs contain more constructs, but have a similar structure, and Listing 1.1 already contains most structural elements.
Why it matters: You can use the earlier example as a starting point for recognizing the structure of larger programs.
Key terms: syntactical aspects, semantic aspects, grammar, declarative parts, definitions of objects, statements, real programs, structural elements, Listing 1.1
2.1 Grammar
This section identifies the textual elements that make up a C program and distinguishes their grammatical form from their meaning.
- Grammar and punctuation roles: Explain that C programs are assembled from different kinds of text elements, including fixed special words and punctuation, and that the same punctuation can serve different purposes.
Why it matters: Recognizing a mark’s role in context makes C code easier to read. - Comments and literal values: Describe how the two comment forms delimit text ignored by the compiler, and distinguish comments from literals that supply fixed values in the program.
Why it matters: This separates explanatory text from values that the program actually uses. - Identifiers and their roles: Explain that identifiers are names for program entities and give examples of the different roles they can have, such as objects, type aliases, functions, and constants.
Why it matters: Recognizing what a name denotes helps you interpret the surrounding code. - Function definition and main: Describe how the example defines main with a declaration followed by a body, and state why main has a special role.
Why it matters: It connects the visible structure of the example to where its execution begins. - Operators attributes and meaning: Identify the operators illustrated in the example and the supplemental role of an attribute, while distinguishing grammatical elements from the meaning they convey.
Why it matters: Spotting a construct’s written form is a first step, not a complete account of what it means.
Key terms: grammar, special words, punctuation, brackets, separators, terminators, comments, /*…*/, C++-style comments, //
2.2 Declarations
This section explains what declarations tell the compiler, where some declarations come from, and how scope limits an identifier’s visibility.
- Declarations and identifier use: Explain why an identifier needs a declaration before use, how this differs from a keyword, and why consistent declarations may be repeated.
Why it matters: This explains both why the compiler needs declarations and why seeing more than one declaration is not necessarily an error. - Information in declaration forms: Describe what the illustrated declarations say about main, A, argv, and the other named items, without relying on later details of their types.
Why it matters: Reading these visible parts of a declaration lets you identify the kind of item a name denotes in the example program. - Variables as named objects: Distinguish a variable’s identifier, object, type, and value using the section’s box analogy.
Why it matters: Keeping a variable’s name, type, object, and value separate prevents confusion when reading later C code. - Declarations supplied by headers: Explain why the example program includes headers for printf, size_t, and EXIT_SUCCESS.
Why it matters: The headers account for names used by the program whose declarations are not written out in its source. - Visibility across nested scopes: Trace where the example identifiers are visible and distinguish block scope from file scope.
Why it matters: Scope tells you where each declared name can be used and why a loop variable is not visible throughout the file.
Key terms: identifier, keyword, declaration, consistent declarations, type, function, array, indices, pointer, maybe_unused
2.3 Definitions
This section distinguishes declarations from definitions and shows how initialized objects, array elements, and functions are defined.
- Declarations and object definitions: Distinguish a declaration that specifies an identifier from a definition that provides an object, and explain how an initializer defines a variable in the simplified examples used here.
Why it matters: The distinction explains why naming a variable is not the same as providing the object that a program uses. - Designated array initializers: Describe how a designated initializer selects an array element and what value an omitted element receives.
Why it matters: It lets you read an array initializer even when it supplies values for only some positions. - Zero-based array indices: Explain where array indexing begins and identify the last index of an array with n elements.
Why it matters: Zero-based positions make it possible to identify the intended array element correctly. - Function definitions and uniqueness: Describe what distinguishes a function definition from a declaration and why each used object or function needs exactly one definition.
Why it matters: The one-definition requirement connects the names used in a program to unambiguous objects and functions.
Key terms: declaration, definition, initialization, initializer, object, storage, designated, array, array positions, indices
2.4 Statements
This section identifies statements as the instruction-bearing part of the main function and introduces the kinds of statements discussed next.
- Statements in the main function: Explain that the second part of the main function consists primarily of statements, which tell the compiler what to do with identifiers declared so far.
Why it matters: This gives you a way to recognize the instruction-bearing part of the example program.
Key terms: statements, identifiers, main function
2.4.1 Iteration
This section explains how a C for statement iterates over a domain and why its loop variable should be defined in the statement's initial part.
- For Loop Execution: Trace the four parts of a for statement and explain how the example repeats its body with i taking the values 0 through 4.
Why it matters: The order of these parts explains exactly which iterations run and when the loop ends. - Loop Variable Placement: Justify defining the loop variable in the initial part of a for statement rather than defining it earlier or reusing it across loops.
Why it matters: Keeping the counter's definition with its loop makes its purpose easier to recognize.
Key terms: for statement, domain iteration, loop body, loop variable, loop condition, iteration counter, initial part of a for loop
2.4.2 Function calls
This subsection explains how a function call transfers control and passes argument values, using printf as an example.
- Function call control transfer: Describe how a function call suspends execution of the current function and hands control to the named function, such as printf.
Why it matters: This identifies what happens when execution reaches a function call. - Argument values in calls: Explain that a call passes the values of its arguments to the called function, so printf can use the value of i but cannot change i itself through that argument. Distinguish this call-by-value behavior from pass by reference, which C does not implement.
Why it matters: It prevents confusing a function's use of an argument's value with permission to change the original variable.
Key terms: function call, current function, called function, arguments, values, call by value, pass by reference, pointers
2.4.3 Function return
This section explains how return statements pass control back to callers, using main and printf to trace a small program’s execution.
- Main return value: Explain that main’s return passes control to its caller and, because main is declared with int, sends back an int value; in this example, the value is EXIT_SUCCESS.
Why it matters: It connects main’s declaration to what its return statement does. - Call and return control flow: Trace how execution moves from the platform’s startup routine to main, then to printf, and returns in the opposite direction; explain that main pauses during the printf call and resumes where it stopped afterward.
Why it matters: It lets you follow which function is executing and where execution resumes after a call.
Key terms: return, main, int, EXIT_SUCCESS, control flow, function call, process-startup routine, printf
2.5 Summary
Where this is used later
- Specifying values (chapter 5) · The discussion of specifying values builds on recognizing literals as fixed values in program text.
- main is special (chapter 7) · That section develops main’s special role.
- Operands and operators (chapter 4) · The later treatment of operands and operators builds on recognizing operators in program text.
- Naming (chapter 9) · The distinction between declarations and the entities they name.
- Array declaration (chapter 6) · The initial reading of brackets and array items supports array declarations.
- Simple functions (chapter 7) · The distinction between a function declaration and other declarations supports simple functions.
- Values (chapter 5) · The distinction between an object and its contents supports the discussion of values.
- Types (chapter 5) · The distinction between an object and its specification supports the discussion of types.
Concepts explained in this chapter
- declarationA C declaration specifies the kind of entity an identifier refers to without necessarily allocating storage or supplying its concrete value.
- identifierAn identifier is a programmer-defined name that denotes a program entity such as a variable, function, or parameter.
- atomic typeA type specifies the kind of values an entity can represent and the operations applicable to those values.
- bindingA variable is a named object whose stored value can be accessed and may change during program execution.
- indexingArray indexing is the C operation of selecting an array element with an index expression, such as A[i].
- function declarationA function definition is a C construct that specifies a function's declaration and body.
- initializationInitialization is the process of providing an initial value for a C object as part of its declaration or creation.
- scopeA scope is a region of a C program within which an identifier is visible and its declaration applies.
- arrayAn array is an aggregate object containing a fixed sequence of items of the same type, accessed by numeric indices.
- blockA block is a grammatical structure that groups declarations and statements within a delimited program region.
- file scopeFile scope is the scope of an identifier declared outside a function or block, extending through the relevant source file.
- public visibilityVisibility is the property determining whether an identifier can be referenced from a particular part of a program.
- valueA value is the data represented by an object or expression at a particular point in program execution.
- functionA function is a named C program unit that can be called to perform an operation and optionally produce a value.
- commentA comment is source text that the C compiler ignores and that can document a program.
- attributeAn attribute is supplemental implementation or semantic information attached to a C program construct.
- literalA literal is source text that denotes a fixed value directly in a C program.
- operatorAn operator is a C symbol or symbol sequence that specifies an operation on one or more operands.
- loopA for statement is a C iteration statement that controls repeated execution using initialization, a continuation condition, and an iteration expression.
- designated initializerA designated initializer is an initializer that explicitly selects an array element or structure member by designation before assigning its value.
- initializerAn initializer is C syntax that supplies an initial value for an object declared in source code.
- stopping criterionA condition is an expression whose evaluated value controls conditional or iterative execution in C.
- control flowControl flow is the order in which execution proceeds among a program's operations and functions.
- callA function call is an expression or statement that requests execution of a function with supplied arguments.
- command-line argumentA command-line argument is a string value supplied to a program when it is invoked from a command-line environment.
- referenceA pointer type is a C type whose values designate objects or functions in storage.
- compound statementA compound statement is a C statement consisting of a brace-delimited sequence of statements treated as one statement.
- global variableA global variable is a C object with program-wide or file-wide lifetime and visibility determined by its linkage and scope.
- header fileA header file is a source file containing declarations, macro definitions, and related information intended to be included by other source files.
- maybe_unused attributeThe maybe_unused attribute suppresses diagnostics for declarations or definitions whose identifiers might not be used.
- secondary blockA secondary block is the block formed by the loop body associated with a for construct in the terminology used here.
- comparisonA comparison operator is a C operator that evaluates a relational condition between two operands and produces a Boolean result.
- constantA named constant is a program constant given an identifier so code can refer to its meaning instead of repeating its value.
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.
