Skip to content
academia.sh

Course Beginner

C Fundamentals

Published Updated

By the end of this course

Start course

01

Language and Compilation

Which design decisions arise from the language's closeness to hardware, the four stages a source passes through on its way to becoming a program observed separately, declarations shared through header files, the text-level preprocessor knowing no types, and which standard compiler warnings are born from.

  1. 01 The Place of C In C, a source turning into a running program is not a single step: it passes through four stages, and each stage looks at a separate question. A three-file measurement core shows these four stages in a single run and writes 4 of fourteen observations to the preprocessor, 4 to the compiler, 3 to the linker, and 3 to runtime.
  2. 02 Compilation Stages Each of the four stages looks at a different input: the preprocessor only text, the compiler a single unit, the linker multiple units, and runtime only data. A small measurement excerpt runs all four side by side; a separate pair of programs also shows how one line of the same source enters two different compilations, through a decision made in the source beforehand.
  3. 03 Header Files A header file does not carry a name, it carries that name's text, and the preprocessor copies it separately into every unit that uses it. This makes it possible for the same declaration to enter two units at once and for both to compile; the measurement proves this by running it, and separately shows what the include guard prevents.
  4. 04 The Preprocessor The preprocessor's four different directives — macro value, conditional body, token pasting, inclusion — are in fact four appearances of a single job: text substitution. Because a macro knows no types, it produces the same expression so that it gives the correct result with two different types; but because it can substitute its argument more than once, it can run a call with a side effect a different number of times than a real function would.
  5. 05 Compiler Warnings and Standards A warning can only be born at the compiler stage, because only that stage sees the types and expressions inside a single unit. What the standard guarantees is set side by side with what it leaves to the implementation — sizeof(char) == 1 is a guarantee, other sizes are not. Nor can a program that compiles without a warning be said to be correct; to show this, a computation that prints no warning but produces a wrong result is run.

02

Basic Syntax

A type's carried value ranges and conversion rules, a variable's scope and storage duration being separate questions, operators changing meaning by type, control flow forms, a function's declaration being separated from its definition, an array and a string resting on the same mechanism, a record type's memory layout, and input and output running through format strings.

  1. 01 Data Types A type's value range, the signed–unsigned distinction and integer promotion being decided at the compiler stage; no size is printed except sizeof(char) == 1.
  2. 02 Variables, Scope and Storage Duration Where a name is visible from being decided at compile time, and how long a value lives being decided at runtime; whether the same name falls into two separate objects in two units being resolved by the linker.
  3. 03 Operators An operator's result being decided at compile time according to the operands' types; measured through precedence, short-circuit evaluation, compound assignment, and the defined–undefined distinction in evaluation order.
  4. 04 Control Flow Which code path a branch follows being determined by data produced at runtime; switch fall-through, loop forms, goto's limited place, and the distinction between which branches exist and which one is chosen.
  5. 05 Functions A call being bound to a definition in another unit being resolved at the linker stage; the declaration–definition distinction, parameter passing always being by copy, and the return value's type determining the caller side's interpretation.
  6. 06 Arrays and Strings An array's element count being determined at compile time through constant folding, and a string's length being determined at runtime by scanning until the terminating byte; the array–pointer relationship measured through element value and difference without printing an address.
  7. 07 Structs, Unions and Enumerations A struct's fields being laid out at compile time, a union sharing the same memory, and enumeration constants being compile-time constants; showing with a tag field that the language does not track which member of a union is valid.
  8. 08 Input and Output A format string's text is known at compile time, but what it means is only known at runtime: of nine observations, one is decided at the preprocessor, two at the compiler, one at the linker, five at runtime. The bounding measurement shows that the language itself does not guarantee the match between a format string and its arguments.

Final exam

C Fundamentals — Final Exam

In preparation

This course's question bank is not complete yet. The exam opens here automatically once enough questions are added.

Start typing to search.

↑↓ ↵ Esc navigate · open · close