Beej S Guide To C Programming Brian Beej Jorgensen Hall 5 Online Ebook Texxtbook Full Chapter PDF

Download as pdf or txt
Download as pdf or txt
You are on page 1of 69

Beej s Guide to C Programming Brian

Beej Jorgensen Hall


Visit to download the full and correct content document:
https://ebookmeta.com/product/beej-s-guide-to-c-programming-brian-beej-jorgensen-
hall-5/
More products digital (pdf, epub, mobi) instant
download maybe you interests ...

Beej s Guide to C Programming Brian Beej Jorgensen Hall

https://ebookmeta.com/product/beej-s-guide-to-c-programming-
brian-beej-jorgensen-hall-5/

Beej s Guide to C Programming Brian Beej Jorgensen Hall

https://ebookmeta.com/product/beej-s-guide-to-c-programming-
brian-beej-jorgensen-hall-6/

Beej s Guide to C Programming Brian Beej Jorgensen Hall

https://ebookmeta.com/product/beej-s-guide-to-c-programming-
brian-beej-jorgensen-hall/

Beej s Guide to C Programming Brian Beej Jorgensen Hall

https://ebookmeta.com/product/beej-s-guide-to-c-programming-
brian-beej-jorgensen-hall-4/
Beej s Guide to C Programming Brian Beej Jorgensen Hall

https://ebookmeta.com/product/beej-s-guide-to-c-programming-
brian-beej-jorgensen-hall-3/

Effective Perl Programming 2nd Edition Joseph N Hall


Joshua Mcadams Brian D Foy

https://ebookmeta.com/product/effective-perl-programming-2nd-
edition-joseph-n-hall-joshua-mcadams-brian-d-foy/

Software Testing A Craftsman s Approach 5th Edition


Paul C. Jorgensen

https://ebookmeta.com/product/software-testing-a-craftsman-s-
approach-5th-edition-paul-c-jorgensen/

C Programming Language The Beginner s Guide 2020th


Edition Unknown

https://ebookmeta.com/product/c-programming-language-the-
beginner-s-guide-2020th-edition-unknown/

Let Us C Authentic guide to C programming language 19th


Edition Yashavant Kanetkar

https://ebookmeta.com/product/let-us-c-authentic-guide-to-c-
programming-language-19th-edition-yashavant-kanetkar/
Beej’s Guide to C Programming

Brian “Beej Jorgensen” Hall

v0.9.13, Copyright © March 29, 2023


Contents

1 Foreword 1
1.1 Audience . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1
1.2 How to Read This Book . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2
1.3 Platform and Compiler . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2
1.4 Official Homepage . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2
1.5 Email Policy . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2
1.6 Mirroring . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
1.7 Note for Translators . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
1.8 Copyright and Distribution . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
1.9 Dedication . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3

2 Hello, World! 5
2.1 What to Expect from C . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
2.2 Hello, World! . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6
2.3 Compilation Details . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8
2.4 Building with gcc . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8
2.5 Building with clang . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8
2.6 Building from IDEs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9
2.7 C Versions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9

3 Variables and Statements 10


3.1 Variables . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10
3.1.1 Variable Names . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11
3.1.2 Variable Types . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11
3.1.3 Boolean Types . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12
3.2 Operators and Expressions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13
3.2.1 Arithmetic . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13
3.2.2 Ternary Operator . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13
3.2.3 Pre-and-Post Increment-and-Decrement . . . . . . . . . . . . . . . . . . . . . . . 14
3.2.4 The Comma Operator . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15
3.2.5 Conditional Operators . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15
3.2.6 Boolean Operators . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16
3.2.7 The sizeof Operator . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16
3.3 Flow Control . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17
3.3.1 The if-else statement . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18
3.3.2 The while statement . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19
3.3.3 The do-while statement . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19
3.3.4 The for statement . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20
3.3.5 The switch Statement . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21

4 Functions 24
4.1 Passing by Value . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25
4.2 Function Prototypes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26
4.3 Empty Parameter Lists . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27

i
CONTENTS ii

5 Pointers—Cower In Fear! 28
5.1 Memory and Variables . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28
5.2 Pointer Types . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30
5.3 Dereferencing . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31
5.4 Passing Pointers as Arguments . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 32
5.5 The NULL Pointer . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33
5.6 A Note on Declaring Pointers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 34
5.7 sizeof and Pointers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 34

6 Arrays 35
6.1 Easy Example . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35
6.2 Getting the Length of an Array . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 36
6.3 Array Initializers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 36
6.4 Out of Bounds! . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 38
6.5 Multidimensional Arrays . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 39
6.6 Arrays and Pointers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 40
6.6.1 Getting a Pointer to an Array . . . . . . . . . . . . . . . . . . . . . . . . . . . . 40
6.6.2 Passing Single Dimensional Arrays to Functions . . . . . . . . . . . . . . . . . . 40
6.6.3 Changing Arrays in Functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41
6.6.4 Passing Multidimensional Arrays to Functions . . . . . . . . . . . . . . . . . . . 42

7 Strings 44
7.1 String Literals . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 44
7.2 String Variables . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 44
7.3 String Variables as Arrays . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 45
7.4 String Initializers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 45
7.5 Getting String Length . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 46
7.6 String Termination . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 46
7.7 Copying a String . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 47

8 Structs 49
8.1 Declaring a Struct . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 49
8.2 Struct Initializers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 50
8.3 Passing Structs to Functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 50
8.4 The Arrow Operator . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 52
8.5 Copying and Returning structs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 52
8.6 Comparing structs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 52

9 File Input/Output 53
9.1 The FILE* Data Type . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 53
9.2 Reading Text Files . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 54
9.3 End of File: EOF . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 55
9.3.1 Reading a Line at a Time . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 55
9.4 Formatted Input . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 56
9.5 Writing Text Files . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 57
9.6 Binary File I/O . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 57
9.6.1 struct and Number Caveats . . . . . . . . . . . . . . . . . . . . . . . . . . . . 59

10 typedef: Making New Types 61


10.1 typedef in Theory . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 61
10.1.1 Scoping . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 61
10.2 typedef in Practice . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 61
10.2.1 typedef and structs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 61
10.2.2 typedef and Other Types . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 63
10.2.3 typedef and Pointers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 63
CONTENTS iii

10.2.4 typedef and Capitalization . . . . . . . . . . . . . . . . . . . . . . . . . . . . 63


10.3 Arrays and typedef . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 64

11 Pointers II: Arithmetic 65


11.1 Pointer Arithmetic . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 65
11.1.1 Adding to Pointers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 65
11.1.2 Changing Pointers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 66
11.1.3 Subtracting Pointers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 67
11.2 Array/Pointer Equivalence . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 68
11.2.1 Array/Pointer Equivalence in Function Calls . . . . . . . . . . . . . . . . . . . . 68
11.3 void Pointers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 69

12 Manual Memory Allocation 74


12.1 Allocating and Deallocating, malloc() and free() . . . . . . . . . . . . . . . . . . . . 74
12.2 Error Checking . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 75
12.3 Allocating Space for an Array . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 76
12.4 An Alternative: calloc() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 76
12.5 Changing Allocated Size with realloc() . . . . . . . . . . . . . . . . . . . . . . . . . 77
12.5.1 Reading in Lines of Arbitrary Length . . . . . . . . . . . . . . . . . . . . . . . 78
12.5.2 realloc() with NULL . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 80
12.6 Aligned Allocations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 80

13 Scope 82
13.1 Block Scope . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 82
13.1.1 Where To Define Variables . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 83
13.1.2 Variable Hiding . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 83
13.2 File Scope . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 83
13.3 for-loop Scope . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 84
13.4 A Note on Function Scope . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 84

14 Types II: Way More Types! 85


14.1 Signed and Unsigned Integers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 85
14.2 Character Types . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 86
14.3 More Integer Types: short, long, long long . . . . . . . . . . . . . . . . . . . . . . . 87
14.4 More Float: double and long double . . . . . . . . . . . . . . . . . . . . . . . . . 89
14.4.1 How Many Decimal Digits? . . . . . . . . . . . . . . . . . . . . . . . . . . . . 90
14.4.2 Converting to Decimal and Back . . . . . . . . . . . . . . . . . . . . . . . . . . . 91
14.5 Constant Numeric Types . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 92
14.5.1 Hexadecimal and Octal . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 93
14.5.2 Integer Constants . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 93
14.5.3 Floating Point Constants . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 95

15 Types III: Conversions 97


15.1 String Conversions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 97
15.1.1 Numeric Value to String . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 97
15.1.2 String to Numeric Value . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 98
15.2 char Conversions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 100
15.3 Numeric Conversions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 101
15.3.1 Boolean . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 101
15.3.2 Integer to Integer Conversions . . . . . . . . . . . . . . . . . . . . . . . . . . . . 101
15.3.3 Integer and Floating Point Conversions . . . . . . . . . . . . . . . . . . . . . . 102
15.4 Implicit Conversions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 102
15.4.1 The Integer Promotions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 102
15.4.2 The Usual Arithmetic Conversions . . . . . . . . . . . . . . . . . . . . . . . . . 102
15.4.3 void* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 103
CONTENTS iv

15.5 Explicit Conversions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 103


15.5.1 Casting . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 103

16 Types IV: Qualifiers and Specifiers 105


16.1 Type Qualifiers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 105
16.1.1 const . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 105
16.1.2 restrict . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 107
16.1.3 volatile . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 108
16.1.4 _Atomic . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 108
16.2 Storage-Class Specifiers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 108
16.2.1 auto . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 108
16.2.2 static . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 109
16.2.3 extern . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 110
16.2.4 register . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 111
16.2.5 _Thread_local . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 112

17 Multifile Projects 113


17.1 Includes and Function Prototypes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 113
17.2 Dealing with Repeated Includes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 115
17.3 static and extern . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 116
17.4 Compiling with Object Files . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 116

18 The Outside Environment 117


18.1 Command Line Arguments . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 117
18.1.1 The Last argv is NULL . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 119
18.1.2 The Alternate: char **argv . . . . . . . . . . . . . . . . . . . . . . . . . . . 119
18.1.3 Fun Facts . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 120
18.2 Exit Status . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 121
18.2.1 Other Exit Status Values . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 122
18.3 Environment Variables . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 123
18.3.1 Setting Environment Variables . . . . . . . . . . . . . . . . . . . . . . . . . . . . 124
18.3.2 Unix-like Alternative Environment Variables . . . . . . . . . . . . . . . . . . . . . 124

19 The C Preprocessor 126


19.1 #include . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 126
19.2 Simple Macros . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 127
19.3 Conditional Compilation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 127
19.3.1 If Defined, #ifdef and #endif . . . . . . . . . . . . . . . . . . . . . . . . . . 128
19.3.2 If Not Defined, #ifndef . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 128
19.3.3 #else . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 129
19.3.4 General Conditional: #if, #elif . . . . . . . . . . . . . . . . . . . . . . . . . 129
19.3.5 Losing a Macro: #undef . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 131
19.4 Built-in Macros . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 131
19.4.1 Mandatory Macros . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 131
19.4.2 Optional Macros . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 132
19.5 Macros with Arguments . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 133
19.5.1 Macros with One Argument . . . . . . . . . . . . . . . . . . . . . . . . . . . . 133
19.5.2 Macros with More than One Argument . . . . . . . . . . . . . . . . . . . . . . . . 134
19.5.3 Macros with Variable Arguments . . . . . . . . . . . . . . . . . . . . . . . . . . 135
19.5.4 Stringification . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 135
19.5.5 Concatenation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 136
19.6 Multiline Macros . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 136
19.7 Example: An Assert Macro . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 137
19.8 The #error Directive . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 139
19.9 The #pragma Directive . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 139
CONTENTS v

19.9.1 Non-Standard Pragmas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 139


19.9.2 Standard Pragmas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 139
19.9.3 _Pragma Operator . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 140
19.10 The #line Directive . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 140
19.11 The Null Directive . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 141

20 structs II: More Fun with structs 142


20.1 Initializers of Nested structs and Arrays . . . . . . . . . . . . . . . . . . . . . . . . 142
20.2 Anonymous structs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 144
20.3 Self-Referential structs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 145
20.4 Flexible Array Members . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 145
20.5 Padding Bytes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 147
20.6 offsetof . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 147
20.7 Fake OOP . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 148
20.8 Bit-Fields . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 150
20.8.1 Non-Adjacent Bit-Fields . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 150
20.8.2 Signed or Unsigned ints . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 151
20.8.3 Unnamed Bit-Fields . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 151
20.8.4 Zero-Width Unnamed Bit-Fields . . . . . . . . . . . . . . . . . . . . . . . . . . . 151
20.9 Unions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 152
20.9.1 Unions and Type Punning . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 152
20.9.2 Pointers to unions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 153
20.9.3 Common Initial Sequences in Unions . . . . . . . . . . . . . . . . . . . . . . . . 154
20.10 Unions and Unnamed Structs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 156
20.11 Passing and Returning structs and unions . . . . . . . . . . . . . . . . . . . . . . . . 157

21 Characters and Strings II 158


21.1 Escape Sequences . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 158
21.1.1 Frequently-used Escapes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 158
21.1.2 Rarely-used Escapes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 159
21.1.3 Numeric Escapes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 161

22 Enumerated Types: enum 162


22.1 Behavior of enum . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 162
22.1.1 Numbering . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 162
22.1.2 Trailing Commas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 163
22.1.3 Scope . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 163
22.1.4 Style . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 163
22.2 Your enum is a Type . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 163

23 Pointers III: Pointers to Pointers and More 166


23.1 Pointers to Pointers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 166
23.1.1 Pointer Pointers and const . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 169
23.2 Multibyte Values . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 170
23.3 The NULL Pointer and Zero . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 171
23.4 Pointers as Integers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 171
23.5 Casting Pointers to other Pointers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 172
23.6 Pointer Differences . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 174
23.7 Pointers to Functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 174

24 Bitwise Operations 177


24.1 Bitwise AND, OR, XOR, and NOT . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 177
24.2 Bitwise Shift . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 177

25 Variadic Functions 179


CONTENTS vi

25.1 Ellipses in Function Signatures . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 179


25.2 Getting the Extra Arguments . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 180
25.3 va_list Functionality . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 181
25.4 Library Functions That Use va_lists . . . . . . . . . . . . . . . . . . . . . . . . . . 182

26 Locale and Internationalization 183


26.1 Setting the Localization, Quick and Dirty . . . . . . . . . . . . . . . . . . . . . . . . . 183
26.2 Getting the Monetary Locale Settings . . . . . . . . . . . . . . . . . . . . . . . . . . . . 184
26.2.1 Monetary Digit Grouping . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 185
26.2.2 Separators and Sign Position . . . . . . . . . . . . . . . . . . . . . . . . . . . . 186
26.2.3 Example Values . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 186
26.3 Localization Specifics . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 186

27 Unicode, Wide Characters, and All That 188


27.1 What is Unicode? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 188
27.2 Code Points . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 188
27.3 Encoding . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 189
27.4 Source and Execution Character Sets . . . . . . . . . . . . . . . . . . . . . . . . . . . 190
27.5 Unicode in C . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 191
27.6 A Quick Note on UTF-8 Before We Swerve into the Weeds . . . . . . . . . . . . . . . 192
27.7 Different Character Types . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 192
27.7.1 Multibyte Characters . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 192
27.7.2 Wide Characters . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 193
27.8 Using Wide Characters and wchar_t . . . . . . . . . . . . . . . . . . . . . . . . . . . 193
27.8.1 Multibyte to wchar_t Conversions . . . . . . . . . . . . . . . . . . . . . . . . . . 194
27.9 Wide Character Functionality . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 195
27.9.1 wint_t . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 195
27.9.2 I/O Stream Orientation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 195
27.9.3 I/O Functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 196
27.9.4 Type Conversion Functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . 196
27.9.5 String and Memory Copying Functions . . . . . . . . . . . . . . . . . . . . . . 196
27.9.6 String and Memory Comparing Functions . . . . . . . . . . . . . . . . . . . . . . 197
27.9.7 String Searching Functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 197
27.9.8 Length/Miscellaneous Functions . . . . . . . . . . . . . . . . . . . . . . . . . . . 197
27.9.9 Character Classification Functions . . . . . . . . . . . . . . . . . . . . . . . . . 198
27.10 Parse State, Restartable Functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . 198
27.11 Unicode Encodings and C . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 200
27.11.1 UTF-8 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 200
27.11.2 UTF-16, UTF-32, char16_t, and char32_t . . . . . . . . . . . . . . . . . . . . . 201
27.11.3 Multibyte Conversions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 201
27.11.4 Third-Party Libraries . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 202

28 Exiting a Program 203


28.1 Normal Exits . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 203
28.1.1 Returning From main() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 203
28.1.2 exit() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 203
28.1.3 Setting Up Exit Handlers with atexit() . . . . . . . . . . . . . . . . . . . . . . 204
28.2 Quicker Exits with quick_exit() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 204
28.3 Nuke it from Orbit: _Exit() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 205
28.4 Exiting Sometimes: assert() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 205
28.5 Abnormal Exit: abort() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 206

29 Signal Handling 207


29.1 What Are Signals? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 207
29.2 Handling Signals with signal() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 207
CONTENTS vii

29.3 Writing Signal Handlers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 208


29.4 What Can We Actually Do? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 210
29.5 Friends Don’t Let Friends signal() . . . . . . . . . . . . . . . . . . . . . . . . . . . 212

30 Variable-Length Arrays (VLAs) 213


30.1 The Basics . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 213
30.2 sizeof and VLAs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 214
30.3 Multidimensional VLAs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 215
30.4 Passing One-Dimensional VLAs to Functions . . . . . . . . . . . . . . . . . . . . . . 215
30.5 Passing Multi-Dimensional VLAs to Functions . . . . . . . . . . . . . . . . . . . . . . 216
30.5.1 Partial Multidimensional VLAs . . . . . . . . . . . . . . . . . . . . . . . . . . . 217
30.6 Compatibility with Regular Arrays . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 217
30.7 typedef and VLAs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 218
30.8 Jumping Pitfalls . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 218
30.9 General Issues . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 218

31 goto 220
31.1 A Simple Example . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 220
31.2 Labeled continue . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 221
31.3 Bailing Out . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 222
31.4 Labeled break . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 223
31.5 Multi-level Cleanup . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 223
31.6 Tail Call Optimization . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 224
31.7 Restarting Interrupted System Calls . . . . . . . . . . . . . . . . . . . . . . . . . . . 225
31.8 goto and Thread Preemption . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 226
31.9 goto and Variable Scope . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 226
31.10 goto and Variable-Length Arrays . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 227

32 Types Part V: Compound Literals and Generic Selections 229


32.1 Compound Literals . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 229
32.1.1 Passing Unnamed Objects to Functions . . . . . . . . . . . . . . . . . . . . . . 230
32.1.2 Unnamed structs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 230
32.1.3 Pointers to Unnamed Objects . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 231
32.1.4 Unnamed Objects and Scope . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 231
32.1.5 Silly Unnamed Object Example . . . . . . . . . . . . . . . . . . . . . . . . . . 232
32.2 Generic Selections . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 232

33 Arrays Part II 236


33.1 Type Qualifiers for Arrays in Parameter Lists . . . . . . . . . . . . . . . . . . . . . . . 236
33.2 static for Arrays in Parameter Lists . . . . . . . . . . . . . . . . . . . . . . . . . . . 236
33.3 Equivalent Initializers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 237

34 Long Jumps with setjmp, longjmp 240


34.1 Using setjmp and longjmp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 240
34.2 Pitfalls . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 241
34.2.1 The Values of Local Variables . . . . . . . . . . . . . . . . . . . . . . . . . . . . 241
34.2.2 How Much State is Saved? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 242
34.2.3 You Can’t Name Anything setjmp . . . . . . . . . . . . . . . . . . . . . . . . . 242
34.2.4 You Can’t setjmp() in a Larger Expression . . . . . . . . . . . . . . . . . . . . 242
34.2.5 When Can’t You longjmp()? . . . . . . . . . . . . . . . . . . . . . . . . . . . 243
34.2.6 You Can’t Pass 0 to longjmp() . . . . . . . . . . . . . . . . . . . . . . . . . . 243
34.2.7 longjmp() and Variable Length Arrays . . . . . . . . . . . . . . . . . . . . . . 243

35 Incomplete Types 244


35.1 Use Case: Self-Referential Structures . . . . . . . . . . . . . . . . . . . . . . . . . . . . 244
CONTENTS viii

35.2 Incomplete Type Error Messages . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 245


35.3 Other Incomplete Types . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 245
35.4 Use Case: Arrays in Header Files . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 246
35.5 Completing Incomplete Types . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 246

36 Complex Numbers 248


36.1 Complex Types . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 248
36.2 Assigning Complex Numbers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 249
36.3 Constructing, Deconstructing, and Printing . . . . . . . . . . . . . . . . . . . . . . . . 249
36.4 Complex Arithmetic and Comparisons . . . . . . . . . . . . . . . . . . . . . . . . . . 250
36.5 Complex Math . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 251
36.5.1 Trigonometry Functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 251
36.5.2 Exponential and Logarithmic Functions . . . . . . . . . . . . . . . . . . . . . . 252
36.5.3 Power and Absolute Value Functions . . . . . . . . . . . . . . . . . . . . . . . . 252
36.5.4 Manipulation Functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 252

37 Fixed Width Integer Types 253


37.1 The Bit-Sized Types . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 253
37.2 Maximum Integer Size Type . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 254
37.3 Using Fixed Size Constants . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 254
37.4 Limits of Fixed Size Integers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 255
37.5 Format Specifiers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 255

38 Date and Time Functionality 257


38.1 Quick Terminology and Information . . . . . . . . . . . . . . . . . . . . . . . . . . . . 257
38.2 Date Types . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 258
38.3 Initialization and Conversion Between Types . . . . . . . . . . . . . . . . . . . . . . . 258
38.3.1 Converting time_t to struct tm . . . . . . . . . . . . . . . . . . . . . . . . . 259
38.3.2 Converting struct tm to time_t . . . . . . . . . . . . . . . . . . . . . . . . . 259
38.4 Formatted Date Output . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 260
38.5 More Resolution with timespec_get() . . . . . . . . . . . . . . . . . . . . . . . . . . 261
38.6 Differences Between Times . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 262

39 Multithreading 263
39.1 Background . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 263
39.2 Things You Can Do . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 264
39.3 Data Races and the Standard Library . . . . . . . . . . . . . . . . . . . . . . . . . . . . 264
39.4 Creating and Waiting for Threads . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 264
39.5 Detaching Threads . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 268
39.6 Thread Local Data . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 269
39.6.1 _Thread_local Storage-Class . . . . . . . . . . . . . . . . . . . . . . . . . . . 271
39.6.2 Another Option: Thread-Specific Storage . . . . . . . . . . . . . . . . . . . . . . 271
39.7 Mutexes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 273
39.7.1 Different Mutex Types . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 276
39.8 Condition Variables . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 277
39.8.1 Timed Condition Wait . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 280
39.8.2 Broadcast: Wake Up All Waiting Threads . . . . . . . . . . . . . . . . . . . . . . 281
39.9 Running a Function One Time . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 281

40 Atomics 282
40.1 Testing for Atomic Support . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 282
40.2 Atomic Variables . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 282
40.3 Synchronization . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 284
40.4 Acquire and Release . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 286
40.5 Sequential Consistency . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 287
CONTENTS ix

40.6 Atomic Assignments and Operators . . . . . . . . . . . . . . . . . . . . . . . . . . . . 288


40.7 Library Functions that Automatically Synchronize . . . . . . . . . . . . . . . . . . . . 288
40.8 Atomic Type Specifier, Qualifier . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 289
40.9 Lock-Free Atomic Variables . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 290
40.9.1 Signal Handlers and Lock-Free Atomics . . . . . . . . . . . . . . . . . . . . . . . 291
40.10 Atomic Flags . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 292
40.11 Atomic structs and unions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 292
40.12 Atomic Pointers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 293
40.13 Memory Order . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 294
40.13.1 Sequential Consistency . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 294
40.13.2 Acquire . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 295
40.13.3 Release . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 295
40.13.4 Consume . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 295
40.13.5 Acquire/Release . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 295
40.13.6 Relaxed . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 295
40.14 Fences . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 295
40.15 References . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 296

41 Function Specifiers, Alignment Specifiers/Operators 298


41.1 Function Specifiers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 298
41.1.1 inline for Speed—Maybe . . . . . . . . . . . . . . . . . . . . . . . . . . . . 298
41.1.2 noreturn and _Noreturn . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 301
41.2 Alignment Specifiers and Operators . . . . . . . . . . . . . . . . . . . . . . . . . . . . 301
41.2.1 alignas and _Alignas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 302
41.2.2 alignof and _Alignof . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 302
Chapter 1

Foreword

C is not a big language, and it is not well served by a big book.


–Brian W. Kernighan, Dennis M. Ritchie
No point in wasting words here, folks, let’s jump straight into the C code:
E((ck?main((z?(stat(M,&t)?P+=a+'{'?0:3:
execv(M,k),a=G,i=P,y=G&255,
sprintf(Q,y/'@'-3?A(*L(V(%d+%d)+%d,0)

And they lived happily ever after. The End.


What’s this? You say something’s still not clear about this whole C programming language thing?
Well, to be quite honest, I’m not even sure what the above code does. It’s a snippet from one of the entries in
the 2001 International Obfuscated C Code Contest1 , a wonderful competition wherein the entrants attempt
to write the most unreadable C code possible, with often surprising results.
The bad news is that if you’re a beginner in this whole thing, all C code you see probably looks obfuscated!
The good news is, it’s not going to be that way for long.
What we’ll try to do over the course of this guide is lead you from complete and utter sheer lost confusion
on to the sort of enlightened bliss that can only be obtained through pure C programming. Right on.
In the old days, C was a simpler language. A good number of the features contained in this book and a lot
of the features in the Library Reference volume didn’t exist when K&R wrote the famous second edition of
their book in 1988. Nevertheless, the language remains small at its core, and I hope I’ve presented it here in
a way that starts with that simple core and builds outward.
And that’s my excuse for writing such a hilariously large book for such a small, concise language.

1.1 Audience
This guide assumes that you’ve already got some programming knowledge under your belt from another
language, such as Python2 , JavaScript3 , Java4 , Rust5 , Go6 , Swift7 , etc. (Objective-C8 devs will have a par-
1
https://www.ioccc.org/
2
https://en.wikipedia.org/wiki/Python_(programming_language)
3
https://en.wikipedia.org/wiki/JavaScript
4
https://en.wikipedia.org/wiki/Java_(programming_language)
5
https://en.wikipedia.org/wiki/Rust_(programming_language)
6
https://en.wikipedia.org/wiki/Go_(programming_language)
7
https://en.wikipedia.org/wiki/Swift_(programming_language)
8
https://en.wikipedia.org/wiki/Objective-C

1
Chapter 1. Foreword 2

ticularly easy time of it!)


We’re going to assume you know what variables are, what loops do, how functions work, and so on.
If that’s not you for whatever reason the best I can hope to provide is some honest entertainment for your
reading pleasure. The only thing I can reasonably promise is that this guide won’t end on a cliffhanger… or
will it?

1.2 How to Read This Book


The guide is in two volumes, and this is the first: the tutorial volume!
The second volume is the library reference9 , and it’s far more reference than tutorial.
If you’re new, go through the tutorial part in order, generally. The higher you get in chapters, the less
important it is to go in order.
And no matter your skill level, the reference part is there with complete examples of the standard library
function calls to help refresh your memory whenever needed. Good for reading over a bowl of cereal or
other time.
Finally, glancing at the index (if you’re reading the print version), the reference section entries are italicized.

1.3 Platform and Compiler


I’ll try to stick to Plain Ol’-Fashioned ISO-standard C10 . Well, for the most part. Here and there I might go
crazy and start talking about POSIX11 or something, but we’ll see.
Unix users (e.g. Linux, BSD, etc.) try running cc or gcc from the command line–you might already have a
compiler installed. If you don’t, search your distribution for installing gcc or clang.
Windows users should check out Visual Studio Community12 . Or, if you’re looking for a more Unix-like
experience (recommended!), install WSL13 and gcc.
Mac users will want to install XCode14 , and in particular the command line tools.
There are a lot of compilers out there, and virtually all of them will work for this book. And a C++ compiler
will compile a lot of (but not all!) C code. Best use a proper C compiler if you can.

1.4 Official Homepage


This official location of this document is https://beej.us/guide/bgc/15 . Maybe this’ll change in the future, but
it’s more likely that all the other guides are migrated off Chico State computers.

1.5 Email Policy


I’m generally available to help out with email questions so feel free to write in, but I can’t guarantee a
response. I lead a pretty busy life and there are times when I just can’t answer a question you have. When
that’s the case, I usually just delete the message. It’s nothing personal; I just won’t ever have the time to give
the detailed answer you require.
9
https://beej.us/guide/bgclr/
10
https://en.wikipedia.org/wiki/ANSI_C
11
https://en.wikipedia.org/wiki/POSIX
12
https://visualstudio.microsoft.com/vs/community/
13
https://docs.microsoft.com/en-us/windows/wsl/install-win10
14
https://developer.apple.com/xcode/
15
https://beej.us/guide/bgc/
Chapter 1. Foreword 3

As a rule, the more complex the question, the less likely I am to respond. If you can narrow down your
question before mailing it and be sure to include any pertinent information (like platform, compiler, error
messages you’re getting, and anything else you think might help me troubleshoot), you’re much more likely
to get a response.
If you don’t get a response, hack on it some more, try to find the answer, and if it’s still elusive, then write
me again with the information you’ve found and hopefully it will be enough for me to help out.
Now that I’ve badgered you about how to write and not write me, I’d just like to let you know that I fully
appreciate all the praise the guide has received over the years. It’s a real morale boost, and it gladdens me to
hear that it is being used for good! :-) Thank you!

1.6 Mirroring
You are more than welcome to mirror this site, whether publicly or privately. If you publicly mirror the site
and want me to link to it from the main page, drop me a line at [email protected].

1.7 Note for Translators


If you want to translate the guide into another language, write me at [email protected] and I’ll link to your
translation from the main page. Feel free to add your name and contact info to the translation.
Please note the license restrictions in the Copyright and Distribution section, below.

1.8 Copyright and Distribution


Beej’s Guide to C is Copyright © 2021 Brian “Beej Jorgensen” Hall.
With specific exceptions for source code and translations, below, this work is licensed under the Creative
Commons Attribution-Noncommercial-No Derivative Works 3.0 License. To view a copy of this license,
visit https://creativecommons.org/licenses/by-nc-nd/3.0/ or send a letter to Creative Commons,
171 Second Street, Suite 300, San Francisco, California, 94105, USA.
One specific exception to the “No Derivative Works” portion of the license is as follows: this guide may
be freely translated into any language, provided the translation is accurate, and the guide is reprinted in its
entirety. The same license restrictions apply to the translation as to the original guide. The translation may
also include the name and contact information for the translator.
The C source code presented in this document is hereby granted to the public domain, and is completely free
of any license restriction.
Educators are freely encouraged to recommend or supply copies of this guide to their students.
Contact [email protected] for more information.

1.9 Dedication
The hardest things about writing these guides are:
• Learning the material in enough detail to be able to explain it
• Figuring out the best way to explain it clearly, a seemingly-endless iterative process
• Putting myself out there as a so-called authority, when really I’m just a regular human trying to make
sense of it all, just like everyone else
• Keeping at it when so many other things draw my attention
Chapter 1. Foreword 4

A lot of people have helped me through this process, and I want to acknowledge those who have made this
book possible.
• Everyone on the Internet who decided to help share their knowledge in one form or another. The free
sharing of instructive information is what makes the Internet the great place that it is.
• The volunteers at cppreference.com16 who provide the bridge that leads from the spec to the real world.
• The helpful and knowledgeable folks on comp.lang.c17 and r/C_Programming18 who got me through
the tougher parts of the language.
• Everyone who submitted corrections and pull-requests on everything from misleading instructions to
typos.
Thank you! ♥

16
https://en.cppreference.com/
17
https://groups.google.com/g/comp.lang.c
18
https://www.reddit.com/r/C_Programming/
Chapter 2

Hello, World!

2.1 What to Expect from C


“Where do these stairs go?”
“They go up.”
—Ray Stantz and Peter Venkman, Ghostbusters
C is a low-level language.
It didn’t use to be. Back in the day when people carved punch cards out of granite, C was an incredible way
to be free of the drudgery of lower-level languages like assembly1 .
But now in these modern times, current-generation languages offer all kinds of features that didn’t exist in
1972 when C was invented. This means C is a pretty basic language with not a lot of features. It can do
anything, but it can make you work for it.
So why would we even use it today?
• As a learning tool: not only is C a venerable piece of computing history, but it is connected to the bare
metal2 in a way that present-day languages are not. When you learn C, you learn about how software
interfaces with computer memory at a low level. There are no seatbelts. You’ll write software that
crashes, I assure you. And that’s all part of the fun!
• As a useful tool: C still is used for certain applications, such as building operating systems3 or in
embedded systems4 . (Though the Rust5 programming language is eyeing both these fields!)
If you’re familiar with another language, a lot of things about C are easy. C inspired many other languages,
and you’ll see bits of it in Go, Rust, Swift, Python, JavaScript, Java, and all kinds of other languages. Those
parts will be familiar.
The one thing about C that hangs people up is pointers. Virtually everything else is familiar, but pointers are
the weird one. The concept behind pointers is likely one you already know, but C forces you to be explicit
about it, using operators you’ve likely never seen before.
It’s especially insidious because once you grok6 pointers, they’re suddenly easy. But up until that moment,
they’re slippery eels.
1
https://en.wikipedia.org/wiki/Assembly_language
2
https://en.wikipedia.org/wiki/Bare_machine
3
https://en.wikipedia.org/wiki/Operating_system
4
https://en.wikipedia.org/wiki/Embedded_system
5
https://en.wikipedia.org/wiki/Rust_(programming_language)
6
https://en.wikipedia.org/wiki/Grok

5
Chapter 2. Hello, World! 6

Everything else in C is just memorizing another way (or sometimes the same way!) of doing something
you’ve done already. Pointers are the weird bit. And, arguably, even pointers are variations on a theme
you’re probably familiar with.
So get ready for a rollicking adventure as close to the core of the computer as you can get without assembly,
in the most influential computer language of all time7 . Hang on!

2.2 Hello, World!


This is the canonical example of a C program. Everyone uses it. (Note that the numbers to the left are for
reader reference only, and are not part of the source code.)
/* Hello world program */

#include <stdio.h>

int main(void)
{
printf("Hello, World!\n"); // Actually do the work here
}

We’re going to don our long-sleeved heavy-duty rubber gloves, grab a scalpel, and rip into this thing to see
what makes it tick. So, scrub up, because here we go. Cutting very gently…
Let’s get the easy thing out of the way: anything between the digraphs /* and */ is a comment and will be
completely ignored by the compiler. Same goes for anything on a line after a //. This allows you to leave
messages to yourself and others, so that when you come back and read your code in the distant future, you’ll
know what the heck it was you were trying to do. Believe me, you will forget; it happens.
Now, what is this #include? GROSS! Well, it tells the C Preprocessor to pull the contents of another file
and insert it into the code right there.
Wait—what’s a C Preprocessor? Good question. There are two stages8 to compilation: the preprocessor
and the compiler. Anything that starts with pound sign, or “octothorpe”, (#) is something the preprocessor
operates on before the compiler even gets started. Common preprocessor directives, as they’re called, are
#include and #define. More on that later.

Before we go on, why would I even begin to bother pointing out that a pound sign is called an octothorpe?
The answer is simple: I think the word octothorpe is so excellently funny, I have to gratuitously spread its
name around whenever I get the opportunity. Octothorpe. Octothorpe, octothorpe, octothorpe.
So anyway. After the C preprocessor has finished preprocessing everything, the results are ready for the
compiler to take them and produce assembly code9 , machine code10 , or whatever it’s about to do. Machine
code is the “language” the CPU understands, and it can understand it very rapidly. This is one of the reasons
C programs tend to be quick.
Don’t worry about the technical details of compilation for now; just know that your source runs through the
preprocessor, then the output of that runs through the compiler, then that produces an executable for you to
run.
What about the rest of the line? What’s <stdio.h>? That is what is known as a header file. It’s the dot-h at
the end that gives it away. In fact it’s the “Standard I/O” (stdio) header file that you will grow to know and
love. It gives us access to a bunch of I/O functionality11 . For our demo program, we’re outputting the string
7
I know someone will fight me on that, but it’s gotta be at least in the top three, right?
8
Well, technically there are more than two, but hey, let’s pretend there are two—ignorance is bliss, right?
9
https://en.wikipedia.org/wiki/Assembly_language
10
https://en.wikipedia.org/wiki/Machine_code
11
Technically, it contains preprocessor directives and function prototypes (more on that later) for common input and output needs.
Chapter 2. Hello, World! 7

“Hello, World!”, so we in particular need access to the printf() function to do this. The <stdio.h> file
gives us this access. Basically, if we tried to use printf() without #include <stdio.h>, the compiler
would have complained to us about it.
How did I know I needed to #include <stdio.h> for printf()? Answer: it’s in the documentation. If
you’re on a Unix system, man 3 printf and it’ll tell you right at the top of the man page what header files
are required. Or see the reference section in this book. :-)
Holy moly. That was all to cover the first line! But, let’s face it, it has been completely dissected. No mystery
shall remain!
So take a breather…look back over the sample code. Only a couple easy lines to go.
Welcome back from your break! I know you didn’t really take a break; I was just humoring you.
The next line is main(). This is the definition of the function main(); everything between the squirrelly
braces ({ and }) is part of the function definition.
(How do you call a different function, anyway? The answer lies in the printf() line, but we’ll get to that
in a minute.)
Now, the main function is a special one in many ways, but one way stands above the rest: it is the function
that will be called automatically when your program starts executing. Nothing of yours gets called before
main(). In the case of our example, this works fine since all we want to do is print a line and exit.

Oh, that’s another thing: once the program executes past the end of main(), down there at the closing
squirrelly brace, the program will exit, and you’ll be back at your command prompt.
So now we know that that program has brought in a header file, stdio.h, and declared a main() function
that will execute when the program is started. What are the goodies in main()?
I am so happy you asked. Really! We only have the one goodie: a call to the function printf(). You can
tell this is a function call and not a function definition in a number of ways, but one indicator is the lack of
squirrelly braces after it. And you end the function call with a semicolon so the compiler knows it’s the end
of the expression. You’ll be putting semicolons after almost everything, as you’ll see.
You’re passing one argument to the function printf(): a string to be printed when you call it. Oh, yeah—
we’re calling a function! We rock! Wait, wait—don’t get cocky. What’s that crazy \n at the end of the string?
Well, most characters in the string will print out just like they are stored. But there are certain characters that
you can’t print on screen well that are embedded as two-character backslash codes. One of the most popular is
\n (read “backslash-N” or simply “newline”) that corresponds to the newline character. This is the character
that causes further printing to continue at the beginning of the next line instead of the current. It’s like hitting
return at the end of the line.
So copy that code into a file called hello.c and build it. On a Unix-like platform (e.g. Linux, BSD, Mac,
or WSL), from the command line you’ll build with a command like so:
gcc -o hello hello.c

(This means “compile hello.c, and output an executable called hello”.)


After that’s done, you should have a file called hello that you can run with this command:
./hello

(The leading ./ tells the shell to “run from the current directory”.)
And see what happens:
Hello, World!

It’s done and tested! Ship it!


Chapter 2. Hello, World! 8

2.3 Compilation Details


Let’s talk a bit more about how to build C programs, and what happens behind the scenes there.
Like other languages, C has source code. But, depending on what language you’re coming from, you might
never have had to compile your source code into an executable.
Compilation is the process of taking your C source code and turning it into a program that your operating
system can execute.
JavaScript and Python devs aren’t used to a separate compilation step at all–though behind the scenes it’s
happening! Python compiles your source code into something called bytecode that the Python virtual machine
can execute. Java devs are used to compilation, but that produces bytecode for the Java Virtual Machine.
When compiling C, machine code is generated. This is the 1s and 0s that can be executed directly and speedily
by the CPU.
Languages that typically aren’t compiled are called interpreted languages. But as we mentioned
with Java and Python, they also have a compilation step. And there’s no rule saying that C can’t
be interpreted. (There are C interpreters out there!) In short, it’s a bunch of gray areas. Com-
pilation in general is just taking source code and turning it into another, more easily-executed
form.
The C compiler is the program that does the compilation.
As we’ve already said, gcc is a compiler that’s installed on a lot of Unix-like operating systems12 . And it’s
commonly run from the command line in a terminal, but not always. You can run it from your IDE, as well.
So how do we do command line builds?

2.4 Building with gcc


If you have a source file called hello.c in the current directory, you can build that into a program called
hello with this command typed in a terminal:

gcc -o hello hello.c

The -o means “output to this file”13 . And there’s hello.c at the end, the name of the file we want to compile.
If your source is broken up into multiple files, you can compile them all together (almost as if they were one
file, but the rules are actually more complex than that) by putting all the .c files on the command line:
gcc -o awesomegame ui.c characters.c npc.c items.c

and they’ll all get built together into a big executable.


That’s enough to get started—later we’ll talk details about multiple source files, object files, and all kinds of
fun stuff.

2.5 Building with clang


On Macs, the stock compiler isn’t gcc—it’s clang. But a wrapper is also installed so you can run gcc and
have it still work.
You can also install the gcc compiler proper through Homebrew14 or some other means.
12
https://en.wikipedia.org/wiki/Unix
13
If you don’t give it an output filename, it will export to a file called a.out by default—this filename has its roots deep in Unix
history.
14
https://formulae.brew.sh/formula/gcc
Chapter 2. Hello, World! 9

2.6 Building from IDEs


If you’re using an Integrated Development Environment (IDE), you probably don’t have to build from the
command line.
With Visual Studio, CTRL-F7 will build, and CTRL-F5 will run.
With VS Code, you can hit F5 to run via the debugger. (You’ll have to install the C/C++ Extension.)
With XCode, you can build with COMMAND-B and run with COMMAND-R. To get the command line tools, Google
for “XCode command line tools” and you’ll find instructions for installing them.
For getting started, I encourage you to also try to build from the command line—it’s history!

2.7 C Versions
C has come a long way over the years, and it had many named version numbers to describe which dialect of
the language you’re using.
These generally refer to the year of the specification.
The most famous are C89, C99, C11, and C2x. We’ll focus on the latter in this book.
But here’s a more complete table:

Version Description
K&R C 1978, the original. Named after Brian Kernighan and Dennis Ritchie.
Ritchie designed and coded the language, and Kernighan co-authored the
book on it. You rarely see original K&R code today. If you do, it’ll look odd,
like Middle English looks odd to modern English readers.
C89, ANSI C, C90 In 1989, the American National Standards Institute (ANSI) produced a C
language specification that set the tone for C that persists to this day. A year
later, the reins were handed to the International Organization for
Standardization (ISO) that produced the identical C90.
C95 A rarely-mentioned addition to C89 that included wide character support.
C99 The first big overhaul with lots of language additions. The thing most people
remember is the addition of //-style comments. This is the most popular
version of C in use as of this writing.
C11 This major version update includes Unicode support and multi-threading. Be
advised that if you start using these language features, you might be
sacrificing portability with places that are stuck in C99 land. But, honestly,
1999 is getting to be a while back now.
C17, C18 Bugfix update to C11. C17 seems to be the official name, but the publication
was delayed until 2018. As far as I can tell, these two are interchangeable,
with C17 being preferred.
C2x What’s coming next! Expected to eventually become C23.

You can force GCC to use one of these standards with the -std= command line argument. If you want it to
be picky about the standard, add -pedantic.
For example:
gcc -std=c11 -pedantic foo.c

For this book, I compile programs for C2x with all warnings set:
gcc -Wall -Wextra -std=c2x -pedantic foo.c
Chapter 3

Variables and Statements

“It takes all kinds to make a world, does it not, Padre?”


“So it does, my son, so it does.”
—Pirate Captain Thomas Bartholomew Red to the Padre, Pirates
There sure can be lotsa stuff in a C program.
Yup.
And for various reasons, it’ll be easier for all of us if we classify some of the types of things you can find in
a program, so we can be clear what we’re talking about.

3.1 Variables
It’s said that “variables hold values”. But another way to think about it is that a variable is a human-readable
name that refers to some data in memory.
We’re going to take a second here and take a peek down the rabbit hole that is pointers. Don’t worry about
it.
You can think of memory as a big array of bytes1 . Data is stored in this “array”2 . If a number is larger than
a single byte, it is stored in multiple bytes. Because memory is like an array, each byte of memory can be
referred to by its index. This index into memory is also called an address, or a location, or a pointer.
When you have a variable in C, the value of that variable is in memory somewhere, at some address. Of
course. After all, where else would it be? But it’s a pain to refer to a value by its numeric address, so we
make a name for it instead, and that’s what the variable is.
The reason I’m bringing all this up is twofold:
1. It’s going to make it easier to understand pointer variables later—they’re variables that hold the address
of other variables!
2. Also, it’s going to make it easier to understand pointers later.
So a variable is a name for some data that’s stored in memory at some address.
1
A “byte” is typically an 8-bit binary number. Think of it as an integer that can only hold the values from 0 to 255, inclusive.
Technically, C allows bytes to be any number of bits and if you want to unambiguously refer to an 8-bit number, you should use the
term octet. But programmers are going assume you mean 8-bits when you say “byte” unless you specify otherwise.
2
I’m seriously oversimplifying how modern memory works, here. But the mental model works, so please forgive me.

10
Chapter 3. Variables and Statements 11

3.1.1 Variable Names


You can use any characters in the range 0-9, A-Z, a-z, and underscore for variable names, with the following
rules:
• You can’t start a variable with a digit 0-9.
• You can’t start a variable name with two underscores.
• You can’t start a variable name with an underscore followed by a capital A-Z.
For Unicode, just try it. There are some rules in the spec in §D.2 that talk about which Unicode codepoint
ranges are allowed in which parts of identifiers, but that’s too much to write about here and is probably
something you’ll never have to think about anyway.

3.1.2 Variable Types


Depending on which languages you already have in your toolkit, you might or might not be familiar with the
idea of types. But C’s kinda picky about them, so we should do a refresher.
Some example types, some of the most basic:

Type Example C Type


Integer 3490 int
Floating point 3.14159 float3
Character (single) 'c' char
String "Hello, world!" char *4

C makes an effort to convert automatically between most numeric types when you ask it to. But other than
that, all conversions are manual, notably between string and numeric.
Almost all of the types in C are variants on these types.
Before you can use a variable, you have to declare that variable and tell C what type the variable holds. Once
declared, the type of variable cannot be changed later at runtime. What you set it to is what it is until it falls
out of scope and is reabsorbed into the universe.
Let’s take our previous “Hello, world” code and add a couple variables to it:
#include <stdio.h>

int main(void)
{
int i; // Holds signed integers, e.g. -3, -2, 0, 1, 10
float f; // Holds signed floating point numbers, e.g. -3.1416

printf("Hello, World!\n"); // Ah, blessed familiarity


}

There! We’ve declared a couple of variables. We haven’t used them yet, and they’re both uninitialized. One
holds an integer number, and the other holds a floating point number (a real number, basically, if you have a
math background).
Uninitialized variables have indeterminate value5 . They have to be initialized or else you must assume they
contain some nonsense number.
3
I’m lying here a little. Technically 3.14159 is of type double, but we’re not there yet and I want you to associate float with
“Floating Point”, and C will happily coerce that type into a float. In short, don’t worry about it until later.
4
Read this as “pointer to a char” or “char pointer”. “Char” for character. Though I can’t find a study, it seems anecdotally most
people pronounce this as “char”, a minority say “car”, and a handful say “care”. We’ll talk more about pointers later.
5
Colloquially, we say they have “random” values, but they aren’t truly—or even pseudo-truly—random numbers.
Chapter 3. Variables and Statements 12

This is one of the places C can “get you”. Much of the time, in my experience, the indeterminate
value is zero… but it can vary from run to run! Never assume the value will be zero, even if you
see it is. Always explicitly initialize variables to some value before you use them6 .
What’s this? You want to store some numbers in those variables? Insanity!
Let’s go ahead and do that:
int main(void)
{
int i;

i = 2; // Assign the value 2 into the variable i

printf("Hello, World!\n");
}

Killer. We’ve stored a value. Let’s print it.


We’re going to do that by passing two amazing arguments to the printf() function. The first argument is
a string that describes what to print and how to print it (called the format string), and the second is the value
to print, namely whatever is in the variable i.
printf() hunts through the format string for a variety of special sequences which start with a percent sign
(%) that tell it what to print. For example, if it finds a %d, it looks to the next parameter that was passed, and
prints it out as an integer. If it finds a %f, it prints the value out as a float. If it finds a %s, it prints a string.
As such, we can print out the value of various types like so:
#include <stdio.h>

int main(void)
{
int i = 2;
float f = 3.14;
char *s = "Hello, world!"; // char * ("char pointer") is the string type

printf("%s i = %d and f = %f!\n", s, i, f);


}

And the output will be:


Hello, world! i = 2 and f = 3.14!

In this way, printf() might be similar to various types of format strings or parameterized strings in other
languages you’re familiar with.

3.1.3 Boolean Types


C has Boolean types, true or false?
1!

Historically, C didn’t have a Boolean type, and some might argue it still doesn’t.
In C, 0 means “false”, and non-zero means “true”.
So 1 is true. And -37 is true. And 0 is false.
You can just declare Boolean types as ints:
6
This isn’t strictly 100% true. When we get to learning about static storage duration, you’ll find the some variables are initialized to
zero automatically. But the safe thing to do is always initialize them.
Chapter 3. Variables and Statements 13

int x = 1;

if (x) {
printf("x is true!\n");
}

If you #include <stdbool.h>, you also get access to some symbolic names that might make things look
more familiar, namely a bool type and true and false values:
#include <stdio.h>
#include <stdbool.h>

int main(void) {
bool x = true;

if (x) {
printf("x is true!\n");
}
}

But these are identical to using integer values for true and false. They’re just a facade to make things look
nice.

3.2 Operators and Expressions


C operators should be familiar to you from other languages. Let’s blast through some of them here.
(There are a bunch more details than this, but we’re going to do enough in this section to get started.)

3.2.1 Arithmetic
Hopefully these are familiar:
i = i + 3; // Addition (+) and assignment (=) operators, add 3 to i
i = i - 8; // Subtraction, subtract 8 from i
i = i * 9; // Multiplication
i = i / 2; // Division
i = i % 5; // Modulo (division remainder)

There are shorthand variants for all of the above. Each of those lines could more tersely be written as:
i += 3; // Same as "i = i + 3", add 3 to i
i -= 8; // Same as "i = i - 8"
i *= 9; // Same as "i = i * 9"
i /= 2; // Same as "i = i / 2"
i %= 5; // Same as "i = i % 5"

There is no exponentiation. You’ll have to use one of the pow() function variants from math.h.
Let’s get into some of the weirder stuff you might not have in your other languages!

3.2.2 Ternary Operator


C also includes the ternary operator. This is an expression whose value depends on the result of a conditional
embedded in it.
// If x > 10, add 17 to y. Otherwise add 37 to y.
Chapter 3. Variables and Statements 14

y += x > 10? 17: 37;

What a mess! You’ll get used to it the more you read it. To help out a bit, I’ll rewrite the above expression
using if statements:
// This expression:

y += x > 10? 17: 37;

// is equivalent to this non-expression:

if (x > 10)
y += 17;
else
y += 37;

Compare those two until you see each of the components of the ternary operator.
Or, another example that prints if a number stored in x is odd or even:
printf("The number %d is %s.\n", x, x % 2 == 0? "even": "odd")

The %s format specifier in printf() means print a string. If the expression x % 2 evaluates to 0, the value
of the entire ternary expression evaluates to the string "even". Otherwise it evaluates to the string "odd".
Pretty cool!
It’s important to note that the ternary operator isn’t flow control like the if statement is. It’s just an expression
that evaluates to a value.

3.2.3 Pre-and-Post Increment-and-Decrement


Now, let’s mess with another thing that you might not have seen.
These are the legendary post-increment and post-decrement operators:
i++; // Add one to i (post-increment)
i--; // Subtract one from i (post-decrement)

Very commonly, these are just used as shorter versions of:


i += 1; // Add one to i
i -= 1; // Subtract one from i

but they’re more subtly different than that, the clever scoundrels.
Let’s take a look at this variant, pre-increment and pre-decrement:
++i; // Add one to i (pre-increment)
--i; // Subtract one from i (pre-decrement)

With pre-increment and pre-decrement, the value of the variable is incremented or decremented before the
expression is evaluated. Then the expression is evaluated with the new value.
With post-increment and post-decrement, the value of the expression is first computed with the value as-is,
and then the value is incremented or decremented after the value of the expression has been determined.
You can actually embed them in expressions, like this:
i = 10;
j = 5 + i++; // Compute 5 + i, _then_ increment i

printf("%d, %d\n", i, j); // Prints 11, 15


Chapter 3. Variables and Statements 15

Let’s compare this to the pre-increment operator:


i = 10;
j = 5 + ++i; // Increment i, _then_ compute 5 + i

printf("%d, %d\n", i, j); // Prints 11, 16

This technique is used frequently with array and pointer access and manipulation. It gives you a way to use
the value in a variable, and also increment or decrement that value before or after it is used.
But by far the most common place you’ll see this is in a for loop:
for (i = 0; i < 10; i++)
printf("i is %d\n", i);

But more on that later.

3.2.4 The Comma Operator


This is an uncommonly-used way to separate expressions that will run left to right:
x = 10, y = 20; // First assign 10 to x, then 20 to y

Seems a bit silly, since you could just replace the comma with a semicolon, right?
x = 10; y = 20; // First assign 10 to x, then 20 to y

But that’s a little different. The latter is two separate expressions, while the former is a single expression!
With the comma operator, the value of the comma expression is the value of the rightmost expression:
x = (1, 2, 3);

printf("x is %d\n", x); // Prints 3, because 3 is rightmost in the comma list

But even that’s pretty contrived. One common place the comma operator is used is in for loops to do multiple
things in each section of the statement:
for (i = 0, j = 10; i < 100; i++, j++)
printf("%d, %d\n", i, j);

We’ll revisit that later.

3.2.5 Conditional Operators


For Boolean values, we have a raft of standard operators:
a == b; // True if a is equivalent to b
a != b; // True if a is not equivalent to b
a < b; // True if a is less than b
a > b; // True if a is greater than b
a <= b; // True if a is less than or equal to b
a >= b; // True if a is greater than or equal to b

Don’t mix up assignment = with comparison ==! Use two equals to compare, one to assign.
We can use the comparison expressions with if statements:
if (a <= 10)
printf("Success!\n");
Chapter 3. Variables and Statements 16

3.2.6 Boolean Operators


We can chain together or alter conditional expressions with Boolean operators for and, or, and not.

Operator Boolean meaning


&& and
|| or
! not

An example of Boolean “and”:


// Do something if x less than 10 and y greater than 20:

if (x < 10 && y > 20)


printf("Doing something!\n");

An example of Boolean “not”:


if (!(x < 12))
printf("x is not less than 12\n");

! has higher precedence than the other Boolean operators, so we have to use parentheses in that case.

Of course, that’s just the same as:


if (x >= 12)
printf("x is not less than 12\n");

but I needed the example!

3.2.7 The sizeof Operator


This operator tells you the size (in bytes) that a particular variable or data type uses in memory.
More particularly, it tells you the size (in bytes) that the type of a particular expression (which might be just
a single variable) uses in memory.
This can be different on different systems, except for char and its variants (which are always 1 byte).
And this might not seem very useful now, but we’ll be making references to it here and there, so it’s worth
covering.
Since this computes the number of bytes needed to store a type, you might think it would return an int. Or…
since the size can’t be negative, maybe an unsigned?
But it turns out C has a special type to represent the return value from sizeof. It’s size_t, pronounced
“size tee”7 . All we know is that it’s an unsigned integer type that can hold the size in bytes of anything you
can give to sizeof.
size_t shows up a lot of different places where counts of things are passed or returned. Think of it as a
value that represents a count.
You can take the sizeof a variable or expression:
int a = 999;

// %zu is the format specifier for type size_t

printf("%zu\n", sizeof a); // Prints 4 on my system


7
The _t is short for type.
Chapter 3. Variables and Statements 17

printf("%zu\n", sizeof(2 + 7)); // Prints 4 on my system


printf("%zu\n", sizeof 3.14); // Prints 8 on my system

// If you need to print out negative size_t values, use %zd

Remember: it’s the size in bytes of the type of the expression, not the size of the expression itself. That’s
why the size of 2+7 is the same as the size of a—they’re both type int. We’ll revisit this number 4 in the
very next block of code…
…Where we’ll see you can take the sizeof a type (note the parentheses are required around a type name,
unlike an expression):
printf("%zu\n", sizeof(int)); // Prints 4 on my system
printf("%zu\n", sizeof(char)); // Prints 1 on all systems

It’s important to note that sizeof is a compile-time operation8 . The result of the expression is determined
entirely at compile-time, not at runtime.
We’ll make use of this later on.

3.3 Flow Control


Booleans are all good, but of course we’re nowhere if we can’t control program flow. Let’s take a look at a
number of constructs: if, for, while, and do-while.
First, a general forward-looking note about statements and blocks of statements brought to you by your local
friendly C developer:
After something like an if or while statement, you can either put a single statement to be executed, or a
block of statements to all be executed in sequence.
Let’s start with a single statement:
if (x == 10) printf("x is 10\n");

This is also sometimes written on a separate line. (Whitespace is largely irrelevant in C—it’s not like Python.)
if (x == 10)
printf("x is 10\n");

But what if you want multiple things to happen due to the conditional? You can use squirrelly braces to mark
a block or compound statement.
if (x == 10) {
printf("x is 10\n");
printf("And also this happens when x is 10\n");
}

It’s a really common style to always use squirrelly braces even if they aren’t necessary:
if (x == 10) {
printf("x is 10\n");
}

Some devs feel the code is easier to read and avoids errors like this where things visually look like they’re
in the if block, but actually they aren’t.
// BAD ERROR EXAMPLE

if (x == 10)
8
Except for with variable length arrays—but that’s a story for another time.
Chapter 3. Variables and Statements 18

printf("This happens if x is 10\n");


printf("This happens ALWAYS\n"); // Surprise!! Unconditional!

while and for and the other looping constructs work the same way as the examples above. If you want to
do multiple things in a loop or after an if, wrap them up in squirrelly braces.
In other words, the if is going to run the one thing after the if. And that one thing can be a single statement
or a block of statements.

3.3.1 The if-else statement


We’ve already been using if for multiple examples, since it’s likely you’ve seen it in a language before, but
here’s another:
int i = 10;

if (i > 10) {
printf("Yes, i is greater than 10.\n");
printf("And this will also print if i is greater than 10.\n");
}

if (i <= 10) printf("i is less than or equal to 10.\n");

In the example code, the message will print if i is greater than 10, otherwise execution continues to the next
line. Notice the squirrley braces after the if statement; if the condition is true, either the first statement or
expression right after the if will be executed, or else the collection of code in the squirlley braces after the
if will be executed. This sort of code block behavior is common to all statements.

Of course, because C is fun this way, you can also do something if the condition is false with an else clause
on your if:
int i = 99;

if (i == 10)
printf("i is 10!\n");
else {
printf("i is decidedly not 10.\n");
printf("Which irritates me a little, frankly.\n");
}

And you can even cascade these to test a variety of conditions, like this:
int i = 99;

if (i == 10)
printf("i is 10!\n");

else if (i == 20)
printf("i is 20!\n");

else if (i == 99) {
printf("i is 99! My favorite\n");
printf("I can't tell you how happy I am.\n");
printf("Really.\n");
}

else
printf("i is some crazy number I've never heard of.\n");
Chapter 3. Variables and Statements 19

Though if you’re going that route, be sure to check out the switch statement for a potentially better solution.
The catch is switch only works with equality comparisons with constant numbers. The above if-else
cascade could check inequality, ranges, variables, or anything else you can craft in a conditional expression.

3.3.2 The while statement


while is your average run-of-the-mill looping construct. Do a thing while a condition expression is true.

Let’s do one!
// Print the following output:
//
// i is now 0!
// i is now 1!
// [ more of the same between 2 and 7 ]
// i is now 8!
// i is now 9!

i = 0;

while (i < 10) {


printf("i is now %d!\n", i);
i++;
}

printf("All done!\n");

That gets you a basic loop. C also has a for loop which would have been cleaner for that example.
A not-uncommon use of while is for infinite loops where you repeat while true:
while (1) {
printf("1 is always true, so this repeats forever.\n");
}

3.3.3 The do-while statement


So now that we’ve gotten the while statement under control, let’s take a look at its closely related cousin,
do-while.

They are basically the same, except if the loop condition is false on the first pass, do-while will execute
once, but while won’t execute at all. In other words, the test to see whether or not to execute the block
happens at the end of the block with do-while. It happens at the beginning of the block with while.
Let’s see by example:
// Using a while statement:

i = 10;

// this is not executed because i is not less than 10:


while(i < 10) {
printf("while: i is %d\n", i);
i++;
}

// Using a do-while statement:


Chapter 3. Variables and Statements 20

i = 10;

// this is executed once, because the loop condition is not checked until
// after the body of the loop runs:

do {
printf("do-while: i is %d\n", i);
i++;
} while (i < 10);

printf("All done!\n");

Notice that in both cases, the loop condition is false right away. So in the while, the loop fails, and the
following block of code is never executed. With the do-while, however, the condition is checked after the
block of code executes, so it always executes at least once. In this case, it prints the message, increments i,
then fails the condition, and continues to the “All done!” output.
The moral of the story is this: if you want the loop to execute at least once, no matter what the loop condition,
use do-while.
All these examples might have been better done with a for loop. Let’s do something less deterministic—
repeat until a certain random number comes up!
#include <stdio.h> // For printf
#include <stdlib.h> // For rand

int main(void)
{
int r;

do {
r = rand() % 100; // Get a random number between 0 and 99
printf("%d\n", r);
} while (r != 37); // Repeat until 37 comes up
}

Side note: did you run that more than once? If you did, did you notice the same sequence of numbers came
up again. And again. And again? This is because rand() is a pseudorandom number generator that must
be seeded with a different number in order to generate a different sequence. Look up the srand()9 function
for more details.

3.3.4 The for statement


Welcome to one of the most popular loops in the world! The for loop!
This is a great loop if you know the number of times you want to loop in advance.
You could do the same thing using just a while loop, but the for loop can help keep the code cleaner.
Here are two pieces of equivalent code—note how the for loop is just a more compact representation:
// Print numbers between 0 and 9, inclusive...

// Using a while statement:

i = 0;
9
https://beej.us/guide/bgclr/html/split/stdlib.html#man-srand
Chapter 3. Variables and Statements 21

while (i < 10) {


printf("i is %d\n", i);
i++;
}

// Do the exact same thing with a for-loop:

for (i = 0; i < 10; i++) {


printf("i is %d\n", i);
}

That’s right, folks—they do exactly the same thing. But you can see how the for statement is a little more
compact and easy on the eyes. (JavaScript users will fully appreciate its C origins at this point.)
It’s split into three parts, separated by semicolons. The first is the initialization, the second is the loop
condition, and the third is what should happen at the end of the block if the loop condition is true. All three
of these parts are optional.
for (initialize things; loop if this is true; do this after each loop)

Note that the loop will not execute even a single time if the loop condition starts off false.
for-loop fun fact!

You can use the comma operator to do multiple things in each clause of the for loop!
for (i = 0, j = 999; i < 10; i++, j--) {
printf("%d, %d\n", i, j);
}

An empty for will run forever:


for(;;) { // "forever"
printf("I will print this again and again and again\n" );
printf("for all eternity until the heat-death of the universe.\n");

printf("Or until you hit CTRL-C.\n");


}

3.3.5 The switch Statement


Depending on what languages you’re coming from, you might or might not be familiar with switch, or C’s
version might even be more restrictive than you’re used to. This is a statement that allows you to take a
variety of actions depending on the value of an integer expression.
Basically, it evaluates an expression to an integer value, jumps to the case that corresponds to that value.
Execution resumes from that point. If a break statement is encountered, then execution jumps out of the
switch.

Let’s do an example where the user enters a number of goats and we print out a gut-feel of how many goats
that is.
#include <stdio.h>

int main(void)
{
int goat_count;

printf("Enter a goat count: ");


scanf("%d", &goat_count); // Read an integer from the keyboard
Chapter 3. Variables and Statements 22

switch (goat_count) {
case 0:
printf("You have no goats.\n");
break;

case 1:
printf("You have a singular goat.\n");
break;

case 2:
printf("You have a brace of goats.\n");
break;

default:
printf("You have a bona fide plethora of goats!\n");
break;
}
}

In that example, if the user enters, say, 2, the switch will jump to the case 2 and execute from there. When
(if) it hits a break, it jumps out of the switch.
Also, you might see that default label there at the bottom. This is what happens when no cases match.
Every case, including default, is optional. And they can occur in any order, but it’s really typical for
default, if any, to be listed last.

So the whole thing acts like an if-else cascade:


if (goat_count == 0)
printf("You have no goats.\n");
else if (goat_count == 1)
printf("You have a singular goat.\n");
else if (goat_count == 2)
printf("You have a brace of goats.\n");
else
printf("You have a bona fide plethora of goats!\n");

With some key differences:


• switch is often faster to jump to the correct code (though the spec makes no such guarantee).
• if-else can do things like relational conditionals like < and >= and floating point and other types,
while switch cannot.
There’s one more neat thing about switch that you sometimes see that is quite interesting: fall through.
Remember how break causes us to jump out of the switch?
Well, what happens if we don’t break?
Turns out we just keep on going into the next case! Demo!
switch (x) {
case 1:
printf("1\n");
// Fall through!
case 2:
printf("2\n");
break;
Chapter 3. Variables and Statements 23

case 3:
printf("3\n");
break;
}

If x == 1, this switch will first hit case 1, it’ll print the 1, but then it just continues on to the next line of
code… which prints 2!
And then, at last, we hit a break so we jump out of the switch.
if x == 2, then we just hit the case 2, print 2, and break as normal.
Not having a break is called fall through.
ProTip: ALWAYS put a comment in the code where you intend to fall through, like I did above. It will save
other programmers from wondering if you meant to do that.
In fact, this is one of the common places to introduce bugs in C programs: forgetting to put a break in your
case. You gotta do it if you don’t want to just roll into the next case10 .

Earlier I said that switch works with integer types—keep it that way. Don’t use floating point or string types
in there. One loophole-ish thing here is that you can use character types because those are secretly integers
themselves. So this is perfectly acceptable:
char c = 'b';

switch (c) {
case 'a':
printf("It's 'a'!\n");
break;

case 'b':
printf("It's 'b'!\n");
break;

case 'c':
printf("It's 'c'!\n");
break;
}

Finally, you can use enums in switch since they are also integer types. But more on that in the enum chapter.

10
This was considered such a hazard that the designers of the Go Programming Language made break the default; you have to
explicitly use Go’s fallthrough statement if you want to fall into the next case.
Chapter 4

Functions

“Sir, not in an environment such as this. That’s why I’ve also been programmed for over thirty
secondary functions that—”
—C3PO, before being rudely interrupted, reporting a now-unimpressive number of additional
functions, Star Wars script
Very much like other languages you’re used to, C has the concept of functions.
Functions can accept a variety of arguments and return a value. One important thing, though: the arguments
and return value types are predeclared—because that’s how C likes it!
Let’s take a look at a function. This is a function that takes an int as an argument, and returns an int.
#include <stdio.h>

int plus_one(int n) // The "definition"


{
return n + 1;
}

The int before the plus_one indicates the return type.


The int n indicates that this function takes one int argument, stored in parameter n. A parameter is a
special type of local variable into which the arguments are copied.
I’m going to drive home the point that the arguments are copied into the parameters, here. Lots of things in
C are easier to understand if you know that the parameter is a copy of the argument, not the argument itself.
More on that in a minute.
Continuing the program down into main(), we can see the call to the function, where we assign the return
value into local variable j:
int main(void)
{
int i = 10, j;

j = plus_one(i); // The "call"

printf("i + 1 is %d\n", j);


}

24
Chapter 4. Functions 25

Before I forget, notice that I defined the function before I used it. If I hadn’t done that, the
compiler wouldn’t know about it yet when it compiles main() and it would have given an
unknown function call error. There is a more proper way to do the above code with function
prototypes, but we’ll talk about that later.
Also notice that main() is a function!
It returns an int.
But what’s this void thing? This is a keyword that’s used to indicate that the function accepts no arguments.
You can also return void to indicate that you don’t return a value:
#include <stdio.h>

// This function takes no arguments and returns no value:

void hello(void)
{
printf("Hello, world!\n");
}

int main(void)
{
hello(); // Prints "Hello, world!"
}

4.1 Passing by Value


I’d mentioned earlier that when you pass an argument to a function, a copy of that argument gets made and
stored in the corresponding parameter.
If the argument is a variable, a copy of the value of that variable gets made and stored in the parameter.
More generally, the entire argument expression is evaluated and its value determined. That value is copied
to the parameter.
In any case, the value in the parameter is its own thing. It is independent of whatever values or variables you
used as arguments when you made the function call.
So let’s look at an example here. Study it and see if you can determine the output before running it:
#include <stdio.h>

void increment(int a)
{
a++;
}

int main(void)
{
int i = 10;

increment(i);

printf("i == %d\n", i); // What does this print?


}
Chapter 4. Functions 26

At first glance, it looks like i is 10, and we pass it to the function increment(). There the value gets
incremented, so when we print it, it must be 11, right?
“Get used to disappointment.”
—Dread Pirate Roberts, The Princess Bride
But it’s not 11—it prints 10! How?
It’s all about the fact that the expressions you pass to functions get copied onto their corresponding parameters.
The parameter is a copy, not the original.
So i is 10 out in main(). And we pass it to increment(). The corresponding parameter is called a in that
function.
And the copy happens, as if by assignment. Loosely, a = i. So at that point, a is 10. And out in main(), i
is also 10.
Then we increment a to 11. But we’re not touching i at all! It remains 10.
Finally, the function is complete. All its local variables are discarded (bye, a!) and we return to main(),
where i is still 10.
And we print it, getting 10, and we’re done.
This is why in the previous example with the plus_one() function, we returned the locally modified value
so that we could see it again in main().
Seems a little bit restrictive, huh? Like you can only get one piece of data back from a function, is what
you’re thinking. There is, however, another way to get data back; C folks call it passing by reference and
that’s a story we’ll tell another time.
But no fancy-schmancy name will distract you from the fact that EVERYTHING you pass to a function WITH-
OUT EXCEPTION is copied into its corresponding parameter, and the function operates on that local copy,
NO MATTER WHAT. Remember that, even when we’re talking about this so-called passing by reference.

4.2 Function Prototypes


So if you recall back in the ice age a few sections ago, I mentioned that you had to define the function before
you used it, otherwise the compiler wouldn’t know about it ahead of time, and would bomb out with an error.
This isn’t quite strictly true. You can notify the compiler in advance that you’ll be using a function of a certain
type that has a certain parameter list. That way the function can be defined anywhere (even in a different
file), as long as the function prototype has been declared before you call that function.
Fortunately, the function prototype is really quite easy. It’s merely a copy of the first line of the function
definition with a semicolon tacked on the end for good measure. For example, this code calls a function that
is defined later, because a prototype has been declared first:
#include <stdio.h>

int foo(void); // This is the prototype!

int main(void)
{
int i;

// We can call foo() here before it's definition because the


// prototype has already been declared, above!

i = foo();
Chapter 4. Functions 27

printf("%d\n", i); // 3490


}

int foo(void) // This is the definition, just like the prototype!


{
return 3490;
}

If you don’t declare your function before you use it (either with a prototype or its definition), you’re per-
forming something called an implicit declaration. This was allowed in the first C standard (C89), and that
standard has rules about it, but is no longer allowed today. And there is no legitimate reason to rely on it in
new code.
You might notice something about the sample code we’ve been using… That is, we’ve been using the good old
printf() function without defining it or declaring a prototype! How do we get away with this lawlessness?
We don’t, actually. There is a prototype; it’s in that header file stdio.h that we included with #include,
remember? So we’re still legit, officer!

4.3 Empty Parameter Lists


You might see these from time to time in older code, but you shouldn’t ever code one up in new code. Always
use void to indicate that a function takes no parameters. There’s never1 a reason to do this in modern code.
If you’re good at just remembering to put void in for empty parameter lists in functions and prototypes, you
can skip the rest of this section.
There are two contexts for this:
• Omitting all parameters where the function is defined
• Omitting all parameters in a prototype
Let’s look at a potential function definition first:
void foo() // Should really have a `void` in there
{
printf("Hello, world!\n");
}

While the spec spells out that the behavior in this instance is as-if you’d indicated void (C11 §6.7.6.3¶14),
the void type is there for a reason. Use it.
But in the case of a function prototype, there is a significant difference between using void and not:
void foo();
void foo(void); // Not the same!

Leaving void out of the prototype indicates to the compiler that there is no additional information about the
parameters to the function. It effectively turns off all that type checking.
With a prototype definitely use void when you have an empty parameter list.

1
Never say “never”.
Chapter 5

Pointers—Cower In Fear!

“How do you get to Carnegie Hall?”


“Practice!”
—20th-century joke of unknown origin
Pointers are one of the most feared things in the C language. In fact, they are the one thing that makes this
language challenging at all. But why?
Because they, quite honestly, can cause electric shocks to come up through the keyboard and physically weld
your arms permanently in place, cursing you to a life at the keyboard in this language from the 70s!
Really? Well, not really. I’m just trying to set you up for success.
Depending on what language you came from, you might already understand the concept of references, where
a variable refers to an object of some type.
This is very much the same, except we have to be more explicit with C about when we’re talking about the
reference or the thing it refers to.

5.1 Memory and Variables


Computer memory holds data of all kinds, right? It’ll hold floats, ints, or whatever you have. To make
memory easy to cope with, each byte of memory is identified by an integer. These integers increase sequen-
tially as you move up through memory1 . You can think of it as a bunch of numbered boxes, where each box
holds a byte2 of data. Or like a big array where each element holds a byte, if you come from a language with
arrays. The number that represents each box is called its address.
Now, not all data types use just a byte. For instance, an int is often four bytes, as is a float, but it really
depends on the system. You can use the sizeof operator to determine how many bytes of memory a certain
type uses.
// %zu is the format specifier for type size_t

printf("an int uses %zu bytes of memory\n", sizeof(int));

// That prints "4" for me, but can vary by system.


1
Typically. I’m sure there are exceptions out there in the dark corridors of computing history.
2
A byte is a number made up of no more than 8 binary digits, or bits for short. This means in decimal digits just like grandma used
to use, it can hold an unsigned number between 0 and 255, inclusive.

28
Chapter 5. Pointers—Cower In Fear! 29

Memory Fun Facts: When you have a data type (like your typical int) that uses more than a
byte of memory, the bytes that make up the data are always adjacent to one another in memory.
Sometimes they’re in the order that you expect, and sometimes they’re not3 . While C doesn’t
guarantee any particular memory order (it’s platform-dependent), it’s still generally possible to
write code in a way that’s platform-independent where you don’t have to even consider these
pesky byte orderings.
So anyway, if we can get on with it and get a drum roll and some foreboding music playing for the definition
of a pointer, a pointer is a variable that holds an address. Imagine the classical score from 2001: A Space
Odyssey at this point. Ba bum ba bum ba bum BAAAAH!
Ok, so maybe a bit overwrought here, yes? There’s not a lot of mystery about pointers. They are the address
of data. Just like an int variable can hold the value 12, a pointer variable can hold the address of data.
This means that all these things mean the same thing, i.e. a number that represents a point in memory:
• Index into memory (if you’re thinking of memory like a big array)
• Address
• Location
I’m going to use these interchangeably. And yes, I just threw location in there because you can never have
enough words that mean the same thing.
And a pointer variable holds that address number. Just like a float variable might hold 3.14159.
Imagine you have a bunch of Post-it® notes all numbered in sequence with their address. (The first one is at
index numbered 0, the next at index 1, and so on.)
In addition to the number representing their positions, you can also write another number of your choice on
each. It could be the number of dogs you have. Or the number of moons around Mars…
…Or, it could be the index of another Post-it note!
If you have written the number of dogs you have, that’s just a regular variable. But if you wrote the index of
another Post-it in there, that’s a pointer. It points to the other note!
Another analogy might be with house addresses. You can have a house with certain qualities, yard, metal
roof, solar, etc. Or you could have the address of that house. The address isn’t the same as the house itself.
One’s a full-blown house, and the other is just a few lines of text. But the address of the house is a pointer
to that house. It’s not the house itself, but it tells you where to find it.
And we can do the same thing in the computer with data. You can have a data variable that’s holding some
value. And that value is in memory at some address. And you could have a different pointer variable hold
the address of that data variable.
It’s not the data variable itself, but, like with a house address, it tells us where to find it.
When we have that, we say we have a “pointer to” that data. And we can follow the pointer to access the
data itself.
(Though it doesn’t seem particularly useful yet, this all becomes indispensable when used with function calls.
Bear with me until we get there.)
So if we have an int, say, and we want a pointer to it, what we want is some way to get the address of that
int, right? After all, the pointer just holds the address of the data. What operator do you suppose we’d use
to find the address of the int?
Well, by a shocking surprise that must come as something of a shock to you, gentle reader, we use the
address-of operator (which happens to be an ampersand: “&”)to find the address of the data. Ampersand.
3
The order that bytes come in is referred to as the endianness of the number. The usual suspects are big-endian (with the most sig-
nificant byte first) and little-endian (with the most-significant byte last), or, uncommonly now, mixed-endian (with the most-significant
bytes somewhere else).
Chapter 5. Pointers—Cower In Fear! 30

So for a quick example, we’ll introduce a new format specifier for printf() so you can print a pointer. You
know already how %d prints a decimal integer, yes? Well, %p prints a pointer. Now, this pointer is going to
look like a garbage number (and it might be printed in hexadecimal4 instead of decimal), but it is merely the
index into memory the data is stored in. (Or the index into memory that the first byte of data is stored in,
if the data is multi-byte.) In virtually all circumstances, including this one, the actual value of the number
printed is unimportant to you, and I show it here only for demonstration of the address-of operator.
#include <stdio.h>

int main(void)
{
int i = 10;

printf("The value of i is %d\n", i);


printf("And its address is %p\n", (void *)&i);

// %p expects the argument to be a pointer to void


// so we cast it to make the compiler happy.
}

On my computer, this prints:


The value of i is 10
And its address is 0x7ffddf7072a4

If you’re curious, that hexadecimal number is 140,727,326,896,068 in decimal (base 10 just like Grandma
used to use). That’s the index into memory where the variable i’s data is stored. It’s the address of i. It’s
the location of i. It’s a pointer to i.
It’s a pointer because it lets you know where i is in memory. Like a home address written on a scrap of paper
tells you where you can find a particular house, this number indicates to us where in memory we can find
the value of i. It points to i.
Again, we don’t really care what the address’s exact number is, generally. We just care that it’s a pointer to
i.

5.2 Pointer Types


So… this is all well and good. You can now successfully take the address of a variable and print it on the
screen. There’s a little something for the ol’ resume, right? Here’s where you grab me by the scruff of the
neck and ask politely what the frick pointers are good for.
Excellent question, and we’ll get to that right after these messages from our sponsor.
ACME ROBOTIC HOUSING UNIT CLEANING SERVICES. YOUR HOMESTEAD WILL BE DRA-
MATICALLY IMPROVED OR YOU WILL BE TERMINATED. MESSAGE ENDS.

Welcome back to another installment of Beej’s Guide. When we met last we were talking about how to make
use of pointers. Well, what we’re going to do is store a pointer off in a variable so that we can use it later.
You can identify the pointer type because there’s an asterisk (*) before the variable name and after its type:
int main(void)
{
int i; // i's type is "int"
int *p; // p's type is "pointer to an int", or "int-pointer"
}
4
That is, base 16 with digits 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, A, B, C, D, E, and F.
Chapter 5. Pointers—Cower In Fear! 31

Hey, so we have here a variable that is a pointer type, and it can point to other ints. That is, it can hold the
address of other ints. We know it points to ints, since it’s of type int* (read “int-pointer”).
When you do an assignment into a pointer variable, the type of the right hand side of the assignment has to
be the same type as the pointer variable. Fortunately for us, when you take the address-of a variable, the
resultant type is a pointer to that variable type, so assignments like the following are perfect:
int i;
int *p; // p is a pointer, but is uninitialized and points to garbage

p = &i; // p is assigned the address of i--p now "points to" i

On the left of the assignment, we have a variable of type pointer-to-int (int*), and on the right side, we
have expression of type pointer-to-int since i is an int (because address-of int gives you a pointer to int).
The address of a thing can be stored in a pointer to that thing.
Get it? I know it still doesn’t quite make much sense since you haven’t seen an actual use for the pointer
variable, but we’re taking small steps here so that no one gets lost. So now, let’s introduce you to the anti-
address-of operator. It’s kind of like what address-of would be like in Bizarro World.

5.3 Dereferencing
A pointer variable can be thought of as referring to another variable by pointing to it. It’s rare you’ll hear
anyone in C land talking about “referring” or “references”, but I bring it up just so that the name of this
operator will make a little more sense.
When you have a pointer to a variable (roughly “a reference to a variable”), you can use the original variable
through the pointer by dereferencing the pointer. (You can think of this as “de-pointering” the pointer, but
no one ever says “de-pointering”.)
Back to our analogy, this is vaguely like looking at a home address and then going to that house.
Now, what do I mean by “get access to the original variable”? Well, if you have a variable called i, and you
have a pointer to i called p, you can use the dereferenced pointer p exactly as if it were the original variable
i!

You almost have enough knowledge to handle an example. The last tidbit you need to know is actually
this: what is the dereference operator? It’s actually called the indirection operator, because you’re accessing
values indirectly via the pointer. And it is the asterisk, again: *. Now, don’t get this confused with the asterisk
you used in the pointer declaration, earlier. They are the same character, but they have different meanings in
different contexts5 .
Here’s a full-blown example:
#include <stdio.h>

int main(void)
{
int i;
int *p; // this is NOT a dereference--this is a type "int*"

p = &i; // p now points to i, p holds address of i

i = 10; // i is now 10
*p = 20; // the thing p points to (namely i!) is now 20!!

5
That’s not all! It’s used in /*comments*/ and multiplication and in function prototypes with variable length arrays! It’s all the
same *, but the context gives it different meaning.
Chapter 5. Pointers—Cower In Fear! 32

printf("i is %d\n", i); // prints "20"


printf("i is %d\n", *p); // "20"! dereference-p is the same as i!
}

Remember that p holds the address of i, as you can see where we did the assignment to p on line 8. What
the indirection operator does is tells the computer to use the object the pointer points to instead of using the
pointer itself. In this way, we have turned *p into an alias of sorts for i.
Great, but why? Why do any of this?

5.4 Passing Pointers as Arguments


Right about now, you’re thinking that you have an awful lot of knowledge about pointers, but absolutely zero
application, right? I mean, what use is *p if you could just simply say i instead?
Well, my friend, the real power of pointers comes into play when you start passing them to functions. Why
is this a big deal? You might recall from before that you could pass all kinds of arguments to functions and
they’d be dutifully copied into parameters, and then you could manipulate local copies of those variables
from within the function, and then you could return a single value.
What if you wanted to bring back more than one single piece of data from the function? I mean, you can
only return one thing, right? What if I answered that question with another question? …Er, two questions?
What happens when you pass a pointer as an argument to a function? Does a copy of the pointer get put into
its corresponding parameter? You bet your sweet peas it does. Remember how earlier I rambled on and on
about how EVERY SINGLE ARGUMENT gets copied into parameters and the function uses a copy of the
argument? Well, the same is true here. The function will get a copy of the pointer.
But, and this is the clever part: we will have set up the pointer in advance to point at a variable… and then
the function can dereference its copy of the pointer to get back to the original variable! The function can’t
see the variable itself, but it can certainly dereference a pointer to that variable!
This is analogous to writing a home address on a piece of paper, and then copying that onto another piece of
paper. You now have two pointers to that house, and both are equally good at getting you to the house itself.
In the case of a function call. one of the copies is stored in a pointer variable out in the calling scope, and the
other is stored in a pointer variable that is the parameter of the function.
Example! Let’s revisit our old increment() function, but this time let’s make it so that it actually increments
the value out in the caller.
#include <stdio.h>

void increment(int *p) // note that it accepts a pointer to an int


{
*p = *p + 1; // add one to the thing p points to
}

int main(void)
{
int i = 10;
int *j = &i; // note the address-of; turns it into a pointer to i

printf("i is %d\n", i); // prints "10"


printf("i is also %d\n", *j); // prints "10"

increment(j); // j is an int*--to i
Chapter 5. Pointers—Cower In Fear! 33

printf("i is %d\n", i); // prints "11"!


}

Ok! There are a couple things to see here… not the least of which is that the increment() function takes
an int* as an argument. We pass it an int* in the call by changing the int variable i to an int* using the
address-of operator. (Remember, a pointer holds an address, so we make pointers to variables by running
them through the address-of operator.)
The increment() function gets a copy of the pointer. Both the original pointer j (in main()) and the copy
of that pointer p (the parameter in increment()) point to the same address, namely the one holding the value
i. (Again, by analogy, like two pieces of paper with the same home address written on them.) Dereferencing
either will allow you to modify the original variable i! The function can modify a variable in another scope!
Rock on!
The above example is often more concisely written in the call just by using address-of right in the argument
list:
printf("i is %d\n", i); // prints "10"
increment(&i);
printf("i is %d\n", i); // prints "11"!

Pointer enthusiasts will recall from early on in the guide, we used a function to read from the keyboard,
scanf()… and, although you might not have recognized it at the time, we used the address-of to pass
a pointer to a value to scanf(). We had to pass a pointer, see, because scanf() reads from the keyboard
(typically) and stores the result in a variable. The only way it can see that variable out in the calling function’s
scope is if we pass a pointer to that variable:
int i = 0;

scanf("%d", &i); // pretend you typed "12"


printf("i is %d\n", i); // prints "i is 12"

See, scanf() dereferences the pointer we pass it in order to modify the variable it points to. And now you
know why you have to put that pesky ampersand in there!

5.5 The NULL Pointer


Any pointer variable of any pointer type can be set to a special value called NULL. This indicates that this
pointer doesn’t point to anything.
int *p;

p = NULL;

Since it doesn’t point to a value, dereferencing it is undefined behavior, and probably will result in a crash:
int *p = NULL;

*p = 12; // CRASH or SOMETHING PROBABLY BAD. BEST AVOIDED.

Despite being called the billion dollar mistake by its creator6 , the NULL pointer is a good sentinel value7 and
general indicator that a pointer hasn’t yet been initialized.
(Of course, like other variables, the pointer points to garbage unless you explicitly assign it to point to an
address or NULL.)
6
https://en.wikipedia.org/wiki/Null_pointer#History
7
https://en.wikipedia.org/wiki/Sentinel_value
Chapter 5. Pointers—Cower In Fear! 34

5.6 A Note on Declaring Pointers


The syntax for declaring a pointer can get a little weird. Let’s look at this example:
int a;
int b;

We can condense that into a single line, right?


int a, b; // Same thing

So a and b are both ints. No problem.


But what about this?
int a;
int *p;

Can we make that into one line? We can. But where does the * go?
The rule is that the * goes in front of any variable that is a pointer type. That is. the * is not part of the int
in this example. it’s a part of variable p.
With that in mind, we can write this:
int a, *p; // Same thing

It’s important to note that the following line does not declare two pointers:
int *p, q; // p is a pointer to an int; q is just an int.

This can be particularly insidious-looking if the programmer writes this following (valid) line of code which
is functionally identical to the one above.
int* p, q; // p is a pointer to an int; q is just an int.

So take a look at this and determine which variables are pointers and which are not:
int *a, b, c, *d, e, *f, g, h, *i;

I’ll drop the answer in a footnote8 .

5.7 sizeof and Pointers


Just a little bit of syntax here that might be confusing and you might see from time to time.
Recall that sizeof operates on the type of the expression.
int *p;

// Prints size of an 'int'


printf("%zu\n", sizeof(int));

// p is type 'int *', so prints size of 'int*'


printf("%zu\n", sizeof p);

// *p is type 'int', so prints size of 'int'


printf("%zu\n", sizeof *p);

You might see code in the wild with that last sizeof in there. Just remember that sizeof is all about the
type of the expression, not the variables in the expression themselves.

8
The pointer type variables are a, d, f, and i, because those are the ones with * in front of them.
Chapter 6

Arrays

“Should array indices start at 0 or 1? My compromise of 0.5 was rejected without, I thought,
proper consideration.”
—Stan Kelly-Bootle, computer scientist
Luckily, C has arrays. I mean, I know it’s considered a low-level language1 but it does at least have the
concept of arrays built-in. And since a great many languages drew inspiration from C’s syntax, you’re
probably already familiar with using [ and ] for declaring and using arrays.
But C only barely has arrays! As we’ll find out later, arrays are just syntactic sugar in C—they’re actually
all pointers and stuff deep down. Freak out! But for now, let’s just use them as arrays. Phew.

6.1 Easy Example


Let’s just crank out an example:
#include <stdio.h>

int main(void)
{
int i;
float f[4]; // Declare an array of 4 floats

f[0] = 3.14159; // Indexing starts at 0, of course.


f[1] = 1.41421;
f[2] = 1.61803;
f[3] = 2.71828;

// Print them all out:

for (i = 0; i < 4; i++) {


printf("%f\n", f[i]);
}
}

When you declare an array, you have to give it a size. And the size has to be fixed2 .
1
These days, anyway.
2
Again, not really, but variable-length arrays—of which I’m not really a fan—are a story for another time.

35
Another random document with
no related content on Scribd:
tegmina do; at first (Fig. 112, A) there is but little difference between
the two, though in the interior of the wing-flap some traces of a
radiate arrangement can be seen, as shown at W in A, Fig. 112; in a
subsequent condition the wing-pads are increased in size and are
more divided, the appearance indicating that the wings themselves
are present and packed about a centre, as shown in W of B, Fig.
112.

Fig. 112.—Notal plates from which the tegmina and wings of Forficula
auricularia are developed in young, A, and more advanced, B,
nymph.

In the young of the common earwig the number of joints[139] in the


antennae increases with age. Camerano, l.c., says that before
emergence from the egg there are apparently only 8 joints in the
antennae, and Fischer states that the larvae of F. auricularia have at
first only 8 antennal joints; later on 12 joints are commonly found,
and, according to Bateson,[140] this number occasionally persists
even in the adult individual. Meinert says[141] that the newly hatched
Forficula has either 6 or 8 joints, and he adds that in the later portion
of the preparatory stage the number is 12. Considerable discrepancy
prevails in books as to the normal number of joints in the antennae
of the adult F. auricularia, the statements varying from 13 to 15. The
latter number may be set aside as erroneous, although it is, curiously
enough, the one given in the standard works of Fischer, Brunner,
and Finot. Meinert gives without hesitation 14 as the number;
Bateson, l.c., found that 14 joints occurred in 70 or 80 per cent of
adult individuals, that 13 was not uncommon, that 12 or 11
occasionally occurred, and that the number may differ in the two
antennae of the same individual. These variations, which seem at
first sight very remarkable, may with probability be considered as
due to the fact that in the young state the number of joints increases
with age, and that the organs are so fragile that one or more of the
joints is very frequently then lost, the loss being more or less
completely repaired during the subsequent development. Thus a
disturbing agency exists, so that the normal number of 14 joints is
often departed from, though it appears to be really natural for this
species. Bateson has also pointed out that when the normal number
of articulations is not present, the relative proportions of joints 3 and
4 are much disturbed. It is, however, probable that the increase in
number of the joints takes place by division of the third or third and
fourth joints following previous growth thereof, as in Termitidae; so
that the variations, as was suggested by Bateson, may be due to
mutilation of the antennae, and consequent incompletion of the
normal form of the parts from which the renovation takes place;
growth preceding segmentation—in some cases the growth may be
like that of the adult, while the segmentation remains more
incomplete. In the young the forceps of the two sexes differ but
slightly; the form of the abdominal rings is, on the contrary, according
to Fischer, already different in the two sexes in the early stage.

The common earwig has a very bad reputation with gardeners, who
consider it to be an injurious Insect, but it is probable that the little
creature is sometimes made the scapegoat for damage done by
other animals; it appears to be fond of sweets, for it often makes its
way to the interior of fruits, and it no doubt nibbles the petals, or
other delicate parts of flowers and vegetables. Camerano, however,
states, l.c., that the specimens he kept in confinement preferred
dead Insects rather than the fruits he offered them. Rühl considers
the earwig to be fond of a carnivorous diet, eating larvae, small
snails, etc., and only attacking flowers when these fail.[142] It has a
great propensity for concealing itself in places where there is only a
small crevice for entry, and it is possible that its presence in fruits is
due to this, rather than to any special fondness for the sweets. This
habit of concealing itself in chinks and crannies in obscure places
makes it an easy matter to trap the Insect by placing pieces of hollow
stalks in the situations it affects; inverted flower-pots with a little hay,
straw, or paper at the top are also effectual traps. We have remarked
that it is very rarely seen on the wing, and though it has been
supposed to fly more freely at night there is very little evidence of the
fact. Another British species, Labia minor, a smaller Insect, is,
however, very commonly seen flying.

Earwigs have the reputation of being fond of their young, and


Camerano describes the female of the common earwig as carefully
collecting its eggs when scattered, lifting them with its mandibles and
placing them in a heap over which it afterwards brooded. De
Geer[143] more than a century ago observed a fondness of the
mother for the young. After the eggs were hatched, Camerano's
individual, however, evinced no interest in the young. A larger
species, Labidura riparia (Fig. 110) is said to move its eggs from
place to place, so as to keep them in situations favourable for their
development.

The name "earwig" is said to be due to an idea that these creatures


are fond of penetrating into the ears of persons when asleep. Hence
these Insects were formerly much dreaded, owing to a fear that they
might penetrate even to the brain. There does not appear to be on
record any occurrence that could justify such a dread, or the belief
that they enter the ears. If they do not do so, it is certainly a curious
fact that a superstition of the kind we have mentioned occurs in
almost every country where the common earwig is abundant; for it
has, in most parts of Europe, a popular name indicating the
prevalence of some such idea. It is known as Ohren-wurm in
German, as perce-oreille in French, and so on. The expanded wing
of the earwig is in shape so very like the human ear, that one is
tempted to suppose this resemblance may in former ages have
given rise to the notion that the earwig has some connexion with the
human ear; but this explanation is rendered very improbable by the
fact that the earwig is scarcely ever seen with its wings expanded,
and that it is a most difficult matter to unfold them artificially, so that it
is very unlikely that the shape of the wings should have been
observed by untutored peoples.

The group Forficulidae seems to be most rich in species in warm and


tropical regions; several unwinged species are met with in the
mountainous districts of Europe; indeed, in some spots their
individuals are extremely numerous under stones. In Britain we have
a list of six species, but only two of these are to be met with; the
others have probably been introduced by the agency of man, and it
is doubtful whether more than one of these immigrants is actually
naturalised here. One of these doubtfully native species is the fine
Labidura riparia (Fig. 110), which was formerly found near
Bournemouth. Altogether about 400 species of earwigs are known at
the present time, and as they are usually much neglected by Insect
collectors, it is certain that this number will be very largely increased,
so that it would be a moderate estimate to put the number of existing
species at about 2000 or 3000. None of them attain a very large
size, Psalis americana being one of the largest and most robust of
the family; a few display brilliant colours, and some exhibit a colour
ornamentation of the surface; there are two or three species known
that display a general resemblance to Insects of other Orders. The
remarkable earwig represented in Fig. 102 (and which appears to be
a nondescript form—either species or variety—closely allied to P.
marmoricauda) was found by Baron von Hügel on the mountains of
Java; the femora in this Insect have a broad face which is turned
upwards instead of outwards, the legs taking a peculiar position; and
it is curious that this exposed surface is ornamented with a pattern.
The feature that most attracts attention on inspecting a collection of
earwigs is, however, the forceps, and this is the most marked
collective character of the group. These curious organs exhibit a very
great variety; in some cases they are as long as the whole of the rest
of the body, in others they are provided with tynes; sometimes they
are quite asymmetrical, as in Anisolabis tasmanica (Fig. 113); in
Opisthocosmia cervipyga, and many others they are curiously
distorted in a variety of ways. The classification of the earwigs is still
in a rudimentary state; the number of joints in the antennae, the form
of the feet, and (in the terrestrial forms) the shape of the rudimentary
wing-cases and wings being the characters that have been made
most use of by systematists; no arrangement into sub-families or
groups of greater importance than genera is adopted.
The only particulars we have as to the embryological development of
the earwig are due to Heymons.[144] The forceps spring from the
eleventh abdominal segment, and represent the cerci of other
Orthoptera. An egg-tooth is found to be present on the head for
piercing the egg-shell. The embryo reverses its curved position
during the development, as other Orthoptera have been observed to
do, but in a somewhat different manner, analogous to that of the
Myriapods.

Several fossil Forficulidae are known; specimens belonging to a


peculiar genus have been described from the Lower Lias of Aargau
and from the Jurassic strata in Eastern Siberia, but the examples
apparently are not in a very satisfactory state of preservation. In the
Tertiary formations earwigs have been found more frequently.
Scudder has described eleven species of one peculiar genus from
the Lower Miocene beds at Florissant in Colorado; some of these
specimens have been found with the wings expanded, and no doubt
that they were fully developed Forficulidae can exist. The fossil
species of earwigs as yet known do not display so remarkable a
development of the forceps as existing forms do.

Fig. 113.—Anisolabis tasmanica ♂.

Brauer and others treat the Forficulidae as a separate Order of


Insects—Dermaptera—but the only structural characters that can be
pointed out as special to the group are the peculiar form of the
tegmina and hind wings—which latter, as we have said on p. 206,
are considered by some to be formed on essentially the same plan
as those of other Orthoptera—the imbrication of the segments, and
the forceps terminating the body. The development, so far as it is
known, is that of the normal Orthoptera. Thus the Forficulidae are a
very distinct division of Orthoptera, the characters that separate
them being comparatively slight, though there are no intermediate
forms. Some of those who treat the Dermaptera as a sub-Order
equivalent to the rest of the divisions of the Order, call the latter
combination Euorthoptera.

Fam. II. Hemimeridae.

Apterous, blind Insects with exserted head, having a constricted neck, mouth
placed quite inferiorly; the thoracic sterna large, imbricate. Hind body elongate, the
segments imbricate, the dorsal plates being large and overlapping the ventral; the
number of visible segments being different according to sex: a pair of long
unsegmented cerci at the extremity. Coxae small, widely separated. Development
intra-uterine.

Fig. 114.—Hemimerus hanseni, female. Africa. (After Hansen.)

Fig. 115.—Under side of head and front of prothorax of Hemimerus. a,


base of antenna; b, articulation of antenna; c, labrum; d,
mandible; e, condyle of mandible; f, articular membrane of
mandible; g, stipes of maxilla; h, exterior lobe; i, palpus of maxilla;
k, submentum; l, mentum; m, terminal lobe of labium; n, labial
palp; o, plate between submentum and sternum; p, prosternum; q,
cervical sclerites. (After Hansen.)
In describing the labium of Mandibulata, p. 97, we alluded to the
genus Hemimerus as reputed to possess a most peculiar mouth.
When our remarks were made little was known about this Insect; but
a very valuable paper[145] by Dr. H. J. Hansen on it has since
appeared, correcting some errors and supplying us with information
on numerous points. M. de Saussure described the Insect as
possessing two lower lips, each bearing articulated palpi, and he
therefore proposed to treat Hemimerus as the representative of a
distinct Order of Insects, to be called Diploglossata. It now appears
that the talented Swiss entomologist was in this case deceived by a
bad preparation, and that the mouth shows but little departure from
the ordinary mandibulate type. There is a large inflexed labrum; the
mandibles are concealed by the maxillae, but are large, compressed,
and on their inner edge toothed. The maxillae are well developed,
are surmounted by two lobes and bear five-jointed palpi. The ligula
appears to be broad and short, and formed of two parts longitudinally
divided; the short palpi consist of three segments. The mentum is
very large. The lingua is present in the form of a free pubescent lobe
with a smaller lobe on each side. The structure of the pleura is not
fully understood; that of the abdomen seems to be very like the
earwigs, with a similar difference in the sexes. The cerci are
something like those of Gryllidae, being long, flexible, and
unsegmented. The legs have rather small coxae, and three-jointed
tarsi, two of which are densely studded with fine hairs beneath, as in
Coleoptera. It is difficult to detect the stigmata, but Dr. Hansen
believes there are ten pairs.

Fig. 116.—Foetus of Hemimerus. (After Hansen.) a, Antenna; b, organ


from the neck; c, cerci; d, membrane (? cast skins).
Fig. 117.—Hemimerus talpoides. Africa. (After de Saussure.) A, Upper;
B, under surface.

The species described by Dr. Hansen as H. talpoides is probably


distinct from that of Walker, though both come from equatorial West
Africa. Dr. Hansen's species, which may be called H. hanseni, has
been found living on the body of a large rat, Cricetomys gambianus;
the Insect occurred on a few specimens only of the mammal, but
when found was present in considerable numbers; it runs with
rapidity among the hairs and apparently also springs. The nature of
its food is by no means clear. Not the least remarkable fact in
connexion with this peculiar Insect is its gestation. The young are
borne inside the mother, apparently about six at a time, the larger
one being of course the nearest to the orifice. Dr. Hansen thinks the
young specimens are connected with the walls of the maternal
passages by means of a process from the neck of each. But the
details of this and other points are insufficiently ascertained; it is,
indeed, difficult to understand how, with a process of the kind of
which a fragment is shown in Fig. 116, b, the Insect could fix itself
after a detachment for change of position. The young is said to be
very like the adult, but with a simpler structure of the antennae and
abdomen. On the whole, it appears probable that Hemimerus is, as
stated by Dr. Hansen, a special family of Orthoptera allied to
Forficulidae; further information both as to structure and
development are, however, required, as the material at the
disposition of the Swedish entomologist was very small.

CHAPTER IX
ORTHOPTERA CONTINUED—BLATTIDAE, COCKROACHES

Fam. III. Blattidae—Cockroaches.

Orthoptera with the head deflexed, in repose concealed from above, being flexed
on to the under-surface with the anterior part directed backwards. All the coxae
large, free, entirely covering the sternal surfaces of the three thoracic segments,
as well as the base of the abdomen. The sternal sclerites of the thoracic segments
little developed, being weak and consisting of pieces that do not form a continuous
exo-skeleton; tegmina and wings extremely variable, sometimes entirely absent.
The wings possess a definite anal region capable of fan-like folding; rarely the
wing is also transversely folded. The three pairs of legs differ but little from one
another.

Fig. 118.—Heterogamia aegyptiaca. A, male; B, female. (After


Brunner.)

The Blattidae, or cockroaches, are an extensive family of Insects,


very much neglected by collectors, and known to the ordinary
observer chiefly from the fact that a few species have become
naturalised in various parts of the world in the houses of man. One
such species is abundant in Britain, and is the "black beetle" of
popular language; the use of the word beetle in connexion with
cockroaches is, however, entomologically incorrect. One or two
members of the family are also well known, owing to their being used
as the "corpora vilia" for students commencing anatomical
investigation of the Arthropoda; for this purpose they are
recommended by their comparatively large size and the ease with
which an abundant supply of specimens may always be procured,
but it must be admitted that in some respects they give but a poor
idea of Insect-structure, and that to some persons they are very
repulsive.
The inflexed position of the head is one of the most characteristic
features of the Blattidae; in activity it is partially released from this
posture, but the mouth does not appear to be capable of the full
extension forwards that is found in other Insects that inflex the head
in repose. The labium is deeply divided, the lingua forms a large lobe
reposing on the cleft. The maxillary palpi have two basal short joints,
and three longer joints beyond these; the labial palps consist of three
joints of moderate length. The under-surface of the head is formed in
large part by the submentum, which extends back to the occipital
foramen.

Fig. 119.—Under-surface of Periplaneta australasiae. c, Coxae.

The front of the head is the aspect that in repose looks directly
downwards; the larger part of it is formed by the clypeus, which is
separated from the epicranium by a very fine suture angulate in the
middle; there is a large many-facetted eye on each side; near to the
eye a circular space serves for the insertion of the antenna; close to
this and to the eye there is a peculiar small area of paler colour,
frequently membranous, called the fenestra, and which in the males
of Corydia and Heterogamia is replaced by an ocellus. The antennae
are very elongate and consist of a large number of minute rings or
joints, frequently about 100. The head is not inserted directly in the
thorax, as is the case in so many Insects; but the front of the thorax
has a very large opening, thus the neck between it and the head is of
more than usual importance; it includes six cervical sclerites.

The pronotum is more or less like a shield in form, and frequently


entirely conceals the head, and thus looks like the most anterior part
of the body; usually it has no marked angles, but in some of the
apterous forms the hind angles are sharp and project backwards. In
contrast to the pronotum the prosternum is small and feeble, and
consists of a slender lateral strip on each side, the two converging
behind to unite with a median piece, the prosternum proper. None of
these pieces of the ventral aspect of the prothorax are ordinarily
visible, the side-pieces being covered by the inflexed head, and the
median piece by the great coxae. In some of the winged Blattidae
(Blabera, e.g.) there is at the base of each anterior coxa a small
space covered by a more delicate membrane, that suggests the
possibility of the existence of a sensory organ there (Fig. 120, i).[146]
At the base of—above and behind—the front coxa the prothoracic
spiracle is situate.

Fig. 120.—Base of front leg and portion of prothorax of Blabera


gigantea. a, Under-side of pronotum; b, fold of pronotum?; c,
epimeron?; d, episternum?; e, trochantin; f, coxa; g, trochanter; h,
base of femur; i, presumed sense organ.

The meso- and meta-thoracic segments differ but slightly from one
another; the notal or dorsal pieces are moderately large, while the
sternal or ventral are remarkably rudimentary, and are frequently
divided on the middle line. Connected with the posterior part of each
sternum there is a piece, bent upwards, called by some anatomists
the furca; when the sterna are divided the furca may extend forwards
between them; in other cases it is so obscure externally as to leave
its existence in some doubt.

The sterna in Blattidae are remarkable for their rudimentary


structure. This is probably correlated with the great development of
the coxae, which serve as shields to the lower part of the body. The
pieces of the sterna are not only small, but are also of feeble
consistence—semi-membranous, in fact—and appear like thicker
portions of the more extensive and delicate membrane in which they
are situate; they sometimes differ considerably in the sexes of the
same species. The coxae have very large bases, and between them
and the sterna are some pieces that are grooved and plicate, so that
it is not easy to decide as to their distinctions and homology (Fig.
120). The second breathing orifice is a slit placed in a horny area in
the membrane between the middle and hind coxae.

The legs are remarkable for the large and numerous spines borne by
the tibiae, and frequently also by the femora: the trochanters are
distinct and of moderate size; the tarsi are five-jointed, frequently the
basal four joints are furnished with a pad beneath; the fifth joint is
elongate, bears two claws, and frequently between these a
projecting lobe or arolium; this process scarcely exists in the young
of Stilopyga orientalis, the common cockroach, though it is well
developed in the adult. The hind body or abdomen is always large,
and its division into rings is very visible, but the exact number of
these that can be seen varies according to age, sex, species, and to
whether the dorsal or ventral surface be examined. The differences
are chiefly due to the retraction and inflexion of the apical segments;
the details of the form of these parts differ in nearly every species. It
is, however, considered that ten dorsal and ventral plates exist,
though the latter are not so easily demonstrated as the former. The
basal segment is often much diminished, the first dorsal plate being
closely connected with the metanotum, while the first ventral may be
still more rudimentary; much variety exists on this point. In the
female two of the ventral terminal plates are frequently inflexed, so
as to be quite invisible without dissection. From the sides of the tenth
segment spring the cerci, flat or compressed processes very various
in size, length, and form, usually more or less distinctly jointed.
Systematists call the seventh ventral plate of the female the "lamina
subgenitalis," or the "lamina subgenitalis spuria," the concealed
eighth plate being in this latter case considered the true subgenital
plate. In the male this term is applied to the ventral plate of the ninth
segment, the corresponding dorsal plate being called the "lamina
supra-analis." These terms are much used in the systematic
definitions of the genera and larger groups.

The males, in addition to the cerci alluded to as common to both


sexes, are provided on the hind margin of the lamina subgenitalis
with a pair of slender styles. These are wanting in the females, but in
the common cockroach the young individuals of that sex are
provided, like the male, with these peculiar organs. M. Peytoureau
has described[147] the mode of their disappearance, viz. by a series
of changes at the ecdyses. Cholodkovsky, who has examined the
styles, considers them to be embryologically the homologues of true
legs.[148] These styles are said not to be present in any shape in
some species—Ectobia, Panesthia, etc.; this probably refers only to
the adults. In some cases a curious condition occurs, inasmuch as
one of the two styles is absent, and is replaced by a notch on the
right side, thus causing an asymmetry—Phyllodromia, Temnopteryx,
etc.

It has been found in several species that there are eight pairs of
abdominal spiracles, making, with the two thoracic, ten pairs in all.
The first of the abdominal spiracles is larger than the others, and in
the winged species may be easily detected by raising the tegmina
and wings, it being more dorsal in position than those following,
which are in some species exposed on the ventral surface owing to
the cutting away of the hind angles of the ventral plates; but the
terminal spiracles are in all cases difficult to detect, and it is possible
that the number may not be the same in all the species of the family.
The cerci exhibit a great deal of variety. In the species with elongate
tegmina and wings the cerci are elongate, and are like antennae in
structure; in many of the purely apterous forms the cerci appear to
be entirely absent (cf. Fig. 130, Gromphadorhina), but on
examination may be found to exist in the form of a small plate, or
papilla scarcely protuberant. In the males of Heterogamia they are,
on the contrary, very like little antennae; in the unwinged females of
this genus they are concealed in a chink existing on the under-
surface of the apex of the body.

The alar organs of Blattidae are of considerable interest from several


points of view. They exist in various conditions as regards size and
development, and in some forms are very large; each tegmen in
some species of the genus Blabera (Fig. 132) may attain a length of
nearly three inches; in other cases wings and tegmina are entirely
absent, and various intermediate conditions are found. In Fig. 121
we give a diagram of the tegmen or front wing, A, and the hind wing,
B, to explain the principal nervures and areas. The former are four in
number, and, adopting Brunner's nomenclature[149] for them, are
named proceeding from before backwards mediastinal, a; radial, b;
infra-median (or ulnar), c; and dividens, d. An adventitious vein, vena
spuria, existing in the hind wings of certain genera is marked sp in B.

Fig. 121.—Diagram of tegmen, A, and wing, B, in Blattidae. Nervures:


a, mediastinal; b, radial; c, ulnar or infra-median; d, dividens; sp,
spuria. Areas: 1, mediastinal or marginal; 2, scapular or radial; 3,
median; 4, anal or axillary.

The vena dividens is of great importance, as it marks off the anal or


axillary field, which in both tegmen and wing has a different system
of minor veins from what obtains in the rest of the organ; the veins
being in the anterior region abundantly branching and dichotomous
(Fig. 132), while in the anal field there is but little furcation, though
the nervures converge much at the base. The mediastinal gives off
minor veins towards the front only, the radial gives off veinlets at first
towards the front, but nearer the tip of the wings sends off minor
veins both backwards and forwards. The infra-median or ulnar vein
is very variable; it is frequently abbreviated, and on the whole is of
subordinate importance to the other three. These latter thus form
four chief areas or fields, viz.—1, mediastinal or marginal; 2,
scapular or radial; 3, median; and 4, anal. These nervures and
divisions may be traced in a large number of existing and fossil
Blattidae, but there are forms existing at present which it is difficult to
reduce to the same plan. In Euthyrhapha, found in the Pacific
Islands, the hind wings are long and project beyond the tegmina, and
have a very peculiar arrangement of the nervures; the species of
Holocampsa also possess abnormal alar organs, while the structure
of these parts in Diaphana (Fig. 122) is so peculiar that Brunner
wisely refrains from attempting to homologise their nervures with
those of the more normal Blattidae. The alar organs are frequently
extremely different in the two sexes of the same species of Blattidae,
and the hind wing may differ much from the tegmen as regards
degree of departure from the normal. So that it is not a matter for
surprise that the nervures in different genera cannot be satisfactorily
homologised.

Fig. 122.—Diaphana fieberi. Brazil. A, The Insect, natural size; B,


tegmen, and C, wing, magnified. (After Brunner.)

But the most peculiar wings in the family are the folded structures
found in some forms of the groups Ectobiides and Oxyhaloides
[Anaplectinae and Plectopterinae of de Saussure]. These have been
studied by de Saussure,[150] and in Fig. 123 we reproduce some of
his sketches, from which it will be seen that in B and C the wing is
divided by an unusual cross-joint into two parts, the apical portion
being also longitudinally divided into two pieces a and b. Such a form
of wing as is here shown has no exact parallel in any of the other
groups of Insects, though the earwigs and some of the Coleoptera
make an approach to it. This structure permits a very perfect folding
of the wing in repose. The peculiarities exhibited have been
explained by de Saussure somewhat as follows. In the ordinary
condition of Orthoptera the axillary or anal field (P) when the wings
are closed collapses like a fan, and also doubles under the anterior
part (H) of the wing along the line a a, in Fig. 123, A, the result being
similar to that shown by our Fig. 124. It will be noticed in Fig. 123, A,
that a small triangular area (t) exists at the tip of the wing just where
the fold takes place, so that when the wing is shut this little piece is
liberated, as shown in t, Fig. 124. In many Blattidae, e.g. Blabera
(Fig. 132), no trace of this little intercalated piece can be found, but
in others it exists in various degrees of development intermediate
between what is shown in Thorax porcellana (Fig. 123, A) and in
Anaplecta azteca (123, B), so that a, b of the latter may be looked on
as a greater development of the condition shown in A at t. It will be
noticed that the superadded part of the wing of 123, B, possesses no
venation, being traversed only by the line along which it folds; but in
the wing of Diploptera silpha, 123, C, the corresponding part is
complexly venated. This venation, as Brunner says,[151] is not an
extension of the ordinary venation of the wing, but is sui generis. It is
curious that though all the degrees of development between A and B
exist in various forms of the tribes Ectobiides and Oxyhaloides, yet
there is nothing to connect the veined apex of Diploptera with the
unveined one of Anaplecta.

Fig. 123.—Hind wings of Blattidae. A, Thorax porcellana; B, Anaplecta


azteca; C, Diploptera silpha. (After de Saussure.)
Fig. 124.—Hind wing of Blatta folded. t, Free triangular area. (After de
Saussure.)

The internal anatomy of Blattids has been investigated in only one or


two species. There are no great peculiarities, but some features of
minor interest exist. The alimentary canal (Fig. 125) is remarkable on
account of the capacious crop, and the small gut-like, chylific
ventricle; eight elongate pouches are situate on this latter part at its
junction with the gizzard.

The Malpighian tubules are very numerous and delicate; there are
extensive salivary glands and reservoirs; and on the anterior part of
the true stomach there are eight caecal diverticula. The great chain
of the nervous system consists in all of eleven ganglia—two
cephalic, three thoracic, and six abdominal.

The ovaries in Stilopyga orientalis consist each of eight egg-tubes,


placed at the periphery of a common receptacle or oviduct, the pair
of receptacles themselves opening into a common chamber—the
uterus—which is surrounded by a much branching serific or
colleterial gland. In this chamber the egg-case is formed from the
secretion of the gland just mentioned. According to Miall and Denny,
[152] there is a spermatheca which opens not into the uterus but into
the cloacal chamber behind it. Lowne doubts this diverticulum being
a true spermatheca. The manner in which the eggs are fertilised and
their capsule modelled is uncertain.[153]
Fig. 125.—Alimentary canal of Stilopyga orientalis. (After Dufour.) a,
Head; b, salivary glands; c, salivary reservoir; d, crop; e,
diverticula placed below proventriculus; f, stomach; g, small
intestine; h, rectum; i, Malpighian tubes; k, extremity of hind body.

The internal reproductive organs of the male are very complex in


Stilopyga orientalis; each testis consists of a number (30 to 40) of
vesicles placed on a tube which is prolonged to form the vas
deferens. There is a very peculiar large complex gland consisting of
longer and shorter utricles, opening into the vesiculae seminales,
and forming a "mushroom-shaped gland."[154] This gland is much
larger than the testes proper, which, it is said, lose early their
functional activity in the species in question, and shrivel. There is
another important accessory gland, the conglobate gland of Miall
and Denny, opening on a portion of the external copulatory armour.

Although some species of Blattidae are domesticated in our houses,


and their bodies have been dissected by a generation of anatomists,
very little is known as to their life histories. The common "black
beetle" of the kitchen is said by Cornelius to be several years in
attaining the adult state. Observations made at Cambridge by the
writer, as well as others now being carried on there by Mr. H. H.
Brindley, quite confirm this view, the extent of growth accomplished
in several months being surprisingly little, and the amount of food
consumed very small. It is therefore not improbable that the life of an
individual of this species may extend to five years. Phyllodromia
germanica, a species that is abundant in the dwellings of the peoples
of north-eastern Europe, attains its full development in the course of
a few months.

We have already alluded to the fact that in the Blattidae the eggs are
laid in a capsule formed in the interior of the mother-Insect. This
capsule is a horny case varying much in size and somewhat less in
form in the different species; it is borne about for some time by the
mother, who may not infrequently be seen running about with it
protruding from the hinder part of the body. Sooner or later the
capsule is deposited in a suitable situation, and the young
cockroaches emerge; it is said that they are sometimes liberated by
the aid of the mother. Mr. Brindley has found it very difficult to
procure the hatching of the young from their capsules.

Fig. 126.—Egg-capsules of European Blattidae. A, Ectobia lapponica;


B, Phyllodromia germanica; C, Heterogamia aegyptiaca. (After
Brunner.)

It is known that some Blattidae are viviparous. In the case of one


such species, Panchlora viridis, it appears probable that the egg-
capsule is either wanting, or is present in only a very imperfect form.
[155]

On emerging the young Blatta is in general form very similar to the


parent, though usually much paler in colour. After casting the skin an
uncertain number of times—not less than five, probably as many as
seven—it reaches the adult condition, the changes of outer form that
it undergoes being of a gradual nature, except that at the last
ecdysis the wings—in the case of the winged species—make their
appearance, and the terminal segments of the body undergo a
greater change of form. What mutations of shape may be undergone
by the thoracic segments previous to the final production of the
wings has not apparently been accurately recorded, Fischer's
opinion being evidently based on very slight observation. The little
that has been recorded as to the post-embryonic development since
the observations of Hummel[156] and Cornelius[157] will be found in
the works of Brunner.[158] According to this latter authority, in the
wingless species the terminal segments of the body have the same
form in the early stages as they have in the adult state, so that this
latter condition can only be recognised by the greater hardness of
the integument. When tegmina or wings are present in a well-
developed form in a Blattid, it is certain that the Insect is adult; and
when there can be seen at the side of the mesonotum or metanotum
a piece, however small, separated by a distinct suture, it may be
correctly assumed that the individual is an adult of a species having
only rudimentary alar organs. The adult female of the common
Stilopyga orientalis shows this phenomenon.

The cockroaches are remarkable for the excessive rapidity with


which they run, or rather scurry, their gait being very peculiar. The
common domestic forms, when alarmed, disappear with great agility,
seeking obscure corners in which to hide themselves, it being part of
their instinct to flee from light. Hence they are called lucifugous, and
are most of them entirely nocturnal in their activities. In the South of
Europe and other warmer regions many Blattidae may, however, be
found on bushes and foliage in the daytime; these, when alarmed,
fall down and run off with such speed and in so tortuous a manner,
that it is a very difficult matter to seize them. It is recorded that the
males of the genus Heterogamia are attracted by lights, though their
apterous females keep themselves concealed underground in sandy
places.

We may take this opportunity of alluding to the attraction that light


exerts on Insects. Many species that conceal themselves during the
daytime and shun light as if it were disagreeable, are at night-time so
fascinated by it that it is the cause of their destruction. The quantity
of Insects killed in this way by electric and other bright lights is now
enormous; in many species the individuals immolate themselves by
myriads. It would appear that only nocturnal and winged species are

You might also like