aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Computer_Science/data_structures/chapter_4/Notes on Data Structures and Programming Techniques (CPSC 223, Spring 2015).html20469
-rwxr-xr-xComputer_Science/data_structures/chapter_4/a.outbin12928 -> 0 bytes
-rwxr-xr-xComputer_Science/data_structures/chapter_4/avl_treebin13712 -> 17912 bytes
-rw-r--r--Computer_Science/data_structures/chapter_4/avl_tree.c68
-rwxr-xr-xComputer_Science/data_structures/chapter_4/avl_tree.c.outbin0 -> 17912 bytes
-rwxr-xr-xComputer_Science/data_structures/chapter_4/binary_search_tree.c.outbin0 -> 13624 bytes
-rw-r--r--Computer_Science/data_structures/chapter_4/depth_or_random_binary_search_tree.pdfbin0 -> 297160 bytes
-rw-r--r--Computer_Science/data_structures/chapter_4/depth_or_random_binary_search_tree_handout.pdfbin0 -> 1056354 bytes
-rw-r--r--Computer_Science/leetcode/15-3_sum.c37
-rw-r--r--Computer_Science/leetcode/15-3_sum.c~7
-rw-r--r--Computer_Science/leetcode/17-letter_combinations_of_a_phone_number.c46
-rw-r--r--Computer_Science/leetcode/17-letter_combinations_of_a_phone_number.c~11
-rw-r--r--Computer_Science/leetcode/5-longest_palindromic_substring.c34
-rw-r--r--Computer_Science/leetcode/5-longest_palindromic_substring.c~7
-rw-r--r--Computer_Science/leetcode/60-permutation_sequence.c33
-rw-r--r--Computer_Science/leetcode/67-add_binary.c75
-rw-r--r--Computer_Science/leetcode/67-add_binary.c~30
-rw-r--r--Computer_Science/leetcode/73-set_matrix_zeros.c46
-rw-r--r--Computer_Science/leetcode/73-set_matrix_zeros.c~7
-rw-r--r--Computer_Science/leetcode/746-min_cost_climbing_stairs.c14
-rw-r--r--Computer_Science/leetcode/746-min_cost_climbing_stairs.c~14
-rw-r--r--Computer_Science/leetcode/75-sort_colors.c41
-rw-r--r--Computer_Science/leetcode/75-sort_colors.c~7
-rw-r--r--Personal/Plan/plan.org43
24 files changed, 20974 insertions, 15 deletions
diff --git a/Computer_Science/data_structures/chapter_4/Notes on Data Structures and Programming Techniques (CPSC 223, Spring 2015).html b/Computer_Science/data_structures/chapter_4/Notes on Data Structures and Programming Techniques (CPSC 223, Spring 2015).html
new file mode 100644
index 0000000..4c11671
--- /dev/null
+++ b/Computer_Science/data_structures/chapter_4/Notes on Data Structures and Programming Techniques (CPSC 223, Spring 2015).html
@@ -0,0 +1,20469 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml"><head>
+ <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+ <meta http-equiv="Content-Style-Type" content="text/css">
+ <meta name="generator" content="pandoc">
+ <meta name="author" content="James Aspnes">
+ <title>Notes on Data Structures and Programming Techniques (CPSC 223, Spring 2015)</title>
+ <style type="text/css">code{white-space: pre;}</style>
+ <style type="text/css">
+div.sourceCode { overflow-x: auto; }
+table.sourceCode, tr.sourceCode, td.lineNumbers, td.sourceCode {
+ margin: 0; padding: 0; vertical-align: baseline; border: none; }
+table.sourceCode { width: 100%; line-height: 100%; }
+td.lineNumbers { text-align: right; padding-right: 4px; padding-left: 4px; color: #aaaaaa; border-right: 1px solid #aaaaaa; }
+td.sourceCode { padding-left: 5px; }
+code > span.kw { color: #007020; font-weight: bold; } /* Keyword */
+code > span.dt { color: #902000; } /* DataType */
+code > span.dv { color: #40a070; } /* DecVal */
+code > span.bn { color: #40a070; } /* BaseN */
+code > span.fl { color: #40a070; } /* Float */
+code > span.ch { color: #4070a0; } /* Char */
+code > span.st { color: #4070a0; } /* String */
+code > span.co { color: #60a0b0; font-style: italic; } /* Comment */
+code > span.ot { color: #007020; } /* Other */
+code > span.al { color: #ff0000; font-weight: bold; } /* Alert */
+code > span.fu { color: #06287e; } /* Function */
+code > span.er { color: #ff0000; font-weight: bold; } /* Error */
+code > span.wa { color: #60a0b0; font-weight: bold; font-style: italic; } /* Warning */
+code > span.cn { color: #880000; } /* Constant */
+code > span.sc { color: #4070a0; } /* SpecialChar */
+code > span.vs { color: #4070a0; } /* VerbatimString */
+code > span.ss { color: #bb6688; } /* SpecialString */
+code > span.im { } /* Import */
+code > span.va { color: #19177c; } /* Variable */
+code > span.cf { color: #007020; font-weight: bold; } /* ControlFlow */
+code > span.op { color: #666666; } /* Operator */
+code > span.bu { } /* BuiltIn */
+code > span.ex { } /* Extension */
+code > span.pp { color: #bc7a00; } /* Preprocessor */
+code > span.at { color: #7d9029; } /* Attribute */
+code > span.do { color: #ba2121; font-style: italic; } /* Documentation */
+code > span.an { color: #60a0b0; font-weight: bold; font-style: italic; } /* Annotation */
+code > span.cv { color: #60a0b0; font-weight: bold; font-style: italic; } /* CommentVar */
+code > span.in { color: #60a0b0; font-weight: bold; font-style: italic; } /* Information */
+ </style>
+ <link href="data:text/css;charset=utf-8,%0Ahtml%20%7B%0Afont%2Dsize%3A%20100%25%3B%0Aoverflow%2Dy%3A%20scroll%3B%0A%2Dwebkit%2Dtext%2Dsize%2Dadjust%3A%20100%25%3B%0A%2Dms%2Dtext%2Dsize%2Dadjust%3A%20100%25%3B%0A%7D%0Abody%20%7B%0Acolor%3A%20%23444%3B%0Afont%2Dfamily%3A%20Georgia%2C%20Palatino%2C%20%27Palatino%20Linotype%27%2C%20Times%2C%20%27Times%20New%20Roman%27%2C%20serif%3B%0Afont%2Dsize%3A%2012px%3B%0Aline%2Dheight%3A%201%2E4%3B%0Apadding%3A%201em%3B%0Amargin%3A%20auto%3B%0Amax%2Dwidth%3A%2044em%3B%0Abackground%3A%20%23fefefe%3B%0A%7D%0Aa%20%7B%0Acolor%3A%20%230645ad%3B%0Atext%2Ddecoration%3A%20none%3B%0A%7D%0Aa%3Avisited%20%7B%0Acolor%3A%20%230b0080%3B%0A%7D%0Aa%3Ahover%20%7B%0Acolor%3A%20%2306e%3B%0A%7D%0Aa%3Aactive%20%7B%0Acolor%3A%20%23faa700%3B%0A%7D%0Aa%3Afocus%20%7B%0Aoutline%3A%20thin%20dotted%3B%0A%7D%0A%2A%3A%3A%2Dmoz%2Dselection%20%7B%0Abackground%3A%20rgba%28255%2C%20255%2C%200%2C%200%2E3%29%3B%0Acolor%3A%20%23000%3B%0A%7D%0A%2A%3A%3Aselection%20%7B%0Abackground%3A%20rgba%28255%2C%20255%2C%200%2C%200%2E3%29%3B%0Acolor%3A%20%23000%3B%0A%7D%0Aa%3A%3A%2Dmoz%2Dselection%20%7B%0Abackground%3A%20rgba%28255%2C%20255%2C%200%2C%200%2E3%29%3B%0Acolor%3A%20%230645ad%3B%0A%7D%0Aa%3A%3Aselection%20%7B%0Abackground%3A%20rgba%28255%2C%20255%2C%200%2C%200%2E3%29%3B%0Acolor%3A%20%230645ad%3B%0A%7D%0Ap%20%7B%0Amargin%3A%201em%200%3B%0A%7D%0Aimg%20%7B%0Amax%2Dwidth%3A%20100%25%3B%0A%7D%0Ah1%2C%20h2%2C%20h3%2C%20h4%2C%20h5%2C%20h6%20%7B%0Acolor%3A%20%23111%3B%0Aline%2Dheight%3A%20125%25%3B%0Amargin%2Dtop%3A%202em%3B%0Afont%2Dweight%3A%20normal%3B%0A%7D%0Ah4%2C%20h5%2C%20h6%20%7B%0Afont%2Dweight%3A%20bold%3B%0A%7D%0Ah1%20%7B%0Afont%2Dsize%3A%202%2E5em%3B%0A%7D%0Ah2%20%7B%0Afont%2Dsize%3A%202em%3B%0A%7D%0Ah3%20%7B%0Afont%2Dsize%3A%201%2E5em%3B%0A%7D%0Ah4%20%7B%0Afont%2Dsize%3A%201%2E2em%3B%0A%7D%0Ah5%20%7B%0Afont%2Dsize%3A%201em%3B%0A%7D%0Ah6%20%7B%0Afont%2Dsize%3A%200%2E9em%3B%0A%7D%0Ablockquote%20%7B%0Acolor%3A%20%23666666%3B%0Amargin%3A%200%3B%0Apadding%2Dleft%3A%203em%3B%0Aborder%2Dleft%3A%200%2E5em%20%23EEE%20solid%3B%0A%7D%0Ahr%20%7B%0Adisplay%3A%20block%3B%0Aheight%3A%202px%3B%0Aborder%3A%200%3B%0Aborder%2Dtop%3A%201px%20solid%20%23aaa%3B%0Aborder%2Dbottom%3A%201px%20solid%20%23eee%3B%0Amargin%3A%201em%200%3B%0Apadding%3A%200%3B%0A%7D%0Apre%2C%20code%2C%20kbd%2C%20samp%20%7B%0Acolor%3A%20%23000%3B%0Afont%2Dfamily%3A%20monospace%2C%20monospace%3B%0A%5Ffont%2Dfamily%3A%20%27courier%20new%27%2C%20monospace%3B%0Afont%2Dsize%3A%200%2E98em%3B%0A%7D%0Apre%20%7B%0Awhite%2Dspace%3A%20pre%3B%0Awhite%2Dspace%3A%20pre%2Dwrap%3B%0Aword%2Dwrap%3A%20break%2Dword%3B%0A%7D%0Ab%2C%20strong%20%7B%0Afont%2Dweight%3A%20bold%3B%0A%7D%0Adfn%20%7B%0Afont%2Dstyle%3A%20italic%3B%0A%7D%0Ains%20%7B%0Abackground%3A%20%23ff9%3B%0Acolor%3A%20%23000%3B%0Atext%2Ddecoration%3A%20none%3B%0A%7D%0Amark%20%7B%0Abackground%3A%20%23ff0%3B%0Acolor%3A%20%23000%3B%0Afont%2Dstyle%3A%20italic%3B%0Afont%2Dweight%3A%20bold%3B%0A%7D%0Asub%2C%20sup%20%7B%0Afont%2Dsize%3A%2075%25%3B%0Aline%2Dheight%3A%200%3B%0Aposition%3A%20relative%3B%0Avertical%2Dalign%3A%20baseline%3B%0A%7D%0Asup%20%7B%0Atop%3A%20%2D0%2E5em%3B%0A%7D%0Asub%20%7B%0Abottom%3A%20%2D0%2E25em%3B%0A%7D%0Aul%2C%20ol%20%7B%0Amargin%3A%201em%200%3B%0Apadding%3A%200%200%200%202em%3B%0A%7D%0Ali%20p%3Alast%2Dchild%20%7B%0Amargin%2Dbottom%3A%200%3B%0A%7D%0Aul%20ul%2C%20ol%20ol%20%7B%0Amargin%3A%20%2E3em%200%3B%0A%7D%0Adl%20%7B%0Amargin%2Dbottom%3A%201em%3B%0A%7D%0Adt%20%7B%0Afont%2Dweight%3A%20bold%3B%0Amargin%2Dbottom%3A%20%2E8em%3B%0A%7D%0Add%20%7B%0Amargin%3A%200%200%20%2E8em%202em%3B%0A%7D%0Add%3Alast%2Dchild%20%7B%0Amargin%2Dbottom%3A%200%3B%0A%7D%0Aimg%20%7B%0Aborder%3A%200%3B%0A%2Dms%2Dinterpolation%2Dmode%3A%20bicubic%3B%0Avertical%2Dalign%3A%20middle%3B%0A%7D%0Afigure%20%7B%0Adisplay%3A%20block%3B%0Atext%2Dalign%3A%20center%3B%0Amargin%3A%201em%200%3B%0A%7D%0Afigure%20img%20%7B%0Aborder%3A%20none%3B%0Amargin%3A%200%20auto%3B%0A%7D%0Afigcaption%20%7B%0Afont%2Dsize%3A%200%2E8em%3B%0Afont%2Dstyle%3A%20italic%3B%0Amargin%3A%200%200%20%2E8em%3B%0A%7D%0Atable%20%7B%0Amargin%2Dbottom%3A%202em%3B%0Aborder%2Dbottom%3A%201px%20solid%20%23ddd%3B%0Aborder%2Dright%3A%201px%20solid%20%23ddd%3B%0Aborder%2Dspacing%3A%200%3B%0Aborder%2Dcollapse%3A%20collapse%3B%0A%7D%0Atable%20th%20%7B%0Apadding%3A%20%2E2em%201em%3B%0Abackground%2Dcolor%3A%20%23eee%3B%0Aborder%2Dtop%3A%201px%20solid%20%23ddd%3B%0Aborder%2Dleft%3A%201px%20solid%20%23ddd%3B%0A%7D%0Atable%20td%20%7B%0Apadding%3A%20%2E2em%201em%3B%0Aborder%2Dtop%3A%201px%20solid%20%23ddd%3B%0Aborder%2Dleft%3A%201px%20solid%20%23ddd%3B%0Avertical%2Dalign%3A%20top%3B%0A%7D%0A%2Eauthor%20%7B%0Afont%2Dsize%3A%201%2E2em%3B%0Atext%2Dalign%3A%20center%3B%0A%7D%0A%40media%20only%20screen%20and%20%28min%2Dwidth%3A%20480px%29%20%7B%0Abody%20%7B%0Afont%2Dsize%3A%2014px%3B%0A%7D%0A%7D%0A%40media%20only%20screen%20and%20%28min%2Dwidth%3A%20768px%29%20%7B%0Abody%20%7B%0Afont%2Dsize%3A%2016px%3B%0A%7D%0A%7D%0A%40media%20print%20%7B%0A%2A%20%7B%0Abackground%3A%20transparent%20%21important%3B%0Acolor%3A%20black%20%21important%3B%0Afilter%3A%20none%20%21important%3B%0A%2Dms%2Dfilter%3A%20none%20%21important%3B%0A%7D%0Abody%20%7B%0Afont%2Dsize%3A%2012pt%3B%0Amax%2Dwidth%3A%20100%25%3B%0A%7D%0Aa%2C%20a%3Avisited%20%7B%0Atext%2Ddecoration%3A%20underline%3B%0A%7D%0Ahr%20%7B%0Aheight%3A%201px%3B%0Aborder%3A%200%3B%0Aborder%2Dbottom%3A%201px%20solid%20black%3B%0A%7D%0Aa%5Bhref%5D%3Aafter%20%7B%0Acontent%3A%20%22%20%28%22%20attr%28href%29%20%22%29%22%3B%0A%7D%0Aabbr%5Btitle%5D%3Aafter%20%7B%0Acontent%3A%20%22%20%28%22%20attr%28title%29%20%22%29%22%3B%0A%7D%0A%2Eir%20a%3Aafter%2C%20a%5Bhref%5E%3D%22javascript%3A%22%5D%3Aafter%2C%20a%5Bhref%5E%3D%22%23%22%5D%3Aafter%20%7B%0Acontent%3A%20%22%22%3B%0A%7D%0Apre%2C%20blockquote%20%7B%0Aborder%3A%201px%20solid%20%23999%3B%0Apadding%2Dright%3A%201em%3B%0Apage%2Dbreak%2Dinside%3A%20avoid%3B%0A%7D%0Atr%2C%20img%20%7B%0Apage%2Dbreak%2Dinside%3A%20avoid%3B%0A%7D%0Aimg%20%7B%0Amax%2Dwidth%3A%20100%25%20%21important%3B%0A%7D%0A%40page%20%3Aleft%20%7B%0Amargin%3A%2015mm%2020mm%2015mm%2010mm%3B%0A%7D%0A%40page%20%3Aright%20%7B%0Amargin%3A%2015mm%2010mm%2015mm%2020mm%3B%0A%7D%0Ap%2C%20h2%2C%20h3%20%7B%0Aorphans%3A%203%3B%0Awidows%3A%203%3B%0A%7D%0Ah2%2C%20h3%20%7B%0Apage%2Dbreak%2Dafter%3A%20avoid%3B%0A%7D%0A%7D%0A" rel="stylesheet" type="text/css">
+ <meta name="viewport" content="width=device-width, initial-scale=1">
+<style></style></head>
+<body>
+<div id="header">
+<h1 class="title">Notes on Data Structures and Programming Techniques (CPSC 223, Spring 2015)</h1>
+<h2 class="author">James Aspnes</h2>
+<h3 class="date">2017-12-02T12:59:47-0500</h3>
+</div>
+<div id="TOC">
+<ul>
+<li><a href="#courseAdministration"><span class="toc-section-number">1</span> Course administration</a><ul>
+<li><a href="#index"><span class="toc-section-number">1.1</span> Overview</a><ul>
+<li><a href="#license"><span class="toc-section-number">1.1.1</span> License</a></li>
+<li><a href="#resources"><span class="toc-section-number">1.1.2</span> Resources</a></li>
+<li><a href="#Documentation"><span class="toc-section-number">1.1.3</span> Documentation</a></li>
+<li><a href="#questions-and-comments"><span class="toc-section-number">1.1.4</span> Questions and comments</a></li>
+</ul></li>
+<li><a href="#schedule"><span class="toc-section-number">1.2</span> Lecture schedule</a><ul>
+<li><a href="#topics-by-date"><span class="toc-section-number">1.2.1</span> Topics by date</a></li>
+<li><a href="#topics-not-covered-in-2015"><span class="toc-section-number">1.2.2</span> Topics not covered in 2015</a></li>
+</ul></li>
+<li><a href="#syllabus"><span class="toc-section-number">1.3</span> Syllabus</a><ul>
+<li><a href="#On-line_course_information"><span class="toc-section-number">1.3.1</span> On-line course information</a></li>
+<li><a href="#Meeting_times"><span class="toc-section-number">1.3.2</span> Meeting times</a></li>
+<li><a href="#Synopsis_of_the_course"><span class="toc-section-number">1.3.3</span> Synopsis of the course</a></li>
+<li><a href="#Prerequisites"><span class="toc-section-number">1.3.4</span> Prerequisites</a></li>
+<li><a href="#Textbook"><span class="toc-section-number">1.3.5</span> Textbook</a></li>
+<li><a href="#Course_requirements"><span class="toc-section-number">1.3.6</span> Course requirements</a></li>
+<li><a href="#staff"><span class="toc-section-number">1.3.7</span> Staff</a><ul>
+<li><a href="#instructor"><span class="toc-section-number">1.3.7.1</span> Instructor</a></li>
+<li><a href="#teaching-fellows"><span class="toc-section-number">1.3.7.2</span> Teaching Fellows</a></li>
+<li><a href="#peer-tutors"><span class="toc-section-number">1.3.7.3</span> Peer tutors</a></li>
+</ul></li>
+<li><a href="#Use_of_outside_help"><span class="toc-section-number">1.3.8</span> Use of outside help</a></li>
+<li><a href="#Clarifications_for_homework_assignments"><span class="toc-section-number">1.3.9</span> Clarifications for homework assignments</a></li>
+<li><a href="#Late_assignments"><span class="toc-section-number">1.3.10</span> Late assignments</a></li>
+</ul></li>
+<li><a href="#introduction"><span class="toc-section-number">1.4</span> Introduction</a><ul>
+<li><a href="#whyC"><span class="toc-section-number">1.4.1</span> Why should you learn to program in C?</a></li>
+<li><a href="#why-should-you-learn-about-data-structures-and-programming-techniques"><span class="toc-section-number">1.4.2</span> Why should you learn about data structures and programming techniques?</a></li>
+</ul></li>
+</ul></li>
+<li><a href="#zoo"><span class="toc-section-number">2</span> The Zoo and the Zoo Annex</a><ul>
+<li><a href="#Getting_an_account"><span class="toc-section-number">2.1</span> Getting an account</a></li>
+<li><a href="#Getting_into_the_room"><span class="toc-section-number">2.2</span> Getting into the room</a></li>
+<li><a href="#Remote_use"><span class="toc-section-number">2.3</span> Remote use</a><ul>
+<li><a href="#fastX"><span class="toc-section-number">2.3.1</span> Access using FastX</a><ul>
+<li><a href="#fastXLicense"><span class="toc-section-number">2.3.1.1</span> Getting a license key</a></li>
+<li><a href="#fastXZooAnnex"><span class="toc-section-number">2.3.1.2</span> FastX in the Zoo Annex</a></li>
+<li><a href="#fastXWindows"><span class="toc-section-number">2.3.1.3</span> Using FastX from Windows</a></li>
+<li><a href="#fastXOSX"><span class="toc-section-number">2.3.1.4</span> Using FastX from OSX</a></li>
+</ul></li>
+<li><a href="#zooSSH"><span class="toc-section-number">2.3.2</span> Terminal access</a></li>
+<li><a href="#GUI_access"><span class="toc-section-number">2.3.3</span> GUI access</a></li>
+</ul></li>
+<li><a href="#compiling"><span class="toc-section-number">2.4</span> How to compile and run programs</a><ul>
+<li><a href="#Creating_the_program"><span class="toc-section-number">2.4.1</span> Creating the program</a></li>
+<li><a href="#Compiling_and_running_a_program"><span class="toc-section-number">2.4.2</span> Compiling and running a program</a></li>
+<li><a href="#Some_notes_on_what_the_program_does"><span class="toc-section-number">2.4.3</span> Some notes on what the program does</a></li>
+</ul></li>
+</ul></li>
+<li><a href="#linux"><span class="toc-section-number">3</span> The Linux programming environment</a><ul>
+<li><a href="#the-shell"><span class="toc-section-number">3.1</span> The shell</a><ul>
+<li><a href="#Getting_a_shell_prompt_in_the_Zoo"><span class="toc-section-number">3.1.1</span> Getting a shell prompt in the Zoo</a></li>
+<li><a href="#The_Unix_filesystem"><span class="toc-section-number">3.1.2</span> The Unix filesystem</a></li>
+<li><a href="#Unix_command-line_programs"><span class="toc-section-number">3.1.3</span> Unix command-line programs</a></li>
+<li><a href="#Stopping_and_interrupting_programs"><span class="toc-section-number">3.1.4</span> Stopping and interrupting programs</a></li>
+<li><a href="#Running_your_own_programs"><span class="toc-section-number">3.1.5</span> Running your own programs</a></li>
+<li><a href="#shellRedirects"><span class="toc-section-number">3.1.6</span> Redirecting input and output</a></li>
+</ul></li>
+<li><a href="#editing"><span class="toc-section-number">3.2</span> Text editors</a><ul>
+<li><a href="#Writing_C_programs_with_Emacs"><span class="toc-section-number">3.2.1</span> Writing C programs with Emacs</a><ul>
+<li><a href="#My_favorite_Emacs_commands"><span class="toc-section-number">3.2.1.1</span> My favorite Emacs commands</a></li>
+</ul></li>
+<li><a href="#Using_Vi_instead_of_Emacs"><span class="toc-section-number">3.2.2</span> Using Vi instead of Emacs</a><ul>
+<li><a href="#My_favorite_Vim_commands"><span class="toc-section-number">3.2.2.1</span> My favorite Vim commands</a><ul>
+<li><a href="#Normal_mode"><span class="toc-section-number">3.2.2.1.1</span> Normal mode</a></li>
+<li><a href="#Insert_mode"><span class="toc-section-number">3.2.2.1.2</span> Insert mode</a></li>
+</ul></li>
+<li><a href="#Settings"><span class="toc-section-number">3.2.2.2</span> Settings</a></li>
+</ul></li>
+</ul></li>
+<li><a href="#compilationTools"><span class="toc-section-number">3.3</span> Compilation tools</a><ul>
+<li><a href="#gcc"><span class="toc-section-number">3.3.1</span> The GNU C compiler <code>gcc</code></a></li>
+<li><a href="#make"><span class="toc-section-number">3.3.2</span> Make</a><ul>
+<li><a href="#Make_gotchas"><span class="toc-section-number">3.3.2.1</span> Make gotchas</a></li>
+</ul></li>
+</ul></li>
+<li><a href="#debugging"><span class="toc-section-number">3.4</span> Debugging tools</a><ul>
+<li><a href="#Debugging_in_general"><span class="toc-section-number">3.4.1</span> Debugging in general</a></li>
+<li><a href="#Assertions"><span class="toc-section-number">3.4.2</span> Assertions</a></li>
+<li><a href="#gdb"><span class="toc-section-number">3.4.3</span> The GNU debugger <code>gdb</code></a><ul>
+<li><a href="#My_favorite_gdb_commands"><span class="toc-section-number">3.4.3.1</span> My favorite gdb commands</a></li>
+<li><a href="#Debugging_strategies"><span class="toc-section-number">3.4.3.2</span> Debugging strategies</a></li>
+<li><a href="#common-applications-of-gdb"><span class="toc-section-number">3.4.3.3</span> Common applications of <code>gdb</code></a><ul>
+<li><a href="#watching-your-program-run"><span class="toc-section-number">3.4.3.3.1</span> Watching your program run</a></li>
+<li><a href="#dealing-with-failed-assertions"><span class="toc-section-number">3.4.3.3.2</span> Dealing with failed assertions</a></li>
+<li><a href="#dealing-with-segmentation-faults"><span class="toc-section-number">3.4.3.3.3</span> Dealing with segmentation faults</a></li>
+<li><a href="#dealing-with-infinite-loops"><span class="toc-section-number">3.4.3.3.4</span> Dealing with infinite loops</a></li>
+<li><a href="#mysterious-variable-changes"><span class="toc-section-number">3.4.3.3.5</span> Mysterious variable changes</a></li>
+</ul></li>
+</ul></li>
+<li><a href="#valgrind"><span class="toc-section-number">3.4.4</span> Valgrind</a><ul>
+<li><a href="#Compilation_flags"><span class="toc-section-number">3.4.4.1</span> Compilation flags</a></li>
+<li><a href="#Automated_testing"><span class="toc-section-number">3.4.4.2</span> Automated testing</a></li>
+<li><a href="#Examples_of_some_common_valgrindErrors"><span class="toc-section-number">3.4.4.3</span> Examples of some common valgrind errors</a><ul>
+<li><a href="#Uninitialized_values"><span class="toc-section-number">3.4.4.3.1</span> Uninitialized values</a></li>
+<li><a href="#Bytes_definitely_lost"><span class="toc-section-number">3.4.4.3.2</span> Bytes definitely lost</a></li>
+<li><a href="#Invalid_write_or_read_operations"><span class="toc-section-number">3.4.4.3.3</span> Invalid write or read operations</a></li>
+</ul></li>
+</ul></li>
+<li><a href="#Not_recommended:_debugging_output"><span class="toc-section-number">3.4.5</span> Not recommended: debugging output</a></li>
+</ul></li>
+<li><a href="#performanceTuning"><span class="toc-section-number">3.5</span> Performance tuning</a><ul>
+<li><a href="#Timing_under_Linux"><span class="toc-section-number">3.5.1</span> Timing under Linux</a></li>
+<li><a href="#profiling"><span class="toc-section-number">3.5.2</span> Profiling with gprof</a><ul>
+<li><a href="#effect-of-optimization-during-compilation"><span class="toc-section-number">3.5.2.1</span> Effect of optimization during compilation</a></li>
+</ul></li>
+</ul></li>
+<li><a href="#versionControl"><span class="toc-section-number">3.6</span> Version control</a><ul>
+<li><a href="#Setting_up_Git"><span class="toc-section-number">3.6.1</span> Setting up Git</a></li>
+<li><a href="#Editing_files"><span class="toc-section-number">3.6.2</span> Editing files</a></li>
+<li><a href="#Renaming_files"><span class="toc-section-number">3.6.3</span> Renaming files</a></li>
+<li><a href="#Adding_and_removing_files"><span class="toc-section-number">3.6.4</span> Adding and removing files</a></li>
+<li><a href="#Recovering_files_from_the_repository"><span class="toc-section-number">3.6.5</span> Recovering files from the repository</a></li>
+<li><a href="#Undoing_bad_commits"><span class="toc-section-number">3.6.6</span> Undoing bad commits</a></li>
+<li><a href="#Looking_at_old_versions"><span class="toc-section-number">3.6.7</span> Looking at old versions</a></li>
+<li><a href="#More_information_about_Git"><span class="toc-section-number">3.6.8</span> More information about Git</a></li>
+</ul></li>
+<li><a href="#submitScript"><span class="toc-section-number">3.7</span> Submitting assignments</a></li>
+</ul></li>
+<li><a href="#c"><span class="toc-section-number">4</span> The C programming language</a><ul>
+<li><a href="#CProgramStructure"><span class="toc-section-number">4.1</span> Structure of a C program</a></li>
+<li><a href="#numericTypes"><span class="toc-section-number">4.2</span> Numeric data types</a><ul>
+<li><a href="#integerTypes"><span class="toc-section-number">4.2.1</span> Integer types in C</a><ul>
+<li><a href="#basicIntegerTypes"><span class="toc-section-number">4.2.1.1</span> Basic integer types</a></li>
+<li><a href="#C99_fixed-width_types"><span class="toc-section-number">4.2.1.2</span> C99 fixed-width types</a></li>
+</ul></li>
+<li><a href="#sizeTypes"><span class="toc-section-number">4.2.2</span> <code>size_t</code> and <code>ptrdiff_t</code></a><ul>
+<li><a href="#integerConstants"><span class="toc-section-number">4.2.2.1</span> Integer constants</a><ul>
+<li><a href="#naming-constants"><span class="toc-section-number">4.2.2.1.1</span> Naming constants</a></li>
+</ul></li>
+<li><a href="#integerOperators"><span class="toc-section-number">4.2.2.2</span> Integer operators</a><ul>
+<li><a href="#Arithmetic_operators"><span class="toc-section-number">4.2.2.2.1</span> Arithmetic operators</a></li>
+<li><a href="#Bitwise_operators"><span class="toc-section-number">4.2.2.2.2</span> Bitwise operators</a></li>
+<li><a href="#Logical_operators"><span class="toc-section-number">4.2.2.2.3</span> Logical operators</a></li>
+<li><a href="#Relational_operators"><span class="toc-section-number">4.2.2.2.4</span> Relational operators</a></li>
+</ul></li>
+<li><a href="#integerStringConversion"><span class="toc-section-number">4.2.2.3</span> Converting to and from strings</a></li>
+</ul></li>
+<li><a href="#floatingPointTypes"><span class="toc-section-number">4.2.3</span> Floating-point types</a><ul>
+<li><a href="#Floating_point_basics"><span class="toc-section-number">4.2.3.1</span> Floating point basics</a></li>
+<li><a href="#Floating-point_constants"><span class="toc-section-number">4.2.3.2</span> Floating-point constants</a></li>
+<li><a href="#Operators"><span class="toc-section-number">4.2.3.3</span> Operators</a></li>
+<li><a href="#Conversion_to_and_from_integer_types"><span class="toc-section-number">4.2.3.4</span> Conversion to and from integer types</a></li>
+<li><a href="#The_IEEE-754_floating-point_standard"><span class="toc-section-number">4.2.3.5</span> The IEEE-754 floating-point standard</a></li>
+<li><a href="#Error"><span class="toc-section-number">4.2.3.6</span> Error</a></li>
+<li><a href="#Reading_and_writing_floating-point_numbers"><span class="toc-section-number">4.2.3.7</span> Reading and writing floating-point numbers</a></li>
+<li><a href="#Non-finite_numbers_in_C"><span class="toc-section-number">4.2.3.8</span> Non-finite numbers in C</a></li>
+<li><a href="#The_math_library"><span class="toc-section-number">4.2.3.9</span> The math library</a></li>
+</ul></li>
+</ul></li>
+<li><a href="#operatorPrecedence"><span class="toc-section-number">4.3</span> Operator precedence</a></li>
+<li><a href="#programmingStyle"><span class="toc-section-number">4.4</span> Programming style</a></li>
+<li><a href="#variables"><span class="toc-section-number">4.5</span> Variables</a><ul>
+<li><a href="#MachineMemory"><span class="toc-section-number">4.5.1</span> Memory</a></li>
+<li><a href="#variablesAsNames"><span class="toc-section-number">4.5.2</span> Variables as names</a><ul>
+<li><a href="#Variable_declarations"><span class="toc-section-number">4.5.2.1</span> Variable declarations</a></li>
+<li><a href="#Variable_names"><span class="toc-section-number">4.5.2.2</span> Variable names</a></li>
+</ul></li>
+<li><a href="#usingVariables"><span class="toc-section-number">4.5.3</span> Using variables</a></li>
+<li><a href="#initializers"><span class="toc-section-number">4.5.4</span> Initialization</a></li>
+<li><a href="#qualifiers"><span class="toc-section-number">4.5.5</span> Storage class qualifiers</a><ul>
+<li><a href="#scopeAndExtent"><span class="toc-section-number">4.5.5.1</span> Scope and extent</a><ul>
+<li><a href="#additional-qualifiers-for-global-variables"><span class="toc-section-number">4.5.5.1.1</span> Additional qualifiers for global variables</a></li>
+</ul></li>
+</ul></li>
+<li><a href="#const"><span class="toc-section-number">4.5.6</span> Marking variables as constant</a><ul>
+<li><a href="#pointers-to-const"><span class="toc-section-number">4.5.6.1</span> Pointers to <code>const</code></a></li>
+</ul></li>
+</ul></li>
+<li><a href="#IO"><span class="toc-section-number">4.6</span> Input and output</a><ul>
+<li><a href="#Character_streams"><span class="toc-section-number">4.6.1</span> Character streams</a></li>
+<li><a href="#characterIO"><span class="toc-section-number">4.6.2</span> Reading and writing single characters</a></li>
+<li><a href="#Formatted_I.2FO"><span class="toc-section-number">4.6.3</span> Formatted I/O</a></li>
+<li><a href="#Rolling_your_own_I.2FO_routines"><span class="toc-section-number">4.6.4</span> Rolling your own I/O routines</a></li>
+<li><a href="#File_I.2FO"><span class="toc-section-number">4.6.5</span> File I/O</a></li>
+</ul></li>
+<li><a href="#statements"><span class="toc-section-number">4.7</span> Statements and control structures</a><ul>
+<li><a href="#Simple_statements"><span class="toc-section-number">4.7.1</span> Simple statements</a></li>
+<li><a href="#Compound_statements"><span class="toc-section-number">4.7.2</span> Compound statements</a><ul>
+<li><a href="#conditionals"><span class="toc-section-number">4.7.2.1</span> Conditionals</a></li>
+<li><a href="#Loops"><span class="toc-section-number">4.7.2.2</span> Loops</a><ul>
+<li><a href="#The_while_loop"><span class="toc-section-number">4.7.2.2.1</span> The while loop</a></li>
+<li><a href="#The_do..while_loop"><span class="toc-section-number">4.7.2.2.2</span> The do..while loop</a></li>
+<li><a href="#forLoop"><span class="toc-section-number">4.7.2.2.3</span> The for loop</a></li>
+<li><a href="#Loops_with_break.2C_continue.2C_and_goto"><span class="toc-section-number">4.7.2.2.4</span> Loops with break, continue, and goto</a></li>
+</ul></li>
+<li><a href="#Choosing_where_to_put_a_loop_exit"><span class="toc-section-number">4.7.2.3</span> Choosing where to put a loop exit</a></li>
+</ul></li>
+</ul></li>
+<li><a href="#functions"><span class="toc-section-number">4.8</span> Functions</a><ul>
+<li><a href="#functionDefinitions"><span class="toc-section-number">4.8.1</span> Function definitions</a></li>
+<li><a href="#functionIdeology"><span class="toc-section-number">4.8.2</span> When to write a function</a></li>
+<li><a href="#Calling_a_function"><span class="toc-section-number">4.8.3</span> Calling a function</a></li>
+<li><a href="#The_return_statement"><span class="toc-section-number">4.8.4</span> The return statement</a></li>
+<li><a href="#Function_declarations_and_modules"><span class="toc-section-number">4.8.5</span> Function declarations and modules</a></li>
+<li><a href="#Static_functions"><span class="toc-section-number">4.8.6</span> Static functions</a></li>
+<li><a href="#Local_variables"><span class="toc-section-number">4.8.7</span> Local variables</a></li>
+<li><a href="#Mechanics_of_function_calls"><span class="toc-section-number">4.8.8</span> Mechanics of function calls</a></li>
+</ul></li>
+<li><a href="#pointers"><span class="toc-section-number">4.9</span> Pointers</a><ul>
+<li><a href="#addressSpace"><span class="toc-section-number">4.9.1</span> Memory and addresses</a></li>
+<li><a href="#Pointer_variables"><span class="toc-section-number">4.9.2</span> Pointer variables</a><ul>
+<li><a href="#Declaring_a_pointer_variable"><span class="toc-section-number">4.9.2.1</span> Declaring a pointer variable</a></li>
+<li><a href="#Assigning_to_pointer_variables"><span class="toc-section-number">4.9.2.2</span> Assigning to pointer variables</a></li>
+<li><a href="#Using_a_pointer"><span class="toc-section-number">4.9.2.3</span> Using a pointer</a></li>
+<li><a href="#Printing_pointers"><span class="toc-section-number">4.9.2.4</span> Printing pointers</a></li>
+</ul></li>
+<li><a href="#The_null_pointer"><span class="toc-section-number">4.9.3</span> The null pointer</a></li>
+<li><a href="#Pointers_and_functions"><span class="toc-section-number">4.9.4</span> Pointers and functions</a></li>
+<li><a href="#pointerArithmetic"><span class="toc-section-number">4.9.5</span> Pointer arithmetic and arrays</a><ul>
+<li><a href="#arrays"><span class="toc-section-number">4.9.5.1</span> Arrays</a></li>
+<li><a href="#arraysAndFunctions"><span class="toc-section-number">4.9.5.2</span> Arrays and functions</a></li>
+<li><a href="#multidimensionalArrays"><span class="toc-section-number">4.9.5.3</span> Multidimensional arrays</a></li>
+<li><a href="#variableLengthArrays"><span class="toc-section-number">4.9.5.4</span> Variable-length arrays</a></li>
+</ul></li>
+<li><a href="#Void_pointers"><span class="toc-section-number">4.9.6</span> Void pointers</a><ul>
+<li><a href="#alignment"><span class="toc-section-number">4.9.6.1</span> Alignment</a></li>
+</ul></li>
+<li><a href="#malloc"><span class="toc-section-number">4.9.7</span> Run-time storage allocation using <code>malloc</code></a></li>
+<li><a href="#functionPointers"><span class="toc-section-number">4.9.8</span> Function pointers</a><ul>
+<li><a href="#Function_pointer_declarations"><span class="toc-section-number">4.9.8.1</span> Function pointer declarations</a></li>
+<li><a href="#Callbacks"><span class="toc-section-number">4.9.8.2</span> Callbacks</a></li>
+<li><a href="#Dispatch_tables"><span class="toc-section-number">4.9.8.3</span> Dispatch tables</a></li>
+</ul></li>
+<li><a href="#The_restrict_keyword"><span class="toc-section-number">4.9.9</span> The restrict keyword</a></li>
+</ul></li>
+<li><a href="#strings"><span class="toc-section-number">4.10</span> Strings</a><ul>
+<li><a href="#C_strings"><span class="toc-section-number">4.10.1</span> C strings</a></li>
+<li><a href="#String_constants"><span class="toc-section-number">4.10.2</span> String constants</a></li>
+<li><a href="#String_buffers"><span class="toc-section-number">4.10.3</span> String buffers</a><ul>
+<li><a href="#string-buffers-and-the-perils-of-gets"><span class="toc-section-number">4.10.3.1</span> String buffers and the perils of <code>gets</code></a></li>
+</ul></li>
+<li><a href="#Operations_on_strings"><span class="toc-section-number">4.10.4</span> Operations on strings</a></li>
+<li><a href="#Finding_the_length_of_a_string"><span class="toc-section-number">4.10.5</span> Finding the length of a string</a><ul>
+<li><a href="#The_strlen_tarpit"><span class="toc-section-number">4.10.5.1</span> The strlen tarpit</a></li>
+</ul></li>
+<li><a href="#Comparing_strings"><span class="toc-section-number">4.10.6</span> Comparing strings</a></li>
+<li><a href="#Formatted_output_to_strings"><span class="toc-section-number">4.10.7</span> Formatted output to strings</a></li>
+<li><a href="#Dynamic_allocation_of_strings"><span class="toc-section-number">4.10.8</span> Dynamic allocation of strings</a></li>
+<li><a href="#argv"><span class="toc-section-number">4.10.9</span> Command-line arguments</a></li>
+</ul></li>
+<li><a href="#structuredDataTypes"><span class="toc-section-number">4.11</span> Structured data types</a><ul>
+<li><a href="#structs"><span class="toc-section-number">4.11.1</span> Structs</a><ul>
+<li><a href="#operations-on-structs"><span class="toc-section-number">4.11.1.1</span> Operations on structs</a></li>
+<li><a href="#structLayout"><span class="toc-section-number">4.11.1.2</span> Layout in memory</a></li>
+<li><a href="#Bit_fields"><span class="toc-section-number">4.11.1.3</span> Bit fields</a></li>
+</ul></li>
+<li><a href="#unions"><span class="toc-section-number">4.11.2</span> Unions</a></li>
+<li><a href="#enums"><span class="toc-section-number">4.11.3</span> Enums</a><ul>
+<li><a href="#specifying-particular-values"><span class="toc-section-number">4.11.3.1</span> Specifying particular values</a></li>
+<li><a href="#what-most-people-do"><span class="toc-section-number">4.11.3.2</span> What most people do</a></li>
+<li><a href="#enumTagsForUnion"><span class="toc-section-number">4.11.3.3</span> Using <code>enum</code> with <code>union</code></a></li>
+</ul></li>
+</ul></li>
+<li><a href="#typedef"><span class="toc-section-number">4.12</span> Type aliases using <code>typedef</code></a><ul>
+<li><a href="#opaqueStructs"><span class="toc-section-number">4.12.1</span> Opaque structs</a></li>
+</ul></li>
+<li><a href="#macros"><span class="toc-section-number">4.13</span> Macros</a><ul>
+<li><a href="#Macros_with_arguments"><span class="toc-section-number">4.13.1</span> Macros with arguments</a><ul>
+<li><a href="#Multiple_arguments"><span class="toc-section-number">4.13.1.1</span> Multiple arguments</a></li>
+<li><a href="#Perils_of_repeating_arguments"><span class="toc-section-number">4.13.1.2</span> Perils of repeating arguments</a></li>
+<li><a href="#Variable-length_argument_lists"><span class="toc-section-number">4.13.1.3</span> Variable-length argument lists</a></li>
+<li><a href="#macros-vs.-inline-functions"><span class="toc-section-number">4.13.1.4</span> Macros vs. inline functions</a></li>
+</ul></li>
+<li><a href="#Multiple_macros"><span class="toc-section-number">4.13.2</span> Macros that include other macros</a></li>
+<li><a href="#Macro_tricks"><span class="toc-section-number">4.13.3</span> More specialized macros</a><ul>
+<li><a href="#Multiple_expressions_in_a_macro"><span class="toc-section-number">4.13.3.1</span> Multiple expressions in a macro</a></li>
+<li><a href="#nonSyntacticMacros"><span class="toc-section-number">4.13.3.2</span> Non-syntactic macros</a></li>
+<li><a href="#Multiple_statements_in_one_macro"><span class="toc-section-number">4.13.3.3</span> Multiple statements in one macro</a></li>
+<li><a href="#String_expansion"><span class="toc-section-number">4.13.3.4</span> String expansion</a></li>
+<li><a href="#Big_macros"><span class="toc-section-number">4.13.3.5</span> Big macros</a></li>
+</ul></li>
+<li><a href="#ifdef"><span class="toc-section-number">4.13.4</span> Conditional compilation</a></li>
+<li><a href="#defining-macros-on-the-command-line"><span class="toc-section-number">4.13.5</span> Defining macros on the command line</a></li>
+<li><a href="#the-if-directive"><span class="toc-section-number">4.13.6</span> The <code>#if</code> directive</a></li>
+<li><a href="#Debugging_macro_expansions"><span class="toc-section-number">4.13.7</span> Debugging macro expansions</a></li>
+<li><a href="#Can_a_macro_call_a_preprocessor_command.3F"><span class="toc-section-number">4.13.8</span> Can a macro call a preprocessor command?</a></li>
+</ul></li>
+</ul></li>
+<li><a href="#dataStructuresAndProgrammingTechniques"><span class="toc-section-number">5</span> Data structures and programming techniques</a><ul>
+<li><a href="#asymptoticNotation"><span class="toc-section-number">5.1</span> Asymptotic notation</a><ul>
+<li><a href="#two-sorting-algorithms"><span class="toc-section-number">5.1.1</span> Two sorting algorithms</a></li>
+<li><a href="#big-o-to-the-rescue"><span class="toc-section-number">5.1.2</span> Big-O to the rescue</a></li>
+<li><a href="#asymptotic-cost-of-programs"><span class="toc-section-number">5.1.3</span> Asymptotic cost of programs</a></li>
+<li><a href="#other-variants-of-asymptotic-notation"><span class="toc-section-number">5.1.4</span> Other variants of asymptotic notation</a></li>
+</ul></li>
+<li><a href="#linkedLists"><span class="toc-section-number">5.2</span> Linked lists</a><ul>
+<li><a href="#stacks"><span class="toc-section-number">5.2.1</span> Stacks</a><ul>
+<li><a href="#Building_a_stack_out_of_an_array"><span class="toc-section-number">5.2.1.1</span> Building a stack out of an array</a></li>
+</ul></li>
+<li><a href="#queues"><span class="toc-section-number">5.2.2</span> Queues</a></li>
+<li><a href="#Looping_over_a_linked_list"><span class="toc-section-number">5.2.3</span> Looping over a linked list</a></li>
+<li><a href="#Looping_over_a_linked_list_backwards"><span class="toc-section-number">5.2.4</span> Looping over a linked list backwards</a></li>
+<li><a href="#deques"><span class="toc-section-number">5.2.5</span> Deques and doubly-linked lists</a><ul>
+<li><a href="#ringBuffers"><span class="toc-section-number">5.2.5.1</span> Alternate implementation using a ring buffer</a></li>
+</ul></li>
+<li><a href="#Circular_linked_lists"><span class="toc-section-number">5.2.6</span> Circular linked lists</a></li>
+<li><a href="#What_linked_lists_are_and_are_not_good_for"><span class="toc-section-number">5.2.7</span> What linked lists are and are not good for</a></li>
+<li><a href="#Further_reading"><span class="toc-section-number">5.2.8</span> Further reading</a></li>
+</ul></li>
+<li><a href="#abstractDataTypes"><span class="toc-section-number">5.3</span> Abstract data types</a><ul>
+<li><a href="#abstractDataTypeExample"><span class="toc-section-number">5.3.1</span> A sequence type</a><ul>
+<li><a href="#Interface"><span class="toc-section-number">5.3.1.1</span> Interface</a></li>
+<li><a href="#adtImplementation"><span class="toc-section-number">5.3.1.2</span> Implementation</a></li>
+<li><a href="#Compiling_and_linking"><span class="toc-section-number">5.3.1.3</span> Compiling and linking</a></li>
+</ul></li>
+<li><a href="#Designing_abstract_data_types"><span class="toc-section-number">5.3.2</span> Designing abstract data types</a><ul>
+<li><a href="#Parnas.27s_Principle"><span class="toc-section-number">5.3.2.1</span> Parnas's Principle</a></li>
+<li><a href="#When_to_build_an_abstract_data_type"><span class="toc-section-number">5.3.2.2</span> When to build an abstract data type</a></li>
+</ul></li>
+</ul></li>
+<li><a href="#hashTables"><span class="toc-section-number">5.4</span> Hash tables</a><ul>
+<li><a href="#dictionaries"><span class="toc-section-number">5.4.1</span> Dictionary data types</a></li>
+<li><a href="#Basics_of_hashing"><span class="toc-section-number">5.4.2</span> Basics of hashing</a></li>
+<li><a href="#Resolving_collisions"><span class="toc-section-number">5.4.3</span> Resolving collisions</a><ul>
+<li><a href="#Chaining"><span class="toc-section-number">5.4.3.1</span> Chaining</a></li>
+<li><a href="#Open_addressing"><span class="toc-section-number">5.4.3.2</span> Open addressing</a></li>
+</ul></li>
+<li><a href="#Choosing_a_hash_function"><span class="toc-section-number">5.4.4</span> Choosing a hash function</a><ul>
+<li><a href="#Division_method"><span class="toc-section-number">5.4.4.1</span> Division method</a></li>
+<li><a href="#Multiplication_method"><span class="toc-section-number">5.4.4.2</span> Multiplication method</a></li>
+<li><a href="#Universal_hashing"><span class="toc-section-number">5.4.4.3</span> Universal hashing</a></li>
+</ul></li>
+<li><a href="#Maintaining_a_constant_load_factor"><span class="toc-section-number">5.4.5</span> Maintaining a constant load factor</a></li>
+<li><a href="#Examples"><span class="toc-section-number">5.4.6</span> Examples</a><ul>
+<li><a href="#A_low-overhead_hash_table_using_open_addressing"><span class="toc-section-number">5.4.6.1</span> A low-overhead hash table using open addressing</a></li>
+<li><a href="#A_string_to_string_dictionary_using_chaining"><span class="toc-section-number">5.4.6.2</span> A string to string dictionary using chaining</a></li>
+</ul></li>
+</ul></li>
+<li><a href="#genericContainers"><span class="toc-section-number">5.5</span> Generic containers</a><ul>
+<li><a href="#Generic_dictionary:_interface"><span class="toc-section-number">5.5.1</span> Generic dictionary: interface</a></li>
+<li><a href="#genericDictionaryImplementation"><span class="toc-section-number">5.5.2</span> Generic dictionary: implementation</a></li>
+</ul></li>
+<li><a href="#recursion"><span class="toc-section-number">5.6</span> Recursion</a><ul>
+<li><a href="#Example_of_recursion_in_C"><span class="toc-section-number">5.6.1</span> Example of recursion in C</a></li>
+<li><a href="#Common_problems_with_recursion"><span class="toc-section-number">5.6.2</span> Common problems with recursion</a><ul>
+<li><a href="#Omitting_the_base_case"><span class="toc-section-number">5.6.2.1</span> Omitting the base case</a></li>
+<li><a href="#Blowing_out_the_stack"><span class="toc-section-number">5.6.2.2</span> Blowing out the stack</a></li>
+<li><a href="#Failure_to_make_progress"><span class="toc-section-number">5.6.2.3</span> Failure to make progress</a></li>
+</ul></li>
+<li><a href="#tailRecursion"><span class="toc-section-number">5.6.3</span> Tail-recursion and iteration</a><ul>
+<li><a href="#binarySearch"><span class="toc-section-number">5.6.3.1</span> Binary search: recursive and iterative versions</a></li>
+</ul></li>
+<li><a href="#mergesort"><span class="toc-section-number">5.6.4</span> Mergesort: a recursive sorting algorithm</a></li>
+<li><a href="#asymptotic-complexity-of-recursive-functions"><span class="toc-section-number">5.6.5</span> Asymptotic complexity of recursive functions</a></li>
+</ul></li>
+<li><a href="#binaryTrees"><span class="toc-section-number">5.7</span> Binary trees</a><ul>
+<li><a href="#Tree_basics"><span class="toc-section-number">5.7.1</span> Tree basics</a></li>
+<li><a href="#Binary_tree_implementations"><span class="toc-section-number">5.7.2</span> Binary tree implementations</a></li>
+<li><a href="#The_canonical_binary_tree_algorithm"><span class="toc-section-number">5.7.3</span> The canonical binary tree algorithm</a></li>
+<li><a href="#Nodes_vs_leaves"><span class="toc-section-number">5.7.4</span> Nodes vs leaves</a></li>
+<li><a href="#Special_classes_of_binary_trees"><span class="toc-section-number">5.7.5</span> Special classes of binary trees</a></li>
+</ul></li>
+<li><a href="#heaps"><span class="toc-section-number">5.8</span> Heaps</a><ul>
+<li><a href="#priorityQueues"><span class="toc-section-number">5.8.1</span> Priority queues</a></li>
+<li><a href="#Expensive_implementations_of_priority_queues"><span class="toc-section-number">5.8.2</span> Expensive implementations of priority queues</a></li>
+<li><a href="#heapStructure"><span class="toc-section-number">5.8.3</span> Structure of a heap</a></li>
+<li><a href="#Packed_heaps"><span class="toc-section-number">5.8.4</span> Packed heaps</a></li>
+<li><a href="#Bottom-up_heapification"><span class="toc-section-number">5.8.5</span> Bottom-up heapification</a></li>
+<li><a href="#heapSort"><span class="toc-section-number">5.8.6</span> Heapsort</a></li>
+<li><a href="#heapMoreInformation"><span class="toc-section-number">5.8.7</span> More information</a></li>
+</ul></li>
+<li><a href="#binarySearchTrees"><span class="toc-section-number">5.9</span> Binary search trees</a><ul>
+<li><a href="#Searching_for_a_node"><span class="toc-section-number">5.9.1</span> Searching for a node</a></li>
+<li><a href="#Inserting_a_new_node"><span class="toc-section-number">5.9.2</span> Inserting a new node</a></li>
+<li><a href="#deleting-a-node"><span class="toc-section-number">5.9.3</span> Deleting a node</a></li>
+<li><a href="#Costs"><span class="toc-section-number">5.9.4</span> Costs</a></li>
+</ul></li>
+<li><a href="#augmentedTrees"><span class="toc-section-number">5.10</span> Augmented trees</a><ul>
+<li><a href="#applications"><span class="toc-section-number">5.10.1</span> Applications</a></li>
+</ul></li>
+<li><a href="#balancedTrees"><span class="toc-section-number">5.11</span> Balanced trees</a><ul>
+<li><a href="#treeRotations"><span class="toc-section-number">5.11.1</span> Tree rotations</a></li>
+<li><a href="#AVLtrees"><span class="toc-section-number">5.11.2</span> AVL trees</a><ul>
+<li><a href="#avlTreeImplementation"><span class="toc-section-number">5.11.2.1</span> Sample implementation</a></li>
+</ul></li>
+<li><a href="#A2.2BIBM-3_trees"><span class="toc-section-number">5.11.3</span> 2–3 trees</a></li>
+<li><a href="#redBlackTrees"><span class="toc-section-number">5.11.4</span> Red-black trees</a></li>
+<li><a href="#B-trees"><span class="toc-section-number">5.11.5</span> B-trees</a></li>
+<li><a href="#splayTrees"><span class="toc-section-number">5.11.6</span> Splay trees</a><ul>
+<li><a href="#how-splaying-works"><span class="toc-section-number">5.11.6.1</span> How splaying works</a></li>
+<li><a href="#splayTreeAnalysis"><span class="toc-section-number">5.11.6.2</span> Analysis</a></li>
+<li><a href="#other-operations"><span class="toc-section-number">5.11.6.3</span> Other operations</a></li>
+<li><a href="#top-down-splaying"><span class="toc-section-number">5.11.6.4</span> Top-down splaying</a></li>
+<li><a href="#splayTreeImplementation"><span class="toc-section-number">5.11.6.5</span> An implementation</a></li>
+<li><a href="#splayTreesMoreInformation"><span class="toc-section-number">5.11.6.6</span> More information</a></li>
+</ul></li>
+<li><a href="#scapegoatTrees"><span class="toc-section-number">5.11.7</span> Scapegoat trees</a></li>
+<li><a href="#skip-lists"><span class="toc-section-number">5.11.8</span> Skip lists</a></li>
+<li><a href="#treeImplementations"><span class="toc-section-number">5.11.9</span> Implementations</a></li>
+</ul></li>
+<li><a href="#graphs"><span class="toc-section-number">5.12</span> Graphs</a><ul>
+<li><a href="#graphDefinitions"><span class="toc-section-number">5.12.1</span> Basic definitions</a></li>
+<li><a href="#Why_graphs_are_useful"><span class="toc-section-number">5.12.2</span> Why graphs are useful</a></li>
+<li><a href="#Operations_on_graphs"><span class="toc-section-number">5.12.3</span> Operations on graphs</a></li>
+<li><a href="#Representations_of_graphs"><span class="toc-section-number">5.12.4</span> Representations of graphs</a><ul>
+<li><a href="#Adjacency_matrices"><span class="toc-section-number">5.12.4.1</span> Adjacency matrices</a></li>
+<li><a href="#Adjacency_lists"><span class="toc-section-number">5.12.4.2</span> Adjacency lists</a><ul>
+<li><a href="#An_implementation"><span class="toc-section-number">5.12.4.2.1</span> An implementation</a></li>
+</ul></li>
+<li><a href="#Implicit_representations"><span class="toc-section-number">5.12.4.3</span> Implicit representations</a></li>
+</ul></li>
+<li><a href="#graphSearch"><span class="toc-section-number">5.12.5</span> Searching for paths in a graph</a><ul>
+<li><a href="#graphSearchImplementation"><span class="toc-section-number">5.12.5.1</span> Implementation of depth-first and breadth-first search</a></li>
+<li><a href="#combinedDFSBFS"><span class="toc-section-number">5.12.5.2</span> Combined implementation of depth-first and breadth-first search</a></li>
+<li><a href="#Other_variations_on_the_basic_algorithm"><span class="toc-section-number">5.12.5.3</span> Other variations on the basic algorithm</a></li>
+</ul></li>
+</ul></li>
+<li><a href="#dynamicProgramming"><span class="toc-section-number">5.13</span> Dynamic programming</a><ul>
+<li><a href="#Memoization"><span class="toc-section-number">5.13.1</span> Memoization</a></li>
+<li><a href="#Dynamic_programming"><span class="toc-section-number">5.13.2</span> Dynamic programming</a><ul>
+<li><a href="#More_examples"><span class="toc-section-number">5.13.2.1</span> More examples</a><ul>
+<li><a href="#Longest_increasing_subsequence"><span class="toc-section-number">5.13.2.1.1</span> Longest increasing subsequence</a></li>
+<li><a href="#All-pairs_shortest_paths"><span class="toc-section-number">5.13.2.1.2</span> All-pairs shortest paths</a></li>
+<li><a href="#longestCommonSubsequence"><span class="toc-section-number">5.13.2.1.3</span> Longest common subsequence</a></li>
+</ul></li>
+</ul></li>
+</ul></li>
+<li><a href="#randomization"><span class="toc-section-number">5.14</span> Randomization</a><ul>
+<li><a href="#Generating_random_values_in_C"><span class="toc-section-number">5.14.1</span> Generating random values in C</a><ul>
+<li><a href="#The_rand_function_from_the_standard_library"><span class="toc-section-number">5.14.1.1</span> The <code>rand</code> function from the standard library</a><ul>
+<li><a href="#supplying-a-seed-with-srand"><span class="toc-section-number">5.14.1.1.1</span> Supplying a seed with <code>srand</code></a></li>
+</ul></li>
+<li><a href="#Better_pseudorandom_number_generators"><span class="toc-section-number">5.14.1.2</span> Better pseudorandom number generators</a></li>
+<li><a href="#Random_numbers_without_the_pseudo"><span class="toc-section-number">5.14.1.3</span> Random numbers without the pseudo</a></li>
+<li><a href="#RANDMAX"><span class="toc-section-number">5.14.1.4</span> Range issues</a></li>
+</ul></li>
+<li><a href="#Randomized_algorithms"><span class="toc-section-number">5.14.2</span> Randomized algorithms</a><ul>
+<li><a href="#Randomized_search"><span class="toc-section-number">5.14.2.1</span> Randomized search</a></li>
+<li><a href="#quicksort"><span class="toc-section-number">5.14.2.2</span> Quickselect and quicksort</a></li>
+</ul></li>
+<li><a href="#randomizedDataStructures"><span class="toc-section-number">5.14.3</span> Randomized data structures</a><ul>
+<li><a href="#skipLists"><span class="toc-section-number">5.14.3.1</span> Skip lists</a></li>
+<li><a href="#Universal_hash_families"><span class="toc-section-number">5.14.3.2</span> Universal hash families</a></li>
+</ul></li>
+</ul></li>
+<li><a href="#stringProcessing"><span class="toc-section-number">5.15</span> String processing</a><ul>
+<li><a href="#radixSearch"><span class="toc-section-number">5.15.1</span> Radix search</a><ul>
+<li><a href="#Tries"><span class="toc-section-number">5.15.1.1</span> Tries</a><ul>
+<li><a href="#Searching_a_trie"><span class="toc-section-number">5.15.1.1.1</span> Searching a trie</a></li>
+<li><a href="#Inserting_a_new_element_into_a_trie"><span class="toc-section-number">5.15.1.1.2</span> Inserting a new element into a trie</a></li>
+<li><a href="#trieImplementation"><span class="toc-section-number">5.15.1.1.3</span> Implementation</a></li>
+</ul></li>
+<li><a href="#Patricia_trees"><span class="toc-section-number">5.15.1.2</span> Patricia trees</a></li>
+<li><a href="#Ternary_search_trees"><span class="toc-section-number">5.15.1.3</span> Ternary search trees</a></li>
+<li><a href="#treesMoreInformation"><span class="toc-section-number">5.15.1.4</span> More information</a></li>
+</ul></li>
+<li><a href="#radixSort"><span class="toc-section-number">5.15.2</span> Radix sort</a><ul>
+<li><a href="#Bucket_sort"><span class="toc-section-number">5.15.2.1</span> Bucket sort</a></li>
+<li><a href="#Classic_LSB_radix_sort"><span class="toc-section-number">5.15.2.2</span> Classic LSB radix sort</a></li>
+<li><a href="#MSB_radix_sort"><span class="toc-section-number">5.15.2.3</span> MSB radix sort</a><ul>
+<li><a href="#Issues_with_recursion_depth"><span class="toc-section-number">5.15.2.3.1</span> Issues with recursion depth</a></li>
+<li><a href="#Implementing_the_buckets"><span class="toc-section-number">5.15.2.3.2</span> Implementing the buckets</a></li>
+<li><a href="#Further_optimization"><span class="toc-section-number">5.15.2.3.3</span> Further optimization</a></li>
+<li><a href="#radixSortImplementation"><span class="toc-section-number">5.15.2.3.4</span> Sample implementation</a></li>
+</ul></li>
+</ul></li>
+</ul></li>
+</ul></li>
+<li><a href="#other-topics-not-covered-in-detail-in-2015"><span class="toc-section-number">6</span> Other topics not covered in detail in 2015</a><ul>
+<li><a href="#more-applications-of-function-pointers"><span class="toc-section-number">6.1</span> More applications of function pointers</a><ul>
+<li><a href="#iterators"><span class="toc-section-number">6.1.1</span> Iterators</a><ul>
+<li><a href="#Option_1:_Function_that_returns_a_sequence"><span class="toc-section-number">6.1.1.1</span> Option 1: Function that returns a sequence</a></li>
+<li><a href="#Option_2:_Iterator_with_first.2Fdone.2Fnext_operations"><span class="toc-section-number">6.1.1.2</span> Option 2: Iterator with first/done/next operations</a></li>
+<li><a href="#Option_3:_Iterator_with_function_argument"><span class="toc-section-number">6.1.1.3</span> Option 3: Iterator with function argument</a></li>
+</ul></li>
+<li><a href="#closures"><span class="toc-section-number">6.1.2</span> Closures</a></li>
+<li><a href="#Objects"><span class="toc-section-number">6.1.3</span> Objects</a></li>
+</ul></li>
+<li><a href="#suffixArrays"><span class="toc-section-number">6.2</span> Suffix arrays</a><ul>
+<li><a href="#Why_do_we_want_to_do_this.3F"><span class="toc-section-number">6.2.1</span> Why do we want to do this?</a></li>
+<li><a href="#String_search_algorithms"><span class="toc-section-number">6.2.2</span> String search algorithms</a></li>
+<li><a href="#Suffix_trees_and_suffix_arrays"><span class="toc-section-number">6.2.3</span> Suffix trees and suffix arrays</a><ul>
+<li><a href="#Building_a_suffix_array"><span class="toc-section-number">6.2.3.1</span> Building a suffix array</a></li>
+<li><a href="#Searching_a_suffix_array"><span class="toc-section-number">6.2.3.2</span> Searching a suffix array</a></li>
+</ul></li>
+</ul></li>
+<li><a href="#Burrows-Wheeler_transform"><span class="toc-section-number">6.3</span> Burrows-Wheeler transform</a><ul>
+<li><a href="#Suffix_arrays_and_the_Burrows-Wheeler_transform"><span class="toc-section-number">6.3.1</span> Suffix arrays and the Burrows-Wheeler transform</a></li>
+<li><a href="#sample-implementation"><span class="toc-section-number">6.3.2</span> Sample implementation</a></li>
+</ul></li>
+<li><a href="#cplusplus"><span class="toc-section-number">6.4</span> C++</a><ul>
+<li><a href="#Hello_world"><span class="toc-section-number">6.4.1</span> Hello world</a></li>
+<li><a href="#References"><span class="toc-section-number">6.4.2</span> References</a></li>
+<li><a href="#Function_overloading"><span class="toc-section-number">6.4.3</span> Function overloading</a></li>
+<li><a href="#Classes"><span class="toc-section-number">6.4.4</span> Classes</a></li>
+<li><a href="#Operator_overloading"><span class="toc-section-number">6.4.5</span> Operator overloading</a></li>
+<li><a href="#Templates"><span class="toc-section-number">6.4.6</span> Templates</a></li>
+<li><a href="#Exceptions"><span class="toc-section-number">6.4.7</span> Exceptions</a></li>
+<li><a href="#Storage_allocation"><span class="toc-section-number">6.4.8</span> Storage allocation</a><ul>
+<li><a href="#Storage_allocation_inside_objects"><span class="toc-section-number">6.4.8.1</span> Storage allocation inside objects</a></li>
+</ul></li>
+<li><a href="#Standard_library"><span class="toc-section-number">6.4.9</span> Standard library</a></li>
+<li><a href="#Things_we_haven.27t_talked_about"><span class="toc-section-number">6.4.10</span> Things we haven't talked about</a></li>
+</ul></li>
+<li><a href="#testingDuringDevelopment"><span class="toc-section-number">6.5</span> Testing during development</a><ul>
+<li><a href="#unitTests"><span class="toc-section-number">6.5.1</span> Unit tests</a><ul>
+<li><a href="#what-to-put-in-the-test-code"><span class="toc-section-number">6.5.1.1</span> What to put in the test code</a></li>
+<li><a href="#example"><span class="toc-section-number">6.5.1.2</span> Example</a></li>
+</ul></li>
+<li><a href="#test-harnesses"><span class="toc-section-number">6.5.2</span> Test harnesses</a><ul>
+<li><a href="#Module_interface"><span class="toc-section-number">6.5.2.1</span> Module interface</a><ul>
+<li><a href="#stack.h"><span class="toc-section-number">6.5.2.1.1</span> stack.h</a></li>
+</ul></li>
+<li><a href="#Test_code"><span class="toc-section-number">6.5.2.2</span> Test code</a><ul>
+<li><a href="#test-stack.c"><span class="toc-section-number">6.5.2.2.1</span> test-stack.c</a></li>
+</ul></li>
+<li><a href="#Makefile"><span class="toc-section-number">6.5.2.3</span> Makefile</a><ul>
+<li><a href="#Makefile-1"><span class="toc-section-number">6.5.2.3.1</span> Makefile</a></li>
+</ul></li>
+</ul></li>
+<li><a href="#Stub_implementation"><span class="toc-section-number">6.5.3</span> Stub implementation</a><ul>
+<li><a href="#stack.c"><span class="toc-section-number">6.5.3.1</span> stack.c</a></li>
+</ul></li>
+<li><a href="#Bounded-space_implementation"><span class="toc-section-number">6.5.4</span> Bounded-space implementation</a><ul>
+<li><a href="#stack.c-1"><span class="toc-section-number">6.5.4.1</span> stack.c</a></li>
+</ul></li>
+<li><a href="#First_fix"><span class="toc-section-number">6.5.5</span> First fix</a></li>
+<li><a href="#Final_version"><span class="toc-section-number">6.5.6</span> Final version</a><ul>
+<li><a href="#stack.c-2"><span class="toc-section-number">6.5.6.1</span> stack.c</a></li>
+</ul></li>
+<li><a href="#Moral"><span class="toc-section-number">6.5.7</span> Moral</a></li>
+<li><a href="#Appendix:_Test_macros"><span class="toc-section-number">6.5.8</span> Appendix: Test macros</a></li>
+</ul></li>
+<li><a href="#algorithmDesignTechniques"><span class="toc-section-number">6.6</span> Algorithm design techniques</a><ul>
+<li><a href="#Basic_principles_of_algorithm_design"><span class="toc-section-number">6.6.1</span> Basic principles of algorithm design</a></li>
+<li><a href="#algorithmDesignTechniquesClassification"><span class="toc-section-number">6.6.2</span> Specific techniques</a></li>
+<li><a href="#Example:_Finding_the_maximum"><span class="toc-section-number">6.6.3</span> Example: Finding the maximum</a></li>
+<li><a href="#algorithmDesignSorting"><span class="toc-section-number">6.6.4</span> Example: Sorting</a></li>
+</ul></li>
+<li><a href="#bitManipulation"><span class="toc-section-number">6.7</span> Bit manipulation</a></li>
+<li><a href="#persistence"><span class="toc-section-number">6.8</span> Persistence</a><ul>
+<li><a href="#A_simple_solution_using_text_files"><span class="toc-section-number">6.8.1</span> A simple solution using text files</a></li>
+<li><a href="#Using_a_binary_file"><span class="toc-section-number">6.8.2</span> Using a binary file</a></li>
+<li><a href="#A_version_that_updates_the_file_in_place"><span class="toc-section-number">6.8.3</span> A version that updates the file in place</a></li>
+<li><a href="#An_even_better_version_using_mmap"><span class="toc-section-number">6.8.4</span> An even better version using mmap</a></li>
+<li><a href="#Concurrency_and_fault-tolerance_issues:_ACIDity"><span class="toc-section-number">6.8.5</span> Concurrency and fault-tolerance issues: ACIDity</a></li>
+</ul></li>
+</ul></li>
+<li><a href="#whatNext"><span class="toc-section-number">7</span> What next?</a><ul>
+<li><a href="#What.27s_wrong_with_C"><span class="toc-section-number">7.1</span> What's wrong with C</a></li>
+<li><a href="#What_C.2B-.2B-_fixes"><span class="toc-section-number">7.2</span> What C++ fixes</a></li>
+<li><a href="#other-c-like-languages"><span class="toc-section-number">7.3</span> Other C-like languages</a></li>
+<li><a href="#Scripting_languages"><span class="toc-section-number">7.4</span> Scripting languages</a></li>
+</ul></li>
+<li><a href="#assignments"><span class="toc-section-number">8</span> Assignments</a><ul>
+<li><a href="#hw1"><span class="toc-section-number">8.1</span> Assignment 1, due Thursday 2015-01-29, at 11:00pm</a><ul>
+<li><a href="#bureaucratic-part"><span class="toc-section-number">8.1.1</span> Bureaucratic part</a></li>
+<li><a href="#a-rotten-cipher"><span class="toc-section-number">8.1.2</span> A rotten cipher</a></li>
+<li><a href="#your-task"><span class="toc-section-number">8.1.3</span> Your task</a></li>
+<li><a href="#hints"><span class="toc-section-number">8.1.4</span> Hints</a></li>
+<li><a href="#testing-your-assignment"><span class="toc-section-number">8.1.5</span> Testing your assignment</a></li>
+<li><a href="#submitting-your-assignment"><span class="toc-section-number">8.1.6</span> Submitting your assignment</a></li>
+<li><a href="#hw1Solution"><span class="toc-section-number">8.1.7</span> Sample solution</a></li>
+</ul></li>
+<li><a href="#hw2"><span class="toc-section-number">8.2</span> Assignment 2, due Wednesday 2015-02-04, at 11:00pm</a><ul>
+<li><a href="#opening-a-safe"><span class="toc-section-number">8.2.1</span> Opening a safe</a></li>
+<li><a href="#submitting-your-assignment-1"><span class="toc-section-number">8.2.2</span> Submitting your assignment</a></li>
+<li><a href="#hw2valgrind"><span class="toc-section-number">8.2.3</span> Valgrind</a></li>
+<li><a href="#hw2Solution"><span class="toc-section-number">8.2.4</span> Sample solution</a></li>
+</ul></li>
+<li><a href="#hw3"><span class="toc-section-number">8.3</span> Assignment 3, due Wednesday 2015-02-11, at 11:00pm</a><ul>
+<li><a href="#quadratic-letter-sequences"><span class="toc-section-number">8.3.1</span> Quadratic letter sequences</a></li>
+<li><a href="#your-task-1"><span class="toc-section-number">8.3.2</span> Your task</a></li>
+<li><a href="#submitting-your-assignment-2"><span class="toc-section-number">8.3.3</span> Submitting your assignment</a></li>
+<li><a href="#hw3Solution"><span class="toc-section-number">8.3.4</span> Sample solution</a></li>
+</ul></li>
+<li><a href="#hw4"><span class="toc-section-number">8.4</span> Assignment 4, due Wednesday 2015-02-18, at 11:00pm</a><ul>
+<li><a href="#an-ascii-art-compositor"><span class="toc-section-number">8.4.1</span> An ASCII art compositor</a></li>
+<li><a href="#submitting-your-assignment-3"><span class="toc-section-number">8.4.2</span> Submitting your assignment</a></li>
+<li><a href="#notes"><span class="toc-section-number">8.4.3</span> Notes</a><ul>
+<li><a href="#input"><span class="toc-section-number">8.4.3.1</span> Input</a></li>
+<li><a href="#output"><span class="toc-section-number">8.4.3.2</span> Output</a></li>
+<li><a href="#general"><span class="toc-section-number">8.4.3.3</span> General</a></li>
+</ul></li>
+<li><a href="#hw4Solution"><span class="toc-section-number">8.4.4</span> Sample solution</a></li>
+</ul></li>
+<li><a href="#hw5"><span class="toc-section-number">8.5</span> Assignment 5, due Wednesday 2015-02-25, at 11:00pm</a><ul>
+<li><a href="#build-a-turing-machine"><span class="toc-section-number">8.5.1</span> Build a Turing machine!</a></li>
+<li><a href="#example-1"><span class="toc-section-number">8.5.2</span> Example</a></li>
+<li><a href="#your-task-2"><span class="toc-section-number">8.5.3</span> Your task</a></li>
+<li><a href="#submitting-your-assignment-4"><span class="toc-section-number">8.5.4</span> Submitting your assignment</a></li>
+<li><a href="#hw5Solution"><span class="toc-section-number">8.5.5</span> Sample solution</a></li>
+</ul></li>
+<li><a href="#hw6"><span class="toc-section-number">8.6</span> Assignment 6, due Wednesday 2015-03-25, at 11:00pm</a><ul>
+<li><a href="#sinking-ships"><span class="toc-section-number">8.6.1</span> Sinking ships</a></li>
+<li><a href="#things-to-watch-out-for"><span class="toc-section-number">8.6.2</span> Things to watch out for</a></li>
+<li><a href="#the-testships-program"><span class="toc-section-number">8.6.3</span> The <code>testShips</code> program</a></li>
+<li><a href="#submitting-your-assignment-5"><span class="toc-section-number">8.6.4</span> Submitting your assignment</a></li>
+<li><a href="#hw6-2015-source-files"><span class="toc-section-number">8.6.5</span> Provided source files</a></li>
+<li><a href="#hw6Solution"><span class="toc-section-number">8.6.6</span> Sample solution</a></li>
+</ul></li>
+<li><a href="#hw7"><span class="toc-section-number">8.7</span> Assignment 7, due Wednesday 2015-04-01, at 11:00pm</a><ul>
+<li><a href="#solitaire-with-big-cards"><span class="toc-section-number">8.7.1</span> Solitaire with big cards</a></li>
+<li><a href="#explanation-of-the-testing-program"><span class="toc-section-number">8.7.2</span> Explanation of the testing program</a></li>
+<li><a href="#submitting-your-assignment-6"><span class="toc-section-number">8.7.3</span> Submitting your assignment</a></li>
+<li><a href="#hw7Solution"><span class="toc-section-number">8.7.4</span> Sample solution</a></li>
+</ul></li>
+<li><a href="#hw8"><span class="toc-section-number">8.8</span> Assignment 8, due Wednesday 2015-04-08, at 11:00pm</a><ul>
+<li><a href="#an-ordered-set"><span class="toc-section-number">8.8.1</span> An ordered set</a></li>
+<li><a href="#the-testorderedset-wrapper"><span class="toc-section-number">8.8.2</span> The <code>testOrderedSet</code> wrapper</a></li>
+<li><a href="#hw8submission"><span class="toc-section-number">8.8.3</span> Submitting your assignment</a></li>
+<li><a href="#hw8Solution"><span class="toc-section-number">8.8.4</span> Sample solution</a></li>
+</ul></li>
+<li><a href="#hw9"><span class="toc-section-number">8.9</span> Assignment 9, due Wednesday 2015-04-15, at 11:00pm</a><ul>
+<li><a href="#finding-a-cycle-in-a-maze"><span class="toc-section-number">8.9.1</span> Finding a cycle in a maze</a></li>
+<li><a href="#input-and-output-format"><span class="toc-section-number">8.9.2</span> Input and output format</a></li>
+<li><a href="#submitting-and-testing-your-program"><span class="toc-section-number">8.9.3</span> Submitting and testing your program</a></li>
+<li><a href="#hw9solution"><span class="toc-section-number">8.9.4</span> Sample solution</a></li>
+</ul></li>
+</ul></li>
+<li><a href="#codingHints"><span class="toc-section-number">9</span> Common C coding and debugging issues</a></li>
+</ul>
+</div>
+<h1 id="courseAdministration"><span class="header-section-number">1</span> Course administration</h1>
+<h2 id="index"><span class="header-section-number">1.1</span> Overview</h2>
+<p>This is the course information for CPSC 223: <em>Data Structures and Programming Techniques</em> for the Spring 2015 semester. This document is available in two formats, both of which should contain the same information:</p>
+<ul>
+<li><a href="http://www.cs.yale.edu/homes/aspnes/classes/223/notes.html">HTML</a></li>
+<li><a href="http://www.cs.yale.edu/homes/aspnes/classes/223/notes.pdf">PDF</a></li>
+</ul>
+<p>Code examples can be downloaded from links in the text, or can be found in the <a href="http://www.cs.yale.edu/homes/aspnes/classes/223/examples/">examples directory</a>.</p>
+<p>The links above point to <code>www.cs.yale.edu</code>. In case this machine is down, a backup copy of these files can be found at <a href="https://www.dropbox.com/sh/omg9qcxkxeiam2o/AACRAJOTj8af6V7RC1cXBHjQa?dl=0" class="uri">https://www.dropbox.com/sh/omg9qcxkxeiam2o/AACRAJOTj8af6V7RC1cXBHjQa?dl=0</a>.</p>
+<p>This document is a work in progress, and is likely to change frequently as the semester progresses.</p>
+<h3 id="license"><span class="header-section-number">1.1.1</span> License</h3>
+<p>Copyright © 2002–2017 by James Aspnes. Distributed under a Creative Commons Attribution-ShareAlike 4.0 International license: <a href="https://creativecommons.org/licenses/by-sa/4.0/" class="uri">https://creativecommons.org/licenses/by-sa/4.0/</a>.</p>
+<h3 id="resources"><span class="header-section-number">1.1.2</span> Resources</h3>
+<ul>
+<li><a href="#schedule">Schedule</a>: list of lectures and events. Includes reading assignments and pointers to lecture notes.</li>
+<li><a href="http://www.cs.yale.edu/homes/aspnes/#calendar">Calendar</a>: shows office hours, lectures, and assignment deadlines.</li>
+<li><a href="#assignments">Assignments</a>: list of homeworks and exams.</li>
+<li><a href="http://cs.yale.edu/homes/aspnes/classes/223/notes.html">Notes</a>: notes on various topics relevant to the course.</li>
+<li><a href="#syllabus">Syllabus</a>.</li>
+<li><a href="https://piazza.com/yale/spring2015/cpsc223">Piazza</a>. This is a web-based question-and-answer system for communicating with course staff and other students.</li>
+<li><a href="http://www.cs.yale.edu/homes/aspnes/pinewiki/CS223.html">2012 web pages</a>: web pages for 2012 version of the course.</li>
+<li><a href="http://www.cs.usfca.edu/%7Egalles/visualization/Algorithms.html">Data structure visualizations</a>. Much better than the ASCII art (at best) illustrations you will find in this document.<a href="#fn1" class="footnoteRef" id="fnref1"><sup>1</sup></a></li>
+</ul>
+<h3 id="Documentation"><span class="header-section-number">1.1.3</span> Documentation</h3>
+<ul>
+<li><a href="#zoo">How to use the Zoo</a></li>
+<li><a href="http://zoo.cs.yale.edu/help/">Zoo help</a></li>
+<li><a href="#codingHints">Coding hints</a></li>
+<li>GNU <a href="http://www.delorie.com/gnu/docs/">Online Documentation</a>,
+<ul>
+<li><a href="http://www.delorie.com/gnu/docs/gcc/gcc_toc.html">gcc</a></li>
+<li><a href="http://www.delorie.com/gnu/docs/gdb/gdb_toc.html">gdb</a></li>
+<li><a href="http://www.gnu.org/software/ddd/manual/html_mono/ddd.html">ddd</a></li>
+<li><a href="http://www.delorie.com/gnu/docs/emacs/emacs_toc.html">emacs</a></li>
+</ul></li>
+<li>Frequently-asked questions (FAQ) for
+<ul>
+<li><a href="http://www.eskimo.com/%7Escs/C-faq.top.html">C</a></li>
+<li><a href="http://www.faqs.org/faqs/C-faq/abridged/">C (abridged)</a></li>
+<li><a href="http://www.faqs.org/faqs/unix-faq/faq/">Unix</a></li>
+<li><a href="http://www.faqs.org/faqs/GNU-Emacs-FAQ/">Emacs</a></li>
+</ul></li>
+<li><a href="http://www.lysator.liu.se/c/">Programming in C</a></li>
+<li><a href="http://valgrind.org/docs/">Valgrind documentation</a></li>
+<li><a href="http://www.mcsr.olemiss.edu/unixhelp/">UNIXhelp for Users</a></li>
+</ul>
+<h3 id="questions-and-comments"><span class="header-section-number">1.1.4</span> Questions and comments</h3>
+<p>Please feel free to send questions or comments on the class or anything connected to it to <a href="mailto:james.aspnes@gmail.com">james.aspnes@gmail.com</a>.</p>
+<p>For questions about individual assignments, you may be able to get a faster response using <a href="http://piazza.com/yale/spring2015/cpsc223">Piazza</a>.
+ Note that questions you ask there are visible to other students if not
+specifically marked private, so be careful about broadcasting your draft
+ solutions.</p>
+<h2 id="schedule"><span class="header-section-number">1.2</span> Lecture schedule</h2>
+<h3 id="topics-by-date"><span class="header-section-number">1.2.1</span> Topics by date</h3>
+<dl>
+<dt>2015-01-12</dt>
+<dd>Introduction. What the course is about. Getting started with C: running the compiler, the <code>main</code> function, integer data types, a few simple programs. Readings: <a href="#courseAdministration">Course administration</a>, <a href="#zoo">The Zoo and the Zoo Annex</a>, <a href="#linux">The Linux programming environment</a>, <a href="#CProgramStructure">Structure of a C program</a>, <a href="#basicIntegerTypes">Basic integer types</a>; Kernighan and Ritchie §§1.1 and 1.2.
+</dd>
+<dt>2015-01-14</dt>
+<dd>Arithmetic in C. Readings: <a href="#integerConstants">Integer constants</a>, <a href="#integerOperators">Integer operators</a>, <a href="#operatorPrecedence">Operator precedence</a>
+ (we didn't actually do the full operator precedence table in class, but
+ it's a nice summary of what operators are available, and if you don't
+like typing parentheses everywhere it's useful to have an idea of how
+precedence and associativity work); K&amp;R §§1.4, 2.2, 2.3, 2.5, 2.6,
+2.8, 2.9, and 2.12.
+</dd>
+<dt>2015-01-16</dt>
+<dd>Local variables and assignment operators. The <code>++</code> and <code>--</code> operators. More specialized operators: <code>,</code> and <code>?:</code>. I/O using <code>getchar</code> and <code>putchar</code>. Control structures: <code>if</code>, <code>switch</code>, <code>while</code>, <code>for</code>. Readings: <a href="#variables">Variables</a>, <a href="#statements">Statements</a> through <a href="#forLoop">The <code>for</code> loop</a>; K&amp;R §1.3, 1.5, 2.1, 2.4, and 3.1–3.6.
+</dd>
+<dt>2015-01-21</dt>
+<dd>Goto-like control structures: <code>break</code>, <code>continue</code>, <code>goto</code>, and <code>return</code>. Functions. Readings: Rest of [Statements]{#statements}, <a href="#functions">Functions</a>{#functions};
+ K&amp;R §3.7, 3.8, 4.1, and 4.5. Examples from lecture (with a bit of
+after-the-fact sprucing up) can be found in the <a href="http://cs.yale.edu/homes/aspnes/classes/223/examples/2015/lecture/2015-01-21/">examples directory</a>.
+</dd>
+<dt>2015-01-26</dt>
+<dd>Start of pointers and arrays: pointer types and pointer variables. The <code>&amp;</code> and <code>*</code> operators. Using a pointer to get a value out of a function. Array declarations. Preventing array modification with <code>const</code>. Storage allocation: <code>malloc</code>, <code>free</code>, and <code>realloc</code>. Readings: <a href="#pointers">Pointers</a> up through <a href="#arraysAndFunctions">Arrays and functions</a>; K&amp;R §5.1–5.4. <a href="http://cs.yale.edu/homes/aspnes/classes/223/examples/2015/lecture/2015-01-26/">Examples</a>.
+</dd>
+<dt>2015-01-28</dt>
+<dd>More on pointers and arrays: Multi-dimensional arrays, C99
+variable-length arrays. Function pointers. Finding storage allocation
+bugs using <a href="#valgrind"><code>valgrind</code></a>. Readings: Rest of <a href="#pointers">Pointers</a>, <a href="#valgrind">Valgrind</a>; K&amp;R §§5.6–5.9, 5.11. <a href="http://cs.yale.edu/homes/aspnes/classes/223/examples/2015/lecture/2015-01-28/">Examples from lecture</a>: original array-of-pointers-to-arrays implementation <a href="http://cs.yale.edu/homes/aspnes/classes/223/examples/2015/lecture/2015-01-28/array2dOriginal.c">array2dOriginal.c</a>, <code>valgrind</code>-approved version after removing <code>printArray2D</code> on uninitialized data <a href="http://cs.yale.edu/homes/aspnes/classes/223/examples/2015/lecture/2015-01-28/array2d.c">array2d.c</a>, buggy version demonstrating how <code>valgrind</code> complains about writing off the end of an array and doing multiple <code>free</code>s of the same block <a href="http://cs.yale.edu/homes/aspnes/classes/223/examples/2015/lecture/2015-01-28/array2dBad.c">array2dBad.c</a>.
+ An issue that came up in lecture is that all of these implementations
+are a little bit inefficient in that they allocate a separate block for
+each row, which means extra overhead for <code>malloc</code>s data and the possibility that the rows may be scattered throughout memory, causing issues with virtual memory paging. Here is <a href="http://cs.yale.edu/homes/aspnes/classes/223/examples/2015/lecture/2015-01-28/array2dPacked.c">yet another implementation</a> that gets space for both the array of row pointers and all rows with a single call to <code>malloc</code> and then does pointer arithmetic to slice the space up.<a href="#fn2" class="footnoteRef" id="fnref2"><sup>2</sup></a> There is also a <a href="http://cs.yale.edu/homes/aspnes/classes/223/examples/pointers/malloc2d.c">generic version</a> of the simple approach in the section on <a href="#multidimensionalArrays">multidimensional arrays</a>.
+</dd>
+<dt>2015-02-02</dt>
+<dd>Strings in C: null-terminated strings. What goes wrong if you forget to put on the null. Various library functions from <code>&lt;string.h&gt;</code> and how one might implement them. The perils of <code>gets</code> and bounded-size buffers, and how to use <code>malloc</code> and <code>realloc</code> to avoid them. Meaning of <code>argv</code>. Readings: <a href="#strings">Strings</a>; K&amp;R §§5.5, 5.10, B2. <a href="http://cs.yale.edu/homes/aspnes/classes/223/examples/2015/lecture/2015-02-02/">Examples from lecture</a>.
+</dd>
+<dt>2015-02-04</dt>
+<dd>Structured data types: <code>struct</code>s, <code>union</code>s, and <code>enum</code>s. Type aliases using <code>typedef</code>. Opaque <code>struct</code> definitions and separating interface from implementation. Readings: <a href="#structuredDataTypes">Structured data types</a>, <a href="#typedef"><code>typedef</code></a>; K&amp;R Chapter 6, §2.5 (for <code>enum</code>s). <a href="http://cs.yale.edu/homes/aspnes/classes/223/examples/2015/lecture/2015-02-04/">Examples from lecture</a>, plus a <a href="http://cs.yale.edu/homes/aspnes/classes/223/examples/2015/lecture/2015-02-04/intArray/">working version of the intArray implementation</a> together with the <a href="http://cs.yale.edu/homes/aspnes/classes/223/examples/2015/lecture/2015-02-04/intArray/stubs/intArrayStub.c">originally stubby intArray.c</a> and the <a href="http://cs.yale.edu/homes/aspnes/classes/223/examples/2015/lecture/2015-02-04/intArray/stubs/intArrayPartial.c">partial version from the end of lecture</a>.
+</dd>
+<dt>2015-02-09</dt>
+<dd>More C stuff: Makefiles. Floating-point arithmetic and the math
+library. Timing code with a profiler. Basics of file I/O. Readings: <a href="#make">Make</a>, <a href="#floatingPointTypes">Floating point types</a>, <a href="#performanceTuning">Performance tuning</a>, <a href="#IO">Input and output</a>; K&amp;R §§2.7 and 7.5, Appendix B4. <a href="http://cs.yale.edu/homes/aspnes/classes/223/examples/2015/lecture/2015-02-09/">Examples from lecture</a>.
+</dd>
+<dt>2015-02-11</dt>
+<dd>Start of data structures: efficiency of different data structures, linked lists. Readings: <a href="#asymptoticNotation">Asymptotic notation</a>, <a href="#linkedLists">Linked lists</a>. <a href="http://cs.yale.edu/homes/aspnes/classes/223/examples/2015/lecture/2015-02-11/">Examples from lecture</a> including improved <a href="http://cs.yale.edu/homes/aspnes/classes/223/examples/2015/lecture/2015-02-11/stack.c">stack.c</a> and working <a href="http://cs.yale.edu/homes/aspnes/classes/223/examples/2015/lecture/2015-02-11/queue.c">queue.c</a>.
+</dd>
+<dt>2015-02-16</dt>
+<dd>Invariants and representation functions for abstract data types. The
+ deque type, with two implementations: a circular doubly-linked list and
+ a ring buffer. Readings: <a href="#abstractDataTypes">Abstract data types</a>, <a href="#deques">deques</a>. <a href="http://cs.yale.edu/homes/aspnes/classes/223/examples/2015/lecture/2015-02-16/">Examples from lecture</a>.
+</dd>
+<dt>2015-02-18</dt>
+<dd>Hash Wednesday: set and map data types, hash tables. Readings: <a href="#hashTables">Hash tables</a>. <a href="http://cs.yale.edu/homes/aspnes/classes/223/examples/2015/lecture/2015-02-18/">Examples from lecture</a>.
+</dd>
+<dt>2015-02-23</dt>
+<dd>Various C preprocessor tricks: macros with arguments, string
+processing in macros, non-syntactic macros, conditional compilation.
+Readings: <a href="#macros">Macros</a>; K&amp;R Appendix A12.3. <a href="http://cs.yale.edu/homes/aspnes/classes/223/examples/2015/lecture/2015-02-23/">Examples from lecture</a>.
+</dd>
+<dt>2015-02-25</dt>
+<dd>Polymorphism in C: generic containers and object-oriented
+programming (of a sort) using structs full of function pointers. Example
+ of using <code>git</code> for version control (you will not be tested on version control). Readings: <a href="#genericContainers">Generic containers</a>, <a href="#versionControl">version control</a>. <a href="http://cs.yale.edu/homes/aspnes/classes/223/examples/2015/lecture/2015-02-23/">Examples from lecture</a>. Unlike the actual example from lecture, this version really works, instead of just inserting 0 over and over again.
+</dd>
+<dt>2015-03-02</dt>
+<dd>Recursion. Readings: <a href="#recursion">Recursion</a>. <a href="http://cs.yale.edu/homes/aspnes/classes/223/examples/2015/lecture/2015-03-02">Examples from lecture</a>.
+</dd>
+<dt>2015-03-04</dt>
+<dd><strong>Exam 1</strong>. This took place at the usual class time
+(1:00–2:15), and was a closed-book test potentially covering all
+material discussed in lecture prior to the exam. Sample exams from
+previous years: <a href="http://cs.yale.edu/homes/aspnes/classes/223/examples/2005/exam1.pdf">2005</a>, <a href="http://cs.yale.edu/homes/aspnes/classes/223/examples/2012/exam1.pdf">2012</a>. <a href="http://cs.yale.edu/homes/aspnes/classes/223/examples/2015/exams/exam1.pdf">Sample solutions</a>.
+</dd>
+<dt>2015-03-23</dt>
+<dd>Binary trees and heaps. Readings: <a href="#binaryTrees">Binary trees</a>, <a href="#heaps">Heaps</a>. <a href="http://cs.yale.edu/homes/aspnes/classes/223/examples/2015/lecture/2015-03-23">Examples from lecture</a>.
+</dd>
+<dt>2015-03-25</dt>
+<dd>Binary search tree implementation basics: insertion, search, deletion, various kinds of traversals. Readings: <a href="#binarySearchTrees">Binary search trees</a>. <a href="http://cs.yale.edu/homes/aspnes/classes/223/examples/2015/lecture/2015-03-25">Examples from lecture</a>.
+</dd>
+<dt>2015-03-30</dt>
+<dd>Balanced binary search trees: augmented trees and AVL trees. We also saw a little bit about <a href="#redBlackTrees">red-black trees</a>, but not enough to actually be useful. Readings: <a href="#augmentedTrees">Augmented trees</a>, <a href="#AVLtrees">AVL trees</a>. Example from lecture: see <a href="#avlTreeImplementation">AVL tree implementation</a>.
+</dd>
+<dt>2015-04-01</dt>
+<dd>Self-adjusting binary search trees: splay trees, a little bit about scapegoat trees. Readings: <a href="#splayTrees">Splay trees</a>. There was no new code in lecture but we did spend a while looking at a pre-prepared <a href="#splayTreeImplementation">splay tree implementation</a>.
+</dd>
+<dt>2015-04-06</dt>
+<dd>Graphs: structure of a graph, graph representations, basic ideas of graph search. Readings: <a href="#graphs">Graphs</a> up to start of <a href="#graphSearch">graph search</a>.
+</dd>
+<dt>2015-04-08</dt>
+<dd>More graphs: depth-first and breadth-first search. Minimum spanning trees and shortest paths. Readings: Rest of <a href="#graphs">graphs</a>. <a href="http://cs.yale.edu/homes/aspnes/classes/223/examples/2015/lecture/2015-04-08/">BFS example from lecture</a>. The program I was using in lecture to make nice pictures of graphs was <code>dot</code>, specifically <code>dot -Tpng</code>. Thanks to the good folks at ITS, this is now installed in the Zoo along with the rest of the <a href="http://graphviz.org/">GraphViz</a> tools.
+</dd>
+<dt>2015-04-13</dt>
+<dd>Dynamic programming: all-pairs shortest paths, longest increasing subsequence, longest common subsequence. Readings: <a href="#dynamicProgramming">Dynamic programming</a>. <a href="http://cs.yale.edu/homes/aspnes/classes/223/examples/2015/lecture/2015-04-13">Examples from lecture</a>.
+</dd>
+<dt>2015-04-15</dt>
+<dd>Randomized data structures. Readings: <a href="#randomization">Randomization</a>. The <a href="http://cs.yale.edu/homes/aspnes/classes/223/examples/2015/lecture/2015-04-15/devurandom.c">devurandom.c</a> example from lecture.
+</dd>
+<dt>2015-04-20</dt>
+<dd>Data structures for strings: tries, TSTs, and variants; radix sort. Readings: <a href="#stringProcessing">String processing</a>.
+</dd>
+<dt>2015-04-22</dt>
+<dd><strong>Exam 2</strong>. This took place at the usual class time
+(1:00–2:15), and was a closed-book test potential covering all material
+discussed in lecture during the semester. Sample exams from previous
+years: <a href="http://cs.yale.edu/homes/aspnes/classes/223/examples/2005/exam2.pdf">2005</a>, <a href="http://cs.yale.edu/homes/aspnes/classes/223/examples/2012/exam2.pdf">2012</a>. <a href="http://cs.yale.edu/homes/aspnes/classes/223/examples/2015/exams/exam2.pdf">Sample solutions</a>.
+</dd>
+</dl>
+<h3 id="topics-not-covered-in-2015"><span class="header-section-number">1.2.2</span> Topics not covered in 2015</h3>
+<p>Here are some topics that were not covered specifically this semester but can be found in the notes.</p>
+<ul>
+<li><a href="#iterators">Iterators</a></li>
+<li><a href="#suffixArrays">Suffix arrays</a></li>
+<li><a href="#testingDuringDevelopment">Testing during development</a></li>
+<li><a href="#algorithmDesignTechniques">Algorithm design techniques</a></li>
+<li><a href="#bitManipulation">Bit manipulation</a></li>
+<li><a href="#persistence">Persistence</a></li>
+<li><a href="#cplusplus">C++</a></li>
+<li><a href="#whatNext">What next</a></li>
+</ul>
+<h2 id="syllabus"><span class="header-section-number">1.3</span> Syllabus</h2>
+<p>Syllabus for Computer Science 223b, Data Structures and Programming Techniques. Instructor: James Aspnes.</p>
+<h3 id="On-line_course_information"><span class="header-section-number">1.3.1</span> On-line course information</h3>
+<p>On-line information about the course, including the lecture schedule,
+ lecture notes, and information about assignments, can be found at <a href="http://www.cs.yale.edu/homes/aspnes/classes/223/notes.html" class="uri">http://www.cs.yale.edu/homes/aspnes/classes/223/notes.html</a>. This document will be updated frequently during the semester, and is also available in <a href="http://www.cs.yale.edu/homes/aspnes/classes/223/notes.pdf">PDF</a> format.</p>
+<h3 id="Meeting_times"><span class="header-section-number">1.3.2</span> Meeting times</h3>
+<p>Lectures are MW 13:00–14:15 in WLH 201 (Sudler Hall). The <a href="#schedule">lecture schedule</a> can be found in the course notes. A <a href="http://www.cs.yale.edu/homes/aspnes/#calendar">calendar</a> is also available.</p>
+<h3 id="Synopsis_of_the_course"><span class="header-section-number">1.3.3</span> Synopsis of the course</h3>
+<p>Topics include programming in C; data structures (arrays, stacks,
+queues, lists, trees, heaps, graphs); sorting and searching; storage
+allocation and management; data abstraction; programming style; testing
+and debugging; writing efficient programs.</p>
+<h3 id="Prerequisites"><span class="header-section-number">1.3.4</span> Prerequisites</h3>
+<p>CPSC 201, or equivalent background. See me if you aren't sure.</p>
+<h3 id="Textbook"><span class="header-section-number">1.3.5</span> Textbook</h3>
+<p>The textbook for this course is:</p>
+<ul>
+<li><em>The C Programming Language (2nd Edition),</em> by Brian W.
+Kernighan and Dennis M. Ritchie. Prentice Hall, 1988. ISBN 0131103628.
+The definitive introduction to C. You should memorize this book.</li>
+</ul>
+<p>If you are on the Yale campus or are using VPN to get to Yale's network, you can access this book at <a href="http://proquest.safaribooksonline.com/book/programming/c/9780133086249" class="uri">http://proquest.safaribooksonline.com/book/programming/c/9780133086249</a>. You do not need to buy a physical copy of this book unless you want to.</p>
+<h3 id="Course_requirements"><span class="header-section-number">1.3.6</span> Course requirements</h3>
+<p>Nine weekly homework assignments, and two in-class exams. Assignments
+ will be weighted equally in computing the final grade. Each exam will
+count as three assignments.</p>
+<h3 id="staff"><span class="header-section-number">1.3.7</span> Staff</h3>
+<p>See the <a href="http://www.cs.yale.edu/homes/aspnes/#calendar">calendar</a> for open office hours.</p>
+<h4 id="instructor"><span class="header-section-number">1.3.7.1</span> Instructor</h4>
+<p>James Aspnes (<a href="mailto:james.aspnes@gmail.com">james.aspnes@gmail.com</a>, <a href="http://www.cs.yale.edu/homes/aspnes/" class="uri">http://www.cs.yale.edu/homes/aspnes/</a>). Office: AKW 401. If my open office hours don't work for you, please send email to make an appointment.</p>
+<h4 id="teaching-fellows"><span class="header-section-number">1.3.7.2</span> Teaching Fellows</h4>
+<ul>
+<li>Yujia Hu <a href="mailto:yujia.hu@yale.edu">yujia.hu@yale.edu</a></li>
+<li>Joshua Lockerman <a href="mailto:joshua.lockerman@yale.edu">joshua.lockerman@yale.edu</a></li>
+<li>Junaid Nomani <a href="mailto:junaid.nomani@yale.edu">junaid.nomani@yale.edu</a></li>
+</ul>
+<h4 id="peer-tutors"><span class="header-section-number">1.3.7.3</span> Peer tutors</h4>
+<ul>
+<li>Iulia Tamas <a href="mailto:iulia.tamas@yale.edu">iulia.tamas@yale.edu</a></li>
+<li>Dylan Visher <a href="mailto:dylan.visher@yale.edu">dylan.visher@yale.edu</a></li>
+<li>Lining Wang <a href="mailto:lining.wang@yale.edu">lining.wang@yale.edu</a></li>
+<li>Blake Woodworth <a href="mailto:blake.woodworth@yale.edu">blake.woodworth@yale.edu</a></li>
+</ul>
+<h3 id="Use_of_outside_help"><span class="header-section-number">1.3.8</span> Use of outside help</h3>
+<p>Students are free to discuss homework problems and course material
+with each other, and to consult with the instructor or a TA. Solutions
+handed in, however, should be the student's own work. If a student
+benefits substantially from hints or solutions received from fellow
+students or from outside sources, then the student should hand in their
+solution but acknowledge the outside sources, and we will apportion
+credit accordingly. Using outside resources in solving a problem is
+acceptable but plagiarism is not.</p>
+<h3 id="Clarifications_for_homework_assignments"><span class="header-section-number">1.3.9</span> Clarifications for homework assignments</h3>
+<p>From time to time, ambiguities and errors may creep into homework
+assignments. Questions about the interpretation of homework assignments
+should be sent to the instructor at <a href="mailto:james.aspnes@gmail.com">james.aspnes@gmail.com</a>. Clarifications will appear in the on-line version of the assignment.</p>
+<h3 id="Late_assignments"><span class="header-section-number">1.3.10</span> Late assignments</h3>
+<p>Assignments submitted after the deadline without a Dean's Excuse are automatically assessed a 2%/hour penalty.</p>
+<h2 id="introduction"><span class="header-section-number">1.4</span> Introduction</h2>
+<p>There are two purposes to this course: to teach you to program in the
+ C programming language, and to teach you how to choose, implement, and
+use data structures and standard programming techniques.</p>
+<h3 id="whyC"><span class="header-section-number">1.4.1</span> Why should you learn to program in C?</h3>
+<ul>
+<li>It is the <em>de facto</em> substandard of programming languages.
+<ul>
+<li>C runs on everything.</li>
+<li>C lets you write programs that use very few resources.</li>
+<li>C gives you near-total control over the system, down to the level of pushing around individual bits with your bare hands.</li>
+<li>C imposes very few constraints on programming style: unlike
+higher-level languages, C doesn't have much of an ideology. There are
+very few programs you can't write in C.</li>
+<li>Many of the programming languages people actually use (Visual Basic,
+ perl, python, ruby, PHP, etc.) are executed by interpreters written in C
+ (or <a href="#cplusplus">C++</a>, an extension to C).</li>
+</ul></li>
+<li>You will learn discipline.
+<ul>
+<li>C makes it easy to shoot yourself in the foot.</li>
+<li>You can learn to avoid this by being careful about where you point it.</li>
+<li>Pain is a powerful teacher of caution.</li>
+</ul></li>
+<li>You will fail CS323 if you don't learn C really well in CS223 (CS majors only).</li>
+</ul>
+<p>On the other hand, there are many reasons why you might not want to
+use C later in life. It's missing a lot of features of modern program
+languages, including:</p>
+<ul>
+<li>A garbage collector.</li>
+<li>Minimal programmer-protection features like array bounds-checking or a strong type system.</li>
+<li>Non-trivial built-in data structures.</li>
+<li>Language support for exceptions, namespaces, object-oriented programming, etc.</li>
+</ul>
+<p>For most problems where minimizing programmer time and maximizing
+robustness are more important than minimizing runtime, other languages
+are a better choice. But for this class, we'll be using C.</p>
+<p>If you want to read a lot of flaming about what C is or is not good for, see <a href="http://c2.com/cgi/wiki?CeeLanguage" class="uri">http://c2.com/cgi/wiki?CeeLanguage</a>.</p>
+<h3 id="why-should-you-learn-about-data-structures-and-programming-techniques"><span class="header-section-number">1.4.2</span> Why should you learn about data structures and programming techniques?</h3>
+<p>For small programs, you don't need much in the way of data
+structures. But as soon as you are representing reasonably complicated
+data, you need some place to store it. Thinking about how you want to
+store and organize this data can be a good framework for organizing the
+rest of your program.</p>
+<p>Many programming environments will give you a rich collection of
+built-in data structures as part of their standard library. C does not:
+unless you use third-party libraries, any data structure you want in C
+you will have to build yourself. For most data structures this will
+require an understanding of pointers and storage allocation, mechanisms
+often hidden in other languages. Understanding these concepts will give
+you a deeper understanding of how computers actually work, and will both
+ let you function in minimalist environments where you don't have a lot
+of support and let you understand what more convenient environments are
+doing under their abstraction barriers.</p>
+<p>The same applies to the various programming techniques we will
+discuss in this class. While some of the issues that come up are
+specific to C and similar low-level languages (particular issues
+involving disciplined management of storage), some techniques will apply
+ no matter what kinds of programs you are writing and all will help in
+understanding what your computer systems are doing even if some of the
+details are hidden.</p>
+<h1 id="zoo"><span class="header-section-number">2</span> The Zoo and the Zoo Annex</h1>
+<p>The main undergraduate computing facility for Computer Science is the
+ Zoo, located on the third floor of AKW. The Zoo contains a large number
+ of Linux workstations.</p>
+<p>You don't need to do your work for this class in the Zoo, but that is
+ where your assignments will be submitted and tested, so if you do
+development elsewhere, you will need to copy your files over and make
+sure that they work there as well.</p>
+<p>The "Zoo Annex" is the informal name for 17HH room 111, which is
+reserved for CS student use from 19:00 to 23:59 Sundays through
+Thursdays. The machines in 17HH 111 run Windows, but once logged in, you
+ can create a Linux desktop remotely from a Zoo machine using a program
+called <a href="#fastX">FastX</a>. You can also download and use FastX
+from your own machine to get access to the full Zoo environment if you
+are running Windows or OSX.</p>
+<p>The best place for information about the Zoo is at <a href="http://zoo.cs.yale.edu/" class="uri">http://zoo.cs.yale.edu/</a>. Below are some points that are of particular relevance for CS223 students.</p>
+<h2 id="Getting_an_account"><span class="header-section-number">2.1</span> Getting an account</h2>
+<p>To get an account in the Zoo, follow the instructions at <a href="http://zoo.cs.yale.edu/accounts.html" class="uri">http://zoo.cs.yale.edu/accounts.html</a>. You will need your NetID and password to sign up for an account.</p>
+<p>Even if you already have an account, you still need to use this form
+to register as a CS 223 student, or you will not be able to submit
+assignments.</p>
+<h2 id="Getting_into_the_room"><span class="header-section-number">2.2</span> Getting into the room</h2>
+<p>The Zoo is located on the third floor of Arthur K Watson Hall, toward
+ the front of the building. If you are a Yale student, your ID should
+get you into the building and the room. If you are not a student, you
+will need to get your ID validated in AKW 008a to get in after hours.</p>
+<h2 id="Remote_use"><span class="header-section-number">2.3</span> Remote use</h2>
+<p>There are several options for remote use of the Zoo. <a href="#fastX">FastX</a> is the most straightforward if you want to replicate the Zoo experience elsewhere. I personally tend to connect using <a href="#zooSSH">ssh</a>.</p>
+<h3 id="fastX"><span class="header-section-number">2.3.1</span> Access using FastX</h3>
+<p>These instructions are adapted from Stan Eisenstat's documentation for CS323.</p>
+<p>To use FastX, you will need an installation key. If you are
+downloading the Windows or OSX version from the Yale Software Library,
+this will appear on the download page. Otherwise, see the instructions
+in the following section.</p>
+<h4 id="fastXLicense"><span class="header-section-number">2.3.1.1</span> Getting a license key</h4>
+<p>In order to use FastX, you will need a license key.</p>
+<ol style="list-style-type: decimal">
+<li>Go to the <a href="http://software.yale.edu/Library/Windows/DT-Starnet-FastX-W">Yale Software Library page for FastX (Windows version)</a>.</li>
+<li>Log in with your NetID and password if required.</li>
+<li>Copy the installation key that appears below the "Download Now" button.</li>
+</ol>
+<h4 id="fastXZooAnnex"><span class="header-section-number">2.3.1.2</span> FastX in the Zoo Annex</h4>
+<p>Using FastX you can turn a window on a Windows machine in the Zoo
+Annex (aka, the 17 Hillhouse, Room 111, cluster) into the same Linux
+desktop that you see when you log into a Zoo node.</p>
+<p>Do the following:</p>
+<ol style="list-style-type: decimal">
+<li>If you are not logged in:
+<ul>
+<li>Press CTRL + ALT + DELETE. A new screen with a Usage Agreement will appear.</li>
+<li>Click "OK". A new screen with a NetID and Password box will appear.</li>
+<li>Enter your NetID and Password and click "Continue". Windows will log you in.</li>
+</ul></li>
+<li>Click on the Windows icon in the lower left-hand corner of the screen. A new box will appear.</li>
+<li>Mouse over the "Search programs and files" box in the new window and
+ type "fastx" (but do not hit return). A list of "Programs" will appear.</li>
+<li>Click on "FastX" under "Programs" to launch FastX. (If a "Licensing" window appears asking for an activation key, enter <a href="#fastXLicense">the installation key from the download page</a>, click "OK", and click "Close" to dismiss the new window that appears.)</li>
+<li>If there is no entry named "Zoo" in the FastX window:
+<ul>
+<li>Click on the green + sign in the upper left-hand corner. A new window will appear.</li>
+<li>Enter "Zoo" in the Name field.</li>
+<li>Enter "node.zoo.cs.yale.edu" in the Host field.</li>
+<li>Do not change the Port or User field.</li>
+<li>Click "Save" to save the configuration.</li>
+</ul></li>
+<li>Double click on the "Zoo" entry. A "Login" box should appear. If a "Password" box appears instead:
+<ul>
+<li>Click "Cancel".</li>
+<li>Click on the green pencil in the upper left-hand corner of the FastX window.</li>
+<li>Delete the contents of the User field. A grayed out "Joe" will appear.</li>
+<li>Click "Save" to save the configuration.</li>
+<li>Double click on the "Zoo" entry again. A "Login" box will appear.</li>
+</ul></li>
+<li>Enter your Yale netID in the "Login" box (it should already be
+there) and click "Continue". (If a warning appears asking whether you
+want to accept a new key, click on "Accept" to dismiss it.) A "Password"
+ box will appear.</li>
+<li>Enter your password in the "Password" box and click on "Continue". A
+ new "Start new session" entry will appear in the right-hand side of the
+ FastX window.</li>
+<li>Click on "Start new session" to produce a pulldown menu and click on
+ either "Gnome" or "KDE" to choose a window manager (Gnome is the
+default in the Zoo) or "Xterm" to open a terminal window.<br>
+<strong>WARNING:</strong> If you click on "Gnome" but the desktop that
+appears does not have the usual "Applications" and "Places" in the upper
+ left-hand corner, then:
+<ol style="list-style-type: decimal">
+<li>Type ALT-F2 (that is, press the ALT and F2 keys simultaneously) to open a command field.</li>
+<li>Enter the command "gnome-shell --mode=classic -r" (without the surrounding quotes) and press the "Enter" key.</li>
+</ol></li>
+<li>A new window with a Zoo Linux desktop should open. You may resize it
+ by dragging on the lower left-hand corner if you prefer a different
+size.</li>
+<li>When you log out of the Linux desktop, close the "FastX" window by clicking the red X in the upper right-hand corner.</li>
+<li>Do not forget to log out of Windows when you are done.</li>
+</ol>
+<h4 id="fastXWindows"><span class="header-section-number">2.3.1.3</span> Using FastX from Windows</h4>
+<p>Using FastX you can turn a window on Windows into the same Linux desktop that you see when you log into a Zoo node.</p>
+<p>To install the software on your own Windows machine:</p>
+<ol style="list-style-type: decimal">
+<li>Go to the <a href="http://software.yale.edu/">Yale Software Library</a> and click on "Windows".</li>
+<li>Scroll through the list and click on "FastX".</li>
+<li>Copy the installation key that appears below the "Download Now" button.</li>
+<li>Click on the "Download Now" button and follow the instructions for installing the software.</li>
+<li>Launch FastX.</li>
+<li>Click on the green + sign in the upper left-hand corner of the FastX window. In the new window that appears:
+<ul>
+<li>Enter "Zoo" in the Name field.</li>
+<li>Enter "node.zoo.cs.yale.edu" in the Host field.</li>
+<li>Do not change the Port field.</li>
+<li>Enter your Yale netID in the User field.</li>
+<li>Click "Save" to save the configuration.</li>
+</ul></li>
+<li>Double click on the "Zoo" entry.</li>
+<li>When the "Licensing" window appears asking for an activation key, enter <a href="#fastXLicense">the number copied above</a> and click "OK". A new window will appear. Click "Close" to dismiss it.</li>
+<li>Quit FastX.</li>
+</ol>
+<p>If you run into difficulties up to this point, seek help from a student tech or one of the instructional staff.</p>
+<p>Once you have installed the software, do the following to run FastX:</p>
+<ol style="list-style-type: decimal">
+<li>Launch FastX.</li>
+<li>Double click on the "Zoo" entry. A "Password" box will appear.</li>
+<li>Enter the password for your Yale netID and click "OK". A "Start a new session" entry will appear in the FastX window.</li>
+<li>Click on "Start new session" to produce a pulldown menu and click on
+ either "Gnome" or "KDE" to choose a window manager (Gnome is the
+default in the Zoo) or "Xterm" to open a terminal window.<br>
+<strong>WARNING:</strong> If you click on "Gnome" but the desktop that
+appears does not have the usual "Applications" and "Places" in the upper
+ left-hand corner, then:
+<ol style="list-style-type: decimal">
+<li>Type ALT-F2 (that is, press the ALT and F2 keys simultaneously) to open a command field.</li>
+<li>Enter the command "gnome-shell --mode=classic -r" (without the surrounding quotes) and press the "Enter" key.</li>
+</ol></li>
+<li>A new window with a Zoo Linux desktop should open. You may resize it
+ by dragging on the lower left-hand corner if you prefer a different
+size.</li>
+<li>When you log out of the Linux desktop, close the "FastX" window by clicking the red X in the upper right-hand corner.</li>
+</ol>
+<h4 id="fastXOSX"><span class="header-section-number">2.3.1.4</span> Using FastX from OSX</h4>
+<p>Using FastX you can turn a window on a Mac into the same Linux desktop that you see when you log into a Zoo node.</p>
+<p>To install the software on your own Mac:</p>
+<ol style="list-style-type: decimal">
+<li>Go to the <a href="http://software.yale.edu/">Yale Software Library</a> and click on "Mac".</li>
+<li>Scroll through the list and click on "FastX".</li>
+<li>Copy the installation key that appears below the "Download Now" button.</li>
+<li>Click on the "Download Now" button and save the downloaded file as "fastx_1016.dmg" (for version 1.0.16).</li>
+<li>Click on the downloaded file "fastx_1016.dmg" to open the disk
+image. A "FastX" disk icon will appear on your desktop, and a folder
+containing a "FastX" icon will appear.</li>
+<li>Drag the "FastX" icon to the folder where you would like to save it, and launch FastX by clicking on it.</li>
+<li>Click on the green + sign in the upper left-hand corner of the FastX window. In the new window that appears:
+<ul>
+<li>Enter "Zoo" in the Name field.</li>
+<li>Enter "node.zoo.cs.yale.edu" in the Host field.</li>
+<li>Do not change the Port field.</li>
+<li>Enter your Yale netID in the User field.</li>
+<li>Click "Save" to save the configuration.</li>
+</ul></li>
+<li>Double click on the "Zoo" entry.</li>
+<li>When the "Licensing" window appears asking for an activation key, enter <a href="#fastXLicense">the number copied above</a> and click "OK". A new window will appear. Click "Close" to dismiss it.</li>
+<li>Quit FastX.</li>
+<li>Drag the "FastX" disk icon and then the "fastx_1016.dmg" icon to the Trash to clean up.</li>
+</ol>
+<p>If you run into difficulties up to this point, seek help from a student tech or one of the instructional staff.</p>
+<p>Once you have installed the software, do the following to run FastX:</p>
+<ol style="list-style-type: decimal">
+<li>Launch FastX from the folder where you saved it.</li>
+<li>Double click on "Zoo". A "Password" box will appear, possibly behind
+ the FastX window. (If it does not, click on the "FastX" icon that is
+flashing in your dock.)</li>
+<li>Enter the password for your Yale netID and click "OK". A "Start a new session" entry will appear in the FastX window.</li>
+<li>Click on "Start new session" to produce a pulldown menu and click on
+ either "Gnome" or "KDE" to choose a window manager (Gnome is the
+default in the Zoo) or "Xterm" to open a terminal window.<br>
+<strong>WARNING:</strong> If you click on "Gnome" but the desktop that
+appears does not have the usual "Applications" and "Places" in the upper
+ left-hand corner, then:
+<ol style="list-style-type: decimal">
+<li>Type ALT-F2 (that is, press the ALT and F2 keys simultaneously) to open a command field.</li>
+<li>Enter the command "gnome-shell --mode=classic -r" (without the surrounding quotes) and press the "Enter" key.</li>
+</ol></li>
+<li>A new window with a Zoo Linux desktop should open behind the FastX
+window. You may resize it by dragging on the lower left-hand corner if
+you prefer a different size.</li>
+<li>When you log out of the Linux desktop, close the "FastX" window by clicking the red dot in the upper left-hand corner.</li>
+</ol>
+<h3 id="zooSSH"><span class="header-section-number">2.3.2</span> Terminal access</h3>
+<pre><code>Date: Mon, 13 Dec 2004 14:34:19 -0500 (EST)
+From: Jim Faulkner &lt;james.faulkner@yale.edu&gt;
+Subject: Accessing the Zoo
+
+Hello all,
+
+I've been asked to write up a quick guide on how to access the Linux
+computers in the Zoo. For those who need this information, please read
+on.
+
+There are 2 ways of accessing the Zoo nodes, by walking up to one and
+logging in on the console (the computers are located on the 3rd floor of
+AKW), or by connecting remotely via SSH. Telnet access is not allowed.
+SSH clients for various operating systems are available here:
+
+http://www.yale.edu/software/
+
+Mac OSX comes with an SSH client by default. A good choice for an SSH
+client if you run Microsoft Windows is PuTTY:
+
+http://www.chiark.greenend.org.uk/~sgtatham/putty/
+
+With the exception of a few legacy accounts, the Zoo uses your campus-wide
+NetID and password for login access. However, you must sign up for a Zoo
+account before access is allowed. To sign up for a Zoo account, go to
+this web page:
+
+http://zoo.cs.yale.edu/accounts.html
+
+Then login with your campus-wide NetID and password. You may choose a
+different shell, or set up your account to be enrolled in a class if that
+is appropriate for you, but neither is necessary. Just click "Submit".
+Within an hour, your Zoo account will be created, and you will receive
+more information via e-mail about how to access the Zoo.
+
+Users cannot log into zoo.cs.yale.edu (the central file server) directly,
+they must log into one of the Zoo nodes. Following is the list of Zoo
+nodes:
+
+aphid.zoo.cs.yale.edu lion.zoo.cs.yale.edu
+bumblebee.zoo.cs.yale.edu macaw.zoo.cs.yale.edu
+cardinal.zoo.cs.yale.edu monkey.zoo.cs.yale.edu
+chameleon.zoo.cs.yale.edu newt.zoo.cs.yale.edu
+cicada.zoo.cs.yale.edu peacock.zoo.cs.yale.edu
+cobra.zoo.cs.yale.edu perch.zoo.cs.yale.edu
+cricket.zoo.cs.yale.edu python.zoo.cs.yale.edu
+frog.zoo.cs.yale.edu rattlesnake.zoo.cs.yale.edu
+gator.zoo.cs.yale.edu rhino.zoo.cs.yale.edu
+giraffe.zoo.cs.yale.edu scorpion.zoo.cs.yale.edu
+grizzly.zoo.cs.yale.edu swan.zoo.cs.yale.edu
+hare.zoo.cs.yale.edu termite.zoo.cs.yale.edu
+hippo.zoo.cs.yale.edu tick.zoo.cs.yale.edu
+hornet.zoo.cs.yale.edu tiger.zoo.cs.yale.edu
+jaguar.zoo.cs.yale.edu tucan.zoo.cs.yale.edu
+koala.zoo.cs.yale.edu turtle.zoo.cs.yale.edu
+ladybug.zoo.cs.yale.edu viper.zoo.cs.yale.edu
+leopard.zoo.cs.yale.edu zebra.zoo.cs.yale.edu
+
+If you have already created an account, you can SSH directly to one of
+the above computers and log in with your campus-wide NetID and
+password. You can also SSH to node.zoo.cs.yale.edu, which will connect
+you to a random Zoo node.
+
+Feel free to contact me if you have any questions about the Zoo.
+
+thanks,
+Jim Faulkner
+Zoo Systems Administrator</code></pre>
+<h3 id="GUI_access"><span class="header-section-number">2.3.3</span> GUI access</h3>
+<p>(These notes from Debayan Gupta.)</p>
+<p>For Mac or Linux users, typing "ssh -X netID@node.zoo.cs.yale.edu"
+into a terminal and then running "nautilus" will produce an X window
+interface.</p>
+<p>When on Windows, I usually use XMing (I've included a step-by-step guide at the end of this mail).</p>
+<p>For transferring files, I use CoreFTP (<a href="http://www.coreftp.com/" class="uri">http://www.coreftp.com</a>). FileZilla (<a href="https://filezilla-project.org/" class="uri">https://filezilla-project.org/</a>) is another option.</p>
+<p>Step-by-step guide to XMIng:</p>
+<p>You can download Xming from here: <a href="http://sourceforge.net/projects/xming/" class="uri">http://sourceforge.net/projects/xming/</a></p>
+<p>Download and install. Do NOT launch Xming at the end of your installation.</p>
+<p>Once you've installed Xming, go to your start menu and find XLaunch (it should be in the same folder as Xming).</p>
+<ol style="list-style-type: decimal">
+<li><p>Start XLaunch, and select "Multiple Windows". Leave "Display Number" as its default value. Click next.</p></li>
+<li><p>Select "Start a program". Click next.</p></li>
+<li><p>Type "nautilus" (or "terminal", if you want a terminal) into the "Start Program" text area. Select "Using PuTTY (plink.exe)".</p></li>
+<li><p>Type in the name of the computer (use "node.zoo.cs.yale.edu") in the "Connect to computer" text box.</p></li>
+<li><p>Type in your netID in the "Login as user" text box (you can leave the password blank). Click next.</p></li>
+<li><p>Make sure "Clipboard" is ticked. Leave everything else blank. Click next.</p></li>
+<li><p>Click "Save Configuration". When saving, make sure your filename
+ends with ".xlaunch" - this will let you connect with a click (you won't
+ need to do all this every time you connect).</p></li>
+<li><p>Click Finish.</p></li>
+<li><p>You will be prompted for your password - enter it. Ignore any security warnings.</p></li>
+<li><p>You now have a remote connection to the Zoo.</p></li>
+</ol>
+<p>For more options and information, you can go to: <a href="http://www.straightrunning.com/XmingNotes/" class="uri">http://www.straightrunning.com/XmingNotes/</a></p>
+<h2 id="compiling"><span class="header-section-number">2.4</span> How to compile and run programs</h2>
+<p>See the chapter on <a href="#zoo">how to use the Zoo</a> for details of particular commands. The basic steps are</p>
+<ul>
+<li>Creating the program with a text editor of your choosing. (I like <code class="backtick">vim</code> for long programs and <code class="backtick">cat</code> for very short ones.)</li>
+<li>Compiling it with <code class="backtick">gcc</code>.</li>
+<li>Running it.</li>
+</ul>
+<p>If any of these steps fail, the next step is debugging. We'll talk about debugging elsewhere.</p>
+<h3 id="Creating_the_program"><span class="header-section-number">2.4.1</span> Creating the program</h3>
+<p>Use your favorite text editor. The program file should have a name of the form <code class="backtick">foo.c</code>; the <code class="backtick">.c</code> at the end tells the C compiler the contents are C source code. Here is a typical C program:</p>
+<div>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"><span class="ot">#include &lt;stdio.h&gt;</span>
+
+<span class="co">/* print the numbers from 1 to 10 */</span>
+
+<span class="dt">int</span>
+main(<span class="dt">int</span> argc, <span class="dt">char</span> **argv)
+{
+ <span class="dt">int</span> i;
+
+ puts(<span class="st">"Now I will count from 1 to 10"</span>);
+ <span class="kw">for</span>(i = <span class="dv">1</span>; i &lt;= <span class="dv">10</span>; i++) {
+ printf(<span class="st">"%d</span><span class="ch">\n</span><span class="st">"</span>, i);
+ }
+
+ <span class="kw">return</span> <span class="dv">0</span>;
+}</code></pre></div>
+<a href="http://cs.yale.edu/homes/aspnes/classes/223/examples/count.c" class="uri">examples/count.c</a>
+</div>
+<h3 id="Compiling_and_running_a_program"><span class="header-section-number">2.4.2</span> Compiling and running a program</h3>
+<p>Here's what happens when I compile and run it on the Zoo:</p>
+<pre><code>$ c99 -g3 -o count count.c
+$ ./count
+Now I will count from 1 to 10
+1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+$</code></pre>
+<p>The first line is the command to compile the program. The dollar sign is my <strong>prompt</strong>, which is printed by the system to tell me it is waiting for a command. The command calls <code>gcc</code> as <code>c99</code> with arguments <code>-g3</code> (enable maximum debugging info), <code>-o</code> (specify executable file name, otherwise defaults to <code>a.out</code>), <code>count</code> (the actual executable file name), and <code>count.c</code> (the source file to compile). This tells <code>gcc</code> that we should compile <code>count.c</code> to <code>count</code> in C99 mode with maximum debugging info included in the executable file.</p>
+<p>The second line runs the output file <code class="backtick">count</code>. Calling it <code class="backtick">./count</code>
+ is necessary because by default the shell (the program that interprets
+what you type) only looks for programs in certain standard system
+directories. To make it run a program in the current directory, we have
+to include the directory name.</p>
+<h3 id="Some_notes_on_what_the_program_does"><span class="header-section-number">2.4.3</span> Some notes on what the program does</h3>
+<p>Noteworthy features of this program include:</p>
+<ul>
+<li>The <code class="backtick">#include&nbsp;&lt;stdio.h&gt;</code> in
+line 1. This is standard C boilerplate, and will appear in any program
+you see that does input or output. The meaning is to tell the compiler
+to include the text of the file <code class="backtick">/usr/include/stdio.h</code>
+ in your program as if you had typed it there yourself. This particular
+file contains declarations for the standard I/O library functions like <code class="backtick">puts</code> (put string) and <code class="backtick">printf</code> (print formatted), as used in the program. If you don't put it in, your program may or may not still compile. Do it anyway.</li>
+<li>Line 3 is a comment; its beginning and end is marked by the <code class="backtick">/*</code> and <code class="backtick">*/</code>
+ characters. Comments are ignored by the compiler but can be helpful for
+ other programmers looking at your code (including yourself, after
+you've forgotten why you wrote something).</li>
+<li>Lines 5 and 6 declare the <code class="backtick">main</code> function. Every C program has to have a <code class="backtick">main</code> function declared in exactly this way—it's what the operating system calls when you execute the program. The <code class="backtick">int</code> on Line 3 says that main returns a value of type <code class="backtick">int</code> (we'll describe this in more detail later in the chapter on <a href="#functions">functions</a>), and that it takes two arguments: <code class="backtick">argc</code> of type <code class="backtick">int</code>, the number of arguments passed to the program from the command line, and <code class="backtick">argv</code>, of a <a href="#pointers">pointer</a>
+ type that we will get to eventually, which is an array of the arguments
+ (essentially all the words on the command line, including the program
+name). Note that it would also work to do this as one line (as K&amp;R
+typically does); the C compiler doesn't care about whitespace, so you
+can format things however you like, subject to the constraint that
+consistency will make it easier for people to read your code.</li>
+<li><p>Everything inside the curly braces is the body of the <code class="backtick">main</code> function. This includes</p>
+<ul>
+<li>The declaration <code class="backtick">int&nbsp;i;</code>, which says that <code class="backtick">i</code> will be a variable that holds an <code class="backtick">int</code> (see the chapter on <a href="#integerTypes">Integer Types</a>).</li>
+<li>Line 10, which prints an informative message using <code class="backtick">puts</code> (discussed in the chapter on <a href="#IO">input and output</a>.</li>
+<li>The <code class="backtick">for</code> loop on Lines 11–13, which executes its body for each value of <code class="backtick">i</code> from 1 to 10. We'll explain how <code class="backtick">for</code> loops work <a href="#forLoop">later</a>. Note that the body of the loop is enclosed in curly braces just like the body of the <code class="backtick">main</code> function. The only statement in the body is the call to <code class="backtick">printf</code> on Line 12; this includes a format string that specifies that we want a decimal-formatted integer followed by a newline (the <code class="backtick">\n</code>).</li>
+<li>The <code class="backtick">return&nbsp;0;</code> on Line 15 tells
+the operating system that the program worked (the convention in Unix is
+that 0 means success). If the program didn't work for some reason, we
+could have returned something else to signal an error.</li>
+</ul></li>
+</ul>
+<h1 id="linux"><span class="header-section-number">3</span> The Linux programming environment</h1>
+<p>The Zoo runs a Unix-like operating system called Linux. Most people run Unix with a command-line interface provided by a <strong>shell</strong>.
+ Each line typed to the shell tells it what program to run (the first
+word in the line) and what arguments to give it (remaining words). The
+interpretation of the arguments is up to the program.</p>
+<h2 id="the-shell"><span class="header-section-number">3.1</span> The shell</h2>
+<p>When you sign up for an account in the Zoo, you are offered a choice
+of possible shell programs. The examples below assume you have chosen <code>bash</code>, the <a href="http://www.gnu.org/software/bash/">Bourne-again shell</a> written by the GNU project. Other shells behave similarly for basic commands.</p>
+<h3 id="Getting_a_shell_prompt_in_the_Zoo"><span class="header-section-number">3.1.1</span> Getting a shell prompt in the Zoo</h3>
+<p>When you log in to a Zoo node directly, you may not automatically get
+ a shell window. If you use the default login environment (which puts
+you into the KDE window manager), you need to click on the picture of
+the display with a shell in from of it in the toolbar at the bottom of
+the screen. If you run Gnome instead (you can change your startup
+environment using the popup menu in the login box), you can click on the
+ foot in the middle of the toolbar. Either approach will pop up a
+terminal emulator from which you can run emacs, gcc, and so forth.</p>
+<p>The default login shell in the Zoo is <code class="backtick">bash</code>, and all examples of shell command lines given in these notes will assume <code class="backtick">bash</code>.
+ You can choose a different login shell on the account sign-up page if
+you want to, but you are probably best off just learning to like <code class="backtick">bash</code>.</p>
+<h3 id="The_Unix_filesystem"><span class="header-section-number">3.1.2</span> The Unix filesystem</h3>
+<p>Most of what one does with Unix programs is manipulate the
+filesystem. Unix files are unstructured blobs of data whose names are
+given by paths consisting of a sequence of directory names separated by
+slashes: for example <code>/home/accts/some-user/cs223/hw1.c</code>. At any time you are in a current working directory (type <code>pwd</code> to find out what it is and <code>cd&nbsp;new-directory</code>
+ to change it). You can specify a file below the current working
+directory by giving just the last part of the pathname. The special
+directory names <code class="backtick">.</code> and <code class="backtick">..</code> can also be used to refer to the current directory and its parent. So <code class="backtick">/home/accts/some-user/cs223/hw1.c</code> is just <code class="backtick">hw1.c</code> or <code class="backtick">./hw1.c</code> if your current working directory is <code class="backtick">/home/accts/some-user/cs223</code>, <code class="backtick">cs223/hw1.c</code> if your current working directory is <code class="backtick">/home/accts/some-user</code>, and <code class="backtick">../cs223/hw1.c</code> if your current working directory is <code class="backtick">/home/accts/some-user/illegal-downloads</code>.</p>
+<p>All Zoo machines share a common filesystem, so any files you create
+or change on one Zoo machine will show up in the same place on all the
+others.</p>
+<h3 id="Unix_command-line_programs"><span class="header-section-number">3.1.3</span> Unix command-line programs</h3>
+<p>Here are some handy Unix commands:</p>
+<dl>
+<dt>man</dt>
+<dd><p><code>man</code>&nbsp;<em>program</em> will show you the on-line documentation (the <em>man page</em>) for a program (e.g., try <code>man&nbsp;man</code> or <code>man&nbsp;ls</code>). Handy if you want to know what a program does. On Linux machines like the ones in the Zoo you can also get information using <code>info&nbsp;program</code>, which has an Emacs-like interface.</p>
+<p>You can also use <code>man</code> <em>function</em> to see documentation for standard library functions. The command <code>man -k</code> <em>string</em> will search for man pages whose titles contain <em>string</em>.</p>
+<p>Sometimes there is more than one man page with the same name. In this case <code>man -k</code> will distingiush them by different manual section numbers, e.g., <code>printf (1)</code> (a shell command) vs. <code>printf (3)</code> (a library routine). To get a man page from a specific section, use <code>man</code> <em>section</em> <em>name</em>, e.g. <code>man 3 printf</code>.</p>
+</dd>
+<dt>ls</dt>
+<dd><p><code>ls</code> lists all the files in the current directory. Some useful variants:</p>
+<ul>
+<li><code>ls&nbsp;/some/other/dir</code>; list files in that directory instead.</li>
+<li><code>ls&nbsp;-l</code>; long output format showing modification dates and owners.</li>
+</ul>
+</dd>
+<dt>mkdir</dt>
+<dd><code>mkdir&nbsp;dir</code> will create a new directory in the current directory named <code>dir</code>.
+</dd>
+<dt>rmdir</dt>
+<dd><code>rmdir&nbsp;dir</code> deletes a directory. It only works on directories that contain no files.
+</dd>
+<dt>cd</dt>
+<dd><code>cd&nbsp;dir</code> changes the current working directory. With no arguments, <code>cd</code> changes back to your home directory.
+</dd>
+<dt>pwd</dt>
+<dd><code>pwd</code> ("print working directory") shows what your current directory is.
+</dd>
+<dt>mv</dt>
+<dd><code>mv&nbsp;old-name&nbsp;new-name</code> changes the name of a file. You can also use this to move files between directories.
+</dd>
+<dt>cp</dt>
+<dd><code>cp&nbsp;old-name&nbsp;new-name</code> makes a copy of a file.
+</dd>
+<dt>rm</dt>
+<dd><code>rm&nbsp;file</code> deletes a file. Deleted files cannot be recovered. Use this command carefully.
+</dd>
+<dt>chmod</dt>
+<dd><p><code>chmod</code> changes the permissions on a file or directory. See the man page for the full details of how this works. Here are some common <code>chmod</code>'s:</p>
+<ul>
+<li><code>chmod&nbsp;644&nbsp;file</code>; owner can read or write the file, others can only read it.</li>
+<li><code>chmod&nbsp;600&nbsp;file</code>; owner can read or write the file, others can't do anything with it.</li>
+<li><code>chmod&nbsp;755&nbsp;file</code>; owner can read, write, or
+execute the file, others can read or execute it. This is typically used
+for programs or for directories (where the execute bit has the special
+meaning of letting somebody find files in the directory).</li>
+<li><code>chmod&nbsp;700&nbsp;file</code>; owner can read, write, or execute the file, others can't do anything with it.</li>
+</ul>
+</dd>
+<dt><code>emacs</code>, <code>gcc</code>, <code>make</code>, <code>gdb</code>, <code>git</code></dt>
+<dd>See corresponding sections.
+</dd>
+</dl>
+<h3 id="Stopping_and_interrupting_programs"><span class="header-section-number">3.1.4</span> Stopping and interrupting programs</h3>
+<p>Sometimes you may have a running program that won't die. Aside from
+costing you the use of your terminal window, this may be annoying to
+other Zoo users, especially if the process won't die even if you close
+the terminal window or log out.</p>
+<p>There are various control-key combinations you can type at a terminal window to interrupt or stop a running program.</p>
+<dl>
+<dt>ctrl-C</dt>
+<dd>Interrupt the process. Many processes (including any program you write unless you trap SIGINT using the <code class="backtick">sigaction</code> system call) will die instantly when you do this. Some won't.
+</dd>
+<dt>ctrl-Z</dt>
+<dd>Suspend the process. This will leave a stopped process lying around. Type <code class="backtick">jobs</code> to list all your stopped processes, <code class="backtick">fg</code> to restart the last process (or <code class="backtick">fg&nbsp;%1</code> to start process <code class="backtick">%1</code> etc.), <code class="backtick">bg</code> to keep running the stopped process in the background, <code class="backtick">kill&nbsp;%1</code> to kill process <code class="backtick">%1</code> politely, <code class="backtick">kill&nbsp;-KILL&nbsp;%1</code> to kill process <code class="backtick">%1</code> whether it wants to die or not.
+</dd>
+<dt>ctrl-D</dt>
+<dd>Send end-of-file to the process. Useful if you are typing test input
+ to a process that expects to get EOF eventually or writing programs
+using <code class="backtick">cat&nbsp;&gt;&nbsp;program.c</code> (not really recommmended). For test input, you are often better putting it into a file and using input redirection (<code class="backtick">./program&nbsp;&lt;&nbsp;test-input-file</code>); this way you can redo the test after you fix the bugs it reveals.
+</dd>
+<dt>ctrl-\</dt>
+<dd>Quit the process. Sends a SIGQUIT, which asks a process to quit and dump core. Mostly useful if ctrl-C and ctrl-Z don't work.
+</dd>
+</dl>
+<p>If you have a runaway process that you can't get rid of otherwise, you can use <code class="backtick">ps&nbsp;g</code> to get a list of all your processes and their process ids. The <code class="backtick">kill</code> command can then be used on the offending process, e.g. <code class="backtick">kill&nbsp;-KILL&nbsp;6666</code> if your evil process has process id 6666. Sometimes the <code class="backtick">killall</code> command can simplify this procedure, e.g. <code class="backtick">killall&nbsp;-KILL&nbsp;evil</code> kills all process with command name <code class="backtick">evil</code>.</p>
+<h3 id="Running_your_own_programs"><span class="header-section-number">3.1.5</span> Running your own programs</h3>
+<p>If you compile your own program, you will need to prefix it with <code class="backtick">./</code> on the command line to tell the shell that you want to run a program in the current directory (called '<code class="backtick">.</code>') instead of one of the standard system directories. So for example, if I've just built a program called <code class="backtick">count</code>, I can run it by typing</p>
+<pre><code>$ ./count</code></pre>
+<p>Here the "<code class="backtick">$&nbsp;</code>" is standing in for whatever your prompt looks like; you should not type it.</p>
+<p>Any words after the program name (separated by <strong>whitespace</strong>—spaces
+ and/or tabs) are passed in as arguments to the program. Sometimes you
+may wish to pass more than one word as a single argument. You can do so
+by wrapping the argument in single quotes, as in</p>
+<pre><code>$ ./count 'this is the first argument' 'this is the second argument'</code></pre>
+<h3 id="shellRedirects"><span class="header-section-number">3.1.6</span> Redirecting input and output</h3>
+<p>Some programs take input from <strong>standard input</strong>
+(typically the terminal). If you are doing a lot of testing, you will
+quickly become tired of typing test input at your program. You can tell
+the shell to <strong>redirect</strong> standard input from a file by putting the file name after a <code class="backtick">&lt;</code> symbol, like this:</p>
+<pre><code>$ ./count &lt; huge-input-file</code></pre>
+<p>A '&gt;' symbol is used to redirect <strong>standard output</strong>, in case you don't want to read it as it flies by on your screen:</p>
+<pre><code>$ ./count &lt; huge-input-file &gt; huger-output-file</code></pre>
+<p>A useful file for both input and output is the special file <code class="backtick">/dev/null</code>. As input, it looks like an empty file. As output, it eats any characters sent to it:</p>
+<pre><code>$ ./sensory-deprivation-experiment &lt; /dev/null &gt; /dev/null</code></pre>
+<p>You can also <strong>pipe</strong> programs together, connecting the output of one to the input of the next. Good programs to put at the end of a pipe are <code class="backtick">head</code> (eats all but the first ten lines), <code class="backtick">tail</code> (eats all but the last ten lines), <code class="backtick">more</code> (lets you page through the output by hitting the space bar, and <code class="backtick">tee</code> (shows you the output but also saves a copy to a file). A typical command might be something like <code class="backtick">./spew&nbsp;|&nbsp;more</code> or <code class="backtick">./slow-but-boring&nbsp;|&nbsp;tee&nbsp;boring-output</code>.
+ Pipes can consist of a long train of programs, each of which processes
+the output of the previous one and supplies the input to the next. A
+typical case might be:</p>
+<pre><code>$ ./do-many-experiments | sort | uniq -c | sort -nr</code></pre>
+<p>which, if <code class="backtick">./do-many-experiments</code> gives
+the output of one experiment on each line, produces a list of distinct
+experimental outputs sorted by decreasing frequency. Pipes like this can
+ often substitute for hours of real programming.</p>
+<h2 id="editing"><span class="header-section-number">3.2</span> Text editors</h2>
+<p>To write your programs, you will need to use a text editor,
+preferably one that knows enough about C to provide tools like automatic
+ indentation and syntax highlighting. There are three reasonable choices
+ for this in the Zoo: <code class="backtick">kate</code>, <code class="backtick">emacs</code>, and <code class="backtick">vim</code> (which can also be run as <code class="backtick">vi</code>).
+ Kate is a GUI-style editor that comes with the KDE window system; it
+plays nicely with the mouse, but Kate skills will not translate well
+into other environements. <a href="http://en.wikipedia.org/wiki/Emacs" title="WikiPedia">Emacs</a> and <a href="http://en.wikipedia.org/wiki/Vi" title="WikiPedia">Vi</a> have been the two contenders for the <a href="http://en.wikipedia.org/wiki/Editor_war" title="WikiPedia">One True Editor</a>
+ since the 1970s—if you learn one (or both) you will be able to use the
+resulting skills everywhere. My personal preference is to use Vi, but
+Emacs has the advantage of using the same editing commands as the shell
+and <code class="backtick">gdb</code> command-line interfaces.</p>
+<h3 id="Writing_C_programs_with_Emacs"><span class="header-section-number">3.2.1</span> Writing C programs with Emacs</h3>
+<p>To start Emacs, type <code>emacs</code> at the command line. If you
+are actually sitting at a Zoo node it should put up a new window. If
+not, Emacs will take over the current window. If you have never used
+Emacs before, you should immediately type <code>C-h&nbsp;t</code> (this means hold down the Control key, type <code>h</code>, then type <code>t</code> without holding down the Control key). This will pop you into the Emacs built-in tutorial.</p>
+<h4 id="My_favorite_Emacs_commands"><span class="header-section-number">3.2.1.1</span> My favorite Emacs commands</h4>
+<p>General note: <code>C-x</code> means hold down Control and press <code>x</code>; <code>M-x</code> means hold down Alt (Emacs calls it "Meta") and press <code>x</code>. For <code>M-x</code> you can also hit Esc and then <code>x</code>.</p>
+<dl>
+<dt>C-h</dt>
+<dd>Get help. Everything you could possibly want to know about Emacs is available through this command. Some common versions: <code>C-h&nbsp;t</code> puts up the tutorial, <code>C-h&nbsp;b</code> lists every command available in the current mode, <code>C-h&nbsp;k</code> tells you what a particular sequence of keystrokes does, and <code>C-h&nbsp;l</code>
+ tells you what the last 50 or so characters you typed were (handy if
+Emacs just garbled your file and you want to know what command to avoid
+in the future).
+</dd>
+<dt>C-x u</dt>
+<dd>Undo. Undoes the last change you made to the current buffer. Type it
+ again to undo more things. A lifesaver. Note that it can only undo back
+ to the time you first loaded the file into Emacs—if you want to be able
+ to back out of bigger changes, use <code class="backtick">git</code> (described below).
+</dd>
+<dt>C-x C-s</dt>
+<dd>Save. Saves changes to the current buffer out to its file on disk.
+</dd>
+<dt>C-x C-f</dt>
+<dd>Edit a different file.
+</dd>
+<dt>C-x C-c</dt>
+<dd>Quit out of Emacs. This will ask you if you want to save any buffers that have been modified. You probably want to answer yes (<code>y</code>) for each one, but you can answer no (<code>n</code>) if you changed some file inside Emacs but want to throw the changes away.
+</dd>
+<dt>C-f</dt>
+<dd>Go forward one character.
+</dd>
+<dt>C-b</dt>
+<dd>Go back one character.
+</dd>
+<dt>C-n</dt>
+<dd>Go to the next line.
+</dd>
+<dt>C-p</dt>
+<dd>Go to the previous line.
+</dd>
+<dt>C-a</dt>
+<dd>Go to the beginning of the line.
+</dd>
+<dt>C-k</dt>
+<dd>Kill the rest of the line starting with the current position. Useful Emacs idiom: <code>C-a&nbsp;C-k</code>.
+</dd>
+<dt>C-y</dt>
+<dd>"Yank." Get back what you just killed.
+</dd>
+<dt>TAB</dt>
+<dd>Re-indent the current line. In C mode this will indent the line according to Emacs's notion of how C should be indented.
+</dd>
+<dt>M-x compile</dt>
+<dd>Compile a program. This will ask you if you want to save out any
+unsaved buffers and then run a compile command of your choice (see the
+section on compiling programs below). The exciting thing about <code>M-x&nbsp;compile</code> is that if your program has errors in it, you can type <code>C-x&nbsp;`</code> to jump to the next error, or at least where <code>gcc</code> thinks the next error is.
+</dd>
+</dl>
+<h3 id="Using_Vi_instead_of_Emacs"><span class="header-section-number">3.2.2</span> Using Vi instead of Emacs</h3>
+<p>If you don't find yourself liking Emacs very much, you might want to
+try Vim instead. Vim is a vastly enhanced reimplementation of the
+classic <code>vi</code> editor, which I personally find easier to use than Emacs. Type <code>vimtutor</code> to run the tutorial.</p>
+<p>One annoying feature of Vim is that it is hard to figure out how to
+quit. If you don't mind losing all of your changes, you can always get
+out by hitting the Escape key a few times and then typing <sub>~</sub>\\\ :qa!\\\ <sub>~</sub></p>
+<p>To run Vim, type <code class="backtick">vim</code> or <code class="backtick">vim&nbsp;filename</code> from the command line. Or you can use the graphical version <code class="backtick">gvim</code>, which pops up its own window.</p>
+<p>Vim is a <em>modal</em> editor, meaning that at any time you are in
+one of several modes (normal mode, insert mode, replace mode,
+operator-pending mode, etc.), and the interpretation of keystrokes
+depends on which mode you are in. So typing <code class="backtick">jjjj</code> in normal mode moves the cursor down four lines, while typing <code class="backtick">jjjj</code> in insert mode inserts the string <code class="backtick">jjjj</code>
+ at the current position. Most of the time you will be in either normal
+mode or insert mode. There is also a command mode entered by hitting <code class="backtick">:</code> that lets you type longer commands, similar to the Unix command-line or M-x in Emacs.</p>
+<h4 id="My_favorite_Vim_commands"><span class="header-section-number">3.2.2.1</span> My favorite Vim commands</h4>
+<h5 id="Normal_mode"><span class="header-section-number">3.2.2.1.1</span> Normal mode</h5>
+<dl>
+<dt>:h</dt>
+<dd>Get help. (Hit Enter at the end of any command that starts with a colon.) Escape
+</dd>
+<dd>Get out of whatever strange mode you are in and go back to normal
+mode. You will need to use this whenever you are done typing code and
+want to get back to typing commands.
+</dd>
+<dt>i</dt>
+<dd>Enter insert mode. You will need to do this to type anything. The command <code class="backtick">a</code> also enters insert mode, but puts new text after the current cursor position instead of before it. u
+</dd>
+<dd><p>Undo. Undoes the last change you made to the current buffer. Type
+ it again to undo more things. If you undid something by mistake, c-<code class="backtick">R</code> (control <code class="backtick">R</code>) will redo the last undo</p>
+<p>(and can also be repeated). :w</p>
+</dd>
+<dd><p>Write the current file to disk. Use <code class="backtick">:w&nbsp;filename</code> to write it to <code class="backtick">filename</code>. Use <code class="backtick">:wa</code> to write all files that you have modified. The command <code class="backtick">ZZ</code> does the</p>
+<p>same thing without having to hit Enter at the end. :e filename</p>
+</dd>
+<dd>Edit a different file.
+</dd>
+<dt>:q</dt>
+<dd>Quit. Vi will refuse to do this if you have unwritten files. See <code class="backtick">:wa</code> for how to fix this, or use <code class="backtick">:q!</code> if you want to throw away your changes and quit anyway. The shortcuts <code class="backtick">:x</code> and <code class="backtick">:wq</code> do a write of the current file followed by quitting.
+</dd>
+<dt>h, j, k, l</dt>
+<dd>Move the cursor left, down, up, or right. You can also use the arrow keys (in both normal mode and insert mode).
+</dd>
+<dt>x</dt>
+<dd>Delete the current character.
+</dd>
+<dt>D</dt>
+<dd>Delete to end of line.
+</dd>
+<dt>dd</dt>
+<dd>Delete all of the current line. This is a special case of a more general <code class="backtick">d</code> command. If you precede it with a number, you can delete multiple lines: <code class="backtick">5dd</code> deletes the next 5 lines. If you replace the second <code class="backtick">d</code> with a motion command, you delete until wherever you land: <code class="backtick">d$</code> deletes to end of line (<code class="backtick">D</code> is faster), <code class="backtick">dj</code> deletes this line and the line after it, <code class="backtick">d%</code> deletes the next matching group of parantheses/braces/brackets and whatever is between them, <code class="backtick">dG</code> deletes to end of file—there are many possibilities. All of these save what you deleted into register <code class="backtick">""</code> so you can get them back with <code class="backtick">p</code>.
+</dd>
+<dt>yy</dt>
+<dd>Like <code class="backtick">dd</code>, but only saves the line to register <code class="backtick">""</code> and doesn't delete it. (Think <em>copy</em>). All the variants of <code class="backtick">dd</code> work with <code class="backtick">yy</code>: <code class="backtick">5yy</code>, <code class="backtick">y$</code>, <code class="backtick">yj</code>, <code class="backtick">y%</code>, etc.
+</dd>
+<dt>p</dt>
+<dd>Pull whatever is in register <code class="backtick">""</code>. (Think <em>paste</em>).
+</dd>
+<dt>&lt;&lt; and &gt;&gt;</dt>
+<dd>Outdent or indent the current line one tab stop.
+</dd>
+<dt>:make</dt>
+<dd>Run <code class="backtick">make</code> in the current directory. You can also give it arguments, e.g., <code class="backtick">:make&nbsp;myprog</code>, <code class="backtick">:make&nbsp;test</code>. Use <code class="backtick">:cn</code> to go to the next error if you get errors.
+</dd>
+<dt>:!</dt>
+<dd>Run a command, e.g., <code class="backtick">:!&nbsp;echo&nbsp;hello&nbsp;world</code> or <code class="backtick">:!&nbsp;gdb&nbsp;myprogram</code>.
+ Returns to Vim when the command exits (control-C can sometimes be
+helpful if your command isn't exiting when it should). This works best
+if you ran Vim from a shell window; it doesn't work very well if Vim is
+running in its own window.
+</dd>
+</dl>
+<h5 id="Insert_mode"><span class="header-section-number">3.2.2.1.2</span> Insert mode</h5>
+<dl>
+<dt>control-P and control-N</dt>
+<dd>These are completion commands that attempt to expand a partial word
+to something it matches elsewhere in the buffer. So if you are a good
+person and have named a variable <code class="backtick">informativeVariableName</code> instead of <code class="backtick">ivn</code>, you can avoid having to type the entire word by typing <code class="backtick">inf</code>&lt;control-P&gt; if it's the only word in your buffer that starts with <code class="backtick">inf</code>.
+</dd>
+<dt>control-O and control-I</dt>
+<dd>Jump to the last cursor position before a big move / back to the place you jumped from.
+</dd>
+<dt>ESC</dt>
+<dd>Get out of insert mode!
+</dd>
+</dl>
+<h4 id="Settings"><span class="header-section-number">3.2.2.2</span> Settings</h4>
+<p>Unlike Emacs, Vim's default settings are not very good for editing C programs. You can fix this by creating a file called <code class="backtick">.vimrc</code> in your home directory with the following commands:</p>
+<div>
+<pre class="vim"><code>set shiftwidth=4
+set autoindent
+set backup
+set cindent
+set hlsearch
+set incsearch
+set showmatch
+set number
+syntax on
+filetype plugin on
+filetype indent on
+</code></pre>
+<a href="http://cs.yale.edu/homes/aspnes/classes/223/examples/sample.vimrc" class="uri">examples/sample.vimrc</a>
+</div>
+<p>(You can download this file by clicking on the link.)</p>
+<p>In Vim, you can type e.g. <code class="backtick">:help&nbsp;backup</code> to find out what each setting does. Note that because <code class="backtick">.vimrc</code> starts with a <code class="backtick">.</code>, it won't be visible to <code class="backtick">ls</code> unless you use <code class="backtick">ls&nbsp;-a</code> or <code class="backtick">ls&nbsp;-A</code>.</p>
+<h2 id="compilationTools"><span class="header-section-number">3.3</span> Compilation tools</h2>
+<h3 id="gcc"><span class="header-section-number">3.3.1</span> The GNU C compiler <code>gcc</code></h3>
+<p>A C program will typically consist of one or more files whose names end with <code>.c</code>. To compile <code>foo.c</code>, you can type <code>gcc&nbsp;foo.c</code>. Assuming <code>foo.c</code> contains no errors egregious enough to be detected by the extremely forgiving C compiler, this will produce a file named <code>a.out</code> that you can then execute by typing <code>./a.out</code>.</p>
+<p>If you want to debug your program using <code>gdb</code> or give it a different name, you will need to use a longer command line. Here's one that compiles <code>foo.c</code> to <code>foo</code> (run it using <code>./foo</code>) and includes the information that <code>gdb</code> needs: <code>gcc&nbsp;-g3&nbsp;-o&nbsp;foo&nbsp;foo.c</code></p>
+<p>If you want to use C99 features, you will need to tell <code>gcc</code> to use C99 instead of its own default dialect of C. You can do this either by adding the argument <code>-std=c99</code> as in <code>gcc -std=c99 -o foo foo.c</code> or by calling <code>gcc</code> as <code>c99</code> as in <code>c99 -o foo foo.c</code>.</p>
+<p>By default, gcc doesn't check everything that might be wrong with
+your program. But if you give it a few extra arguments, it will warn you
+ about many (but not all) potential problems: <code>c99 -g3&nbsp;-Wall&nbsp;-pedantic&nbsp;-o&nbsp;foo&nbsp;foo.c</code>.</p>
+<h3 id="make"><span class="header-section-number">3.3.2</span> Make</h3>
+<p>For complicated programs involving multiple source files, you are probably better off using <code>make</code> than calling <code>gcc</code>
+ directly. Make is a "rule-based expert system" that figures out how to
+compile programs given a little bit of information about their
+components.</p>
+<p>For example, if you have a file called <code>foo.c</code>, try typing <code>make&nbsp;foo</code> and see what happens.</p>
+<p>In general you will probably want to write a <code>Makefile</code>, which is named <code>Makefile</code> or <code>makefile</code> and tells <code>make</code> how to compile programs in the same directory. Here's a typical Makefile:</p>
+<div>
+<div class="sourceCode"><pre class="sourceCode makefile"><code class="sourceCode makefile"><span class="co"># Any line that starts with a sharp is a comment and is ignored</span>
+<span class="co"># by Make.</span>
+
+<span class="co"># These lines set variables that control make's default rules.</span>
+<span class="co"># We STRONGLY recommend putting "-Wall -pedantic -g3" in your CFLAGS.</span>
+<span class="dt">CC</span><span class="ch">=</span><span class="st">gcc</span>
+<span class="dt">CFLAGS=-std</span><span class="ch">=</span><span class="st">c99 -Wall -pedantic -g3</span>
+
+<span class="co"># The next line is a dependency line.</span>
+<span class="co"># It says that if somebody types "make all"</span>
+<span class="co"># make must first make "hello-world".</span>
+<span class="co"># By default the left-hand-side of the first dependency is what you</span>
+<span class="co"># get if you just type "make" with no arguments.</span>
+<span class="dv">all:</span><span class="dt"> hello-world</span>
+
+<span class="co"># How do we make hello-world?</span>
+<span class="co"># The dependency line says you need to first make hello-world.o</span>
+<span class="co"># and hello-library.o</span>
+<span class="dv">hello-world:</span><span class="dt"> hello-world.o hello-library.o</span>
+ <span class="co"># Subsequent lines starting with a TAB character give</span>
+ <span class="co"># commands to execute.</span>
+ <span class="co"># This command uses make built-in variables to avoid</span>
+ <span class="co"># retyping (and getting things wrong):</span>
+ <span class="co"># $@ = target hello-world</span>
+ <span class="co"># $^ = dependencies hello-world.o and hello-library.o</span>
+ <span class="ch">$(</span><span class="dt">CC</span><span class="ch">)</span> <span class="ch">$(</span><span class="dt">CFLAGS</span><span class="ch">)</span> -o <span class="ch">$@</span> <span class="ch">$^</span>
+ <span class="co"># You can put whatever commands you want.</span>
+ echo <span class="st">"I just built hello-world! Hooray!"</span>
+
+<span class="co"># Here we are saying that hello-world.o and hello-library.o</span>
+<span class="co"># should be rebuilt whenever their corresponding source file</span>
+<span class="co"># or hello-library.h changes.</span>
+<span class="co"># There are no commands attached to these dependency lines, so</span>
+<span class="co"># make will have to figure out how to do that somewhere else</span>
+<span class="co"># (probably from the builtin .c -&gt; .o rule).</span>
+<span class="dv">hello-world.o:</span><span class="dt"> hello-world.c hello-library.h</span>
+<span class="dv">hello-library.o:</span><span class="dt"> hello-library.c hello-library.h</span>
+
+<span class="co"># Command lines can do more than just build things. For example,</span>
+<span class="co"># "make test" will rebuild hello-world (if necessary) and then run it.</span>
+<span class="dv">test:</span><span class="dt"> hello-world</span>
+ ./hello-world
+
+<span class="co"># This lets you type "make clean" and get rid of anything you can</span>
+<span class="co"># rebuild. The $(RM) variable is predefined to "rm -f"</span>
+<span class="dv">clean:</span>
+ <span class="ch">$(</span><span class="dt">RM</span><span class="ch">)</span> hello-world *.o</code></pre></div>
+<a href="http://cs.yale.edu/homes/aspnes/classes/223/examples/usingMake/Makefile" class="uri">examples/usingMake/Makefile</a>
+</div>
+<p>Given a Makefile, make looks at each dependency line and asks: (a)
+does the target on the left hand side exist, and (b) is it older than
+the files it depends on. If so, it looks for a set of commands for
+rebuilding the target, after first rebuilding any of the files it
+depends on; the commands it runs will be underneath some dependency line
+ where the target appears on the left-hand side. It has built-in rules
+for doing common tasks like building <code>.o</code> files (which contain machine code) from <code>.c</code> files (which contain C source code). If you have a fake target like <code>all</code> above, it will try to rebuild everything <code>all</code> depends on because there is no file named <code>all</code> (one hopes).</p>
+<h4 id="Make_gotchas"><span class="header-section-number">3.3.2.1</span> Make gotchas</h4>
+<p>Make really really cares that the command lines start with a TAB
+character. TAB looks like eight spaces in Emacs and other editors, but
+it isn't the same thing. If you put eight spaces in (or a space and a
+TAB), Make will get horribly confused and give you an incomprehensible
+error message about a "missing separator". This misfeature is so scary
+that I avoided using make for years because I didn't understand what was
+ going on. Don't fall into that trap—make really is good for you,
+especially if you ever need to recompile a huge program when only a few
+source files have changed.</p>
+<p>If you use GNU Make (on a zoo node), note that beginning with version
+ 3.78, GNU Make prints a message that hints at a possible SPACEs-vs-TAB
+problem, like this:</p>
+<pre><code>$ make
+Makefile:23:*** missing separator (did you mean TAB instead of 8 spaces?). Stop.</code></pre>
+<p>If you need to repair a Makefile that uses spaces, one way of converting leading spaces into TABs is to use the <code>unexpand</code> program:</p>
+<pre><code>$ mv Makefile Makefile.old
+$ unexpand Makefile.old &gt; Makefile</code></pre>
+<h2 id="debugging"><span class="header-section-number">3.4</span> Debugging tools</h2>
+<p>The standard debugger on the Zoo is <code class="backtick">gdb</code>. Also useful is the memory error checker <code>valgrind</code>. Below are some notes on debugging in general and using these programs in particular.</p>
+<h3 id="Debugging_in_general"><span class="header-section-number">3.4.1</span> Debugging in general</h3>
+<p>Basic method of all debugging:</p>
+<ol style="list-style-type: decimal">
+<li>Know what your program is supposed to do.</li>
+<li>Detect when it doesn't.</li>
+<li>Fix it.</li>
+</ol>
+<p>A tempting mistake is to skip step 1, and just try randomly tweaking
+things until the program works. Better is to see what the program is
+doing internally, so you can see exactly where and when it is going
+wrong. A second temptation is to attempt to intuit where things are
+going wrong by staring at the code or the program's output. Avoid this
+temptation as well: let the computer tell you what it is really doing
+inside your program instead of guessing.</p>
+<h3 id="Assertions"><span class="header-section-number">3.4.2</span> Assertions</h3>
+<p>Every non-trivial C program should include <code class="backtick">&lt;assert.h&gt;</code>, which gives you the <code class="backtick">assert</code> macro (see Appendix B6 of K&amp;R). The <code class="backtick">assert</code> macro tests if a condition is true and halts your program with an error message if it isn't:</p>
+<div>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"><span class="ot">#include &lt;assert.h&gt;</span>
+
+<span class="dt">int</span>
+main(<span class="dt">int</span> argc, <span class="dt">char</span> **argv)
+{
+ assert(<span class="dv">2+2</span> == <span class="dv">5</span>);
+ <span class="kw">return</span> <span class="dv">0</span>;
+}</code></pre></div>
+<a href="http://cs.yale.edu/homes/aspnes/classes/223/examples/debugging/no.c" class="uri">examples/debugging/no.c</a>
+</div>
+<p>Compiling and running this program produces the following output:</p>
+<pre><code>$ gcc -o no no.c
+$ ./no
+no: no.c:6: main: Assertion `2+2 == 5' failed.</code></pre>
+<p>Line numbers and everything, even if you compile with the optimizer
+turned on. Much nicer than a mere segmentation fault, and if you run it
+under the debugger, the debugger will stop exactly on the line where the
+ <code class="backtick">assert</code> failed so you can poke around and see why.</p>
+<h3 id="gdb"><span class="header-section-number">3.4.3</span> The GNU debugger <code>gdb</code></h3>
+<p>The standard debugger on Linux is called <code class="backtick">gdb</code>. This lets you run your program under remote control, so that you can stop it and see what is going on inside.</p>
+<p>You can also use <code>ddd</code>, which is a graphical front-end for <code>gdb</code>. There is an <a href="http://www.gnu.org/software/ddd/manual/html_mono/ddd.html">extensive tutorial</a> available for <code>ddd</code>, so we will concentrate on the command-line interface to <code>gdb</code> here.</p>
+<p>We'll look at a contrived example. Suppose you have the following program <code>bogus.c</code>:</p>
+<div>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"><span class="ot">#include &lt;stdio.h&gt;</span>
+
+<span class="co">/* Print the sum of the integers from 1 to 1000 */</span>
+<span class="dt">int</span>
+main(<span class="dt">int</span> argc, <span class="dt">char</span> **argv)
+{
+ <span class="dt">int</span> i;
+ <span class="dt">int</span> sum;
+
+ sum = <span class="dv">0</span>;
+ <span class="kw">for</span>(i = <span class="dv">0</span>; i -= <span class="dv">1000</span>; i++) {
+ sum += i;
+ }
+ printf(<span class="st">"%d</span><span class="ch">\n</span><span class="st">"</span>, sum);
+ <span class="kw">return</span> <span class="dv">0</span>;
+}</code></pre></div>
+<a href="http://cs.yale.edu/homes/aspnes/classes/223/examples/debugging/bogus.c" class="uri">examples/debugging/bogus.c</a>
+</div>
+<p>Let's compile and run it and see what happens. Note that we include the flag <code>-g3</code> to tell the compiler to include debugging information. This allows <code>gdb</code> to translate machine addresses back into identifiers and line numbers in the original program for us.</p>
+<pre><code>$ c99 -g3 -o bogus bogus.c
+$ ./bogus
+-34394132
+$</code></pre>
+<p>That doesn't look like the sum of 1 to 1000. So what went wrong? If
+we were clever, we might notice that the test in the for loop is using
+the mysterious <code>-=</code> operator instead of the <code>&lt;=</code>
+ operator that we probably want. But let's suppose we're not so clever
+right now—it's four in the morning, we've been working on <code>bogus.c</code> for twenty-nine straight hours, and there's a <code>-=</code>
+ up there because in our befuddled condition we know in our bones that
+it's the right operator to use. We need somebody else to tell us that we
+ are deluding ourselves, but nobody is around this time of night. So
+we'll have to see what we can get the computer to tell us.</p>
+<p>The first thing to do is fire up <code>gdb</code>, the debugger. This
+ runs our program in stop-motion, letting us step through it a piece at a
+ time and watch what it is actually doing. In the example below gdb is
+run from the command line. You can also run it directly from Emacs with <code>M-x&nbsp;gdb</code>,
+ which lets Emacs track and show you where your program is in the source
+ file with a little arrow, or (if you are logged in directly on a Zoo
+machine) by running <code class="backtick">ddd</code>, which wraps <code class="backtick">gdb</code> in a graphical user interface.</p>
+<pre><code>$ gdb bogus
+GNU gdb 4.17.0.4 with Linux/x86 hardware watchpoint and FPU support
+Copyright 1998 Free Software Foundation, Inc.
+GDB is free software, covered by the GNU General Public License, and you are
+welcome to change it and/or distribute copies of it under certain conditions.
+Type "show copying" to see the conditions.
+There is absolutely no warranty for GDB. Type "show warranty" for details.
+This GDB was configured as "i386-redhat-linux"...
+(gdb) run
+Starting program: /home/accts/aspnes/tmp/bogus
+-34394132
+
+Program exited normally.</code></pre>
+<p>So far we haven't learned anything. To see our program in action, we
+need to slow it down a bit. We'll stop it as soon as it enters <code>main</code>, and step through it one line at a time while having it print out the values of the variables.</p>
+<pre><code>(gdb) break main
+Breakpoint 1 at 0x8048476: file bogus.c, line 9.
+(gdb) run
+Starting program: /home/accts/aspnes/tmp/bogus
+
+Breakpoint 1, main (argc=1, argv=0xbffff9ac) at bogus.c:9
+9 sum = 0;
+(gdb) display sum
+1: sum = 1
+(gdb) n
+10 for(i = 0; i -= 1000; i++)
+1: sum = 0
+(gdb) display i
+2: i = 0
+(gdb) n
+11 sum += i;
+2: i = -1000
+1: sum = 0
+(gdb) n
+10 for(i = 0; i -= 1000; i++)
+2: i = -1000
+1: sum = -1000
+(gdb) n
+11 sum += i;
+2: i = -1999
+1: sum = -1000
+(gdb) n
+10 for(i = 0; i -= 1000; i++)
+2: i = -1999
+1: sum = -2999
+(gdb) quit
+The program is running. Exit anyway? (y or n) y
+$</code></pre>
+<p>Here we are using <code>break&nbsp;main</code> to tell the program to stop as soon as it enters <code>main</code>, <code>display</code> to tell it to show us the value of the variables <code>i</code> and <code>sum</code> whenever it stops, and <code>n</code> (short for <code>next</code>) to execute the program one line at a time.</p>
+<p>When stepping through a program, gdb displays the line it will execute <em>next</em> as well as any variables you've told it to display. This means that any changes you see in the variables are the result of the <em>previous</em> displayed line. Bearing this in mind, we see that <code>i</code> drops from 0 to -1000 the very first time we hit the top of the <code>for</code> loop and drops to -1999 the next time. So something bad is happening in the top of that <code>for</code> loop, and if we squint at it a while we might begin to suspect that <code>i&nbsp;-=&nbsp;1000</code> is not the nice simple test we might have hoped it was.</p>
+<h4 id="My_favorite_gdb_commands"><span class="header-section-number">3.4.3.1</span> My favorite gdb commands</h4>
+<dl>
+<dt>help</dt>
+<dd>Get a description of gdb's commands.
+</dd>
+<dt>run</dt>
+<dd>Runs your program. You can give it arguments that get passed in to
+your program just as if you had typed them to the shell. Also used to
+restart your program from the beginning if it is already running.
+</dd>
+<dt>quit</dt>
+<dd>Leave gdb, killing your program if necessary.
+</dd>
+<dt>break</dt>
+<dd>Set a breakpoint, which is a place where gdb will automatically stop your program. Some examples: - <code>break&nbsp;somefunction</code> stops before executing the first line <code>somefunction</code>. - <code>break&nbsp;117</code> stops before executing line number 117.
+</dd>
+<dt>list</dt>
+<dd>Show part of your source file with line numbers (handy for figuring out where to put breakpoints). Examples: - <code>list&nbsp;somefunc</code> lists all lines of <code>somefunc</code>. - <code>list&nbsp;117-123</code> lists lines 117 through 123.
+</dd>
+<dt>next</dt>
+<dd>Execute the next line of the program, including completing any procedure calls in that line.
+</dd>
+<dt>step</dt>
+<dd>Execute the next step of the program, which is either the next line
+if it contains no procedure calls, or the entry into the called
+procedure.
+</dd>
+<dt>finish</dt>
+<dd>Continue until you get out of the current procedure (or hit a
+breakpoint). Useful for getting out of something you stepped into that
+you didn't want to step into.
+</dd>
+<dt>cont</dt>
+<dd>(Or <code>continue</code>). Continue until (a) the end of the
+program, (b) a fatal error like a Segmentation Fault or Bus Error, or
+(c) a breakpoint. If you give it a numeric argument (e.g., <code>cont&nbsp;1000</code>) it will skip over that many breakpoints before stopping.
+</dd>
+<dt>print</dt>
+<dd>Print the value of some expression, e.g. <code>print&nbsp;i</code>.
+</dd>
+<dt>display</dt>
+<dd>Like <code>print</code>, but runs automatically every time the program stops. Useful for watching values that change often.
+</dd>
+<dt>set disable-randomization off</dt>
+<dd>Not something you will need every day, but you should try this
+before running your program if it is producing segmentation faults
+outside of <code>gdb</code> but not inside. Normally the Linux kernel
+randomizes the position of bits of your program before running it, to
+make its response to buffer overflow attacks less predictable. By
+default, <code>gdb</code> turns this off so that the behavior of your
+program is consistent from one execution to the next. But sometimes this
+ means that a pointer that had been bad with address randomization
+(causing a segmentation fault) turns out not to be bad without. This
+option will restore the standard behavior outside <code>gdb</code> and give you some hope of finding what went wrong.
+</dd>
+</dl>
+<h4 id="Debugging_strategies"><span class="header-section-number">3.4.3.2</span> Debugging strategies</h4>
+<p>In general, the idea behind debugging is that a bad program starts
+out sane, but after executing for a while it goes bananas. If you can
+find the exact moment in its execution where it first starts acting up,
+you can see exactly what piece of code is causing the problem and have a
+ reasonably good chance of being able to fix it. So a typical debugging
+strategy is to put in a breakpoint (using <code>break</code>) somewhere before the insanity hits, "instrument" the program (using <code>display</code>) so that you can watch it going insane, and step through it (using <code>next</code>, <code>step</code>, or breakpoints and <code>cont</code>) until you find the point of failure. Sometimes this process requires restarting the program (using <code>run</code>) if you skip over this point without noticing it immediately.</p>
+<p>For large or long-running programs, it often makes sense to do binary
+ search to find the point of failure. Put in a breakpoint somewhere
+(say, on a function that is called many times or at the top of a major
+loop) and see what the state of the program is after going through the
+breakpoint 1000 times (using something like <code>cont&nbsp;1000</code>).
+ If it hasn't gone bonkers yet, try restarting and going through 2000
+times. Eventually you bracket the error as occurring (for example)
+somewhere between the 4000th and 8000th occurrence of the breakpoint.
+Now try stepping through 6000 times; if the program is looking good, you
+ know the error occurs somewhere between the 6000th and 8000th
+breakpoint. A dozen or so more experiments should be enough isolate the
+bug to a specific line of code.</p>
+<p><em>The key to all debugging</em> is knowing what your code is
+supposed to do. If you don't know this, you can't tell the lunatic who
+thinks he's Napoleon from lunatic who really is Napoleon. If you're
+confused about what your code is supposed to be doing, you need to
+figure out what exactly you want it to do. If you can figure that out,
+often it will be obvious what is going wrong. If it isn't obvious, you
+can always go back to <code>gdb</code>.</p>
+<h4 id="common-applications-of-gdb"><span class="header-section-number">3.4.3.3</span> Common applications of <code>gdb</code></h4>
+<p>Here are some typical classes of bugs and how to squish them with <code>gdb</code>. (The same instructions usually work for <code>ddd</code>.)</p>
+<h5 id="watching-your-program-run"><span class="header-section-number">3.4.3.3.1</span> Watching your program run</h5>
+<ol style="list-style-type: decimal">
+<li>Compile your program with the <code>-g3</code> flag. You can still run <code>gdb</code> if you don't do this, but it won't be able to show you variable names or source lines.</li>
+<li>Run <code>gdb</code> with <code>gdb</code> <em>programname</em>.</li>
+<li>Type <code>break main</code> to stop at the start of the <code>main</code> routine.</li>
+<li>Run your program with <code>run</code> <em>arguments</em>. The <code>run</code> command stands in for the program name. You can also redirect input as in the shell with <code>run</code> <em>arguments</em> &lt; <em>filename</em>.</li>
+<li>When the program stops, you can display variables in the current function or expressions involving these variables using <code>display</code>, as in <code>display x</code>, <code>display a[i]</code>, <code>display z+17</code>. In <code>ddd</code>, double-clicking on a variable name will have the same effect. Use <code>undisplay</code> to get rid of any displays you don't want.</li>
+<li>To step through your program, use <code>next</code> (always goes to next line in the current function, not dropping down into function calls), <code>step</code> (go to the next executed line, even if it is inside a called function), <code>finish</code> (run until the current function returns), and <code>cont</code> (run until the end of the program or the next breakpoint).</li>
+</ol>
+<p>This can be handy if you don't particularly know what is going on in your program and want to see.</p>
+<h5 id="dealing-with-failed-assertions"><span class="header-section-number">3.4.3.3.2</span> Dealing with failed assertions</h5>
+<p>Run the program as described above. When you hit the bad <code>assert</code>, you will stop several functions deep from where it actually happened. Use <code>up</code> to get up to the function that has the call to <code>assert</code> then use <code>print</code> or <code>display</code> to figure out what is going on.</p>
+<p>Example program:</p>
+<div>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"><span class="ot">#include &lt;stdio.h&gt;</span>
+<span class="ot">#include &lt;stdlib.h&gt;</span>
+<span class="ot">#include &lt;assert.h&gt;</span>
+
+<span class="dt">int</span>
+main(<span class="dt">int</span> argc, <span class="dt">char</span> **argv)
+{
+ <span class="dt">int</span> x;
+
+ x = <span class="dv">3</span>;
+
+ assert(x+x == <span class="dv">4</span>);
+
+ <span class="kw">return</span> <span class="dv">0</span>;
+}</code></pre></div>
+<a href="http://cs.yale.edu/homes/aspnes/classes/223/examples/debugging/assertFailed.c" class="uri">examples/debugging/assertFailed.c</a>
+</div>
+<p>With <code>gdb</code> in action:</p>
+<pre><code>$ gcc -g3 -o assertFailed assertFailed.c
+22:59:39 (Sun Feb 15) zeniba aspnes ~/g/classes/223/notes/examples/debugging
+$ gdb assertFailed
+GNU gdb (Ubuntu 7.7.1-0ubuntu5~14.04.2) 7.7.1
+Copyright (C) 2014 Free Software Foundation, Inc.
+License GPLv3+: GNU GPL version 3 or later &lt;http://gnu.org/licenses/gpl.html&gt;
+This is free software: you are free to change and redistribute it.
+There is NO WARRANTY, to the extent permitted by law. Type "show copying"
+and "show warranty" for details.
+This GDB was configured as "i686-linux-gnu".
+Type "show configuration" for configuration details.
+For bug reporting instructions, please see:
+&lt;http://www.gnu.org/software/gdb/bugs/&gt;.
+Find the GDB manual and other documentation resources online at:
+&lt;http://www.gnu.org/software/gdb/documentation/&gt;.
+For help, type "help".
+Type "apropos word" to search for commands related to "word"...
+Reading symbols from assertFailed...done.
+(gdb) run
+Starting program: /home/aspnes/g/classes/223/notes/examples/debugging/assertFailed
+assertFailed: assertFailed.c:12: main: Assertion `x+x == 4' failed.
+
+Program received signal SIGABRT, Aborted.
+0xb7fdd416 in __kernel_vsyscall ()
+(gdb) up
+#1 0xb7e43577 in __GI_raise (sig=sig@entry=6) at ../nptl/sysdeps/unix/sysv/linux/raise.c:56
+56 ../nptl/sysdeps/unix/sysv/linux/raise.c: No such file or directory.
+(gdb) up
+#2 0xb7e469a3 in __GI_abort () at abort.c:89
+89 abort.c: No such file or directory.
+(gdb) up
+#3 0xb7e3c6c7 in __assert_fail_base (fmt=0xb7f7a8b4 "%s%s%s:%u: %s%sAssertion `%s' failed.\n%n",
+ assertion=assertion@entry=0x804850f "x+x == 4", file=file@entry=0x8048500 "assertFailed.c",
+ line=line@entry=12, function=function@entry=0x8048518 &lt;__PRETTY_FUNCTION__.2355&gt; "main") at assert.c:92
+92 assert.c: No such file or directory.
+(gdb) up
+#4 0xb7e3c777 in __GI___assert_fail (assertion=0x804850f "x+x == 4", file=0x8048500 "assertFailed.c", line=12,
+ function=0x8048518 &lt;__PRETTY_FUNCTION__.2355&gt; "main") at assert.c:101
+101 in assert.c
+(gdb) up
+#5 0x0804845d in main (argc=1, argv=0xbffff434) at assertFailed.c:12
+12 assert(x+x == 4);
+(gdb) print x
+$1 = 3</code></pre>
+<p>Here we see that <code>x</code> has value 3, which may or may not be the right value, but certainly violates the assertion.</p>
+<h5 id="dealing-with-segmentation-faults"><span class="header-section-number">3.4.3.3.3</span> Dealing with segmentation faults</h5>
+<p>Very much like the previous case. Run <code>gdb</code> until the segmentation fault hits, then look around for something wrong.</p>
+<div>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"><span class="ot">#include &lt;stdio.h&gt;</span>
+<span class="ot">#include &lt;stdlib.h&gt;</span>
+<span class="ot">#include &lt;assert.h&gt;</span>
+
+<span class="dt">int</span>
+main(<span class="dt">int</span> argc, <span class="dt">char</span> **argv)
+{
+ <span class="dt">int</span> a[<span class="dv">1000</span>];
+ <span class="dt">int</span> i;
+
+ i = -<span class="dv">1771724</span>;
+
+ printf(<span class="st">"%d</span><span class="ch">\n</span><span class="st">"</span>, a[i]);
+
+ <span class="kw">return</span> <span class="dv">0</span>;
+}</code></pre></div>
+<a href="http://cs.yale.edu/homes/aspnes/classes/223/examples/debugging/segmentationFault.c" class="uri">examples/debugging/segmentationFault.c</a>
+</div>
+<pre><code>$ gcc -g3 -o segmentationFault segmentationFault.c
+23:04:18 (Sun Feb 15) zeniba aspnes ~/g/classes/223/notes/examples/debugging
+$ gdb segmentationFault
+GNU gdb (Ubuntu 7.7.1-0ubuntu5~14.04.2) 7.7.1
+[...]
+Reading symbols from segmentationFault...done.
+(gdb) run
+Starting program: /home/aspnes/g/classes/223/notes/examples/debugging/segmentationFault
+
+Program received signal SIGSEGV, Segmentation fault.
+0x08048435 in main (argc=1, argv=0xbffff434) at segmentationFault.c:13
+13 printf("%d\n", a[i]);
+(gdb) print a[i]
+$1 = 0
+(gdb) print i
+$2 = -1771724</code></pre>
+<p>Curiously, <code>gdb</code> has no problem coming up with a value for <code>a[i]</code>. But <code>i</code> looks pretty suspicious.</p>
+<h5 id="dealing-with-infinite-loops"><span class="header-section-number">3.4.3.3.4</span> Dealing with infinite loops</h5>
+<p>Run <code>gdb</code>, wait a while, then hit control-C. This will stop <code>gdb</code>
+ wherever it is. If you have an infinite loop, it's likely that you will
+ be in it, and that the index variables will be doing something
+surprising. Use <code>display</code> to keep an eye on them and do <code>next</code> a few times.</p>
+<pre><code>
+$ gcc -g3 -o infiniteLoop infiniteLoop.c
+23:08:05 (Sun Feb 15) zeniba aspnes ~/g/classes/223/notes/examples/debugging
+$ gdb infiniteLoop
+GNU gdb (Ubuntu 7.7.1-0ubuntu5~14.04.2) 7.7.1
+[...]
+Reading symbols from infiniteLoop...done.
+(gdb) run
+Starting program: /home/aspnes/g/classes/223/notes/examples/debugging/infiniteLoop
+^C
+Program received signal SIGINT, Interrupt.
+main (argc=1, argv=0xbffff434) at infiniteLoop.c:11
+11 i *= 37;
+(gdb) display i
+1: i = 0
+(gdb) n
+10 for(i = 0; i &lt; 10; i += 0) {
+1: i = 0
+(gdb) n
+11 i *= 37;
+1: i = 0
+(gdb) n
+10 for(i = 0; i &lt; 10; i += 0) {
+1: i = 0
+(gdb) n
+11 i *= 37;
+1: i = 0
+(gdb) n
+10 for(i = 0; i &lt; 10; i += 0) {
+1: i = 0
+(gdb) n
+11 i *= 37;
+1: i = 0</code></pre>
+<h5 id="mysterious-variable-changes"><span class="header-section-number">3.4.3.3.5</span> Mysterious variable changes</h5>
+<p>Sometimes pointer botches don't manifest as good, honest segmentation
+ faults but instead as mysterious changes to seemingly unrelated
+variables. You can catch these in the act using conditional breakpoints.
+ The downside is that you can only put conditional breakpoints on
+particular lines.</p>
+<p>Here's a program that violates array bounds (which C doesn't detect):</p>
+<div>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"><span class="ot">#include &lt;stdio.h&gt;</span>
+<span class="ot">#include &lt;stdlib.h&gt;</span>
+<span class="ot">#include &lt;assert.h&gt;</span>
+
+<span class="dt">int</span>
+main(<span class="dt">int</span> argc, <span class="dt">char</span> **argv)
+{
+ <span class="dt">int</span> x;
+ <span class="dt">int</span> a[<span class="dv">10</span>];
+ <span class="dt">int</span> i;
+
+ x = <span class="dv">5</span>;
+
+ <span class="kw">for</span>(i = -<span class="dv">1</span>; i &lt; <span class="dv">11</span>; i++) {
+ a[i] = <span class="dv">37</span>;
+ }
+
+ assert(x == <span class="dv">5</span>);
+
+ <span class="kw">return</span> <span class="dv">0</span>;
+}</code></pre></div>
+<a href="http://cs.yale.edu/homes/aspnes/classes/223/examples/debugging/mysteryChange.c" class="uri">examples/debugging/mysteryChange.c</a>
+</div>
+<p>In the debugging session below, it takes a couple of attempts to catch the change in <code>x</code> before hitting the failed assertion.</p>
+<pre><code>$ gcc -g3 -o mysteryChange mysteryChange.c
+23:15:41 (Sun Feb 15) zeniba aspnes ~/g/classes/223/notes/examples/debugging
+$ gdb mysteryChange
+GNU gdb (Ubuntu 7.7.1-0ubuntu5~14.04.2) 7.7.1
+[...]
+Reading symbols from mysteryChange...done.
+(gdb) run
+Starting program: /home/aspnes/g/classes/223/notes/examples/debugging/mysteryChange
+mysteryChange: mysteryChange.c:18: main: Assertion `x == 5' failed.
+
+Program received signal SIGABRT, Aborted.
+0xb7fdd416 in __kernel_vsyscall ()
+(gdb) list main
+2 #include &lt;stdlib.h&gt;
+3 #include &lt;assert.h&gt;
+4
+5 int
+6 main(int argc, char **argv)
+7 {
+8 int x;
+9 int a[10];
+10 int i;
+11
+(gdb) list
+12 x = 5;
+13
+14 for(i = -1; i &lt; 11; i++) {
+15 a[i] = 37;
+16 }
+17
+18 assert(x == 5);
+19
+20 return 0;
+21 }
+(gdb) break 14 if x != 5
+Breakpoint 1 at 0x804842e: file mysteryChange.c, line 14.
+(gdb) run
+The program being debugged has been started already.
+Start it from the beginning? (y or n) y
+
+Starting program: /home/aspnes/g/classes/223/notes/examples/debugging/mysteryChange
+mysteryChange: mysteryChange.c:18: main: Assertion `x == 5' failed.
+
+Program received signal SIGABRT, Aborted.
+0xb7fdd416 in __kernel_vsyscall ()
+(gdb) break 15 if x != 5
+Breakpoint 2 at 0x8048438: file mysteryChange.c, line 15.
+(gdb) run
+The program being debugged has been started already.
+Start it from the beginning? (y or n) y
+
+Starting program: /home/aspnes/g/classes/223/notes/examples/debugging/mysteryChange
+
+Breakpoint 2, main (argc=1, argv=0xbffff434) at mysteryChange.c:15
+15 a[i] = 37;
+(gdb) print i
+$1 = 0
+(gdb) print a[0]
+$2 = 134520832
+(gdb) print a[-1]
+$3 = 37
+(gdb) print x
+$4 = 37</code></pre>
+<p>One thing to note is that a breakpoint stops before the line it is on executes. So when we hit the breakpoint on line 15 (<code>gdb</code> having observed that <code>x != 5</code> is true), <code>i</code> has the value 0, but the damage happened in the previous interation when <code>i</code>
+ was -1. If we want to see exactly what happened then, we'd need to go
+back in time. We can't do this, but we could set an earlier breakpoint
+and run the program again.</p>
+<h3 id="valgrind"><span class="header-section-number">3.4.4</span> Valgrind</h3>
+<p>The <code class="backtick">valgrind</code> program can be used to
+detect some (but not all) common errors in C programs that use pointers
+and dynamic storage allocation. On the Zoo, you can run <code class="backtick">valgrind</code> on your program by putting <code class="backtick">valgrind</code> at the start of the command line:</p>
+<pre><code>valgrind ./my-program arg1 arg2 &lt; test-input</code></pre>
+<p>This will run your program and produce a report of any allocations
+and de-allocations it did. It will also warn you about common errors
+like using unitialized memory, dereferencing pointers to strange places,
+ writing off the end of blocks allocated using <code class="backtick">malloc</code>, or failing to free blocks.</p>
+<p>You can suppress all of the output except errors using the <code class="backtick">-q</code> option, like this:</p>
+<pre><code>valgrind -q ./my-program arg1 arg2 &lt; test-input</code></pre>
+<p>You can also turn on more tests, e.g.</p>
+<pre><code>valgrind -q --tool=memcheck --leak-check=yes ./my-program arg1 arg2 &lt; test-input</code></pre>
+<p>See <code class="backtick">valgrind&nbsp;--help</code> for more information about the (many) options, or look at the documentation at <a href="http://valgrind.org/" class="uri">http://valgrind.org/</a> for detailed information about what the output means. For some common <code class="backtick">valgrind</code> messages, see the examples section below.</p>
+<p>If you want to run <code>valgrind</code> on your own machine, you may be able to find a version that works at <a href="http://valgrind.org/" class="uri">http://valgrind.org</a>.
+ Unfortunately, this is only likely to work if you are running a
+Unix-like operating system (which includes Linux and Mac OSX, but not
+Windows).</p>
+<h4 id="Compilation_flags"><span class="header-section-number">3.4.4.1</span> Compilation flags</h4>
+<p>You can run <code class="backtick">valgrind</code> on any program (try <code class="backtick">valgrind&nbsp;ls</code>); it does not require special compilation. However, the output of <code class="backtick">valgrind</code> will be more informative if you compile your program with debugging information turned on using the <code class="backtick">-g</code> or <code class="backtick">-g3</code> flags (this is also useful if you plan to watch your program running using <code class="backtick">gdb</code>, ).</p>
+<h4 id="Automated_testing"><span class="header-section-number">3.4.4.2</span> Automated testing</h4>
+<p>Unless otherwise specified, automated testing of your program will be done using the script in <code class="backtick">/c/cs223/bin/vg</code>; this runs <code class="backtick">/c/cs223/bin/valgrind</code> with the <code class="backtick">--tool=memcheck</code>, <code class="backtick">--leak-check=yes</code>, and <code class="backtick">-q</code> options, throws away your program's output, and replaces it with <code class="backtick">valgrind</code>'s output. If you have a program named <code class="backtick">./prog</code>, running <code class="backtick">/c/cs223/bin/vg&nbsp;./prog</code> should produce no output.</p>
+<h4 id="Examples_of_some_common_valgrindErrors"><span class="header-section-number">3.4.4.3</span> Examples of some common valgrind errors</h4>
+<p>Here are some examples of <code class="backtick">valgrind</code> output. In each case the example program is compiled with <code class="backtick">-g3</code> so that <code class="backtick">valgrind</code> can report line numbers from the source code.</p>
+<h5 id="Uninitialized_values"><span class="header-section-number">3.4.4.3.1</span> Uninitialized values</h5>
+<p>Consider this unfortunate program, which attempts to compare two strings, one of which we forgot to ensure was null-terminated:</p>
+<div>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"><span class="ot">#include &lt;stdio.h&gt;</span>
+
+<span class="dt">int</span>
+main(<span class="dt">int</span> argc, <span class="dt">char</span> **argv)
+{
+ <span class="dt">char</span> a[<span class="dv">2</span>];
+
+ a[<span class="dv">0</span>] = 'a';
+
+ <span class="kw">if</span>(!strcmp(a, <span class="st">"a"</span>)) {
+ puts(<span class="st">"a is </span><span class="ch">\"</span><span class="st">a</span><span class="ch">\"</span><span class="st">"</span>);
+ }
+
+ <span class="kw">return</span> <span class="dv">0</span>;
+}</code></pre></div>
+<a href="http://cs.yale.edu/homes/aspnes/classes/223/examples/valgrindErrors/uninitialized.c" class="uri">examples/valgrindErrors/uninitialized.c</a>
+</div>
+<p>Run without valgrind, we see no errors, because we got lucky and it turned out our hand-built string was null-terminated anyway:</p>
+<pre><code>$ ./uninitialized
+a is "a"</code></pre>
+<p>But <code class="backtick">valgrind</code> is not fooled:</p>
+<pre><code>$ valgrind -q ./uninitialized
+==4745== Conditional jump or move depends on uninitialised value(s)
+==4745== at 0x4026663: strcmp (mc_replace_strmem.c:426)
+==4745== by 0x8048435: main (uninitialized.c:10)
+==4745==
+==4745== Conditional jump or move depends on uninitialised value(s)
+==4745== at 0x402666C: strcmp (mc_replace_strmem.c:426)
+==4745== by 0x8048435: main (uninitialized.c:10)
+==4745==
+==4745== Conditional jump or move depends on uninitialised value(s)
+==4745== at 0x8048438: main (uninitialized.c:10)
+==4745== </code></pre>
+<p>Here we get a lot of errors, but they are all complaining about the same call to <code class="backtick">strcmp</code>. Since it's unlikely that <code class="backtick">strcmp</code>
+ itself is buggy, we have to assume that we passed some uninitialized
+location into it that it is looking at. The fix is to add an assignment <code class="backtick">a[1]&nbsp;=&nbsp;'\0'</code> so that no such location exists.</p>
+<h5 id="Bytes_definitely_lost"><span class="header-section-number">3.4.4.3.2</span> Bytes definitely lost</h5>
+<p>Here is a program that calls <code class="backtick">malloc</code> but not <code class="backtick">free</code>:</p>
+<div>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"><span class="ot">#include &lt;stdio.h&gt;</span>
+<span class="ot">#include &lt;stdlib.h&gt;</span>
+
+<span class="dt">int</span>
+main(<span class="dt">int</span> argc, <span class="dt">char</span> **argv)
+{
+ <span class="dt">char</span> *s;
+
+ s = malloc(<span class="dv">26</span>);
+
+ <span class="kw">return</span> <span class="dv">0</span>;
+}</code></pre></div>
+<a href="http://cs.yale.edu/homes/aspnes/classes/223/examples/valgrindErrors/missing_free.c" class="uri">examples/valgrindErrors/missing_free.c</a>
+</div>
+<p>With no extra arguments, <code class="backtick">valgrind</code> will not look for this error. But if we turn on <code class="backtick">--leak-check=yes</code>, it will complain:</p>
+<pre><code>$ valgrind -q --leak-check=yes ./missing_free
+==4776== 26 bytes in 1 blocks are definitely lost in loss record 1 of 1
+==4776== at 0x4024F20: malloc (vg_replace_malloc.c:236)
+==4776== by 0x80483F8: main (missing_free.c:9)
+==4776== </code></pre>
+<p>Here the stack trace in the output shows where the bad block was allocated: inside <code class="backtick">malloc</code> (specifically the paranoid replacement <code class="backtick">malloc</code> supplied by <code class="backtick">valgrind</code>), which was in turn called by <code class="backtick">main</code> in line 9 of <code class="backtick">missing_free.c</code>.
+ This lets us go back and look at what block was allocated in that line
+and try to trace forward to see why it wasn't freed. Sometimes this is
+as simple as forgetting to include a <code class="backtick">free</code>
+statement anywhere, but in more complicated cases it may be because I
+somehow lose the pointer to the block by overwriting the last variable
+that points to it or by embedding it in some larger structure whose
+components I forget to free individually.</p>
+<h5 id="Invalid_write_or_read_operations"><span class="header-section-number">3.4.4.3.3</span> Invalid write or read operations</h5>
+<p>These are usually operations that you do off the end of a block from <code class="backtick">malloc</code> or on a block that has already been freed.</p>
+<p>An example of the first case:</p>
+<div>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"><span class="ot">#include &lt;stdio.h&gt;</span>
+<span class="ot">#include &lt;stdlib.h&gt;</span>
+<span class="ot">#include &lt;assert.h&gt;</span>
+
+<span class="dt">int</span>
+main(<span class="dt">int</span> argc, <span class="dt">char</span> **argv)
+{
+ <span class="dt">char</span> *s;
+
+ s = malloc(<span class="dv">1</span>);
+ s[<span class="dv">0</span>] = 'a';
+ s[<span class="dv">1</span>] = '\<span class="dv">0</span>';
+
+ puts(s);
+
+ <span class="kw">return</span> <span class="dv">0</span>;
+}</code></pre></div>
+<a href="http://cs.yale.edu/homes/aspnes/classes/223/examples/valgrindErrors/invalid_operations.c" class="uri">examples/valgrindErrors/invalid_operations.c</a>
+</div>
+<pre><code>==7141== Invalid write of size 1
+==7141== at 0x804843B: main (invalid_operations.c:12)
+==7141== Address 0x419a029 is 0 bytes after a block of size 1 alloc'd
+==7141== at 0x4024F20: malloc (vg_replace_malloc.c:236)
+==7141== by 0x8048428: main (invalid_operations.c:10)
+==7141==
+==7141== Invalid read of size 1
+==7141== at 0x4026063: __GI_strlen (mc_replace_strmem.c:284)
+==7141== by 0x409BCE4: puts (ioputs.c:37)
+==7141== by 0x8048449: main (invalid_operations.c:14)
+==7141== Address 0x419a029 is 0 bytes after a block of size 1 alloc'd
+==7141== at 0x4024F20: malloc (vg_replace_malloc.c:236)
+==7141== by 0x8048428: main (invalid_operations.c:10)
+==7141== </code></pre>
+<p>An example of the second:</p>
+<div>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"><span class="ot">#include &lt;stdio.h&gt;</span>
+<span class="ot">#include &lt;stdlib.h&gt;</span>
+<span class="ot">#include &lt;assert.h&gt;</span>
+
+<span class="dt">int</span>
+main(<span class="dt">int</span> argc, <span class="dt">char</span> **argv)
+{
+ <span class="dt">char</span> *s;
+
+ s = malloc(<span class="dv">2</span>);
+ free(s);
+
+ s[<span class="dv">0</span>] = 'a';
+ s[<span class="dv">1</span>] = '\<span class="dv">0</span>';
+
+ puts(s);
+
+ <span class="kw">return</span> <span class="dv">0</span>;
+}</code></pre></div>
+<a href="http://cs.yale.edu/homes/aspnes/classes/223/examples/valgrindErrors/freed_block.c" class="uri">examples/valgrindErrors/freed_block.c</a>
+</div>
+<pre><code>==7144== Invalid write of size 1
+==7144== at 0x804846D: main (freed_block.c:13)
+==7144== Address 0x419a028 is 0 bytes inside a block of size 2 free'd
+==7144== at 0x4024B3A: free (vg_replace_malloc.c:366)
+==7144== by 0x8048468: main (freed_block.c:11)
+==7144==
+==7144== Invalid write of size 1
+==7144== at 0x8048477: main (freed_block.c:14)
+==7144== Address 0x419a029 is 1 bytes inside a block of size 2 free'd
+==7144== at 0x4024B3A: free (vg_replace_malloc.c:366)
+==7144== by 0x8048468: main (freed_block.c:11)
+==7144==
+==7144== Invalid read of size 1
+==7144== at 0x4026058: __GI_strlen (mc_replace_strmem.c:284)
+==7144== by 0x409BCE4: puts (ioputs.c:37)
+==7144== by 0x8048485: main (freed_block.c:16)
+[... more lines of errors deleted ...]</code></pre>
+<p>In both cases the problem is that we are operating on memory that is
+not guaranteed to be allocated to us. For short programs like these, we
+might get lucky and have the program work anyway. But we still want to
+avoid bugs like this because we might not get lucky.</p>
+<p>How do we know which case is which? If I write off the end of an existing block, I'll see something like <code class="backtick">Address&nbsp;0x419a029&nbsp;is&nbsp;0&nbsp;bytes&nbsp;after&nbsp;a&nbsp;block&nbsp;of&nbsp;size&nbsp;1&nbsp;alloc'd</code>,
+ telling me that I am working on an address after a block that is still
+allocated. When I try to write to a freed block, the message changes to <code class="backtick">Address&nbsp;0x419a029&nbsp;is&nbsp;1&nbsp;bytes&nbsp;inside&nbsp;a&nbsp;block&nbsp;of&nbsp;size&nbsp;2&nbsp;free'd</code>, where the <code class="backtick">free'd</code>
+ part tells me I freed something I probably shouldn't have. Fixing the
+first class of bugs is usually just a matter of allocating a bigger
+block (but don't just do this without figuring out <em>why</em> you need
+ a bigger block, or you'll just be introducing random mutations into
+your code that may cause other problems elsewhere). Fixing the second
+class of bugs usually involves figuring out why you freed this block
+prematurely. In some cases you may need to re-order what you are doing
+so that you don't free a block until you are completely done with it.</p>
+<h3 id="Not_recommended:_debugging_output"><span class="header-section-number">3.4.5</span> Not recommended: debugging output</h3>
+<p>A tempting but usually bad approach to debugging is to put lots of <code class="backtick">printf</code> statements in your code to show what is going on. The problem with this compared to using <code class="backtick">assert</code> is that there is no built-in test to see if the output is actually what you'd expect. The problem compared to <code class="backtick">gdb</code>
+ is that it's not flexible: you can't change your mind about what is
+getting printed out without editing the code. A third problem is that
+the output can be misleading: in particular, <code class="backtick">printf</code>
+ output is usually buffered, which means that if your program dies
+suddenly there may be output still in the buffer that is never flushed
+to <code class="backtick">stdout</code>. This can be very confusing, and can lead you to believe that your program fails earlier than it actually does.</p>
+<p>If you really need to use <code class="backtick">printf</code> or something like it for debugging output, here are a few rules of thumb to follow to mitigate the worst effects:</p>
+<ol style="list-style-type: decimal">
+<li>Use <code class="backtick">fprintf(stderr,&nbsp;...)</code> instead of <code class="backtick">printf(...)</code>;
+ this allows you to redirect your program's regular output somewhere
+that keeps it separate from the debugging output (but beware of
+misleading interleaving of the two streams—buffering may mean that
+output to <code class="backtick">stdout</code> and <code class="backtick">stderr</code> appears to arrive out of order). It also helps that output to <code class="backtick">stderr</code> is usually unbuffered, avoiding the problem of lost output.</li>
+<li>If you must output to <code class="backtick">stdout</code>, put <code class="backtick">fflush(stdout)</code> after any output operation you suspect is getting lost in the buffer. The <code class="backtick">fflush</code> function forces any buffered output to be emitted immediately.</li>
+<li>Keep all arguments passed to <code class="backtick">printf</code> as simple as possible and beware of faults in your debugging code itself. If you write <code class="backtick">printf("a[key]&nbsp;==&nbsp;%d\n",&nbsp;a[key])</code> and <code class="backtick">key</code> is some bizarre value, you will never see the result of this <code class="backtick">printf</code> because your program will segfault while evaluating <code class="backtick">a[key]</code>. Naturally, this is more likely to occur if the argument is <code class="backtick">a[key]-&gt;size[LEFTOVERS].cleanupFunction(a[key])</code> than if it's just <code class="backtick">a[key]</code>,
+ and if it happens it will be harder to figure out where in this complex
+ chain of array indexing and pointer dereferencing the disaster
+happened. Better is to wait for your program to break in <code class="backtick">gdb</code>, and use the <code class="backtick">print</code>
+ statement on increasingly large fragments of the offending expression
+to see where the bogus array index or surprising null pointer is hiding.</li>
+<li>Wrap your debugging output in an <code>#ifdef</code> so you can turn it on and off easily.</li>
+</ol>
+<p>Bearing in mind that this is a bad idea, here is an example of how one might do it as well as possible:</p>
+<div>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"><span class="ot">#include &lt;stdio.h&gt;</span>
+<span class="ot">#include &lt;stdlib.h&gt;</span>
+<span class="ot">#include &lt;assert.h&gt;</span>
+
+<span class="co">/* initialize the application */</span>
+<span class="dt">void</span>
+init(<span class="dt">void</span>)
+{
+ <span class="dt">int</span> x;
+
+ x = *((<span class="dt">int</span> *) <span class="bn">0xbad1dea</span>); <span class="co">/* if we are lucky, maybe the optimizer will remove it? */</span>
+}
+
+<span class="dt">int</span>
+main(<span class="dt">int</span> argc, <span class="dt">char</span> **argv)
+{
+ init();
+
+<span class="ot">#ifdef DEBUGGING_OUTPUT</span>
+ <span class="co">/*</span>
+<span class="co"> * this type of debugging output is not recommended</span>
+<span class="co"> * but if you do it anyway:</span>
+<span class="co"> *</span>
+<span class="co"> * 1. Use stderr, which flushes automatically.</span>
+<span class="co"> * 2. Be wary of buffered data on stdout.</span>
+<span class="co"> * 3. Wrap your debugging statement in an #ifdef,</span>
+<span class="co"> * so it is not active by default.</span>
+<span class="co"> */</span>
+ fputs(<span class="st">"Returned from init() in main()</span><span class="ch">\n</span><span class="st">"</span>, stderr);
+<span class="ot">#endif</span>
+
+ <span class="kw">return</span> <span class="dv">0</span>;
+}</code></pre></div>
+<a href="http://cs.yale.edu/homes/aspnes/classes/223/examples/debugging/usingPrintf.c" class="uri">examples/debugging/usingPrintf.c</a>
+</div>
+<p>Note that we get much more useful information if we run this under <code>gdb</code> (which will stop exactly on the bad line in <code>init</code>), but not seeing the result of the <code>fputs</code> at least tells us something.</p>
+<h2 id="performanceTuning"><span class="header-section-number">3.5</span> Performance tuning</h2>
+<p>Chapter 7 of Kernighan and Pike, <em>The Practice of Programming</em>
+ (Addison-Wesley, 1998) gives an excellent overview of performance
+tuning. This page will be limited to some Linux-specific details and an
+example.</p>
+<h3 id="Timing_under_Linux"><span class="header-section-number">3.5.1</span> Timing under Linux</h3>
+<p>Use <code class="backtick">time</code>, e.g.</p>
+<pre><code>$ time wc /usr/share/dict/words
+ 45378 45378 408865 /usr/share/dict/words
+
+real 0m0.010s
+user 0m0.006s
+sys 0m0.004s</code></pre>
+<p>This measures "real time" (what it sounds like), "user time" (the
+amount of time the program runs), and "system time" (the amount of time
+the operating system spends supporting your program, e.g. by loading it
+from disk and doing I/O). Real time need not be equal to the sum of user
+ time and system time, since the operating system may be simultaneously
+running other programs.</p>
+<p>Particularly for fast programs, times can vary from one execution to the next, e.g.</p>
+<pre><code>$ time wc /usr/share/dict/words
+ 45378 45378 408865 /usr/share/dict/words
+
+real 0m0.009s
+user 0m0.008s
+sys 0m0.001s
+$ time wc /usr/share/dict/words
+ 45378 45378 408865 /usr/share/dict/words
+
+real 0m0.009s
+user 0m0.007s
+sys 0m0.002s</code></pre>
+<p>This arises because of measurement errors and variation in how long
+different operations take. But usually the variation will not be much.</p>
+<p>Note also that <code class="backtick">time</code> is often a builtin operation of your shell, so the output format may vary depending on what shell you use.</p>
+<h3 id="profiling"><span class="header-section-number">3.5.2</span> Profiling with gprof</h3>
+<p>The problem with <code class="backtick">time</code> is that it only
+tells you how much time your whole program took, but not where it spent
+its time. This is similar to looking at a program without a debugger:
+you can't see what's happening inside. If you want to see where your
+program is spending its time, you need to use a profiler.</p>
+<p>For example, here's a short but slow program for calculating the number of primes less than some limit passed as <code class="backtick">argv[1]</code>:</p>
+<div>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"><span class="ot">#include &lt;stdio.h&gt;</span>
+<span class="ot">#include &lt;stdlib.h&gt;</span>
+
+<span class="co">/* return 1 if n is prime, 0 otherwise */</span>
+<span class="dt">int</span>
+isPrime(<span class="dt">int</span> n)
+{
+ <span class="dt">int</span> factor;
+
+ <span class="kw">if</span>(n &lt; <span class="dv">2</span>) <span class="kw">return</span> <span class="dv">0</span>;
+ <span class="co">/* else */</span>
+ <span class="kw">for</span>(factor = <span class="dv">2</span>; factor &lt; n; factor++) {
+ <span class="kw">if</span>(n % factor == <span class="dv">0</span>) <span class="kw">return</span> <span class="dv">0</span>;
+ }
+ <span class="co">/* else */</span>
+ <span class="kw">return</span> <span class="dv">1</span>;
+}
+
+<span class="co">/* return number of primes &lt; n */</span>
+<span class="dt">int</span>
+countPrimes(<span class="dt">int</span> n)
+{
+ <span class="dt">int</span> i;
+ <span class="dt">int</span> count;
+
+ count = <span class="dv">0</span>;
+
+ <span class="kw">for</span>(i = <span class="dv">0</span>; i &lt; n; i++) {
+ <span class="kw">if</span>(isPrime(i)) count++;
+ }
+
+ <span class="kw">return</span> count;
+}
+
+<span class="dt">int</span>
+main(<span class="dt">int</span> argc, <span class="dt">char</span> **argv)
+{
+ <span class="kw">if</span>(argc != <span class="dv">2</span>) {
+ fprintf(stderr, <span class="st">"Usage: %s n</span><span class="ch">\n</span><span class="st">"</span>, argv[<span class="dv">0</span>]);
+ <span class="kw">return</span> <span class="dv">1</span>;
+ }
+
+ printf(<span class="st">"%d</span><span class="ch">\n</span><span class="st">"</span>, countPrimes(atoi(argv[<span class="dv">1</span>])));
+
+ <span class="kw">return</span> <span class="dv">0</span>;
+}</code></pre></div>
+<a href="http://cs.yale.edu/homes/aspnes/classes/223/examples/profiling/countPrimes.c" class="uri">examples/profiling/countPrimes.c</a>
+</div>
+<p>And now we'll time <code class="backtick">countPrimes&nbsp;100000</code>:</p>
+<pre><code>$ c99 -g3 -o countPrimes countPrimes.c
+$ time ./countPrimes 100000
+9592
+
+real 0m4.711s
+user 0m4.608s
+sys 0m0.004s</code></pre>
+<p>This shows that the program took just under five seconds of real
+time, of which most was spent in user mode and a very small fraction was
+ spent in kernel (sys) mode. The user-mode part corresponds to the code
+we wrote and any library routines we call that don't require special
+privileges from the operation system. The kernel-mode part will mostly
+be I/O (not much in this case). Real time is generally less useful than
+CPU time, because it depends on how loaded the CPU is. Also, none of
+these times are especially precise, because the program only gets
+charged for time on a context switch (when it switches between user and
+kernel mode or some other program takes over the CPU for a bit) or when
+the kernel decides to see what it is up to (typically every 10
+milliseconds).</p>
+<p>The overall cost is not too bad, but the reason I picked 100000 and
+not some bigger number was that it didn't terminate fast enough for
+larger inputs. We'd like to see why it is taking so long, to have some
+idea what to try to speed up. So we'll compile it with the <code class="backtick">-pg</code> option to <code class="backtick">gcc</code>, which inserts <strong>profiling</strong> code that counts how many times each function is called and how long (on average) each call takes.</p>
+<p>Because the profile is not very smart about shared libraries, we also including the <code>--static</code>
+ option to force the resulting program to be statically linked. This
+means that all the code that is used by the program is baked into the
+executable instead of being linked in at run-time. (Normally we don't do
+ this because it makes for big executables and big running programs,
+since statically-linked libraries can't be shared between more than one
+running program.)</p>
+<pre><code>$ c99 -pg --static -g3 -o countPrimes countPrimes.c
+$ time ./countPrimes 100000
+9592
+
+real 0m4.723s
+user 0m4.668s
+sys 0m0.000s</code></pre>
+<p>Hooray! We've made the program slightly slower. But we also just produced a file <code class="backtick">gmon.out</code> that we can read with <code class="backtick">gprof</code>. Note that we have to pass the name of the program so that <code>gprof</code> can figure out which executable generated <code>gmon.out</code>.</p>
+<pre><code>$ gprof countPrimes
+Flat profile:
+
+Each sample counts as 0.01 seconds.
+ % cumulative self self total
+ time seconds seconds calls s/call s/call name
+100.00 4.66 4.66 100000 0.00 0.00 isPrime
+ 0.00 4.66 0.00 1 0.00 4.66 countPrimes
+ 0.00 4.66 0.00 1 0.00 4.66 main
+
+[...much explanatory text deleted]</code></pre>
+<p>It looks like we are spending all of our time in <code>isPrime</code>, at least if we read the columns on the left. The per-call columns are not too helpful because of granularity: <code>isPrime</code>
+ is too fast for the profiler to wake up and detect how long it runs
+for. The total columns are less suspicious because they are obtained by
+sampling: from time to time, the profiler looks and sees what function
+it's in, and charges each function a fraction of the total CPU time
+proportional to how often it gets sampled. So we probable aren't really
+spending zero time in <code>countPrimes</code> and <code>main</code>, but the amount of time we do spend is small enough not to be detected.</p>
+<p>This is handy because it means we don't need to bother trying to
+speed up the rest of the program. We have two things we can try:</p>
+<ol style="list-style-type: decimal">
+<li>Call <code>isPrime</code> less.</li>
+<li>Make <code>isPrime</code> faster.</li>
+</ol>
+<p>Let's start by seeing if we can make <code>isPrime</code> faster.</p>
+<p>What <code class="backtick">isPrime</code> is doing is testing if a number <code class="backtick">n</code> is prime by the most direct way possible: dividing by all numbers less than <code class="backtick">n</code> until it finds a factor. That's a lot of divisions: if <code class="backtick">n</code> is indeed prime, it's linear in <code class="backtick">n</code>. Since division is a relatively expensive operation, the first thing to try is to get rid of some.</p>
+<p>Here's a revised version of <code class="backtick">isPrime</code>:</p>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"><span class="co">/* return 1 if n is prime, 0 otherwise */</span>
+<span class="dt">int</span>
+isPrime(<span class="dt">int</span> n)
+{
+ <span class="dt">int</span> factor;
+
+ <span class="kw">if</span>(n &lt; <span class="dv">2</span>) { <span class="kw">return</span> <span class="dv">0</span>; }
+ <span class="kw">if</span>(n % <span class="dv">2</span> == <span class="dv">0</span>) {
+ <span class="co">/* special case for the only even prime */</span>
+ <span class="kw">return</span> n == <span class="dv">2</span>;
+ }
+ <span class="co">/* else */</span>
+ <span class="kw">for</span>(factor = <span class="dv">3</span>; factor &lt; n; factor+=<span class="dv">2</span>) {
+ <span class="kw">if</span>(n % factor == <span class="dv">0</span>) <span class="kw">return</span> <span class="dv">0</span>;
+ }
+ <span class="co">/* else */</span>
+ <span class="kw">return</span> <span class="dv">1</span>;
+}</code></pre></div>
+<p><a href="http://cs.yale.edu/homes/aspnes/classes/223/examples/profiling/countPrimesSkipEvenFactors.c" class="uri">examples/profiling/countPrimesSkipEvenFactors.c</a></p>
+<p>The trick is to check first if <code class="backtick">n</code> is divisible by <code class="backtick">2</code>,
+ and only test odd potential factors thereafter. This requires some
+extra work to handle 2, but maybe the extra code complexity will be
+worth it.</p>
+<p>Let's see how the timing goes:</p>
+<pre><code>$ c99 -pg --static -g3 -o countPrimes ./countPrimesSkipEvenFactors.c
+$ time ./countPrimes 100000
+9592
+
+real 0m2.608s
+user 0m2.400s
+sys 0m0.004s
+$ gprof countPrimes
+Flat profile:
+
+Each sample counts as 0.01 seconds.
+ % cumulative self self total
+ time seconds seconds calls s/call s/call name
+100.00 2.29 2.29 100000 0.00 0.00 isPrime
+ 0.00 2.29 0.00 1 0.00 2.29 countPrimes
+ 0.00 2.29 0.00 1 0.00 2.29 main
+
+[...]</code></pre>
+<p>Twice as fast! And the answer is still the same, too—this is important.</p>
+<p>Can we test even fewer factors? Suppose <code class="backtick">n</code> has a non-trivial factor <code class="backtick">x</code>. Then <code class="backtick">n</code> equals <code class="backtick">x*y</code> for some <code class="backtick">y</code> which is also nontrivial. One of <code class="backtick">x</code> or <code class="backtick">y</code> will be no bigger than the square root of <code class="backtick">n</code>. So perhaps we can stop when we reach the square root of <code class="backtick">n</code>,</p>
+<p>Let's try it:</p>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"><span class="ot">#include &lt;math.h&gt;</span>
+
+<span class="co">/* return 1 if n is prime, 0 otherwise */</span>
+<span class="dt">int</span>
+isPrime(<span class="dt">int</span> n)
+{
+ <span class="dt">int</span> factor;
+
+ <span class="kw">if</span>(n &lt; <span class="dv">2</span>) { <span class="kw">return</span> <span class="dv">0</span>; }
+ <span class="kw">if</span>(n % <span class="dv">2</span> == <span class="dv">0</span>) {
+ <span class="co">/* special case for the only even prime */</span>
+ <span class="kw">return</span> n == <span class="dv">2</span>;
+ }
+ <span class="co">/* else */</span>
+ <span class="kw">for</span>(factor = <span class="dv">3</span>; factor &lt; sqrt(n)+<span class="dv">1</span>; factor+=<span class="dv">2</span>) {
+ <span class="kw">if</span>(n % factor == <span class="dv">0</span>) <span class="kw">return</span> <span class="dv">0</span>;
+ }
+ <span class="co">/* else */</span>
+ <span class="kw">return</span> <span class="dv">1</span>;
+}
+}</code></pre></div>
+<p><a href="http://cs.yale.edu/homes/aspnes/classes/223/examples/profiling/countPrimesSqrt.c" class="uri">examples/profiling/countPrimesSqrt.c</a></p>
+<p>I added <code class="backtick">+1</code> to the return value of <code class="backtick">sqrt</code> both to allow for <code>factor</code> to be equal to the square root of <code>n</code>, and because the output of <code class="backtick">sqrt</code> is not exact, and it would be embarrassing if I announced that 25 was prime because I stopped at 4.9999999997.</p>
+<p>Using the math library not only requires including <code class="backtick">&lt;math.h&gt;</code> but also requires compiling with the <code class="backtick">-lm</code> flag after all <code class="backtick">.c</code> or <code class="backtick">.o</code> files, to link in the library routines:</p>
+<pre><code>$ c99 -pg --static -g3 -o countPrimes ./countPrimesSqrt.c -lm
+$ time ./countPrimes 1000000
+78498
+
+real 0m1.008s
+user 0m0.976s
+sys 0m0.000s
+$ gprof countPrimes
+Flat profile:
+
+Each sample counts as 0.01 seconds.
+ % cumulative self self total
+ time seconds seconds calls ms/call ms/call name
+ 50.00 0.02 0.02 100000 0.00 0.00 isPrime
+ 50.00 0.04 0.02 __sqrt_finite
+ 0.00 0.04 0.00 1 0.00 20.00 countPrimes
+ 0.00 0.04 0.00 1 0.00 20.00 main
+
+[...]</code></pre>
+<p>Whoosh!</p>
+<p>Can we optimize further? Let's see what happens on a bigger input:</p>
+<pre><code>$ time ./countPrimes 1000000
+78498
+
+real 0m0.987s
+user 0m0.960s
+sys 0m0.000s
+$ gprof countPrimes
+Flat profile:
+
+Each sample counts as 0.01 seconds.
+ % cumulative self self total
+ time seconds seconds calls ms/call ms/call name
+ 51.04 0.49 0.49 __sqrt_finite
+ 44.79 0.92 0.43 1000000 0.00 0.00 isPrime
+ 3.65 0.96 0.04 sqrt
+ 0.52 0.96 0.01 1 5.00 435.00 main
+ 0.00 0.96 0.00 1 0.00 430.00 countPrimes
+
+[...]</code></pre>
+<p>This is still very good, although we're spending a lot of time in <code>sqrt</code> (more specifically, its internal helper routine <code>__sqrt_finite</code>). Can we do better?</p>
+<p>Maybe moving the <code class="backtick">sqrt</code> out of the loop in <code class="backtick">isPrime</code> will make a difference:</p>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"><span class="co">/* return 1 if n is prime, 0 otherwise */</span>
+<span class="dt">int</span>
+isPrime(<span class="dt">int</span> n)
+{
+ <span class="dt">int</span> factor;
+ <span class="dt">int</span> sqrtValue;
+
+ <span class="kw">if</span>(n &lt; <span class="dv">2</span>) { <span class="kw">return</span> <span class="dv">0</span>; }
+ <span class="kw">if</span>(n % <span class="dv">2</span> == <span class="dv">0</span>) {
+ <span class="co">/* special case for the only even prime */</span>
+ <span class="kw">return</span> n == <span class="dv">2</span>;
+ }
+ <span class="co">/* else */</span>
+ sqrtValue = sqrt(n) + <span class="dv">1</span>;
+ <span class="kw">for</span>(factor = <span class="dv">3</span>; factor &lt; sqrtValue; factor+=<span class="dv">2</span>) {
+ <span class="kw">if</span>(n % factor == <span class="dv">0</span>) <span class="kw">return</span> <span class="dv">0</span>;
+ }
+ <span class="co">/* else */</span>
+ <span class="kw">return</span> <span class="dv">1</span>;
+}</code></pre></div>
+<p><a href="http://cs.yale.edu/homes/aspnes/classes/223/examples/profiling/countPrimesSqrtOutsideLoop.c" class="uri">examples/profiling/countPrimesSqrtOutsideLoop.c</a></p>
+<pre><code>$ c99 -pg --static -g3 -o countPrimes ./countPrimesSqrtOutsideLoop.c -lm
+$ time ./countPrimes 1000000
+78498
+
+real 0m0.413s
+user 0m0.392s
+sys 0m0.000s
+$ gprof countPrimes
+Flat profile:
+
+Each sample counts as 0.01 seconds.
+ % cumulative self self total
+ time seconds seconds calls ms/call ms/call name
+ 97.44 0.38 0.38 1000000 0.00 0.00 isPrime
+ 2.56 0.39 0.01 1 10.00 390.00 countPrimes
+ 0.00 0.39 0.00 1 0.00 390.00 main
+
+[...]</code></pre>
+<p>This worked! We are now spending almost so little time in <code>sqrt</code> that the profiler doesn't notice it.</p>
+<p>What if we get rid of the call to <code class="backtick">sqrt</code> and test if <code class="backtick">factor&nbsp;*&nbsp;factor&nbsp;&lt;=&nbsp;n</code> instead? This way we could dump the math library:</p>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"><span class="co">/* return 1 if n is prime, 0 otherwise */</span>
+<span class="dt">int</span>
+isPrime(<span class="dt">int</span> n)
+{
+ <span class="dt">int</span> factor;
+
+ <span class="kw">if</span>(n &lt; <span class="dv">2</span>) { <span class="kw">return</span> <span class="dv">0</span>; }
+ <span class="kw">if</span>(n % <span class="dv">2</span> == <span class="dv">0</span>) {
+ <span class="co">/* special case for the only even prime */</span>
+ <span class="kw">return</span> n == <span class="dv">2</span>;
+ }
+ <span class="co">/* else */</span>
+ <span class="kw">for</span>(factor = <span class="dv">3</span>; factor*factor &lt;= n; factor+=<span class="dv">2</span>) {
+ <span class="kw">if</span>(n % factor == <span class="dv">0</span>) <span class="kw">return</span> <span class="dv">0</span>;
+ }
+ <span class="co">/* else */</span>
+ <span class="kw">return</span> <span class="dv">1</span>;
+}</code></pre></div>
+<p><a href="http://cs.yale.edu/homes/aspnes/classes/223/examples/profiling/countPrimesSquaring.c" class="uri">examples/profiling/countPrimesSquaring.c</a></p>
+<pre><code>$ c99 -pg --static -g3 -o countPrimes ./countPrimesSquaring.c
+$ time ./countPrimes 1000000
+78498
+
+real 0m0.450s
+user 0m0.428s
+sys 0m0.000s</code></pre>
+<p>This is slower, but not much slower. We might need to decide how much
+ we care about avoiding floating-point computation in our program.</p>
+<p>At this point we could decide that <code class="backtick">countPrimes</code>
+ is fast enough, or maybe we could look for further improvements, say,
+by testing out many small primes at the beginning instead of just <code class="backtick">2</code>, calling <code class="backtick">isPrime</code> only on odd values of <code class="backtick">i</code>,
+ or reading a computational number theory textbook to find out how we
+ought to be doing this. A reasonable strategy for code for your own use
+is often to start running one version and make improvements on a
+separate copy while it's running. If the first version terminates before
+ you are done writing new code, it's probably fast enough.</p>
+<h4 id="effect-of-optimization-during-compilation"><span class="header-section-number">3.5.2.1</span> Effect of optimization during compilation</h4>
+<p>We didn't use any optimization flags for this example, because the
+optimizer can do a lot of rewriting that can make the output of the
+profiler confusing. For example, at high optimization levels, the
+compiler will often avoid function-call overhead by inserting the body
+of a helper function directly into its caller. But this can make a big
+difference in performance, so in real life you will want to compile with
+ optimization turned on. Here's how the performance of <code>countPrimes 100000</code> is affected by optimization level:</p>
+<table>
+<thead>
+<tr class="header">
+<th align="left">Version</th>
+<th align="right">No optimization</th>
+<th align="right">With -O1</th>
+<th align="right">With -O2</th>
+<th align="right">With -O3</th>
+</tr>
+</thead>
+<tbody>
+<tr class="odd">
+<td align="left"><code>countPrimes.c</code></td>
+<td align="right">4.600</td>
+<td align="right">4.060</td>
+<td align="right">3.928</td>
+<td align="right">3.944</td>
+</tr>
+<tr class="even">
+<td align="left"><code>countPrimesSkipEvenFactors.c</code></td>
+<td align="right">2.260</td>
+<td align="right">1.948</td>
+<td align="right">1.964</td>
+<td align="right">1.984</td>
+</tr>
+<tr class="odd">
+<td align="left"><code>countPrimesSqrt.c</code></td>
+<td align="right">0.036</td>
+<td align="right">0.028</td>
+<td align="right">0.028</td>
+<td align="right">0.028</td>
+</tr>
+<tr class="even">
+<td align="left"><code>countPrimesSqrtOutsideLoop.c</code></td>
+<td align="right">0.012</td>
+<td align="right">0.012</td>
+<td align="right">0.008</td>
+<td align="right">0.008</td>
+</tr>
+<tr class="odd">
+<td align="left"><code>countPrimesSquaring.c</code></td>
+<td align="right">0.012</td>
+<td align="right">0.012</td>
+<td align="right">0.008</td>
+<td align="right">0.012</td>
+</tr>
+</tbody>
+</table>
+<p>In each case, the reported time is the sum of user and system time in seconds.<a href="#fn3" class="footnoteRef" id="fnref3"><sup>3</sup></a></p>
+<p>For the smarter routines, more optimization doesn't necessarily help,
+ although some of this may be experimental error since I was too lazy to
+ get a lot of samples by running each program more than once, and the
+times for the faster programs are so small that granularity is going to
+be an issue.</p>
+<p>Here's the same table using <code>countPrimes 10000000</code> on the three fastest programs:</p>
+<table>
+<thead>
+<tr class="header">
+<th align="left">Version</th>
+<th align="right">No optimization</th>
+<th align="right">With -O1</th>
+<th align="right">With -O2</th>
+<th align="right">With -O3</th>
+</tr>
+</thead>
+<tbody>
+<tr class="odd">
+<td align="left"><code>countPrimesSqrt.c</code></td>
+<td align="right">24.236</td>
+<td align="right">18.840</td>
+<td align="right">18.720</td>
+<td align="right">18.564</td>
+</tr>
+<tr class="even">
+<td align="left"><code>countPrimesSqrtOutsideLoop.c</code></td>
+<td align="right">9.388</td>
+<td align="right">9.364</td>
+<td align="right">9.368</td>
+<td align="right">9.360</td>
+</tr>
+<tr class="odd">
+<td align="left"><code>countPrimesSquaring.c</code></td>
+<td align="right">9.748</td>
+<td align="right">9.248</td>
+<td align="right">9.236</td>
+<td align="right">9.160</td>
+</tr>
+</tbody>
+</table>
+<p>Again there are the usual caveats that I am a lazy person and should
+probably be doing more do deal with sampling and granularity issues, but
+ if you believe these numbers, we actually win by going to <code>countPrimesSquaring</code> once the optimizer is turned on. I suspect that it is benefiting from <a href="http://en.wikipedia.org/wiki/Strength_reduction">strength reduction</a>, which would generate the product <code>factor*factor</code> in <code>isPrime</code> incrementally using addition rather than multiplying from scratch each time.</p>
+<p>It's also worth noting that the optimizer works better if we leave a lot of easy optimization lying around. For <code>countPrimesSqrt.c</code>, my guess is that most of the initial gains are from avoiding function call overhead on <code>sqrt</code>
+ by compiling it in-line. But even the optimizer is not smart enough to
+recognize that we are computing the same value over and over again, so
+we still win by pulling <code>sqrt</code> out of the loop in <code>countPrimesSqrtOutsideLoop.c</code>.</p>
+<p>If I wanted to see if my guesses about the optimizer were correct, there I could use <code>gcc -S</code> and look at the assembler code. But see earlier comments about laziness.</p>
+<h2 id="versionControl"><span class="header-section-number">3.6</span> Version control</h2>
+<p>When you are programming, you will make mistakes. If you program long
+ enough, these will eventually include true acts of boneheadedness like
+accidentally deleting all of your source files. You are also likely to
+spend some of your time trying out things that don't work, at the end of
+ which you'd like to go back to the last version of your program that
+did work. All these problems can be solved by using a <strong>version control system</strong>.</p>
+<p>There are six respectable version control systems installed on the Zoo: <code class="backtick">rcs</code>, <code class="backtick">cvs</code>, <code class="backtick">svn</code>, <code class="backtick">bzr</code>, <code class="backtick">hg</code>, and <code class="backtick">git</code>. If you are familiar with any of them, you should use that. If you have to pick one from scratch, I recommend using <code class="backtick">git</code>. A brief summary of <code>git</code> is given below. For more details, see the tutorials available at <a href="http://git-scm.com/" class="uri">http://git-scm.com</a>.</p>
+<h3 id="Setting_up_Git"><span class="header-section-number">3.6.1</span> Setting up Git</h3>
+<p>Typically you run <code class="backtick">git</code> inside a directory that holds some project you are working on (say, <code class="backtick">hw1</code>). Before you can do anything with <code class="backtick">git</code>, you will need to create the <em>repository</em>, which is a hidden directory <code class="backtick">.git</code> that records changes to your files:</p>
+<pre><code>$ mkdir git-demo
+$ cd git-demo
+$ git init
+Initialized empty Git repository in /home/classes/cs223/class/aspnes.james.ja54/git-demo/.git/</code></pre>
+<p>Now let's create a file and add it to the repository:</p>
+<pre><code>$ echo 'int main(int argc, char **argv) { return 0; }' &gt; tiny.c
+$ git add tiny.c</code></pre>
+<p>The <code class="backtick">git&nbsp;status</code> command will tell us that Git knows about <code class="backtick">tiny.c</code>, but hasn't commited the changes to the repository yet:</p>
+<pre><code>$ git status
+# On branch master
+#
+# Initial commit
+#
+# Changes to be committed:
+# (use "git rm --cached &lt;file&gt;..." to unstage)
+#
+# new file: tiny.c
+#</code></pre>
+<p>The <code class="backtick">git&nbsp;commit</code> command will commit
+ the actual changes, along with a message saying what you did. For short
+ messages, the easiest way to do this is to include the message on the
+command line:</p>
+<pre><code>$ git commit -a -m"add very short C program"
+[master (root-commit) 5393616] add very short C program
+ Committer: James Aspnes &lt;ja54@tick.zoo.cs.yale.edu&gt;
+Your name and email address were configured automatically based
+on your username and hostname. Please check that they are accurate.
+You can suppress this message by setting them explicitly:
+
+ git config --global user.name "Your Name"
+ git config --global user.email you@example.com
+
+If the identity used for this commit is wrong, you can fix it with:
+
+ git commit --amend --author='Your Name &lt;you@example.com&gt;'
+
+ 1 files changed, 1 insertions(+), 0 deletions(-)
+ create mode 100644 tiny.c</code></pre>
+<p>The <code class="backtick">-a</code> argument tells Git to include any changes I made to files it already knows about. The <code class="backtick">-m</code> argument sets the commit message.</p>
+<p>Because this is the first time I ever did a commit, and because I
+didn't tell Git who I was before, it complains that its guess for my
+name and email address may be wrong. It also tells me what to do to get
+it to shut up about this next time:</p>
+<pre><code>$ git config --global user.name "James Aspnes"
+$ git config --global user.email "aspnes@cs.yale.edu"
+$ git commit --amend --author="James Aspnes &lt;aspnes@cs.yale.edu&gt;" -m"add a very short C program"
+[master a44e1e1] add a very short C program
+ 1 files changed, 1 insertions(+), 0 deletions(-)
+ create mode 100644 tiny.c</code></pre>
+<p>Note that I repeated the <code class="backtick">-m</code> business to <code class="backtick">git&nbsp;commit&nbsp;--amend</code>; if I hadn't, it would have run the default editor (<code class="backtick">vim</code>) to let me edit my commit message. If I don't like <code class="backtick">vim</code>, I can change the default using <code class="backtick">git&nbsp;config&nbsp;--global&nbsp;core.editor</code>, e.g.:</p>
+<pre><code>$ git config --global core.editor "emacs -nw"</code></pre>
+<p>I can see what commits I've done so far using <code class="backtick">git&nbsp;log</code>:</p>
+<pre><code>$ git log
+commit a44e1e195de4ce785cd95cae3b93c817d598a9ee
+Author: James Aspnes &lt;aspnes@cs.yale.edu&gt;
+Date: Thu Dec 29 20:21:21 2011 -0500
+
+ add a very short C program</code></pre>
+<h3 id="Editing_files"><span class="header-section-number">3.6.2</span> Editing files</h3>
+<p>Suppose I edit <code class="backtick">tiny.c</code> using my favorite editor to turn it into the classic hello-world program:</p>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"><span class="ot">#include &lt;stdio.h&gt;</span>
+
+<span class="dt">int</span>
+main(<span class="dt">int</span> argc, <span class="dt">char</span> **argv)
+{
+ puts(<span class="st">"hello, world"</span>);
+ <span class="kw">return</span> <span class="dv">0</span>;
+}</code></pre></div>
+<p>I can see what files have changed using <code class="backtick">git&nbsp;status</code>:</p>
+<pre><code>$ git status
+# On branch master
+# Changed but not updated:
+# (use "git add &lt;file&gt;..." to update what will be committed)
+# (use "git checkout -- &lt;file&gt;..." to discard changes in working directory)
+#
+# modified: tiny.c
+#
+no changes added to commit (use "git add" and/or "git commit -a")</code></pre>
+<p>Notice how Git reminds me to use <code class="backtick">git&nbsp;commit&nbsp;-a</code> to include these changes in my next commit. I can also do <code class="backtick">git&nbsp;add&nbsp;tiny.c</code> if I just want include the changes to <code class="backtick">tiny.c</code> (maybe I made changes to a different file that I want to commit separately), but usually that's too much work.</p>
+<p>If I want to know the details of the changes since my last commit, I can do <code class="backtick">git&nbsp;diff</code>:</p>
+<pre><code>$ git diff
+diff --git a/tiny.c b/tiny.c
+index 0314ff1..f8d9dcd 100644
+--- a/tiny.c
++++ b/tiny.c
+@@ -1 +1,8 @@
+-int main(int argc, char **argv) { return 0; }
++#include &lt;stdio.h&gt;
++
++int
++main(int argc, char **argv)
++{
++ puts("hello, world");
++ return 0;
++}</code></pre>
+<p>Since I like these changes, I do a commit:</p>
+<pre><code>$ git commit -a -m"expand previous program to hello world"
+[master 13a73be] expand previous program to hello world
+ 1 files changed, 8 insertions(+), 1 deletions(-)</code></pre>
+<p>Now there are two commits in my log:</p>
+<pre><code>$ git log | tee /dev/null
+commit 13a73bedd3a48c173898d1afec05bd6fa0d7079a
+Author: James Aspnes &lt;aspnes@cs.yale.edu&gt;
+Date: Thu Dec 29 20:34:06 2011 -0500
+
+ expand previous program to hello world
+
+commit a44e1e195de4ce785cd95cae3b93c817d598a9ee
+Author: James Aspnes &lt;aspnes@cs.yale.edu&gt;
+Date: Thu Dec 29 20:21:21 2011 -0500
+
+ add a very short C program</code></pre>
+<h3 id="Renaming_files"><span class="header-section-number">3.6.3</span> Renaming files</h3>
+<p>You can rename a file with <code class="backtick">git&nbsp;mv</code>. This is just like regular <code class="backtick">mv</code>, except that it tells Git what you are doing.</p>
+<pre><code>$ git mv tiny.c hello.c
+$ git status
+# On branch master
+# Changes to be committed:
+# (use "git reset HEAD &lt;file&gt;..." to unstage)
+#
+# renamed: tiny.c -&gt; hello.c
+#</code></pre>
+<p>These changes don't get written to the repository unless you do another <code class="backtick">git&nbsp;commit</code>:</p>
+<pre><code>$ git commit -a -m"give better name to hello program"
+[master 6d2116c] give better name to hello program
+ 1 files changed, 0 insertions(+), 0 deletions(-)
+ rename tiny.c =&gt; hello.c (100%)</code></pre>
+<h3 id="Adding_and_removing_files"><span class="header-section-number">3.6.4</span> Adding and removing files</h3>
+<p>To add a file, create it and then call <code class="backtick">git&nbsp;add</code>:</p>
+<pre><code>$ cp hello.c goodbye.c
+$ git status
+# On branch master
+# Untracked files:
+# (use "git add &lt;file&gt;..." to include in what will be committed)
+#
+# goodbye.c
+nothing added to commit but untracked files present (use "git add" to track)
+$ git add goodbye.c
+$ git commit -a -m"we need a second program to say goodbye"
+[master 454b24c] we need a second program to say goodbye
+ 1 files changed, 8 insertions(+), 0 deletions(-)
+ create mode 100644 goodbye.c</code></pre>
+<p>To remove a file, use <code>git rm</code>:</p>
+<pre><code>$ git rm goodbye.c
+$ git status
+# On branch master
+# Changed but not updated:
+# (use "git add/rm &lt;file&gt;..." to update what will be committed)
+# (use "git checkout -- &lt;file&gt;..." to discard changes in working directory)
+#
+# deleted: goodbye.c
+#
+no changes added to commit (use "git add" and/or "git commit -a")
+$ git commit -a -m"no, goodbye.c was a bad idea"
+[master defa0e0] no, goodbye.c was a bad idea
+ 1 files changed, 0 insertions(+), 8 deletions(-)
+ delete mode 100644 goodbye.c</code></pre>
+<h3 id="Recovering_files_from_the_repository"><span class="header-section-number">3.6.5</span> Recovering files from the repository</h3>
+<p>If you make a mistake, you can back out using the repository. Here I will delete my <code class="backtick">hello.c</code> file and then get it back using <code class="backtick">git&nbsp;checkout&nbsp;--&nbsp;hello.c</code>:</p>
+<pre><code>$ rm hello.c
+$ ls
+$ git checkout -- hello.c
+$ ls
+hello.c</code></pre>
+<p>I can also get back old versions of files by putting the commit id before the <code class="backtick">--</code>:</p>
+<pre><code>$ git checkout a44e1 -- tiny.c
+$ ls
+hello.c tiny.c</code></pre>
+<p>The commit id can be any unique prefix of the ridiculously long hex name shown by <code class="backtick">git&nbsp;log</code>.</p>
+<p>Having recovered <code class="backtick">tiny.c</code>, I will keep it around by adding it to a new commit:</p>
+<pre><code>$ git commit -a -m"keep tiny.c around"
+[master 23d6219] keep tiny.c around
+ 1 files changed, 1 insertions(+), 0 deletions(-)
+ create mode 100644 tiny.c</code></pre>
+<h3 id="Undoing_bad_commits"><span class="header-section-number">3.6.6</span> Undoing bad commits</h3>
+<p>Suppose I commit a change that I didn't want to make. For example,
+let's suppose I decide to add some punctuation to the greeting in <code class="backtick">hello.c</code> but botch my edit:</p>
+<pre><code>$ vim hello.c
+$ git commit -a -m"add exclamation point"
+[master f40d8d3] add exclamation point
+ 1 files changed, 1 insertions(+), 1 deletions(-)</code></pre>
+<p>Only now does it occur to me to test my program:</p>
+<pre><code>$ c99 -o hello hello.c
+$ ./hello
+hello, wolrd!</code></pre>
+<p>Disaster!</p>
+<p>I can use <code class="backtick">git&nbsp;diff</code> to see what went wrong. The command below compares the current working directory to <code class="backtick">HEAD^</code>, the commit before the most recent commit:<a href="#fn4" class="footnoteRef" id="fnref4"><sup>4</sup></a></p>
+<pre><code>$ git diff HEAD^ | tee /dev/null
+diff --git a/hello.c b/hello.c
+index f8d9dcd..dc227a8 100644
+--- a/hello.c
++++ b/hello.c
+@@ -3,6 +3,6 @@
+ int
+ main(int argc, char **argv)
+ {
+- puts("hello, world");
++ puts("hello, wolrd!");
+ return 0;
+ }</code></pre>
+<p>And I see my mistake leaping out at me on the new line I added (which <code class="backtick">git&nbsp;diff</code> puts a <code class="backtick">+</code> in front of). But now what do I do? I already commited the change, which means that I can't get it out of the history.<a href="#fn5" class="footnoteRef" id="fnref5"><sup>5</sup></a></p>
+<p>Instead, I use <code class="backtick">git&nbsp;revert</code> on <code class="backtick">HEAD</code>, the most recent commit:</p>
+<pre><code>$ git revert HEAD
+[master fca3166] Revert "add exclamation point"
+ 1 files changed, 1 insertions(+), 1 deletions(-)</code></pre>
+<p>(Not shown here is where it popped up a <code class="backtick">vim</code> session to let me edit the commit message; I just hit <code class="backtick">:x</code>&lt;ENTER&gt; to get out of it without changing the default.)</p>
+<p>Now everything is back to the way it was before the bad commit:</p>
+<pre><code>$ ./hello
+hello, world</code></pre>
+<h3 id="Looking_at_old_versions"><span class="header-section-number">3.6.7</span> Looking at old versions</h3>
+<p>Running <code class="backtick">git&nbsp;log</code> will now show me the entire history of my project, newest commits first:</p>
+<pre><code>fca3166a697c6d72fb9e8aec913bb8e36fb5fe4e Revert "add exclamation point"
+f40d8d386890103abacd0bf4142ecad62eed5aeb add exclamation point
+23d6219c9380ba03d9be0672f0a7b25d18417731 keep tiny.c around
+defa0e0430293ca910f077d5dd19fccc47ab0521 no, goodbye.c was a bad idea
+454b24c307121b5a597375a99a37a825b0dc7e81 we need a second program to say goodbye
+6d2116c4c72a6ff92b8b276eb88ddb556d1b8fdd give better name to hello program
+13a73bedd3a48c173898d1afec05bd6fa0d7079a expand previous program to hello world
+a44e1e195de4ce785cd95cae3b93c817d598a9ee add a very short C program</code></pre>
+<p>If I want to look at an old version (say, after I created <code class="backtick">goodbye.c</code>), I can go back to it using <code class="backtick">git&nbsp;checkout</code>:</p>
+<pre><code>$ git checkout 454b2
+Note: checking out '454b2'.
+
+You are in 'detached HEAD' state. You can look around, make experimental
+changes and commit them, and you can discard any commits you make in this
+state without impacting any branches by performing another checkout.
+
+If you want to create a new branch to retain commits you create, you may
+do so (now or later) by using -b with the checkout command again. Example:
+
+ git checkout -b new_branch_name
+
+HEAD is now at 454b24c... we need a second program to say goodbye
+$ ls
+goodbye.c hello hello.c</code></pre>
+<p>Now I have both <code class="backtick">goodbye.c</code> and <code class="backtick">hello.c</code>, as well as my compiled program <code class="backtick">hello</code>,
+ since I didn't tell Git about it. Note that I also got lots of
+horrendous warnings about the fact that I am living in the past and
+shouldn't expect to make any permanent changes here.</p>
+<p>To go back to the last commit, use <code class="backtick">git&nbsp;checkout&nbsp;master</code>:</p>
+<pre><code>$ git checkout master
+Previous HEAD position was 454b24c... we need a second program to say goodbye
+Switched to branch 'master'
+$ ls
+hello hello.c tiny.c</code></pre>
+<h3 id="More_information_about_Git"><span class="header-section-number">3.6.8</span> More information about Git</h3>
+<p>All Git commands take a <code class="backtick">--help</code> argument that brings up their manual page. There is also extensive documentation at <a href="http://git-scm.com/">http://git-scm.com</a>.</p>
+<h2 id="submitScript"><span class="header-section-number">3.7</span> Submitting assignments</h2>
+<p>The submit command is is found in <code>/c/cs223/bin</code> on the Zoo. Here is the documentation (adapted from comments in the script):</p>
+<pre><code>submit assignment-number file(s)
+unsubmit assignment-number file(s)
+check assignment-number
+makeit assignment-number [file]
+protect assignment-number file(s)
+unprotect assignment-number file(s)
+retrieve assignment-number file[s]
+testit assignment-number test
+
+The submit program can be invoked in eight different ways:
+
+ /c/cs223/bin/submit 1 Makefile tokenize.c unique.c time.log
+
+submits the named source files as your solution to Homework #1;
+
+ /c/cs223/bin/check 2
+
+lists the files that you have submitted for Homework #2;
+
+ /c/cs223/bin/unsubmit 3 error.submit bogus.solution
+
+deletes the named files that you had submitted previously for Homework #3
+(i.e., withdraws them from submission, which is useful if you accidentally
+submit the wrong file);
+
+ /c/cs223/bin/makeit 4 tokenize unique
+
+runs "make" on the files that you submitted previously for Homework #4;
+
+ /c/cs223/bin/protect 5 tokenize.c time.log
+
+protects the named files that you submitted previously for Homework #5 (so
+they cannot be deleted accidentally); and
+
+ /c/cs223/bin/unprotect 6 unique.c time.log
+
+unprotects the named files that you submitted previously for Homework #6
+(so they can be deleted); and
+
+ /c/cs223/bin/retrieve 7 Csquash.c
+
+retrieves copies of the named files that you submitted previously for Homework #7
+
+ /c/cs223/bin/testit 8 BigTest
+
+runs the test script /c/cs223/Hwk8/test.BigTest.</code></pre>
+<p>The <code>submit</code> program will only work if there is a directory with your name and login on it under <code>/c/cs223/class</code>.
+ If there is no such directory, you need to make sure that you have
+correctly signed up for CS223 using the web form. Note that it may take
+up to an hour for this directory to appear after you sign up.</p>
+<h1 id="c"><span class="header-section-number">4</span> The C programming language</h1>
+<p>The C programming language was developed at Bell Laboratories in the
+early 1970s as the system programming language for Unix, based on the
+earlier and even more primitive languages BCPL and B. When originally
+developed, it was targeted at machines that were extremely limited by
+modern standards: the first Unix implementation (and the B compiler that
+ supported it) ran on a DEC PDP-7 with only 8192 18-bit words of memory (<a href="http://cm.bell-labs.com/who/dmr/chist.html">Dennis
+ M. Ritchie, The development of the C language, in Thomas J. Bergin,
+Jr., and Richard G. Gibson, Jr., History of Programming Languages-II
+ed., ACM Press, 1996</a>). So using as few resources as possible, both in the compiler and in the resulting code, was a priority.</p>
+<p>This priority is reflected in the features (and lack of features) of
+C, and is partly responsible for its success. Programs written in C
+place almost no demands on the system they run on and give the
+programmer nearly complete control over their execution: this allows
+programs that were previously written in assembly language, like
+operating system kernels and device drivers, to be implemented in C. So C
+ is often the first language ported to any new architecture, and many
+higher-level languages are either executed using interpreters written in
+ C or use C as in intermediate language in the compilation process.</p>
+<p>Since its initial development, C has gone through four major versions:</p>
+<ul>
+<li>The original <strong>K&amp;R C</strong> defined in the 1978 first edition of Kernighan and Ritchie's book <em>The C Programming Language</em>;</li>
+<li><strong>ANSI C</strong>, from 1988, which fixed some oddities in the syntax and which is documented in the 1988 second edition of <em>The C Programming Language</em>;</li>
+<li><strong>C99</strong>, from 1999, the ISO/IEC 9899:1999 standard for
+C, which added some features from C++ and many new features for
+high-performance numerical computing;</li>
+<li><strong>C11</strong>, from 2011, the ISO/IEC 9899:2011 standard for
+C, which relaxed some of the requirements of C99 that most compilers
+hadn't bothered implementing and which added a few extra features.</li>
+</ul>
+<p>Unfortunately, C99 and C11 both exemplify the uselessness of standards committees in general and the <a href="http://www.iso.org/">ISO</a>
+ in particular. Because the ISO has no power to enforce standards on
+compiler writers, and because they will charge you CHF 198 just to look
+at the C11 standard, many compiler writers have ignored much of C99 and
+C11. In particular, Microsoft pretty much gave up on adding any features
+ after ANSI C, and support for C99 and C11 is spotty in <code>gcc</code> and <code>clang</code>,
+ the two dominant open source C compilers. So if you want to write
+portable C code, it is safest to limit yourself to features in ANSI C.</p>
+<p>For this class, we will permit you to use any feature of C99 that <code>gcc</code> supports, which also includes all features of ANSI C. You can compile with C99 support by using <code>gcc --std=c99</code> or by calling <code>gcc</code> as <code>c99</code>, as in <code>c99 -o hello hello.c</code>. Compiling with straight <code>gcc</code> will give you GNU's own peculiar dialect of C, which is basically ANSI C with some extras. For maximum portability when using <code>gcc</code>, it is safest to use <code>gcc -ansi -pedantic</code>, which expects straight ANSI C and will complain about any extensions.</p>
+<h2 id="CProgramStructure"><span class="header-section-number">4.1</span> Structure of a C program</h2>
+<p>A C program consists of one or more files (which act a little bit
+like modules in more structured programming languages, each of which
+typically contains <strong>definitions</strong> of <strong>functions</strong>, each of which consists of <strong>statements</strong>, which are either <strong>compound statements</strong> like <code>if</code>, <code>while</code>, etc. or <strong>expressions</strong> that typically perform some sort of arithmetic or call other functions. Files may also include <strong>declarations</strong>
+ of global variables (not recommended), and functions will often contain
+ declarations of local variables that can only be used inside that
+function.</p>
+<p>Here is a typical small C program that sums a range of integers.
+Since this is our first real program, it's a little heavy on the
+comments (shown between <code>/*</code> and <code>*/</code>).</p>
+<div>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"><span class="ot">#include &lt;stdio.h&gt; </span><span class="co">/* This is needed to get the declarations of fprintf and printf */</span>
+<span class="ot">#include &lt;stdlib.h&gt; </span><span class="co">/* This is needed to get the declaration of atoi */</span>
+
+<span class="co">/* Return the sum of all integers i</span>
+<span class="co"> * such that start &lt;= i and i &lt; end. */</span>
+<span class="dt">int</span>
+sumRange(<span class="dt">int</span> start, <span class="dt">int</span> end)
+{
+ <span class="dt">int</span> i; <span class="co">/* loop variable */</span>
+ <span class="dt">int</span> sum; <span class="co">/* sum of all values so far */</span>
+
+ <span class="co">/* a mathematician would use a formula for this,</span>
+<span class="co"> * but we are computer programmers! */</span>
+ sum = <span class="dv">0</span>;
+
+ <span class="co">/* The three parts of the header for this loop mean:</span>
+<span class="co"> * 1. Set i to start initially.</span>
+<span class="co"> * 2. Keep doing the loop as long as i is less than end.</span>
+<span class="co"> * 3. After each iteration, add 1 to i.</span>
+<span class="co"> */</span>
+ <span class="kw">for</span>(i = start; i &lt; end; i++) {
+ sum += i; <span class="co">/* This adds i to sum */</span>
+ }
+
+ <span class="co">/* This exits the function immediately,</span>
+<span class="co"> * sending the value of sum back to the caller. */</span>
+ <span class="kw">return</span> sum;
+}
+
+<span class="dt">int</span>
+main(<span class="dt">int</span> argc, <span class="dt">char</span> **argv)
+{
+ <span class="dt">int</span> start; <span class="co">/* initial value in range */</span>
+ <span class="dt">int</span> end; <span class="co">/* one past the last value in the range */</span>
+
+ <span class="co">/* This tests for the wrong number of arguments.</span>
+<span class="co"> * The != operator returns true (1) if its arguments are not equal,</span>
+<span class="co"> * and false (0) otherwise.</span>
+<span class="co"> * Note that the program name itself counts as an argument</span>
+<span class="co"> * (which is why we want the argument count to be 3)</span>
+<span class="co"> * and appears in position 0 in the argument vector</span>
+<span class="co"> * (which means we can get it using argv[0]). */</span>
+ <span class="kw">if</span>(argc != <span class="dv">3</span>) {
+ fprintf(stderr, <span class="st">"Usage: %s</span><span class="ch">\n</span><span class="st"> start end"</span>, argv[<span class="dv">0</span>]);
+ <span class="kw">return</span> <span class="dv">1</span>;
+ }
+
+ <span class="co">/* Convert start and end positions from strings to ints */</span>
+ start = atoi(argv[<span class="dv">1</span>]);
+ end = atoi(argv[<span class="dv">2</span>]);
+
+ <span class="co">/* Call sumRange and print the result */</span>
+ printf(<span class="st">"sumRange(%d, %d) = %d</span><span class="ch">\n</span><span class="st">"</span>, start, end, sumRange(start, end));
+
+ <span class="kw">return</span> <span class="dv">0</span>;
+}</code></pre></div>
+<a href="http://cs.yale.edu/homes/aspnes/classes/223/examples/sumRange.c" class="uri">examples/sumRange.c</a>
+</div>
+<p>This is what the program does if we compile and run it:</p>
+<pre><code>$ c99 -g -Wall -pedantic -o sumRange sumRange.c
+$ ./sumRange 1 100
+sumRange(1, 100) = 4950</code></pre>
+<p>The <code>sumRange.c</code> program contains two functions, <code>sumRange</code> and <code>main</code>. The <code>sumRange</code> function does the actual work, while <code>main</code>
+ is the main routine of the program that gets called with the
+command-line arguments when the program is run. Every C program must
+have a routine named <code>main</code> with these particular arguments.</p>
+<p>In addition, <code>main</code> may call three library functions, <code>fprintf</code> (which in this case is used to generate error messages), <code>printf</code> (which generates ordinary output), and <code>atoi</code>
+ (which is used to translate the command-line arguments into numerical
+values). These functions must all be declared before they can be used.
+In the case of <code>sumRange</code>, putting the definition of <code>sumRange</code> before the definition of <code>main</code> is enough. For the library routines, the <strong>include files</strong> <code>stdio.h</code> and <code>stdlib.h</code>
+ contain declarations of the functions that contain enough information
+about there return types and arguments that the compiler knows how to
+generate machine code to call them. These files are included in <code>sumRange.c</code> by the <strong>C preprocessor</strong>, which pastes in the contents of any file specified by the <code>#include</code> command, strips out any comments (delimited by <code>/*</code> and <code>*/</code>, or by <code>//</code>
+ and the end of the line if you are using C99), and does some other
+tricks that allow you to muck with the source code before the actual
+compiler sees it (see <a href="#macros">Macros</a>). You can see what the output of the preprocessor looks like by calling the C compiler with the <code>-E</code> option, as in <code>c99 -E sumRange.c</code>.</p>
+<p>The <strong>body</strong> of each function consists of some <strong>variable declarations</strong> followed by a sequence of <strong>statements</strong>
+ that tell the computer what to do. Unlike some languages, every
+variable used in a C program must be declared. A declaration specifies
+the <strong>type</strong> of a variable, which tells the compiler how
+much space to allocate for it and how to interpret some operations on
+its value. Statements may be <strong>compound statements</strong> like the <code>if</code> statement in <code>main</code> that executes its body only if the program is called with the wrong number of command-line arguments or the <code>for</code> loop in <code>sumRange</code> that executes its body as long as the test in its header remains true; or they may be <strong>simple statements</strong> that consist of a single <strong>expression</strong> followed by a semicolon.</p>
+<p>An <strong>expression</strong> is usually either a bare function call whose value is discarded (for example, the calls to <code>fprintf</code> and <code>printf</code> in <code>main</code>), or an arithmetic expression (which may include function calls, like the calls to <code>atoi</code> or in <code>main</code>) whose value is assigned to some variable using the <strong>assignment operator</strong> <code>=</code> or sometimes variants like <code>+=</code> (which is shorthand for adding a value to an existing variable: <code>x += y</code> is equivalent to <code>x = x+y</code>).</p>
+<p>When you compile a C program, after running the preprocessor, the compiler generates <strong>assembly language</strong>
+ code that is a human-readable description of the ultimate machine code
+for your target CPU. Assembly language strips out all the human-friendly
+ features of your program and reduces it to simple instructions usually
+involving moving things from one place to the other or performing a
+single arithmetic operation. For example, the C line</p>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"> x = y + <span class="dv">1</span>; <span class="co">/* add 1 to y, store result in x */</span></code></pre></div>
+<p>gets translated into x86 assembly as</p>
+<div class="sourceCode"><pre class="sourceCode gnuassembler"><code class="sourceCode gnuassembler"> movl -<span class="dv">24</span>(%rbp), %edi
+ addl $1, %edi
+ movl %edi, -<span class="dv">28</span>(%rbp)</code></pre></div>
+<p>These three operations copy the value of <code>y</code> into the CPU register <code>%edi</code>, add 1 to the <code>%edi</code> register, and then copy the value back into <code>x</code>. This corresponds directly to what you would have to do to evaluate <code>x = y + 1</code> if you could only do one very basic operation at a time and couldn't do arithmetic operations on memory locations: fetch <code>y</code>, add 1, store <code>x</code>. Note that the CPU doesn't know about the names <code>y</code> and <code>x</code>; instead, it computes their addresses by adding -24 and -28 respectively to the base pointer register <code>%rbp</code>. This is why it can be hard to debug compiled code unless you tell the compiler to keep around extra information.</p>
+<p>For an arbitrary C program, if you are using <code>gcc</code>, you can see what your code looks like in assembly language using the <code>-S</code> option. For example, <code>c99 -S sumRange.c</code> will create a file <code>sumRange.s</code> that looks like this:</p>
+<div>
+<div class="sourceCode"><pre class="sourceCode gnuassembler"><code class="sourceCode gnuassembler"> <span class="kw">.file</span> <span class="st">"sumRange.c"</span>
+ <span class="kw">.text</span>
+ <span class="kw">.globl</span> sumRange
+ <span class="kw">.type</span> sumRange, <span class="co">@function</span>
+<span class="kw">sumRange:</span>
+.LFB0<span class="kw">:</span>
+ .cfi_startproc
+ pushl %ebp
+ .cfi_def_cfa_offset <span class="dv">8</span>
+ .cfi_offset <span class="dv">5</span>, -<span class="dv">8</span>
+ movl %esp, %ebp
+ .cfi_def_cfa_register <span class="dv">5</span>
+ subl $16, %esp
+ movl $0, -<span class="dv">4</span>(%ebp)
+ movl <span class="dv">8</span>(%ebp), %eax
+ movl %eax, -<span class="dv">8</span>(%ebp)
+ jmp .L2
+.L3<span class="kw">:</span>
+ movl -<span class="dv">8</span>(%ebp), %eax
+ addl %eax, -<span class="dv">4</span>(%ebp)
+ addl $1, -<span class="dv">8</span>(%ebp)
+.L2<span class="kw">:</span>
+ movl -<span class="dv">8</span>(%ebp), %eax
+ cmpl <span class="dv">12</span>(%ebp), %eax
+ jl .L3
+ movl -<span class="dv">4</span>(%ebp), %eax
+ leave
+ .cfi_restore <span class="dv">5</span>
+ .cfi_def_cfa <span class="dv">4</span>, <span class="dv">4</span>
+ ret
+ .cfi_endproc
+.LFE0<span class="kw">:</span>
+ <span class="kw">.size</span> sumRange, .-sumRange
+ <span class="kw">.section</span> <span class="kw">.rodata</span>
+.LC0<span class="kw">:</span>
+ <span class="kw">.string</span> <span class="st">"Usage: %s</span><span class="ch">\n</span><span class="st"> start end"</span>
+.LC1<span class="kw">:</span>
+ <span class="kw">.string</span> <span class="st">"sumRange(%d, %d) = %d</span><span class="ch">\n</span><span class="st">"</span>
+ <span class="kw">.text</span>
+ <span class="kw">.globl</span> main
+ <span class="kw">.type</span> main, <span class="co">@function</span>
+<span class="kw">main:</span>
+.LFB1<span class="kw">:</span>
+ .cfi_startproc
+ pushl %ebp
+ .cfi_def_cfa_offset <span class="dv">8</span>
+ .cfi_offset <span class="dv">5</span>, -<span class="dv">8</span>
+ movl %esp, %ebp
+ .cfi_def_cfa_register <span class="dv">5</span>
+ andl $-<span class="dv">16</span>, %esp
+ subl $32, %esp
+ cmpl $3, <span class="dv">8</span>(%ebp)
+ je .L6
+ movl <span class="dv">12</span>(%ebp), %eax
+ movl (%eax), %edx
+ movl stderr, %eax
+ movl %edx, <span class="dv">8</span>(%esp)
+ movl $.LC0, <span class="dv">4</span>(%esp)
+ movl %eax, (%esp)
+ call fprintf
+ movl $1, %eax
+ jmp .L7
+.L6<span class="kw">:</span>
+ movl <span class="dv">12</span>(%ebp), %eax
+ addl $4, %eax
+ movl (%eax), %eax
+ movl %eax, (%esp)
+ call atoi
+ movl %eax, <span class="dv">24</span>(%esp)
+ movl <span class="dv">12</span>(%ebp), %eax
+ addl $8, %eax
+ movl (%eax), %eax
+ movl %eax, (%esp)
+ call atoi
+ movl %eax, <span class="dv">28</span>(%esp)
+ movl <span class="dv">28</span>(%esp), %eax
+ movl %eax, <span class="dv">4</span>(%esp)
+ movl <span class="dv">24</span>(%esp), %eax
+ movl %eax, (%esp)
+ call sumRange
+ movl %eax, <span class="dv">12</span>(%esp)
+ movl <span class="dv">28</span>(%esp), %eax
+ movl %eax, <span class="dv">8</span>(%esp)
+ movl <span class="dv">24</span>(%esp), %eax
+ movl %eax, <span class="dv">4</span>(%esp)
+ movl $.LC1, (%esp)
+ call printf
+ movl $0, %eax
+.L7<span class="kw">:</span>
+ leave
+ .cfi_restore <span class="dv">5</span>
+ .cfi_def_cfa <span class="dv">4</span>, <span class="dv">4</span>
+ ret
+ .cfi_endproc
+.LFE1<span class="kw">:</span>
+ <span class="kw">.size</span> main, .-main
+ <span class="kw">.ident</span> <span class="st">"GCC: (Ubuntu 4.8.2-19ubuntu1) 4.8.2"</span>
+ <span class="kw">.section</span> .note.GNU-stack,<span class="st">""</span>,<span class="co">@progbits</span></code></pre></div>
+<a href="http://cs.yale.edu/homes/aspnes/classes/223/examples/sumRange.s" class="uri">examples/sumRange.s</a>
+</div>
+<p>You usually don't need to look at assembly language, but it can
+sometimes be enlightening to see what the compiler is doing with your
+code. One thing that I find interesting about this particular code
+(which is for the x86 architecture) is that most of the instructions are
+ <code>movl</code>, the x86 instruction for copying a 32-bit quantity
+from one location to another: most of what this program is doing is
+copying data into the places expected by the library functions it is
+calling. Also noteworthy is that the beautiful compound statements like <code>if</code> and <code>for</code> that so eloquently express the intent of the programmer get turned into a pile of jump (<code>jmp</code>) and conditional jump (<code>jl</code>, <code>je</code>) instructions, the machine code versions of the often dangerous and confusing <code>goto</code> statement. This is because CPUs are dumb: they don't know how to carry out an <code>if</code>
+ branch or a loop, and all they can do instead is be told to replace the
+ value of their program counter register with some new value instead of
+just incrementing it as they usually do.</p>
+<p>Assembly language is not the last stage in this process. The <strong>assembler</strong> (<code>as</code>) is a program that translates the assembly language in <code>sumRange.s</code> into machine code (which will be store in <code>sumRange.o</code>
+ if we aren't compiling a single program all at once). Machine code is
+not human-readable, and is close to the raw stream of bytes that gets
+stored in the computer's memory to represent a running program. The
+missing parts are that the addresses of each function and global
+variables are generally left unspecified, so that they can be moved
+around to make room for other functions and variables coming from other
+files and from system libraries. The job of stitching all of these
+pieces together, putting everything in the right place, filling in any
+placeholder addresses, and generating the <strong>executable file</strong> <code>sumRange</code> that we can actually run is given to the <strong>linker</strong> <code>ld</code>.</p>
+<p>The whole process looks like this:</p>
+<pre><code>sumRange.c (source code)
+ |
+ v
+[preprocessor (cpp)]
+ |
+ v
+preprocessed version of sumRange.c
+ |
+ v
+[compiler (gcc)]
+ |
+ v
+sumRange.s (assembly code)
+ |
+ v
+[assembler (as)]
+ |
+ v
+sumRange.o (machine code)
+ |
+ v
+[linker (ld)] &lt;- system library (glibc.a)
+ |
+ v
+sumRange (executable)</code></pre>
+<p>The good news is, you don't actually have to run all of these steps yourself; instead, <code>gcc</code> (which you may be calling as <code>c99</code>) will take care of everything for you, particularly for simple programs like <code>sumRange.c</code> that fit in a single file.</p>
+<h2 id="numericTypes"><span class="header-section-number">4.2</span> Numeric data types</h2>
+<p>All data stored inside a computer is ultimately represented as a sequence of <strong>bits</strong>, 0 or 1 values, typically organized into <strong>words</strong> consisting of several 8-bit <strong>bytes</strong>.<a href="#fn6" class="footnoteRef" id="fnref6"><sup>6</sup></a></p>
+<p>A typical desktop computer might have enough RAM to store <span class="math inline">2<sup>32</sup></span> bytes (4 gigabytes); the Zoo machines store <span class="math inline">2<sup>35</sup></span> bytes (32 gigabytes). However, the <strong>address space</strong> of a process might be much larger: on a 64-bit machine, the address space is <span class="math inline">2<sup>64</sup></span> bytes. There's no way to store <span class="math inline">2<sup>64</sup></span> different addresses in <span class="math inline">2<sup>35</sup></span> bytes of RAM; instead, a <strong>memory mapper</strong>,
+ typically built in to the CPU, translates the large addresses of the
+parts of the address space that are actually used into smaller addresses
+ corresponding to actual RAM locations. In some cases, regions of memory
+ that have not been used in a while will be <strong>swapped out</strong> to disk, leaving more RAM free for other parts of the process (or other processes). This technique is known as <strong>virtual memory</strong>
+ and is usually invisible to the programmer. The use of virtual memory
+can increase the available space beyond the size of the RAM a little
+bit, but if you try to run a process that is actively using
+significantly more space that can be stored in RAM, it will slow down
+dramatically, because disk drives are roughly ten million times slower
+than memory.</p>
+<p>The most basic kind of data represents integer values from some bounded range. C supports several <strong>integer data types</strong>,
+ varying in their size (and thus range), and whether or not they are
+considered to be signed. These are described in more detail <a href="#integerTypes">below</a>.</p>
+<p>For numerical computation, integer data types can be inconvenient. So C also supports <strong>floating-point types</strong> that consist of a fixed-size <strong>mantissa</strong>, which is essentially an integer, together with an <strong>exponent</strong> that is used to multiply the mantissa by <span class="math inline">2<sup><em>x</em></sup></span> for some <span class="math inline"><em>x</em></span>.
+ These allow very small or very large values to be represented with
+small relative error, but do not allow exact computation because of the
+limited precision of the mantissa. Floating-point types are also
+described <a href="#floatingPointTypes">below</a>.</p>
+<p>All other data is represented by converting it to either integer or
+floating-point numbers. For example, text characters in C are
+represented as small integer values, so that the character constant <code>'z'</code> representation a lower-case "z" is exactly the same as the integer constant <code>122</code> (which is the <a href="http://en.wikipedia.org/wiki/ASCII">ASCII</a> code for "z"). A string like <code>"hi there"</code>
+ is represented by a sequence of 8-bit ASCII characters, with a special 0
+ character to mark the end of the string. Strings that go beyond the
+English characters available in the ASCII encoding are typically
+represented using <a href="http://www.unicode.org/">Unicode</a> and
+encoded as sequences of bytes using a particular representation called
+UTF-8. The color of a pixel in an image might be represented as three
+8-bit integers representing the intensity of red, green, and blue in the
+ color, while an image itself might be a long sequence of such 3-byte
+RGB values. At the bottom, every operation applied to these more complex
+ data types translates into a whole lot of copies and arithmetic
+operations on individual bytes and words.</p>
+<p>From the CPU's point of view, even much of this manipulation consists
+ of operating on integers that happen to represent addresses instead of
+data. So when a C program writes a zero to the 19th entry in a sequence
+of 4-byte integers, somewhere in the implementation of this operation
+the CPU will be adding <span class="math inline">4 ⋅ 19</span> to a base
+ address for the sequence to computer where to write this value. Unlike
+many higher-level languages, C allows the program direct access to
+address computations via <strong>pointer types</strong>, which are tricky enough to get <a href="#pointers">their own chapter</a>.
+ Indeed, most of the structured types that C provides for representing
+more complicated data can best be understood as a thin layer of
+abstraction on top of pointers. We will see examples of these in later
+chapters as well.</p>
+<p>For now, we concentrate on integer and floating-point types, and on the operations that can be applied to them.</p>
+<h3 id="integerTypes"><span class="header-section-number">4.2.1</span> Integer types in C</h3>
+<p>Most variables in C programs tend to hold integer values, and indeed
+most variables in C programs tend to be the default-width integer type <code>int</code>.
+ Declaring a variable to have a particular integer type controls how
+much space is used to store the variable (any values too big to fit will
+ be truncated) and specifies that the arithmetic on the variable is done
+ using integer operations.</p>
+<h4 id="basicIntegerTypes"><span class="header-section-number">4.2.1.1</span> Basic integer types</h4>
+<p>The standard C integer types are:</p>
+<table style="width:96%;">
+<colgroup>
+<col width="37%">
+<col width="25%">
+<col width="33%">
+</colgroup>
+<thead>
+<tr class="header">
+<th align="left">Name</th>
+<th align="left">Typical size</th>
+<th align="left">Signed by default?</th>
+</tr>
+</thead>
+<tbody>
+<tr class="odd">
+<td align="left"><p><code>char</code></p></td>
+<td align="left"><p>8 bits</p></td>
+<td align="left"><p>unspecified</p></td>
+</tr>
+<tr class="even">
+<td align="left"><p><code>short</code></p></td>
+<td align="left"><p>16 bits</p></td>
+<td align="left"><p>signed</p></td>
+</tr>
+<tr class="odd">
+<td align="left"><p><code>int</code></p></td>
+<td align="left"><p>32 bits</p></td>
+<td align="left"><p>signed</p></td>
+</tr>
+<tr class="even">
+<td align="left"><p><code>long</code></p></td>
+<td align="left"><p>32 bits</p></td>
+<td align="left"><p>signed</p></td>
+</tr>
+<tr class="odd">
+<td align="left"><p><code>long long</code></p></td>
+<td align="left"><p>64 bits</p></td>
+<td align="left"><p>signed</p></td>
+</tr>
+</tbody>
+</table>
+<p>The typical size is for 32-bit architectures like the Intel i386. Some 64-bit machines might have 64-bit <code class="backtick">int</code>s and <code class="backtick">long</code>s, and some microcontrollers have 16-bit <code class="backtick">int</code>s.
+ Particularly bizarre architectures might have even wilder sizes, but
+you are not likely to see this unless you program vintage 1970s
+supercomputers. The general convention is that <code class="backtick">int</code> is the most convenient size for whatever computer you are using and should be used by default.</p>
+<p>Many compilers also support a <code class="backtick">long&nbsp;long</code>
+ type that is usually twice the length of a long (e.g. 64 bits on i386
+machines). This type was not officially added to the C standard prior to
+ C99, so it may or may not be available if you insist on following the
+ANSI specification strictly.</p>
+<p>Each of these types comes in signed and unsigned variants.<br>
+This controls the interpretation of some operations (mostly comparisons
+and shifts) and determines the range of the type: for example, an <code>unsigned char</code> holds values in the range 0 through 255 while a <code>signed char</code> holds values in the range -128 through 127, and in general an unsigned <span class="math inline"><em>n</em></span>-bit type runs from 0 through <span class="math inline">2<sup><em>n</em></sup> − 1</span> while the signed version runs from <span class="math inline">−2<sup><em>n</em> − 1</sup></span> through <span class="math inline">2<sup><em>n</em> − 1</sup> − 1</span>. The representation of signed integers uses <strong>two's-complement</strong> notation, which means that a positive value <span class="math inline"><em>x</em></span> is represented as the unsigned value <span class="math inline"><em>x</em></span> while a negative value <span class="math inline">−<em>x</em></span> is represented as the unsigned value <span class="math inline">2<sup><em>n</em></sup> − <em>x</em></span>. For example, if we had a peculiar implementation of C that used 3-bit <code>int</code>s, the binary values and their interpretation as <code>int</code> or <code>unsigned int</code> would look like this:</p>
+<table style="width:71%;">
+<colgroup>
+<col width="9%">
+<col width="29%">
+<col width="31%">
+</colgroup>
+<thead>
+<tr class="header">
+<th align="left">bits</th>
+<th align="left">as <code>unsigned int</code></th>
+<th align="left">as <code>int</code></th>
+</tr>
+</thead>
+<tbody>
+<tr class="odd">
+<td align="left"><p>000</p></td>
+<td align="left"><p>0</p></td>
+<td align="left"><p>0</p></td>
+</tr>
+<tr class="even">
+<td align="left"><p>001</p></td>
+<td align="left"><p>1</p></td>
+<td align="left"><p>1</p></td>
+</tr>
+<tr class="odd">
+<td align="left"><p>010</p></td>
+<td align="left"><p>2</p></td>
+<td align="left"><p>2</p></td>
+</tr>
+<tr class="even">
+<td align="left"><p>011</p></td>
+<td align="left"><p>3</p></td>
+<td align="left"><p>3</p></td>
+</tr>
+<tr class="odd">
+<td align="left"><p>100</p></td>
+<td align="left"><p>4</p></td>
+<td align="left"><p>-4</p></td>
+</tr>
+<tr class="even">
+<td align="left"><p>101</p></td>
+<td align="left"><p>5</p></td>
+<td align="left"><p>-3</p></td>
+</tr>
+<tr class="odd">
+<td align="left"><p>110</p></td>
+<td align="left"><p>6</p></td>
+<td align="left"><p>-2</p></td>
+</tr>
+<tr class="even">
+<td align="left"><p>111</p></td>
+<td align="left"><p>7</p></td>
+<td align="left"><p>-1</p></td>
+</tr>
+</tbody>
+</table>
+<p>The reason we get one extra negative value for an unsigned integer
+type is this allows us to interpret the first bit as the sign, which
+makes life a little easier for whoever is implementing our CPU. Two
+useful features of this representation are:</p>
+<ol style="list-style-type: decimal">
+<li>We can convert freely between signed and unsigned values as long as we are in the common range of both, and</li>
+<li>Addition and subtraction work exactly the same we for both signed
+and unsigned values. For example, on our hypothetical 3-bit machine, <span class="math inline">1 + 5</span> represented as <span class="math inline">001 + 101 = 110</span> gives the same answer as <span class="math inline">1 + ( − 3)=001 + 101 = 110</span>. In the first case we interpret <span class="math inline">110</span> as <span class="math inline">6</span>, while in the second we interpret it as <span class="math inline">−2</span>, but both answers are right in their respective contexts.</li>
+</ol>
+<p>Note that in order to make this work, we can't detect overflow: when
+the CPU adds two 3-bit integers, it doesn't know if we are adding <span class="math inline">7 + 6 = 111 + 110 = 1101 = 13</span> or <span class="math inline">( − 1)+(−2)=111 + 110 = 101 = ( − 3)</span>. In both cases the result is truncated to <span class="math inline">101</span>, which gives the incorrect answer <span class="math inline">5</span> when we are adding unsigned values.</p>
+<p>This can often lead to surprising uncaught errors in C programs,
+although using more than 3 bits will make overflow less likely. It is
+usually a good idea to pick a size for a variable that is substantially
+larger than the largest value you expect the variable to hold (although
+most people just default to <code>int</code>), unless you are very short
+ on space or time (larger values take longer to read and write to
+memory, and may make some arithmetic operations take longer).</p>
+<p>Taking into account signed and unsigned versions, the full collection of integer types looks like this:</p>
+<table>
+<colgroup>
+<col width="33%">
+<col width="33%">
+<col width="33%">
+</colgroup>
+<tbody>
+<tr class="odd">
+<td align="left"><p><code>char</code></p></td>
+<td align="left"><p><code>signed char</code></p></td>
+<td align="left"><p><code>unsigned char</code></p></td>
+</tr>
+<tr class="even">
+<td align="left"><p><code>short</code></p></td>
+<td align="left"></td>
+<td align="left"><p><code>unsigned short</code></p></td>
+</tr>
+<tr class="odd">
+<td align="left"><p><code>int</code></p></td>
+<td align="left"></td>
+<td align="left"><p><code>unsigned int</code></p></td>
+</tr>
+<tr class="even">
+<td align="left"><p><code>long</code></p></td>
+<td align="left"></td>
+<td align="left"><p><code>unsigned long</code></p></td>
+</tr>
+<tr class="odd">
+<td align="left"><p><code>long long</code></p></td>
+<td align="left"></td>
+<td align="left"><p><code>unsigned long long</code></p></td>
+</tr>
+</tbody>
+</table>
+<p>So these are all examples of declarations of integer variables:</p>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"> <span class="dt">int</span> i;
+ <span class="dt">char</span> c;
+ <span class="dt">signed</span> <span class="dt">char</span> temperature; <span class="co">/* degrees Celsius, only valid for Earth's surface */</span>
+ <span class="dt">long</span> netWorthInPennies;
+ <span class="dt">long</span> <span class="dt">long</span> billGatesNetWorthInPennies;
+ <span class="dt">unsigned</span> <span class="dt">short</span> shaveAndAHaircutTwoBytes;</code></pre></div>
+<p>For <code class="backtick">char</code>s, whether the character is signed <span class="math inline">( − 128…127)</span> or unsigned <span class="math inline">(0…255)</span> is at the whim of the compiler. If it matters, declare your variables as <code class="backtick">signed&nbsp;char</code> or <code class="backtick">unsigned&nbsp;char</code>. For storing actual 8-bit characters that you aren't doing arithmetic on, it shouldn't matter.</p>
+<p>There is a slight gotcha for character processing with input function like <code>getchar</code> and <code>getc</code>. These return the special value <code>EOF</code> (defined in <code>stdio.h</code> to be <span class="math inline">−1</span>) to indicate end of file. But <span class="math inline">255</span>, which represents <code>'ÿ'</code> in the ISO Latin-1 alphabet and in Unicode and which may also appear quite often in binary files, will map to <span class="math inline">−1</span> if you put it in a character. So you should store the output of these functions in an <code>int</code> if you need to test for end of file. Once you have done this test, it's OK to put the non-end-of-file character back in a <code>char</code>.</p>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"> <span class="co">/* right */</span>
+ <span class="dt">int</span> c;
+
+ <span class="kw">while</span>((c = getchar()) != EOF) {
+ putchar(c);
+ }</code></pre></div>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"> <span class="co">/* WRONG */</span>
+ <span class="dt">char</span> c;
+
+ <span class="kw">while</span>((c = getchar()) != EOF) { <span class="co">/* &lt;- DON'T DO THIS! */</span>
+ putchar(c);
+ }</code></pre></div>
+<h4 id="C99_fixed-width_types"><span class="header-section-number">4.2.1.2</span> C99 fixed-width types</h4>
+<p>C99 provides a <code>stdint.h</code> header file that defines integer types with known size independent of the machine architecture. So in C99, you can use <code>int8_t</code> instead of <code>signed&nbsp;char</code> to guarantee a signed type that holds exactly 8 bits, or <code>uint64_t</code> instead of <code>unsigned&nbsp;long&nbsp;long</code> to get a 64-bit unsigned integer type. The full set of types typically defined are <code>int8_t</code>, <code>int16_t</code>, <code>int32_t</code>, and <code>int64_t</code> for signed integers and <code>uint8_t</code>, <code>uint16_t</code>, <code>uint32_t</code>, and <code>uint64_t</code>
+ for unsigned integers. There are also types for integers that contain
+the fewest number of bits greater than some minimum (e.g., <code>int_least16_t</code>
+ is a signed type with at least 16 bits, chosen to minimize space) or
+that are the fastest type with at least the given number of bits (e.g., <code>int_fast16_t</code> is a signed type with at least 16 bits, chosen to minimize time). The <code>stdint.h</code> file also defines constants giving the minimum and maximum values of these and standard integer types; for example, <code>INT_MIN</code> and <code>INT_MAX</code> give the smallest and largest values that can be stored in an <code>int</code>.</p>
+<p>All of these types are defined as aliases for standard integer types using <a href="#typedef"><code>typedef</code></a>; the main advantage of using <code>stdint.h</code> over defining them yourself is that if somebody ports your code to a new architecture, <code>stdint.h</code> should take care of choosing the right types automatically. The main disadvantage is that, like many C99 features, <code>stdint.h</code>
+ is not universally available on all C compilers. Also, because these
+fixed-width types are a late addition to the language, the built-in
+routines for printing and parsing integers, as well as the mechanisms
+for specifying the size of an integer constant, are not adapted to deal
+with them.</p>
+<p>But if you do need to print or parse types defined in <code class="backtick">stdint.h</code>, the larger <code class="backtick">inttypes.h</code> header defines macros that give the corresponding format strings for <code>printf</code> and <code>scanf</code>. The <code>inttypes.h</code> file includes <code>stdint.h</code>, so you do not need to include both. Below is an example of a program that uses the various features provided by <code>inttypes.h</code> and <code>stdint.h</code>.</p>
+<div>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"><span class="ot">#include &lt;stdio.h&gt;</span>
+<span class="ot">#include &lt;stdlib.h&gt;</span>
+<span class="ot">#include &lt;assert.h&gt;</span>
+
+<span class="ot">#include &lt;inttypes.h&gt;</span>
+
+<span class="co">/* example of using fixed-width types */</span>
+
+<span class="co">/* largest value we can apply 3x+1 to without overflow */</span>
+<span class="ot">#define MAX_VALUE ((UINT64_MAX - 1) / 3)</span>
+
+<span class="dt">int</span>
+main(<span class="dt">int</span> argc, <span class="dt">char</span> **argv)
+{
+ <span class="dt">uint64_t</span> big;
+
+ <span class="kw">if</span>(argc != <span class="dv">2</span>) {
+ fprintf(stderr, <span class="st">"Usage: %s number</span><span class="ch">\n</span><span class="st">"</span>, argv[<span class="dv">0</span>]);
+ <span class="kw">return</span> <span class="dv">1</span>;
+ }
+
+ <span class="co">/* parse argv[1] as a uint64_t */</span>
+ <span class="co">/* SCNu64 expands to the format string for scanning uint64_t (without the %) */</span>
+ <span class="co">/* We then rely on C concatenating adjacent string constants. */</span>
+ sscanf(argv[<span class="dv">1</span>], <span class="st">"%"</span> SCNu64, &amp;big);
+
+ <span class="co">/* do some arithmetic on big */</span>
+ <span class="kw">while</span>(big != <span class="dv">1</span>) {
+ <span class="co">/* PRIu64 expands to the format string for printing uint64_t */</span>
+ printf(<span class="st">"%"</span> PRIu64 <span class="st">"</span><span class="ch">\n</span><span class="st">"</span>, big);
+
+ <span class="kw">if</span>(big % <span class="dv">2</span> == <span class="dv">0</span>) {
+ big /= <span class="dv">2</span>;
+ } <span class="kw">else</span> <span class="kw">if</span>(big &lt;= MAX_VALUE) {
+ big = <span class="dv">3</span>*big + <span class="dv">1</span>;
+ } <span class="kw">else</span> {
+ <span class="co">/* overflow! */</span>
+ puts(<span class="st">"overflow"</span>);
+ <span class="kw">return</span> <span class="dv">1</span>;
+ }
+ }
+
+ puts(<span class="st">"Reached 1"</span>);
+ <span class="kw">return</span> <span class="dv">0</span>;
+}</code></pre></div>
+<a href="http://cs.yale.edu/homes/aspnes/classes/223/examples/integerTypes/fixedWidth.c" class="uri">examples/integerTypes/fixedWidth.c</a>
+</div>
+<h3 id="sizeTypes"><span class="header-section-number">4.2.2</span> <code>size_t</code> and <code>ptrdiff_t</code></h3>
+<p>The type aliases <code>size_t</code> and <code>ptrdiff_t</code> are provided in <code>stddef.h</code> to represent the return types of the <code>sizeof</code> operator and <a href="#pointerArithmetic">pointer subtraction</a>. On a 32-bit architecture, <code>size_t</code> will be equivalent to the unsigned 32-bit integer type <code>uint32_t</code> (or just <code>unsigned int</code>) and <code>ptrdiff_t</code> will be equivalent to the signed 32-bit integer type <code>int32_t</code> (<code>int</code>). On a 64-bit architecture, <code>size_t</code> will be equivalent to <code>uint64_t</code> and <code>ptrdiff_t</code> will be equivalent to <code>int64_t</code>.</p>
+<p>The place where you will most often see <code>size_t</code> is as an argument to <a href="#malloc"><code>malloc</code></a>, where it gives the number of bytes to allocate.</p>
+<p>Because <code>stdlib.h</code> includes <code>stddef.h</code>, it is often not necessary to include <code>stddef.h</code> explicitly.</p>
+<h4 id="integerConstants"><span class="header-section-number">4.2.2.1</span> Integer constants</h4>
+<p>Constant integer values in C can be written in any of four different ways:</p>
+<ul>
+<li>In the usual decimal notation, e.g. <code class="backtick">0</code>, <code class="backtick">1</code>, <code class="backtick">-127</code>, <code class="backtick">9919291</code>, <code class="backtick">97</code>.</li>
+<li>In <strong>octal</strong> or base 8, when the leading digit is <code class="backtick">0</code>, e.g. <code class="backtick">01</code> for 1, <code class="backtick">010</code> for 8, <code class="backtick">0777</code> for 511, <code class="backtick">0141</code> for 97. Octal is not used much any more, but it is still conventional for representing Unix file permissions.</li>
+<li>In <strong>hexadecimal</strong> or base 16, when prefixed with <code class="backtick">0x</code>. The letters <code class="backtick">a</code> through <code class="backtick">f</code> are used for the digits 10 through 15. For example, <code class="backtick">0x61</code> is another way to write 97.</li>
+<li>Using a <strong>character constant</strong>, which is a single <a href="http://en.wikipedia.org/wiki/ASCII" title="WikiPedia">ASCII</a> character or an <strong>escape sequence</strong> inside single quotes. The value is the ASCII value of the character: <code class="backtick">'a'</code> is 97.<a href="#fn7" class="footnoteRef" id="fnref7"><sup>7</sup></a> Unlike languages with separate character types, C characters are identical to integers; you can (but shouldn't) calculate <span class="math inline">97<sup>2</sup></span> by writing <code class="backtick">'a'*'a'</code>. You can also store a character anywhere.</li>
+</ul>
+<p>Except for character constants, you can insist that an integer constant is unsigned or long by putting a <code class="backtick">u</code> or <code class="backtick">l</code> after it. So <code class="backtick">1ul</code> is an <code class="backtick">unsigned&nbsp;long</code> version of 1. By default integer constants are (signed) <code class="backtick">int</code>s. For <code class="backtick">long&nbsp;long</code> constants, use <code class="backtick">ll</code>, e.g., the <code class="backtick">unsigned&nbsp;long&nbsp;long</code> constant <code class="backtick">0xdeadbeef01234567ull</code>. It is also permitted to write the <code class="backtick">l</code> as <code class="backtick">L</code>, which can be less confusing if the <code class="backtick">l</code> looks too much like a <code class="backtick">1</code>.</p>
+<p>Some examples:</p>
+<table style="width:79%;">
+<colgroup>
+<col width="20%">
+<col width="58%">
+</colgroup>
+<tbody>
+<tr class="odd">
+<td align="left"><p>'a'</p></td>
+<td align="left"><p><code>int</code></p></td>
+</tr>
+<tr class="even">
+<td align="left"><p>97</p></td>
+<td align="left"><p><code>int</code></p></td>
+</tr>
+<tr class="odd">
+<td align="left"><p>97u</p></td>
+<td align="left"><p><code>unsigned int</code></p></td>
+</tr>
+<tr class="even">
+<td align="left"><p>0xbea00diful</p></td>
+<td align="left"><p><code>unsigned long</code>, written in hexadecimal</p></td>
+</tr>
+<tr class="odd">
+<td align="left"><p>0777s</p></td>
+<td align="left"><p><code>short</code>, written in octal</p></td>
+</tr>
+</tbody>
+</table>
+<p>A curious omission is that there is no way to write a binary integer
+directly in C. So if you want to write the bit pattern 00101101, you
+will need to encode it in hexadecimal as <code>0x2d</code> (or octal as <code>055</code>). Another potential trap is that leading zeros matter: <code>012</code> is an octal value corresponding to what normal people call 10.</p>
+<h5 id="naming-constants"><span class="header-section-number">4.2.2.1.1</span> Naming constants</h5>
+<p>Having a lot of numeric constants in your program—particularly if the
+ same constant shows up in more than one place—is usually a sign of bad
+programming. There are a few constants, like 0 and 1, that make sense on
+ their own, but many constant values are either mostly arbitrary, or
+might change if the needs of the program change. It's helpful to assign
+these constants names that explain their meaning, instead of requiring
+the user to guess why there is a <code>37</code> here or an <code>0x1badd00d</code>
+ there. This is particularly important if the constants might change in
+later versions of the program, since even though you could change every <code>37</code> in your program into a <code>38</code>, this might catch other <code>37</code> values that have different intended meanings.</p>
+<p>For example, suppose that you have a function (call it <code class="backtick">getchar</code>)
+ that needs to signal that sometimes it didn't work. The usual way is to
+ return a value that the function won't normally return. Now, you could
+just tell the user what value that is:</p>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"><span class="co">/* get a character (as an `int` ASCII code) from `stdin` */</span>
+<span class="co">/* return -1 on end of file */</span>
+<span class="dt">int</span> getchar(<span class="dt">void</span>);</code></pre></div>
+<p>and now the user can write</p>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"> <span class="kw">while</span>((c = getchar()) != -<span class="dv">1</span>) {
+ ...
+ }</code></pre></div>
+<p>But then somebody reading the code has to remember that <code class="backtick">-1</code> means "end of file" and not "signed version of <code class="backtick">0xff</code>" or "computer room on fire, evacuate immediately." It's much better to define a constant <code class="backtick">EOF</code> that happens to equal <code class="backtick">-1</code>, because among other things if you change the special return value from <code class="backtick">getchar</code> later then this code will still work (assuming you fixed the definition of <code class="backtick">EOF</code>):</p>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"> <span class="kw">while</span>((c = getchar()) != EOF) {
+ ...
+ }</code></pre></div>
+<p>So how do you declare a constant in C? The traditional approach is to
+ use the C preprocessor, the same tool that gets run before the compiler
+ to expand out <code class="backtick">#include</code> directives. To define <code class="backtick">EOF</code>, the file <code class="backtick">/usr/include/stdio.h</code> includes the text</p>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"><span class="ot">#define EOF (-1)</span></code></pre></div>
+<p>What this means is that whenever the characters <code class="backtick">EOF</code> appear in a C program as a separate word (e.g. in <code class="backtick">1+EOF*3</code> but not in <code class="backtick">appurtenancesTherEOF</code>), then the preprocessor will replace them with the characters <code class="backtick">(-1)</code>. The parentheses around the <code class="backtick">-1</code> are customary to ensure that the <code class="backtick">-1</code> gets treated as a separate constant and not as part of some larger expression. So from the compiler's perspective, <code>EOF</code> really is <code>-1</code>, but from the programmer's perspective, it's end-of-file. This is a special case of the C preprocessor's <a href="#macros">macro</a> mechanism.</p>
+<p>In general, any time you have a non-trivial constant in a program, it should be <code class="backtick">#define</code>d.
+ Examples are things like array dimensions, special tags or return
+values from functions, maximum or minimum values for some quantity, or
+standard mathematical constants (e.g., <code class="backtick">/usr/include/math.h</code> defines <code class="backtick">M_PI</code> as pi to umpteen digits). This allows you to write</p>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"> <span class="dt">char</span> buffer[MAX_FILENAME_LENGTH<span class="dv">+1</span>];
+
+ area = M_PI*r*r;
+
+ <span class="kw">if</span>(status == COMPUTER_ROOM_ON_FIRE) {
+ evacuate();
+ }</code></pre></div>
+<p>instead of</p>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"> <span class="dt">char</span> buffer[<span class="dv">513</span>];
+
+ area = <span class="fl">3.141592319</span>*r*r;
+
+ <span class="kw">if</span>(status == <span class="dv">136</span>) {
+ evacuate();
+ }</code></pre></div>
+<p>which is just an invitation to errors (including the one in the area computation).</p>
+<p>Like <code class="backtick">typedef</code>s, <code class="backtick">#define</code>s that are intended to be globally visible are best done in header files; in large programs you will want to <code class="backtick">#include</code> them in many source files. The usual convention is to write <code class="backtick">#define</code>d names in all-caps to remind the user that they are macros and not real variables.</p>
+<h4 id="integerOperators"><span class="header-section-number">4.2.2.2</span> Integer operators</h4>
+<h5 id="Arithmetic_operators"><span class="header-section-number">4.2.2.2.1</span> Arithmetic operators</h5>
+<p>The usual <code class="backtick">+</code> (addition), <code class="backtick">-</code> (negation or subtraction), and <code class="backtick">*</code>
+ (multiplication) operators work on integers pretty much the way you'd
+expect. The only caveat is that if the result lies outside of the range
+of whatever variable you are storing it in, it will be truncated instead
+ of causing an error:</p>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"> <span class="dt">unsigned</span> <span class="dt">char</span> c;
+
+ c = -<span class="dv">1</span>; <span class="co">/* sets c = 255 */</span>
+ c = <span class="dv">255</span> + <span class="dv">255</span>; <span class="co">/* sets c = 254 */</span>
+ c = <span class="dv">256</span> * <span class="dv">1772717</span>; <span class="co">/* sets c = 0 */</span></code></pre></div>
+<p>This can be a source of subtle bugs if you aren't careful. The usual
+giveaway is that values you thought should be large positive integers
+come back as random-looking negative integers.</p>
+<p>Division (<code class="backtick">/</code>) of two integers also truncates: <code class="backtick">2/3</code> is 0, <code class="backtick">5/3</code> is 1, etc. For positive integers it will always round down.</p>
+<p>Prior to C99, if either the numerator or denominator is negative, the
+ behavior was unpredictable and depended on what your processor chose to
+ do. In practice this meant you should never use <code class="backtick">/</code>
+ if one or both arguments might be negative. The C99 standard specified
+that integer division always removes the fractional part, effectively
+rounding toward 0; so <code class="backtick">(-3)/2</code> is <code class="backtick">-1</code>, <code class="backtick">3/-2</code> is <code class="backtick">-1</code>, and <code class="backtick">(-3)/-2</code> is <code class="backtick">1</code>.</p>
+<p>There is also a remainder operator <code class="backtick">%</code> with e.g. <code class="backtick">2%3</code> = 2, <code class="backtick">5%3</code> = 2, <code class="backtick">27&nbsp;%&nbsp;2</code> = 1, etc. The sign of the modulus is ignored, so <code class="backtick">2%-3</code> is also <code class="backtick">2</code>. The sign of the dividend carries over to the remainder: <code class="backtick">(-3)%2</code> and <code class="backtick">(-3)%(-2)</code> are both <code class="backtick">-1</code>. The reason for this rule is that it guarantees that <code class="backtick">y&nbsp;==&nbsp;x*(y/x)&nbsp;+&nbsp;y%x</code> is always true.</p>
+<h5 id="Bitwise_operators"><span class="header-section-number">4.2.2.2.2</span> Bitwise operators</h5>
+<p>In addition to the arithmetic operators, integer types support <strong>bitwise logical</strong>
+ operators that apply some Boolean operation to all the bits of their
+arguments in parallel. What this means is that the i-th bit of the
+output is equal to some operation applied to the i-th bit(s) of the
+input(s). The bitwise logical operators are <code class="backtick">~</code> (bitwise negation: used with one argument as in <code class="backtick">~0</code> for the all-1's binary value), <code class="backtick">&amp;</code>
+ (bitwise AND), '|' (bitwise OR), and '^' (bitwise XOR, i.e. sum mod 2).
+ These are mostly used for manipulating individual bits or small groups
+of bits inside larger words, as in the expression <code class="backtick">x&nbsp;&amp;&nbsp;0x0f</code>, which strips off the bottom four bits stored in <code class="backtick">x</code>.</p>
+<p>Examples:</p>
+<table style="width:83%;">
+<colgroup>
+<col width="20%">
+<col width="20%">
+<col width="20%">
+<col width="20%">
+</colgroup>
+<thead>
+<tr class="header">
+<th align="left"><code>x</code></th>
+<th align="left"><code>y</code></th>
+<th align="left">expression</th>
+<th align="left">value</th>
+</tr>
+</thead>
+<tbody>
+<tr class="odd">
+<td align="left"><p>0011</p></td>
+<td align="left"><p>0101</p></td>
+<td align="left"><p><code>x&amp;y</code></p></td>
+<td align="left"><p>0001</p></td>
+</tr>
+<tr class="even">
+<td align="left"><p>0011</p></td>
+<td align="left"><p>0101</p></td>
+<td align="left"><p><code>x|y</code></p></td>
+<td align="left"><p>0111</p></td>
+</tr>
+<tr class="odd">
+<td align="left"><p>0011</p></td>
+<td align="left"><p>0101</p></td>
+<td align="left"><p><code>x^y</code></p></td>
+<td align="left"><p>0110</p></td>
+</tr>
+<tr class="even">
+<td align="left"><p>0011</p></td>
+<td align="left"><p>0101</p></td>
+<td align="left"><p><code>~x</code></p></td>
+<td align="left"><p>1100</p></td>
+</tr>
+</tbody>
+</table>
+<p>The shift operators <code class="backtick">&lt;&lt;</code> and <code class="backtick">&gt;&gt;</code> shift the bit sequence left or right: <code class="backtick">x&nbsp;&lt;&lt;&nbsp;y</code> produces the value <span class="math inline"><em>x</em> ⋅ 2<sup><em>y</em></sup></span> (ignoring overflow); this is equivalent to shifting every bit in <code class="backtick">x</code> <code class="backtick">y</code> positions to the left and filling in <code class="backtick">y</code> zeros for the missing positions. In the other direction, <code class="backtick">x&nbsp;&gt;&gt;&nbsp;y</code> produces the value <span class="math inline">⌊<em>x</em> ⋅ 2<sup>−</sup><em>y</em>⌋</span> by shifting <code class="backtick">x</code> <code class="backtick">y</code> positions to the right. The behavior of the right shift operator depends on whether <code class="backtick">x</code>
+ is unsigned or signed; for unsigned values, it shifts in zeros from the
+ left end always; for signed values, it shifts in additional copies of
+the leftmost bit (the sign bit). This makes <code class="backtick">x&nbsp;&gt;&gt;&nbsp;y</code> have the same sign as <code class="backtick">x</code> if <code class="backtick">x</code> is signed.</p>
+<p>If <code class="backtick">y</code> is negative, it reverses the direction of the shift; so <code class="backtick">x&nbsp;&lt;&lt;&nbsp;-2</code> is equivalent to <code class="backtick">x&nbsp;&gt;&gt;&nbsp;2</code>.</p>
+<p>Examples (<code class="backtick">unsigned&nbsp;char&nbsp;x</code>):</p>
+<table style="width:78%;">
+<colgroup>
+<col width="19%">
+<col width="19%">
+<col width="19%">
+<col width="19%">
+</colgroup>
+<thead>
+<tr class="header">
+<th align="left"><code>x</code></th>
+<th align="left"><code>y</code></th>
+<th align="left"><code>x &lt;&lt; y</code></th>
+<th align="left"><code>x &gt;&gt; y</code></th>
+</tr>
+</thead>
+<tbody>
+<tr class="odd">
+<td align="left"><p>00000001</p></td>
+<td align="left"><p>1</p></td>
+<td align="left"><p>00000010</p></td>
+<td align="left"><p>00000000</p></td>
+</tr>
+<tr class="even">
+<td align="left"><p>11111111</p></td>
+<td align="left"><p>3</p></td>
+<td align="left"><p>11111000</p></td>
+<td align="left"><p>00011111</p></td>
+</tr>
+<tr class="odd">
+<td align="left"><p>10111001</p></td>
+<td align="left"><p>-2</p></td>
+<td align="left"><p>00101110</p></td>
+<td align="left"><p>11100100</p></td>
+</tr>
+</tbody>
+</table>
+<p>Examples (<code class="backtick">signed&nbsp;char&nbsp;x</code>):</p>
+<table style="width:78%;">
+<colgroup>
+<col width="19%">
+<col width="19%">
+<col width="19%">
+<col width="19%">
+</colgroup>
+<thead>
+<tr class="header">
+<th align="left"><code>x</code></th>
+<th align="left"><code>y</code></th>
+<th align="left"><code>x &lt;&lt; y</code></th>
+<th align="left"><code>x &gt;&gt; y</code></th>
+</tr>
+</thead>
+<tbody>
+<tr class="odd">
+<td align="left"><p>00000001</p></td>
+<td align="left"><p>1</p></td>
+<td align="left"><p>00000010</p></td>
+<td align="left"><p>00000000</p></td>
+</tr>
+<tr class="even">
+<td align="left"><p>11111111</p></td>
+<td align="left"><p>3</p></td>
+<td align="left"><p>11111000</p></td>
+<td align="left"><p>11111111</p></td>
+</tr>
+<tr class="odd">
+<td align="left"><p>10111001</p></td>
+<td align="left"><p>-2</p></td>
+<td align="left"><p>11101110</p></td>
+<td align="left"><p>11100100</p></td>
+</tr>
+</tbody>
+</table>
+<p>Shift operators are often used with bitwise logical operators to set
+or extract individual bits in an integer value. The trick is that <code class="backtick">(1&nbsp;&lt;&lt;&nbsp;i)</code> contains a 1 in the <code class="backtick">i</code>-th least significant bit and zeros everywhere else. So <code class="backtick">x&nbsp;&amp;&nbsp;(1&lt;&lt;i)</code> is nonzero if and only if <code class="backtick">x</code> has a 1 in the <code class="backtick">i</code>-th place. This can be used to print out an integer in binary format (which standard <code class="backtick">printf</code> won't do).</p>
+<p>The following program gives an example of this technique. For example, when called as <code>./testPrintBinary 123</code>, it will print <code>111010</code> followed by a newline.</p>
+<div>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"><span class="ot">#include &lt;stdio.h&gt;</span>
+<span class="ot">#include &lt;stdlib.h&gt;</span>
+
+<span class="co">/* print out all bits of n */</span>
+<span class="dt">void</span>
+print_binary(<span class="dt">unsigned</span> <span class="dt">int</span> n)
+{
+ <span class="dt">unsigned</span> <span class="dt">int</span> mask = <span class="dv">0</span>;
+
+ <span class="co">/* this grotesque hack creates a bit pattern 1000... */</span>
+ <span class="co">/* regardless of the size of an unsigned int */</span>
+ mask = ~mask ^ (~mask &gt;&gt; <span class="dv">1</span>);
+
+ <span class="kw">for</span>(; mask != <span class="dv">0</span>; mask &gt;&gt;= <span class="dv">1</span>) {
+ putchar((n &amp; mask) ? '<span class="dv">1</span>' : '<span class="dv">0</span>');
+ }
+}
+
+<span class="dt">int</span>
+main(<span class="dt">int</span> argc, <span class="dt">char</span> **argv)
+{
+ <span class="kw">if</span>(argc != <span class="dv">2</span>) {
+ fprintf(stderr, <span class="st">"Usage: %s n</span><span class="ch">\n</span><span class="st">"</span>, argv[<span class="dv">0</span>]);
+ <span class="kw">return</span> <span class="dv">1</span>;
+ }
+
+ print_binary(atoi(argv[<span class="dv">1</span>]));
+ putchar(<span class="ch">'\n'</span>);
+
+ <span class="kw">return</span> <span class="dv">0</span>;
+}</code></pre></div>
+<a href="http://cs.yale.edu/homes/aspnes/classes/223/examples/integerTypes/testPrintBinary.c" class="uri">examples/integerTypes/testPrintBinary.c</a>
+</div>
+<p>In the other direction, we can set the <code class="backtick">i</code>-th bit of <code class="backtick">x</code> to 1 by doing <code class="backtick">x&nbsp;|&nbsp;(1&nbsp;&lt;&lt;&nbsp;i)</code> or to 0 by doing <code class="backtick">x&nbsp;&amp;&nbsp;~(1&nbsp;&lt;&lt;&nbsp;i)</code>. See the section on <a href="#bitManipulation">bit manipulation</a>. for applications of this to build arbitrarily-large bit vectors.</p>
+<h5 id="Logical_operators"><span class="header-section-number">4.2.2.2.3</span> Logical operators</h5>
+<p>To add to the confusion, there are also three <strong>logical</strong> operators that work on the <strong>truth-values</strong> of integers, where 0 is defined to be false and anything else is defined by be true. These are <code class="backtick">&amp;&amp;</code> (logical AND), <code class="backtick">||</code>, (logical OR), and <code class="backtick">!</code> (logical NOT). The result of any of these operators is always 0 or 1 (so <code class="backtick">!!x</code>, for example, is 0 if <code class="backtick">x</code> is 0 and 1 if <code class="backtick">x</code> is anything else). The <code class="backtick">&amp;&amp;</code> and <code class="backtick">||</code>
+ operators evaluate their arguments left-to-right and ignore the second
+argument if the first determines the answer (this is the only place in C
+ where argument evaluation order is specified); so</p>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"> <span class="dv">0</span> &amp;&amp; executeProgrammer();
+ <span class="dv">1</span> || executeProgrammer();</code></pre></div>
+<p>is in a very weak sense perfectly safe code to run.</p>
+<p>Watch out for confusing <code class="backtick">&amp;</code> with <code class="backtick">&amp;&amp;</code>. The expression <code class="backtick">1&nbsp;&amp;&nbsp;2</code> evaluates to 0, but <code class="backtick">1&nbsp;&amp;&amp;&nbsp;2</code> evaluates to 1. The statement <code class="backtick">0&nbsp;&amp;&nbsp;executeProgrammer();</code> is also unlikely to do what you want.</p>
+<p>Yet another logical operator is the <strong>ternary operator</strong> <code class="backtick">?:</code>, where <code class="backtick">x&nbsp;?&nbsp;y&nbsp;:&nbsp;z</code> equals the value of <code class="backtick">y</code> if <code class="backtick">x</code> is nonzero and <code class="backtick">z</code> if <code class="backtick">x</code> is zero. Like <code class="backtick">&amp;&amp;</code> and <code class="backtick">||</code>, it only evaluates the arguments it needs to:</p>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"> fileExists(badFile) ? deleteFile(badFile) : createFile(badFile);</code></pre></div>
+<p>Most uses of <code class="backtick">?:</code> are better done using an <a href="#conditionals">if-then-else statement</a>.</p>
+<h5 id="Relational_operators"><span class="header-section-number">4.2.2.2.4</span> Relational operators</h5>
+<p>Logical operators usually operate on the results of <strong>relational operators</strong> or comparisons: these are <code class="backtick">==</code> (equality), <code class="backtick">!=</code> (inequality), <code class="backtick">&lt;</code> (less than), <code class="backtick">&gt;</code> (greater than), <code class="backtick">&lt;=</code> (less than or equal to) and <code class="backtick">&gt;=</code> (greater than or equal to). So, for example,</p>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"> <span class="kw">if</span>(size &gt;= MIN_SIZE &amp;&amp; size &lt;= MAX_SIZE) {
+ puts(<span class="st">"just right"</span>);
+ }</code></pre></div>
+<p>tests if <code class="backtick">size</code> is in the (inclusive) range [<code class="backtick">MIN_SIZE</code>..<code class="backtick">MAX_SIZE</code>].</p>
+<p>Beware of confusing <code class="backtick">==</code> with <code class="backtick">=</code>. The code</p>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"> <span class="co">/* DANGER! DANGER! DANGER! */</span>
+ <span class="kw">if</span>(x = <span class="dv">5</span>) {
+ ...</code></pre></div>
+<p>is perfectly legal C, and will set <code class="backtick">x</code> to 5 rather than testing if it's equal to 5. Because 5 happens to be nonzero, the body of the <code class="backtick">if</code> statement will always be executed. This error is so common and so dangerous that <code class="backtick">gcc</code> will warn you about any tests that look like this if you use the <code class="backtick">-Wall</code> option. Some programmers will go so far as to write the test as <code class="backtick">5&nbsp;==&nbsp;x</code> just so that if their finger slips, they will get a syntax error on <code class="backtick">5&nbsp;=&nbsp;x</code> even without special compiler support.</p>
+<h4 id="integerStringConversion"><span class="header-section-number">4.2.2.3</span> Converting to and from strings</h4>
+<p>To input or output integer values, you will need to convert them from or to strings. Converting from a string is easy using the <code class="backtick">atoi</code> or <code class="backtick">atol</code> functions declared in <code class="backtick">stdlib.h</code>; these take a string as an argument and return an <code class="backtick">int</code> or <code class="backtick">long</code>, respectively. C99 also provides <code>atoll</code> for converting to <code>long long</code>. These routines have no ability to signal an error other than returning 0, so if you do <code>atoi("Sweden")</code>, that's what you'll get.</p>
+<p>Output is usually done using <code class="backtick">printf</code> (or <code class="backtick">sprintf</code> if you want to write to a string without producing output). Use the <code class="backtick">%d</code> format specifier for <code class="backtick">int</code>s, <code class="backtick">short</code>s, and <code class="backtick">char</code>s that you want the numeric value of, <code class="backtick">%ld</code> for <code class="backtick">long</code>s, and <code class="backtick">%lld</code> for <code class="backtick">long&nbsp;long</code>s.</p>
+<p>A contrived program that uses all of these features is given below:</p>
+<div>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"><span class="ot">#include &lt;stdio.h&gt;</span>
+<span class="ot">#include &lt;stdlib.h&gt;</span>
+
+<span class="co">/* This program can be used to show how atoi etc. handle overflow. */</span>
+<span class="co">/* For example, try "overflow 1000000000000". */</span>
+<span class="dt">int</span>
+main(<span class="dt">int</span> argc, <span class="dt">char</span> **argv)
+{
+ <span class="dt">char</span> c;
+ <span class="dt">int</span> i;
+ <span class="dt">long</span> l;
+ <span class="dt">long</span> <span class="dt">long</span> ll;
+
+ <span class="kw">if</span>(argc != <span class="dv">2</span>) {
+ fprintf(stderr, <span class="st">"Usage: %s n</span><span class="ch">\n</span><span class="st">"</span>, argv[<span class="dv">0</span>]);
+ <span class="kw">return</span> <span class="dv">1</span>;
+ }
+
+ c = atoi(argv[<span class="dv">1</span>]);
+ i = atoi(argv[<span class="dv">1</span>]);
+ l = atol(argv[<span class="dv">1</span>]);
+ ll = atoll(argv[<span class="dv">1</span>]);
+
+ printf(<span class="st">"char: %d int: %d long: %ld long long: %lld"</span>, c, i, l, ll);
+
+ <span class="kw">return</span> <span class="dv">0</span>;
+}</code></pre></div>
+<a href="http://cs.yale.edu/homes/aspnes/classes/223/examples/integerTypes/overflow.c" class="uri">examples/integerTypes/overflow.c</a>
+</div>
+<h3 id="floatingPointTypes"><span class="header-section-number">4.2.3</span> Floating-point types</h3>
+<p>Real numbers are represented in C by the <strong>floating point</strong> types <code class="backtick">float</code>, <code class="backtick">double</code>, and <code class="backtick">long&nbsp;double</code>.
+ Just as the integer types can't represent all integers because they fit
+ in a bounded number of bytes, so also the floating-point types can't
+represent all real numbers. The difference is that the integer types can
+ represent values within their range exactly, while floating-point types
+ almost always give only an approximation to the correct value, albeit
+across a much larger range. The three floating point types differ in how
+ much space they use (32, 64, or 80 bits on x86 CPUs; possibly different
+ amounts on other machines), and thus how much precision they provide.
+Most math library routines expect and return <code class="backtick">double</code>s (e.g., <code class="backtick">sin</code> is declared as <code class="backtick">double&nbsp;sin(double)</code>, but there are usually <code class="backtick">float</code> versions as well (<code class="backtick">float&nbsp;sinf(float)</code>).</p>
+<h4 id="Floating_point_basics"><span class="header-section-number">4.2.3.1</span> Floating point basics</h4>
+<p>The core idea of floating-point representations (as opposed to <strong>fixed point representations</strong> as used by, say, <code class="backtick">int</code>s), is that a number <span class="math inline"><em>x</em></span> is written as <span class="math inline"><em>m</em> ⋅ <em>b</em><sup><em>e</em></sup></span> where <span class="math inline"><em>m</em></span> is a <strong>mantissa</strong> or fractional part, <span class="math inline"><em>b</em></span> is a <strong>base</strong>, and <span class="math inline"><em>e</em></span> is an <strong>exponent</strong>. On modern computers the base is almost always <span class="math inline">2</span>, and for most floating-point representations the mantissa will be scaled to be between <span class="math inline">1</span> and <span class="math inline"><em>b</em></span>. This is done by adjusting the exponent, e.g.</p>
+<table>
+<tbody>
+<tr class="odd">
+<td align="left"><span class="math inline">1 = 1 ⋅ 2<sup>0</sup></span></td>
+</tr>
+<tr class="even">
+<td align="left"><span class="math inline">2 = 1 ⋅ 2<sup>1</sup></span></td>
+</tr>
+<tr class="odd">
+<td align="left"><span class="math inline">0.375 = 1.5 ⋅ 2<sup>−2</sup></span></td>
+</tr>
+</tbody>
+</table>
+<p>etc.</p>
+<p>The mantissa is usually represented in base <span class="math inline">2</span>, as a binary fraction. So (in a very low-precision format), $1 would be <span class="math inline">1.000 ⋅ 2<sup>0</sup></span>, <span class="math inline">2</span> would be <span class="math inline">1.000 ⋅ 2<sup>1</sup></span>, and <span class="math inline">0.375 = 3/8</span> would be <span class="math inline">1.100 ⋅ 2<sup>−2</sup></span>, where the first <span class="math inline">1</span> after the decimal point counts as <span class="math inline">1/2</span>, the second as <span class="math inline">1/4</span>, etc. Note that for a properly-scaled (or <strong>normalized</strong>) floating-point number in base <span class="math inline">2</span> the digit before the decimal point is always <span class="math inline">1</span>. For this reason it is usually dropped to save space (although this requires a special representation for <span class="math inline">0</span>).</p>
+<p>Negative values are typically handled by adding a <strong>sign bit</strong> that is <span class="math inline">0</span> for positive numbers and <span class="math inline">1</span> for negative numbers.</p>
+<h4 id="Floating-point_constants"><span class="header-section-number">4.2.3.2</span> Floating-point constants</h4>
+<p>Any number that has a decimal point in it will be interpreted by the
+compiler as a floating-point number. Note that you have to put at least
+one digit after the decimal point: <code class="backtick">2.0</code>, <code class="backtick">3.75</code>, <code class="backtick">-12.6112</code>. You can specific a floating point number in scientific notation using <code class="backtick">e</code> for the exponent: <code class="backtick">6.022e23</code>.</p>
+<h4 id="Operators"><span class="header-section-number">4.2.3.3</span> Operators</h4>
+<p>Floating-point types in C support most of the same arithmetic and relational operators as integer types; <code class="backtick">x&nbsp;&gt;&nbsp;y</code>, <code class="backtick">x&nbsp;/&nbsp;y</code>, <code class="backtick">x&nbsp;+&nbsp;y</code> all make sense when <code class="backtick">x</code> and <code class="backtick">y</code> are <code class="backtick">float</code>s.
+ If you mix two different floating-point types together, the
+less-precise one will be extended to match the precision of the
+more-precise one; this also works if you mix integer and floating point
+types as in <code class="backtick">2&nbsp;/&nbsp;3.0</code>. Unlike
+integer division, floating-point division does not discard the
+fractional part (although it may produce round-off error: <code class="backtick">2.0/3.0</code> gives <code class="backtick">0.66666666666666663</code>, which is not quite exact). Be careful about accidentally using integer division when you mean to use floating-point division: <code class="backtick">2/3</code> is <code class="backtick">0</code>. Casts can be used to force floating-point division (see below).</p>
+<p>Some operators that work on integers will <em>not</em> work on floating-point types. These are <code class="backtick">%</code> (use <code class="backtick">modf</code> from the math library if you really need to get a floating-point remainder) and all of the bitwise operators <code class="backtick">~</code>, <code class="backtick">&lt;&lt;</code>, <code class="backtick">&gt;&gt;</code>, <code class="backtick">&amp;</code>, <code class="backtick">^</code>, and <code class="backtick">|</code>.</p>
+<h4 id="Conversion_to_and_from_integer_types"><span class="header-section-number">4.2.3.4</span> Conversion to and from integer types</h4>
+<p>Mixed uses of floating-point and integer types will convert the integers to floating-point.</p>
+<p>You can convert floating-point numbers to and from integer types explicitly using casts. A typical use might be:</p>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"><span class="co">/* return the average of a list */</span>
+<span class="dt">double</span>
+average(<span class="dt">int</span> n, <span class="dt">int</span> a[])
+{
+ <span class="dt">int</span> sum = <span class="dv">0</span>;
+ <span class="dt">int</span> i;
+
+ <span class="kw">for</span>(i = <span class="dv">0</span>; i &lt; n; i++) {
+ sum += a[i];
+ }
+
+ <span class="kw">return</span> (<span class="dt">double</span>) sum / n;
+}</code></pre></div>
+<p>If we didn't put in the <code class="backtick">(double)</code> to convert <code class="backtick">sum</code> to a <code class="backtick">double</code>,
+ we'd end up doing integer division, which would truncate the fractional
+ part of our average. Note that casts bind tighter than arithmetic
+operations, so the <code>(double)</code> applies to just <code>sum</code>, and not the whole expression <code>sum / n</code>.</p>
+<p>In the other direction, we can write:</p>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"> i = (<span class="dt">int</span>) f;</code></pre></div>
+<p>to convert a <code class="backtick">float&nbsp;f</code> to <code class="backtick">int&nbsp;i</code>. This conversion loses information by throwing away the fractional part of <code class="backtick">f</code>: if <code class="backtick">f</code> was <code class="backtick">3.2</code>, <code class="backtick">i</code> will end up being just <code class="backtick">3</code>.</p>
+<p>The math library contains a pile of functions for converting values of type <code>double</code> to integer values of type <code>double</code> that give more control over the rounding: see for example the descriptions of <code>floor</code>, <code>ceil</code>, <code>round</code>, <code>trunc</code>, and <code>nearbyint</code> in the <a href="http://www.gnu.org/software/libc/manual/html_node/Rounding-Functions.html">GNU libc reference manual</a>.</p>
+<h4 id="The_IEEE-754_floating-point_standard"><span class="header-section-number">4.2.3.5</span> The IEEE-754 floating-point standard</h4>
+<p>The IEEE-754 floating-point standard is a standard for representing
+and manipulating floating-point quantities that is followed by all
+modern computer systems. It defines several standard representations of
+floating-point numbers, all of which have the following basic pattern
+(the specific layout here is for 32-bit <code class="backtick">float</code>s):</p>
+<pre><code>bit 31 30 23 22 0
+ S EEEEEEEE MMMMMMMMMMMMMMMMMMMMMMM</code></pre>
+<p>The bit numbers are counting from the least-significant bit. The
+first bit is the sign (0 for positive, 1 for negative). The following 8
+bits are the exponent in <strong>excess-127</strong> binary notation;
+this means that the binary pattern 01111111 = 127 represents an exponent
+ of 0, 1000000 = 128, represents 1, 01111110 = 126 represents -1, and so
+ forth. The mantissa fits in the remaining 24 bits, with its leading 1
+stripped off as described above.</p>
+<p>Certain numbers have a special representation. Because 0 cannot be
+represented in the standard form (there is no 1 before the decimal
+point), it is given the special representation <code class="backtick">0&nbsp;00000000&nbsp;00000000000000000000000</code>. (There is also a -0 = <code class="backtick">1&nbsp;00000000&nbsp;00000000000000000000000</code>, which looks equal to +0 but prints differently.) Numbers with exponents of 11111111 = 255 = 2<sup>128</sup> represent non-numeric quantities such as "not a number" (<code class="backtick">NaN</code>), returned by operations like (<code class="backtick">0.0/0.0</code>) and positive or negative infinity. A table of some typical floating-point numbers (generated by the program <a href="http://cs.yale.edu/homes/aspnes/classes/223/examples/floatingPoint/float.c">float.c</a>) is given below:</p>
+<pre><code> 0 = 0 = 0 00000000 00000000000000000000000
+ -0 = -0 = 1 00000000 00000000000000000000000
+ 0.125 = 0.125 = 0 01111100 00000000000000000000000
+ 0.25 = 0.25 = 0 01111101 00000000000000000000000
+ 0.5 = 0.5 = 0 01111110 00000000000000000000000
+ 1 = 1 = 0 01111111 00000000000000000000000
+ 2 = 2 = 0 10000000 00000000000000000000000
+ 4 = 4 = 0 10000001 00000000000000000000000
+ 8 = 8 = 0 10000010 00000000000000000000000
+ 0.375 = 0.375 = 0 01111101 10000000000000000000000
+ 0.75 = 0.75 = 0 01111110 10000000000000000000000
+ 1.5 = 1.5 = 0 01111111 10000000000000000000000
+ 3 = 3 = 0 10000000 10000000000000000000000
+ 6 = 6 = 0 10000001 10000000000000000000000
+ 0.1 = 0.10000000149011612 = 0 01111011 10011001100110011001101
+ 0.2 = 0.20000000298023224 = 0 01111100 10011001100110011001101
+ 0.4 = 0.40000000596046448 = 0 01111101 10011001100110011001101
+ 0.8 = 0.80000001192092896 = 0 01111110 10011001100110011001101
+ 1e+12 = 999999995904 = 0 10100110 11010001101010010100101
+ 1e+24 = 1.0000000138484279e+24 = 0 11001110 10100111100001000011100
+ 1e+36 = 9.9999996169031625e+35 = 0 11110110 10000001001011111001110
+ inf = inf = 0 11111111 00000000000000000000000
+ -inf = -inf = 1 11111111 00000000000000000000000
+ nan = nan = 0 11111111 10000000000000000000000</code></pre>
+<p>What this means in practice is that a 32-bit floating-point value (e.g. a <code class="backtick">float</code>) can represent any number between <code class="backtick">1.17549435e-38</code> and <code class="backtick">3.40282347e+38</code>, where the <code class="backtick">e</code>
+ separates the (base 10) exponent. Operations that would create a
+smaller value will underflow to 0 (slowly—IEEE 754 allows "denormalized"
+ floating point numbers with reduced precision for very small values)
+and operations that would create a larger value will produce <code class="backtick">inf</code> or <code class="backtick">-inf</code> instead.</p>
+<p>For a 64-bit <code class="backtick">double</code>, the size of both the exponent and mantissa are larger; this gives a range from <code class="backtick">1.7976931348623157e+308</code> to <code class="backtick">2.2250738585072014e-308</code>, with similar behavior on underflow and overflow.</p>
+<p>Intel processors internally use an even larger 80-bit floating-point
+format for all operations. Unless you declare your variables as <code class="backtick">long&nbsp;double</code>,
+ this should not be visible to you from C except that some operations
+that might otherwise produce overflow errors will not do so, provided
+all the variables involved sit in registers (typically the case only for
+ local variables and function parameters).</p>
+<h4 id="Error"><span class="header-section-number">4.2.3.6</span> Error</h4>
+<p>In general, floating-point numbers are not exact: they are likely to contain <strong>round-off error</strong> because of the truncation of the mantissa to a fixed number of bits. This is particularly noticeable for large values (e.g. <code class="backtick">1e+12</code> in the table above), but can also be seen in fractions with values that aren't powers of 2 in the denominator (e.g. <code class="backtick">0.1</code>).
+ Round-off error is often invisible with the default float output
+formats, since they produce fewer digits than are stored internally, but
+ can accumulate over time, particularly if you subtract floating-point
+quantities with values that are close (this wipes out the mantissa
+without wiping out the error, making the error much larger relative to
+the number that remains).</p>
+<p>The easiest way to avoid accumulating error is to use high-precision floating-point numbers (this means using <code class="backtick">double</code> instead of <code class="backtick">float</code>). On modern CPUs there is little or no time penalty for doing so, although storing <code class="backtick">double</code>s instead of <code class="backtick">float</code>s will take twice as much space in memory.</p>
+<p>Note that a consequence of the internal structure of IEEE 754
+floating-point numbers is that small integers and fractions with small
+numerators and power-of-2 denominators can be represented <em>exactly</em>—indeed,
+ the IEEE 754 standard carefully defines floating-point operations so
+that arithmetic on such exact integers will give the same answers as
+integer arithmetic would (except, of course, for division that produces a
+ remainder). This fact can sometimes be exploited to get higher
+precision on integer values than is available from the standard integer
+types; for example, a <code class="backtick">double</code> can represent any integer between -2<sup>53</sup> and 2<sup>53</sup> exactly, which is a much wider range than the values from <code class="backtick">2^-31^&nbsp;to&nbsp;2^31^-1&nbsp;that&nbsp;fit&nbsp;in&nbsp;a&nbsp;32-bit&nbsp;</code>int<code class="backtick">&nbsp;or&nbsp;</code>long<code class="backtick">.&nbsp;&nbsp;(A&nbsp;64-bit&nbsp;</code>long long<code class="backtick">&nbsp;does&nbsp;better.)&nbsp;&nbsp;So&nbsp;</code>double`
+ should be considered for applications where large precise integers are
+needed (such as calculating the net worth in pennies of a billionaire.)</p>
+<p>One consequence of round-off error is that it is very difficult to
+test floating-point numbers for equality, unless you are sure you have
+an exact value as described above. It is generally not the case, for
+example, that <code class="backtick">(0.1+0.1+0.1)&nbsp;==&nbsp;0.3</code> in C. This can produce odd results if you try writing something like <code class="backtick">for(f&nbsp;=&nbsp;0.0;&nbsp;f&nbsp;&lt;=&nbsp;0.3;&nbsp;f&nbsp;+=&nbsp;0.1)</code>: it will be hard to predict in advance whether the loop body will be executed with <code class="backtick">f&nbsp;=&nbsp;0.3</code> or not. (Even more hilarity ensues if you write <code class="backtick">for(f&nbsp;=&nbsp;0.0;&nbsp;f&nbsp;!=&nbsp;0.3;&nbsp;f&nbsp;+=&nbsp;0.1)</code>, which after not quite hitting <code class="backtick">0.3</code>
+ exactly keeps looping for much longer than I am willing to wait to see
+it stop, but which I suspect will eventually converge to some constant
+value of <code class="backtick">f</code> large enough that adding <code class="backtick">0.1</code>
+ to it has no effect.) Most of the time when you are tempted to test
+floats for equality, you are better off testing if one lies within a
+small distance from the other, e.g. by testing <code class="backtick">fabs(x-y)&nbsp;&lt;=&nbsp;fabs(EPSILON&nbsp;*&nbsp;y)</code>, where <code class="backtick">EPSILON</code>
+ is usually some application-dependent tolerance. This isn't quite the
+same as equality (for example, it isn't transitive), but it usually
+closer to what you want.</p>
+<h4 id="Reading_and_writing_floating-point_numbers"><span class="header-section-number">4.2.3.7</span> Reading and writing floating-point numbers</h4>
+<p>Any numeric constant in a C program that contains a decimal point is treated as a <code class="backtick">double</code> by default. You can also use <code class="backtick">e</code> or <code class="backtick">E</code> to add a base-10 exponent (see the table for some examples of this.) If you want to insist that a constant value is a <code class="backtick">float</code> for some reason, you can append <code class="backtick">F</code> on the end, as in <code class="backtick">1.0F</code>.</p>
+<p>For I/O, floating-point values are most easily read and written using <code class="backtick">scanf</code> (and its relatives <code class="backtick">fscanf</code> and <code class="backtick">sscanf</code>) and <code class="backtick">printf</code>. For <code class="backtick">printf</code>,
+ there is an elaborate variety of floating-point format codes; the
+easiest way to find out what these do is experiment with them. For <code class="backtick">scanf</code>, pretty much the only two codes you need are <code class="backtick">"%lf"</code>, which reads a <code class="backtick">double</code> value into a <code class="backtick">double&nbsp;*</code>, and <code class="backtick">"%f"</code>, which reads a <code class="backtick">float</code> value into a <code class="backtick">float&nbsp;*</code>. Both these formats are exactly the same in <code class="backtick">printf</code>, since a <code class="backtick">float</code> is promoted to a <code class="backtick">double</code> before being passed as an argument to <code class="backtick">printf</code> (or any other function that doesn't declare the type of its arguments). But you have to be careful with the arguments to <code class="backtick">scanf</code> or you will get odd results as only 4 bytes of your 8-byte <code class="backtick">double</code> are filled in, or—even worse—8 bytes of your 4-byte <code class="backtick">float</code> are.</p>
+<h4 id="Non-finite_numbers_in_C"><span class="header-section-number">4.2.3.8</span> Non-finite numbers in C</h4>
+<p>The values <code class="backtick">nan</code>, <code class="backtick">inf</code>, and <code class="backtick">-inf</code> can't be written in this form as floating-point constants in a C program, but <code class="backtick">printf</code> will generate them and <code class="backtick">scanf</code> seems to recognize them. With some machines and compilers you may be able to use the macros <code class="backtick">INFINITY</code> and <code class="backtick">NAN</code> from <code class="backtick">&lt;math.h&gt;</code> to generate infinite quantities. The macros <code class="backtick">isinf</code> and <code class="backtick">isnan</code> can be used to detect such quantities if they occur.</p>
+<h4 id="The_math_library"><span class="header-section-number">4.2.3.9</span> The math library</h4>
+<p>(See also K&amp;R Appendix B4.)</p>
+<p>Many mathematical functions on floating-point values are not linked
+into C programs by default, but can be obtained by linking in the math
+library. Examples would be the trigonometric functions <code class="backtick">sin</code>, <code class="backtick">cos</code>, and <code class="backtick">tan</code> (plus more exotic ones), <code class="backtick">sqrt</code> for taking square roots, <code class="backtick">pow</code> for exponentiation, <code class="backtick">log</code> and <code class="backtick">exp</code> for base-e logs and exponents, and <code class="backtick">fmod</code> for when you really want to write <code class="backtick">x%y</code> but one or both variables is a <code class="backtick">double</code>. The standard math library functions all take <code class="backtick">double</code>s as arguments and return <code class="backtick">double</code> values; most implementations also provide some extra functions with similar names (e.g., <code class="backtick">sinf</code>) that use <code class="backtick">float</code>s instead, for applications where space or speed is more important than accuracy.</p>
+<p>There are two parts to using the math library. The first is to include the line</p>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"><span class="ot">#include &lt;math.h&gt;</span></code></pre></div>
+<p>somewhere at the top of your source file. This tells the preprocessor
+ to paste in the declarations of the math library functions found in <code class="backtick">/usr/include/math.h</code>.</p>
+<p>The second step is to link to the math library when you compile. This is done by passing the flag <code class="backtick">-lm</code> to <code class="backtick">gcc</code> <em>after</em> your C program source file(s). A typical command might be:</p>
+<pre><code>c99 -o program program.c -lm</code></pre>
+<p>If you don't do this, you will get errors from the compiler about
+missing functions. The reason is that the math library is not linked in
+by default, since for many system programs it's not needed.</p>
+<h2 id="operatorPrecedence"><span class="header-section-number">4.3</span> Operator precedence</h2>
+<p><strong>Operator precedence</strong> in C controls the interpretation of ambiguous expressions like <code class="backtick">2+3*4</code>, which could in principle be parsed either as <code class="backtick">2+(3*4)</code> (the right way) or as <code class="backtick">(2+3)*4</code>
+ (the cheap calculator way). For the most part, C parses unparenthesized
+ expressions the right way, but if you are not sure what it will do with
+ an expression, you can always put in parentheses to force it to do the
+right thing.</p>
+<p>There is a table on page 53 of Kernighan and Ritchie that shows the precedence of all operators in C, which we reproduce below.</p>
+<p>The interpretation of this table is that higher entries bind tighter than lower ones; so the fact that <code class="backtick">*</code> has higher precedence that <code class="backtick">+</code> and both have higher precedence that <code class="backtick">&gt;</code> means that <code class="backtick">2+3*4&nbsp;&gt;&nbsp;5</code> gets parsed as <code class="backtick">(2+(3*4))&nbsp;&gt;&nbsp;5</code>.</p>
+<p>Associativity controls how an expression with multiple operators of the same precedence is interpreted. The fact that <code class="backtick">+</code> and <code class="backtick">-</code> associate left-to-right means that the expression <code class="backtick">2+3-4-5</code> is interpreted as <code class="backtick">(((2+3)-4)-5)</code>: the leftmost operation is done first. Unary operators, ternary <code class="backtick">?:</code> and assignment operators are the only ones that associate right-to-left. For assignment operators, this is so <code class="backtick">x&nbsp;=&nbsp;y&nbsp;=&nbsp;0</code> is interpreted as <code class="backtick">x&nbsp;=&nbsp;(y&nbsp;=&nbsp;0)</code> (assigning <code class="backtick">0</code> to both <code class="backtick">x</code> and <code class="backtick">y</code>) and not <code class="backtick">(x&nbsp;=&nbsp;y)&nbsp;=&nbsp;0</code> (which would give an error because <code class="backtick">(x&nbsp;=&nbsp;y)</code> isn't something you can assign to). For unary operators, this mostly affects expressions like <code class="backtick">*p++</code>, which is equivalent to <code class="backtick">*(p++)</code> (increment the pointer first then dereference it) rather than <code class="backtick">(*p)++</code> (increment the thing that <code class="backtick">p</code> points to).</p>
+<table>
+<colgroup>
+<col width="62%">
+<col width="37%">
+</colgroup>
+<tbody>
+<tr class="odd">
+<td align="left"><p><code>()</code> <code>[]</code> <code>-&gt;</code> <code>.</code></p></td>
+<td align="left"><p>function calls and indexing</p></td>
+</tr>
+<tr class="even">
+<td align="left"><p><code>!</code> <code>~</code> <code>-</code> (unary) <code>*</code> (unary) <code>&amp;</code>(unary) <code>++</code> <code>--</code> <code>(</code><em>type</em><code>)</code> <code>sizeof</code></p></td>
+<td align="left"><p>unary operators (associate right-to-left)</p></td>
+</tr>
+<tr class="odd">
+<td align="left"><p><code>*</code> (binary) <code>/</code> <code>%</code></p></td>
+<td align="left"><p>multiplication and division</p></td>
+</tr>
+<tr class="even">
+<td align="left"><p><code>+</code> (binary) <code>-</code> (binary)</p></td>
+<td align="left"><p>addition and subtraction</p></td>
+</tr>
+<tr class="odd">
+<td align="left"><p><code>&lt;&lt;</code> <code>&gt;&gt;</code></p></td>
+<td align="left"><p>shifts</p></td>
+</tr>
+<tr class="even">
+<td align="left"><p><code>&lt;</code> <code>&lt;=</code> <code>&gt;=</code> <code>&gt;</code></p></td>
+<td align="left"><p>inequalities</p></td>
+</tr>
+<tr class="odd">
+<td align="left"><p><code>==</code> <code>!=</code></p></td>
+<td align="left"><p>equality</p></td>
+</tr>
+<tr class="even">
+<td align="left"><p><code>&amp;</code> (binary)</p></td>
+<td align="left"><p>bitwise AND</p></td>
+</tr>
+<tr class="odd">
+<td align="left"><p><code>^</code></p></td>
+<td align="left"><p>bitwise XOR</p></td>
+</tr>
+<tr class="even">
+<td align="left"><p><code>|</code></p></td>
+<td align="left"><p>bitwise OR</p></td>
+</tr>
+<tr class="odd">
+<td align="left"><p><code>&amp;&amp;</code></p></td>
+<td align="left"><p>logical AND</p></td>
+</tr>
+<tr class="even">
+<td align="left"><p><code>||</code></p></td>
+<td align="left"><p>logical OR</p></td>
+</tr>
+<tr class="odd">
+<td align="left"><p><code>?:</code></p></td>
+<td align="left"><p>ternary if (associates right-to-left)</p></td>
+</tr>
+<tr class="even">
+<td align="left"><p><code>=</code> <code>+=</code> <code>-=</code> <code>*=</code> <code>/=</code> <code>%=</code> <code>&amp;=</code> <code>^=</code> <code>|=</code> <code>&lt;&lt;=</code> <code>&gt;&gt;=</code></p></td>
+<td align="left"><p>assignment (associate right-to-left)</p></td>
+</tr>
+<tr class="odd">
+<td align="left"><p><code>,</code></p></td>
+<td align="left"><p>comma</p></td>
+</tr>
+</tbody>
+</table>
+<h2 id="programmingStyle"><span class="header-section-number">4.4</span> Programming style</h2>
+<p>The C programming language imposes very few constraints on how
+programs are formatted and organized. Both of the following are
+legitimate C programs, which compile to exactly the same machine code
+using <code>gcc</code> with a high enough optimization level:</p>
+<div>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"><span class="co">/*</span>
+<span class="co"> * Count down from COUNTDOWN_START (defined below) to 0.</span>
+<span class="co"> * Prints all numbers in the range including both endpoints.</span>
+<span class="co"> */</span>
+
+<span class="ot">#include &lt;stdio.h&gt;</span>
+
+<span class="ot">#define COUNTDOWN_START (10)</span>
+
+<span class="dt">int</span>
+main(<span class="dt">int</span> argc, <span class="dt">char</span> **argv)
+{
+ <span class="kw">for</span>(<span class="dt">int</span> i = COUNTDOWN_START; i &gt;= <span class="dv">0</span>; i--) {
+ printf(<span class="st">"%d</span><span class="ch">\n</span><span class="st">"</span>, i);
+ }
+
+ <span class="kw">return</span> <span class="dv">0</span>;
+}</code></pre></div>
+<a href="http://cs.yale.edu/homes/aspnes/classes/223/examples/style/countdown.c" class="uri">examples/style/countdown.c</a>
+</div>
+<div>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"><span class="ot">#include &lt;stdio.h&gt;</span>
+<span class="dt">int</span> main(<span class="dt">int</span> _,<span class="dt">char</span>**xb){_=<span class="bn">0xb</span>;<span class="kw">while</span>(_--)printf(<span class="st">"%d</span><span class="ch">\n</span><span class="st">"</span>,_);<span class="kw">return</span> ++_;}</code></pre></div>
+<a href="http://cs.yale.edu/homes/aspnes/classes/223/examples/style/badCountdown.c" class="uri">examples/style/badCountdown.c</a>
+</div>
+<p>The difference between these programs is that the first is designed
+to be easy to read and understand while the second is not. Though
+computer can't tell the difference between them, the second will be much
+ harder to debug or modify to accomplish some new task.</p>
+<p>Certain formatting and programming conventions have evolved over the
+years to make C code as comprehensible as possible, and as we introduce
+various features of C, we will talk about how best to use them to make
+your programs understood by both computers and humans.</p>
+<p>Submitted assignments may be graded for style in addition to
+correctness. Below is a checklist that has been used in past versions of
+ the course to identify some of the more egregious violations of
+reasonable coding practice. For more extreme examples of what not to do,
+ see the <a href="http://www.ioccc.org/">International Obfuscated C Code Contest</a>.</p>
+<pre><code>Style grading checklist
+Score is 20 points minus 1 for each box checked (but never less than 0)
+
+Comments
+
+[ ] Undocumented module.
+[ ] Undocumented function other than main.
+[ ] Underdocumented function: return value or args not described.
+[ ] Undocumented program input and output (when main is provided).
+[ ] Undocumented struct or union components.
+[ ] Undocumented #define.
+[ ] Failure to cite code taken from other sources.
+[ ] Insufficient comments.
+[ ] Excessive comments.
+
+Naming
+
+[ ] Meaningless function name.
+[ ] Confusing variable name.
+[ ] Inconsistent variable naming style (UgLyName, ugly_name, NAME___UGLY_1).
+[ ] Inconsistent use of capitalization to distinguish constants.
+
+Whitespace
+
+[ ] Inconsistent or misleading indentation.
+[ ] Spaces not used or used misleadingly to break up complicated expressions.
+[ ] Blank lines not used or used misleadingly to break up long function bodies.
+
+Macros
+
+[ ] Non-trivial constant with no symbolic name.
+[ ] Failure to parenthesize expression in macro definition.
+[ ] Dependent constant not written as expression of earlier constant.
+[ ] Underdocumented parameterized macro.
+
+Global variables
+
+[ ] Inappropriate use of a global variable.
+
+Functions
+
+[ ] Kitchen-sink function that performs multiple unrelated tasks.
+[ ] Non-void function that returns no useful value.
+[ ] Function with too many arguments.
+
+Code organization
+
+[ ] Lack of modularity.
+[ ] Function used in multiple source files but not declared in header file.
+[ ] Internal-use-only function not declared static.
+[ ] Full struct definition in header files when components should be hidden.
+[ ] #include "file.c"
+[ ] Substantial repetition of code.
+
+Miscellaneous
+
+[ ] Other obstacle to readability not mentioned above.</code></pre>
+<h2 id="variables"><span class="header-section-number">4.5</span> Variables</h2>
+<p>Variables in C are a direct abstraction of physical memory locations.
+ To understand how variables work, it helps to start by understanding
+how computer memory works.</p>
+<h3 id="MachineMemory"><span class="header-section-number">4.5.1</span> Memory</h3>
+<p>Basic model: memory consists of many bytes of storage, each of which
+has an address which is itself a sequence of bits. Though the actual
+memory architecture of a modern computer is complex, from the point of
+view of a C program we can think of as simply a large <strong>address space</strong>
+ that the CPU can store things in (and load things from), provided it
+can supply an address to the memory. Because we don't want to have to
+type long strings of bits all the time, the C compiler lets us give
+names to particular regions of the address space, and will even find
+free space for us to use.</p>
+<h3 id="variablesAsNames"><span class="header-section-number">4.5.2</span> Variables as names</h3>
+<p>A <strong>variable</strong> is a name given in a program for some region of memory. Each variable has a <strong>type</strong>,
+ which tells the compiler how big the region of memory corresponding to
+it is and how to treat the bits stored in that region when performing
+various kinds of operations (e.g. integer variables are added together
+by very different circuitry than floating-point variables, even though
+both represent numbers as bits). In modern programming languages, a
+variable also has a <strong>scope</strong> (a limit on where the name is
+ meaningful, which allows the same name to be used for different
+variables in different parts of the program) and an <strong>extent</strong> (the duration of the variable's existence, controlling when the program allocates and deallocates space for it).</p>
+<h4 id="Variable_declarations"><span class="header-section-number">4.5.2.1</span> Variable declarations</h4>
+<p>Before you can use a variable in C, you must <strong>declare</strong> it. Variable declarations show up in three places:</p>
+<ul>
+<li>Outside a function. These declarations declare <strong>global variables</strong> that are visible throughout the program (i.e. they have <strong>global scope</strong>). Use of global variables is almost always a mistake.</li>
+<li>In the argument list in the header of a function. These variables are <strong>parameters</strong> to the function. They are only visible inside the function body (<strong>local scope</strong>), exist only from when the function is called to when the function returns (<strong>bounded extent</strong>—note
+ that this is different from what happens in some garbage-collected
+languages like Scheme), and get their initial values from the arguments
+to the function when it is called.</li>
+<li>At the start of any block delimited by curly braces. Such variables
+are visible only within the block (local scope again) and exist only
+when the containing function is active (bounded extent). The convention
+in C is has generally been to declare all such <strong>local variables</strong> at the top of a function; this is different from the convention in <a href="#cplusplus">C++</a>
+ or Java, which encourage variables to be declared when they are first
+used. This convention may be less strong in C99 code, since C99 adopts
+the C++ rule of allowing variables to be declared anywhere (which can be
+ particularly useful for index variables in <code class="backtick">for</code> loops).</li>
+</ul>
+<p>Another feature of function parameters and local variables is that if a function is called more than once (even if the function <a href="#recursion">calls itself</a>), each copy of the function gets its own local variables.</p>
+<p>Variable declarations consist of a type name followed by one or more
+variable names separated by commas and terminated by a semicolon (except
+ in argument lists, where each declaration is terminated by a comma). I
+personally find it easiest to declare variables one per line, to
+simplify documenting them. It is also possible for global and local
+variables (but not function arguments) to assign an initial value to a
+variable by putting in something like <code class="backtick">=&nbsp;0</code>
+ after the variable name. It is good practice to put a comment after
+each variable declaration that explains what the variable does (with a
+possible exception for conventionally-named loop variables like <code class="backtick">i</code> or <code class="backtick">j</code> in short functions). Below is an example of a program with some variable declarations in it:</p>
+<div>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"><span class="ot">#include &lt;stdio.h&gt;</span>
+<span class="ot">#include &lt;ctype.h&gt;</span>
+
+<span class="co">/* This program counts the number of digits in its input. */</span>
+
+<span class="co">/*</span>
+<span class="co"> *This global variable is not used; it is here only to demonstrate</span>
+<span class="co"> * what a global variable declaration looks like.</span>
+<span class="co"> */</span>
+<span class="dt">unsigned</span> <span class="dt">long</span> SpuriousGlobalVariable = <span class="dv">127</span>;
+
+<span class="dt">int</span>
+main(<span class="dt">int</span> argc, <span class="dt">char</span> **argv)
+{
+ <span class="dt">int</span> c; <span class="co">/* character read */</span>
+ <span class="dt">int</span> count = <span class="dv">0</span>; <span class="co">/* number of digits found */</span>
+
+ <span class="kw">while</span>((c = getchar()) != EOF) {
+ <span class="kw">if</span>(isdigit(c)) {
+ count++;
+ }
+ }
+
+ printf(<span class="st">"%d</span><span class="ch">\n</span><span class="st">"</span>, count);
+
+ <span class="kw">return</span> <span class="dv">0</span>;
+}</code></pre></div>
+<a href="http://cs.yale.edu/homes/aspnes/classes/223/examples/variables/countDigits.c" class="uri">examples/variables/countDigits.c</a>
+</div>
+<h4 id="Variable_names"><span class="header-section-number">4.5.2.2</span> Variable names</h4>
+<p>The evolution of variable names in different programming languages:</p>
+<dl>
+<dt>11101001001001</dt>
+<dd>Physical addresses represented as bits.
+</dd>
+<dt><code>#FC27</code></dt>
+<dd>Typical assembly language address represented in hexadecimal to save
+ typing (and because it's easier for humans to distinguish #A7 from #B6
+than to distinguish 10100111 from 10110110.)
+</dd>
+<dt><code>A1$</code></dt>
+<dd>A string variable in BASIC, back in the old days where BASIC
+variables were one uppercase letter, optionally followed by a number,
+optionally followed by $ for a string variable and % for an integer
+variable. These type tags were used because BASIC interpreters didn't
+have a mechanism for declaring variable types.
+</dd>
+<dt><code>IFNXG7</code></dt>
+<dd>A typical FORTRAN variable name, back in the days of 6-character all-caps variable names. The <code class="backtick">I</code>
+ at the start means it's an integer variable. The rest of the letters
+probably abbreviate some much longer description of what the variable
+means. The default type based on the first letter was used because
+FORTRAN programmers were lazy, but it could be overridden by an explicit
+ declaration.
+</dd>
+<dt><code>i</code>, <code>j</code>, <code>c</code>, <code>count</code>, <code>top_of_stack</code>, <code>accumulatedTimeInFlight</code></dt>
+<dd>Typical names from modern C programs. There is no type information
+contained in the name; the type is specified in the declaration and
+remembered by the compiler elsewhere. Note that there are two different
+conventions for representing multi-word names: the first is to replace
+spaces with underscores, and the second is to capitalize the first
+letter of each word (possibly excluding the first letter), a style
+called <a href="http://c2.com/cgi/wiki?FindPage&amp;value=CamelCase">camel case</a>. You should pick <strong>one</strong> of these two conventions and stick to it.
+</dd>
+<dt><code>prgcGradeDatabase</code></dt>
+<dd><p>An example of <strong>Hungarian notation</strong>, a style of
+variable naming in which the type of the variable is encoded in the
+first few character. The type is now back in the variable name again.
+This is <em>not</em> enforced by the compiler: even though <code class="backtick">iNumberOfStudents</code> is supposed to be an <code class="backtick">int</code>, there is nothing to prevent you from declaring <code class="backtick">float&nbsp;iNumberOfStudents</code> if you are teaching a class on improper chainsaw handling and want to allow for the possibility of fractional students. See <a href="http://msdn.microsoft.com/en-us/library/aa260976%28v=vs.60%29.aspx">this MSDN page</a> for a much more detailed explanation of the system.</p>
+<p>Not clearly an improvement on standard naming conventions, but it is popular in some programming shops.</p>
+</dd>
+</dl>
+<p>In C, variable names are called <strong>identifiers</strong>. These are also used to identify things that are not variables, like functions and user-defined types.</p>
+<p>An identifier in C must start with a lower or uppercase letter or the underscore character <code class="backtick">_</code>.
+ Typically variables starting with underscores are used internally by
+system libraries, so it's dangerous to name your own variables this way.
+ Subsequent characters in an identifier can be letters, digits, or
+underscores. So for example <code class="backtick">a</code>, <code class="backtick">____a___a_a_11727_a</code>, <code class="backtick">AlbertEinstein</code>, <code class="backtick">aAaAaAaAaAAAAAa</code>, and <code class="backtick">______</code> are all legal identifiers in C, but <code class="backtick">$foo</code> and <code class="backtick">01</code> are not.</p>
+<p>The basic principle of variable naming is that a variable name is a
+substitute for the programmer's memory. It is generally best to give
+identifiers names that are easy to read and describe what the variable
+is used for. Such variables are called <strong>self-documenting</strong>. None of the variable names in the preceding list are any good by this standard. Better names would be <code class="backtick">total_input_characters</code>, <code class="backtick">dialedWrongNumber</code>, or <code class="backtick">stepsRemaining</code>. Non-descriptive single-character names are acceptable for certain conventional uses, such as the use of <code class="backtick">i</code> and <code class="backtick">j</code> for loop iteration variables, or <code class="backtick">c</code>
+ for an input character. Such names should only be used when the scope
+of the variable is small, so that it's easy to see all the places where
+it is used at the same time.</p>
+<p>C identifiers are case-sensitive, so <code class="backtick">aardvark</code>, <code class="backtick">AArDvARK</code>, and <code class="backtick">AARDVARK</code>
+ are all different variables. Because it is hard to remember how you
+capitalized something before, it is important to pick a standard
+convention and stick to it. The traditional convention in C goes like
+this:</p>
+<ul>
+<li>Ordinary variables and functions are lowercased or camel-cased, e.g. <code class="backtick">count</code>, <code class="backtick">countOfInputBits</code>.</li>
+<li>User-defined types (and in some conventions global variables) are capitalized, e.g. <code class="backtick">Stack</code>, <code class="backtick">TotalBytesAllocated</code>.</li>
+<li>Constants created with <code class="backtick">#define</code> or <code class="backtick">enum</code> are put in all-caps: <code class="backtick">MAXIMUM_STACK_SIZE</code>, <code class="backtick">BUFFER_LIMIT</code>.</li>
+</ul>
+<h3 id="usingVariables"><span class="header-section-number">4.5.3</span> Using variables</h3>
+<p>Ignoring <a href="#pointers">pointers</a> for the moment, there are essentially two things you can do to a variable. You can assign a value to it using the <code class="backtick">=</code> operator, as in:</p>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"> x = <span class="dv">2</span>; <span class="co">/* assign 2 to x */</span>
+ y = <span class="dv">3</span>; <span class="co">/* assign 3 to y */</span></code></pre></div>
+<p>or you can use its value in an expression:</p>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"> x = y<span class="dv">+1</span>; <span class="co">/* assign y+1 to x */</span></code></pre></div>
+<p>The assignment operator is an ordinary operator, and assignment expressions can be used in larger expressions:</p>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"> x = (y=<span class="dv">2</span>)*<span class="dv">3</span>; <span class="co">/* sets y to 2 and x to 6 */</span></code></pre></div>
+<p>This feature is usually only used in certain standard idioms, since it's confusing otherwise.</p>
+<p>There are also shorthand operators for expressions of the form <em>variable</em> <code class="backtick">=</code> <em>variable</em> <em>operator</em> <em>expression</em>. For example, writing <code class="backtick">x&nbsp;+=&nbsp;y</code> is equivalent to writing <code class="backtick">x&nbsp;=&nbsp;x&nbsp;+&nbsp;y</code>, <code class="backtick">x&nbsp;/=&nbsp;y</code> is the same as <code class="backtick">x&nbsp;=&nbsp;x&nbsp;/&nbsp;y</code>, etc.</p>
+<p>For the special case of adding or subtracting 1, you can abbreviate still further with the <code>++</code> and <code>--</code>
+ operators. These come in two versions, depending on whether you want
+the result of the expression (if used in a larger expression) to be the
+value of the variable before or after the variable is incremented:</p>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"> x = <span class="dv">0</span>;
+ y = x++; <span class="co">/* sets x to 1 and y to 0 (the old value) */</span>
+ y = ++x; <span class="co">/* sets x to 2 and y to 2 (the new value) */</span>
+ y = x--; <span class="co">/* sets x to 1 and y to 2 (the old value) */</span>
+ y = --x; <span class="co">/* sets x to 0 and y to 0 (the new value) */</span></code></pre></div>
+<p>The intuition is that if the <code class="backtick">++</code> comes before the variable, the increment happens before the value of the variable is read (a <strong>preincrement</strong>; if it comes after, it happens after the value is read (a <strong>postincrement</strong>).
+ This is confusing enough that it is best not to use the value of
+preincrement or postincrement operations except in certain standard
+idioms. But using <code>x++</code> or <code class="backtick">++x</code> by itself as a substitute for <code class="backtick">x&nbsp;=&nbsp;x+1</code> is perfectly acceptable style.<a href="#fn8" class="footnoteRef" id="fnref8"><sup>8</sup></a></p>
+<h3 id="initializers"><span class="header-section-number">4.5.4</span> Initialization</h3>
+<p>It is a serious error to use the value of a variable that has never
+been assigned to, because you will get whatever junk is sitting in
+memory at the address allocated to the variable, and this might be some
+arbitrary leftover value from a previous function call that doesn't even
+ represent the same type.<a href="#fn9" class="footnoteRef" id="fnref9"><sup>9</sup></a></p>
+<p>Fortunately, C provides a way to guarantee that a variable is
+initialized as soon as it is declared. Many of the examples in the notes
+ do not use this mechanism, because of bad habits learned by the
+instructor using early versions of C that imposed tighter constraints on
+ initialization. But initializing variables is a good habit to get in
+the practice of doing.</p>
+<p>For variables with simple types (that is, not <a href="#arrays">arrays</a>, <a href="#structs">structs</a>, or <a href="#unions">unions</a>), an initializer looks like an assignment:</p>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"> <span class="dt">int</span> sum = <span class="dv">0</span>;
+ <span class="dt">int</span> n = <span class="dv">100</span>;
+ <span class="dt">int</span> nSquared = n*n;
+ <span class="dt">double</span> gradeSchoolPi = <span class="fl">3.14</span>;
+ <span class="dt">const</span> <span class="dt">char</span> * <span class="dt">const</span> greeting = <span class="st">"Hi!"</span>;
+ <span class="dt">const</span> <span class="dt">int</span> greetingLength = strlen(greeting);</code></pre></div>
+<p>For ordinary local variables, the initializer value can be any
+expression, including expressions that call other functions. There is an
+ exception for variables allocated when the program starts (which
+includes global variables outside functions and <code>static</code> variables inside functions), which can only be initialized to constant expressions.</p>
+<p>The last two examples show how initializers can set the values of variables that are declared to be <a href="#const"><code>const</code></a> (the variable <code>greeting</code> is both constant itself, because of <code>const greeting</code>, and points to data that is also constant, because it is of type <code>const char</code>).
+ This is the only way to set the values of such variables without
+cheating, because the compiler will complain if you try to do an
+ordinary assignment to a variable declared to be constant.</p>
+<p>For fixed-size <a href="#arrays">arrays</a> and <a href="#structs">structs</a>,
+ it is possible to supply an initializer for each component, by
+enclosing the initializer values in braces, separated by commas. For
+example:</p>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"> <span class="dt">int</span> threeNumbers[<span class="dv">3</span>] = { <span class="dv">1</span>, <span class="dv">2</span>, <span class="dv">3</span> };
+
+ <span class="kw">struct</span> numericTitle {
+ <span class="dt">int</span> number;
+ <span class="dt">const</span> <span class="dt">char</span> *name;
+ };
+
+ <span class="kw">struct</span> numericTitle s = { <span class="dv">7</span>, <span class="st">"Samurai"</span> };
+ <span class="kw">struct</span> numericTitle n = { <span class="dv">3</span>, <span class="st">"Ninjas"</span> };</code></pre></div>
+<h3 id="qualifiers"><span class="header-section-number">4.5.5</span> Storage class qualifiers</h3>
+<p>It is possible to specify additional information about how a variable can be used using <strong>storage class qualifiers</strong>, which usually go before the type of a variable in a declaration.</p>
+<h4 id="scopeAndExtent"><span class="header-section-number">4.5.5.1</span> Scope and extent</h4>
+<p>Most variables that you will use in C are either parameters to <a href="#functions">functions</a> or local variables inside functions. These have <strong>local scope</strong>, meaning the variable names can only be used in the function in which they are declared, and <strong>automatic extent</strong>,
+ meaning the space for the variable is allocated, typically on the
+stack, when the function is called, and reclaimed when the function
+exits. (If the function calls itself, you get another copy of all the
+local variables; see <a href="#recursion">recursion</a>.)</p>
+<p>On <em>very rare</em> occasions you might want to have a variable that survives the entire execution of a program (has <strong>static extent</strong>) or that is visible throughout the program (has <strong>global scope</strong>). C provides a mechanism for doing this <em>that you shold never use under normal circumstances</em>.
+ Pretty much the only time you are going to want to have a variable with
+ static extent is if you are keeping track of some piece of information
+that (a) you only need one instance of, (b) you need to survive between
+function calls, and (c) it would be annoying to pass around as an extra
+argument to any function that uses it. An example would be the internal
+data structures used by <a href="#malloc"><code>malloc</code></a>, or the count variable in the function below:</p>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"><span class="co">/* returns the number of times this function has previously been called */</span>
+<span class="co">/* this can be used to generate unique numerical identifiers */</span>
+<span class="dt">unsigned</span> <span class="dt">long</span> <span class="dt">long</span>
+ticketMachine(<span class="dt">void</span>)
+{
+ <span class="dt">static</span> <span class="dt">unsigned</span> <span class="dt">long</span> <span class="dt">long</span> count = <span class="dv">0</span>;
+
+ <span class="kw">return</span> count++;
+}</code></pre></div>
+<p>To declare a local variable with static extent, use the <code>static</code>
+ qualifier as in the above example. To declare a global variable with
+static extent, declare it outside a function. In both cases you should
+provide an <a href="#initializers">initializer</a> for the variable.</p>
+<h5 id="additional-qualifiers-for-global-variables"><span class="header-section-number">4.5.5.1.1</span> Additional qualifiers for global variables</h5>
+<p>It is possible to put some additional constraints on the visibility
+of global variables. By default, a global variable will be visible
+everywhere, but functions files other than the one in which it is
+defined won't necessarily know what type it has. This latter problem can
+ be fixed using an <code>extern</code> declaration, which says that
+there is a variable somewhere else of a particular type that we are
+declaring (but not defining, so no space is allocated). In contrast, the
+ <code>static</code> keyword (on a global variable) specifies that it
+will only be visible in the current file, even if some other file
+includes a declaration of a global variable of the same name.</p>
+<p>Here are three variable declarations that illustrate how this works:</p>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"> <span class="dt">unsigned</span> <span class="dt">short</span> Global = <span class="dv">5</span>; <span class="co">/* global variable, can be used anywhere */</span>
+
+ <span class="kw">extern</span> <span class="dt">float</span> GlobalFloat; <span class="co">/* this global variable, defined somewhere else, has type float */</span>
+
+ <span class="dt">static</span> <span class="dt">char</span> Character = 'c'; <span class="co">/* global variable, can only be used by functions in this file */</span></code></pre></div>
+<p>(Note the convention of putting capital letters on global variables to distinguish them from local variables.)</p>
+<p>Typically, an <code>extern</code> definition would appear in a header
+ file so that it can be included in any function that uses the variable,
+ while an ordinary global variable definition would appear in a C file
+so it only occurs once.</p>
+<h3 id="const"><span class="header-section-number">4.5.6</span> Marking variables as constant</h3>
+<p>The <strong>const</strong> qualifier declares a variable to be constant:</p>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"> <span class="dt">const</span> <span class="dt">int</span> three = <span class="dv">3</span>; <span class="co">/* this will always be 3 */</span></code></pre></div>
+<p>It is an error to apply any sort of assignment (<code>=</code>, <code>+=,</code>++<code>, etc.) to a variable qualified as</code>const`.</p>
+<h4 id="pointers-to-const"><span class="header-section-number">4.5.6.1</span> Pointers to <code>const</code></h4>
+<p>A <a href="#pointers">pointer</a> to a region that should not be modified should be declared with <code>const</code> type:</p>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"> <span class="dt">const</span> <span class="dt">char</span> *string = <span class="st">"You cannot modify this string."</span>;</code></pre></div>
+<p>The <code>const</code> in the declaration above applies to the characters that <code>string</code> points to: <code>string</code> is not <code>const</code> itself, but is instead a <em>pointer to <code>const</code></em>. It is still possible to make <code>string</code> point somewhere else, say by doing an assignment:</p>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"> string = <span class="st">"You cannot modify this string either."</span></code></pre></div>
+<p>If you want to make it so that you can't assign to <code>string</code>, put <code>const</code> right before the variable name:</p>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"> <span class="co">/* prevent assigning to string as well */</span>
+ <span class="dt">const</span> <span class="dt">char</span> * <span class="dt">const</span> string = <span class="st">"You cannot modify this string."</span>;</code></pre></div>
+<p>Now <code>string</code> is a <code>const</code> pointer to <code>const</code>: you can neither modify <code>string</code> nor the values it points to.</p>
+<p>Note that <code>const</code> only restricts what you can do using
+this particular variable name. If you can get at the memory that
+something points to by some other means, say through another pointer,
+you may be able to change the values in these memory locations anyway:</p>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"> <span class="dt">int</span> x = <span class="dv">5</span>;
+ <span class="dt">const</span> <span class="dt">int</span> *p = &amp;x;
+ <span class="dt">int</span> *q;
+
+ *p = <span class="dv">1</span>; <span class="co">/* will cause an error at compile time */</span>
+ x = <span class="dv">3</span>; <span class="co">/* also changes *p, but will not cause an error */</span></code></pre></div>
+<h2 id="IO"><span class="header-section-number">4.6</span> Input and output</h2>
+<p>Input and output from C programs is typically done through theconst <strong>standard I/O library</strong>, whose functions etc. are declared in <code class="backtick">stdio.h</code>.
+ A detailed descriptions of the functions in this library is given in
+Appendix B of Kernighan and Ritchie. We'll talk about some of the more
+useful functions and about how input-output (I/O) works on Unix-like
+operating systems in general.</p>
+<h3 id="Character_streams"><span class="header-section-number">4.6.1</span> Character streams</h3>
+<p>The standard I/O library works on <strong>character streams</strong>,
+ objects that act like long sequences of incoming or outgoing
+characters. What a stream is connected to is often not apparent to a
+program that uses it; an output stream might go to a terminal, to a
+file, or even to another program (appearing there as an input stream).</p>
+<p>Three standard streams are available to all programs: these are <code class="backtick">stdin</code> (standard input), <code class="backtick">stdout</code> (standard output), and <code class="backtick">stderr</code> (standard error). Standard I/O functions that do not take a stream as an argument will generally either read from <code class="backtick">stdin</code> or write to <code class="backtick">stdout</code>. The <code class="backtick">stderr</code> stream is used for error messages. It is kept separate from <code class="backtick">stdout</code> so that you can see these messages even if you redirect output to a file:</p>
+<pre><code>$ ls no-such-file &gt; /tmp/dummy-output
+ls: no-such-file: No such file or directory</code></pre>
+<h3 id="characterIO"><span class="header-section-number">4.6.2</span> Reading and writing single characters</h3>
+<p>To read a single character from <code class="backtick">stdin</code>, use <code class="backtick">getchar</code>:</p>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"> <span class="dt">int</span> c;
+
+ c = getchar();</code></pre></div>
+<p>The <code class="backtick">getchar</code> routine will return the special value <code class="backtick">EOF</code> (usually -1; short for <em>end of file</em>)
+ if there are no more characters to read, which can happen when you hit
+the end of a file or when the user types the end-of-file key control-D
+to the terminal. Note that the return value of <code class="backtick">getchar</code> is declared to be an <code class="backtick">int</code> since <code class="backtick">EOF</code> lies outside the normal character range.</p>
+<p>To write a single character to <code class="backtick">stdout</code>, use <code class="backtick">putchar</code>:</p>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"> putchar('!');</code></pre></div>
+<p>Even though <code class="backtick">putchar</code> can only write single bytes, it takes an <code class="backtick">int</code> as an argument. Any value outside the range 0..255 will be truncated to its last byte, as in the usual conversion from <code class="backtick">int</code> to <code class="backtick">unsigned&nbsp;char</code>.</p>
+<p>Both <code class="backtick">getchar</code> and <code class="backtick">putchar</code> are wrappers for more general routines <code class="backtick">getc</code> and <code class="backtick">putc</code> that allow you to specify which stream you are using. To illustrate <code class="backtick">getc</code> and <code class="backtick">putc</code>, here's how we might define <code class="backtick">getchar</code> and <code class="backtick">putchar</code> if they didn't exist already:</p>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"><span class="dt">int</span>
+getchar2(<span class="dt">void</span>)
+{
+ <span class="kw">return</span> getc(stdin);
+}
+
+<span class="dt">int</span>
+putchar2(<span class="dt">int</span> c)
+{
+ <span class="kw">return</span> putc(c, stdout);
+}</code></pre></div>
+<p>Note that <code class="backtick">putc</code>, <code class="backtick">putchar2</code> as defined above, and the original <code class="backtick">putchar</code> all return an <code class="backtick">int</code> rather than <code class="backtick">void</code>; this is so that they can signal whether the write succeeded. If the write succeeded, <code class="backtick">putchar</code> or <code class="backtick">putc</code> will return the value written. If the write failed (say because the disk was full), then <code class="backtick">putc</code> or <code class="backtick">putchar</code> will return <code class="backtick">EOF</code>.</p>
+<p>Here's another example of using <code class="backtick">putc</code> to make a new function <code class="backtick">putcerr</code> that writes a character to <code class="backtick">stderr</code>:</p>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"><span class="dt">int</span>
+putcerr(<span class="dt">int</span> c)
+{
+ <span class="kw">return</span> putc(c, stderr);
+}</code></pre></div>
+<p>A rather odd feature of the C standard I/O library is that if you
+don't like the character you just got, you can put it back using the <code class="backtick">ungetc</code> function. The limitations on <code class="backtick">ungetc</code> are that (a) you can only push one character back, and (b) that character can't be <code class="backtick">EOF</code>. The <code class="backtick">ungetc</code>
+ function is provided because it makes certain high-level input tasks
+easier; for example, if you want to parse a number written as a sequence
+ of digits, you need to be able to read characters until you hit the
+first non-digit. But if the non-digit is going to be used elsewhere in
+your program, you don't want to eat it. The solution is to put it back
+using <code class="backtick">ungetc</code>.</p>
+<p>Here's a function that uses <code class="backtick">ungetc</code> to peek at the next character on <code class="backtick">stdin</code> without consuming it:</p>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"><span class="co">/* return the next character from stdin without consuming it */</span>
+<span class="dt">int</span>
+peekchar(<span class="dt">void</span>)
+{
+ <span class="dt">int</span> c;
+
+ c = getchar();
+ <span class="kw">if</span>(c != EOF) ungetc(c, stdin); <span class="co">/* puts it back */</span>
+
+ <span class="kw">return</span> c;
+}</code></pre></div>
+<h3 id="Formatted_I.2FO"><span class="header-section-number">4.6.3</span> Formatted I/O</h3>
+<p>Reading and writing data one character at a time can be painful. The C
+ standard I/O library provides several convenient routines for reading
+and writing formatted data. The most commonly used one is <code class="backtick">printf</code>,
+ which takes as arguments a format string followed by zero or more
+values that are filled in to the format string according to patterns
+appearing in it.</p>
+<p>Here are some typical <code class="backtick">printf</code> statements:</p>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"> printf(<span class="st">"Hello</span><span class="ch">\n</span><span class="st">"</span>); <span class="co">/* print "Hello" followed by a newline */</span>
+ printf(<span class="st">"%c"</span>, c); <span class="co">/* equivalent to putchar(c) */</span>
+ printf(<span class="st">"%d"</span>, n); <span class="co">/* print n (an int) formatted in decimal */</span>
+ printf(<span class="st">"%u"</span>, n); <span class="co">/* print n (an unsigned int) formatted in decimal */</span>
+ printf(<span class="st">"%o"</span>, n); <span class="co">/* print n (an unsigned int) formatted in octal */</span>
+ printf(<span class="st">"%x"</span>, n); <span class="co">/* print n (an unsigned int) formatted in hexadecimal */</span>
+ printf(<span class="st">"%f"</span>, x); <span class="co">/* print x (a float or double) */</span>
+
+ <span class="co">/* print total (an int) and average (a double) on two lines with labels */</span>
+ printf(<span class="st">"Total: %d</span><span class="ch">\n</span><span class="st">Average: %f</span><span class="ch">\n</span><span class="st">"</span>, total, average);</code></pre></div>
+<p>For a full list of formatting codes see Table B-1 in Kernighan and Ritchie, or run <code class="backtick">man&nbsp;3&nbsp;printf</code>.</p>
+<p>The inverse of <code class="backtick">printf</code> is <code class="backtick">scanf</code>. The <code class="backtick">scanf</code> function reads formatted data from <code class="backtick">stdin</code> according to the format string passed as its first argument and stuffs the results into variables whose <em>addresses</em> are given by the later arguments. This requires prefixing each such argument with the <code class="backtick">&amp;</code> operator, which takes the address of a variable.</p>
+<p>Format strings for <code class="backtick">scanf</code> are close enough to format strings for <code class="backtick">printf</code> that you can usually copy them over directly. However, because <code class="backtick">scanf</code> arguments don't go through argument promotion (where all small integer types are converted to <code class="backtick">int</code> and <code class="backtick">float</code>s are converted to <code class="backtick">double</code>), you have to be much more careful about specifying the type of the argument correctly. For example, while <code>printf("%f", x)</code> will work whether<code>x</code> is a <code>float</code> or a <code>double</code>, <code>scanf("%f", &amp;x)</code> will work only if <code>x</code> is a <code>float</code>, which means that <code>scanf("%lf", &amp;x)</code> is needed if <code>x</code> is in fact a <code>double</code>.</p>
+<p>Some examples:</p>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"> scanf(<span class="st">"%c"</span>, &amp;c); <span class="co">/* like c = getchar(); c must be a char; will NOT put EOF in c */</span>
+ scanf(<span class="st">"%d"</span>, &amp;n); <span class="co">/* read an int formatted in decimal */</span>
+ scanf(<span class="st">"%u"</span>, &amp;n); <span class="co">/* read an unsigned int formatted in decimal */</span>
+ scanf(<span class="st">"%o"</span>, &amp;n); <span class="co">/* read an unsigned int formatted in octal */</span>
+ scanf(<span class="st">"%x"</span>, &amp;n); <span class="co">/* read an unsigned int formatted in hexadecimal */</span>
+ scanf(<span class="st">"%f"</span>, &amp;x); <span class="co">/* read a float */</span>
+ scanf(<span class="st">"%lf"</span>, &amp;x); <span class="co">/* read a double */</span>
+
+ <span class="co">/* read total (an int) and average (a float) on two lines with labels */</span>
+ <span class="co">/* (will also work if input is missing newlines or uses other whitespace, see below) */</span>
+ scanf(<span class="st">"Total: %d</span><span class="ch">\n</span><span class="st">Average: %f</span><span class="ch">\n</span><span class="st">"</span>, &amp;total, &amp;average);</code></pre></div>
+<p>For a full list of formatting codes, run <code>man 3 scanf</code>.</p>
+<p>The <code class="backtick">scanf</code> routine usually eats
+whitespace (spaces, tabs, newlines, etc.) in its input whenever it sees a
+ conversion specification or a whitespace character in its format
+string. The one exception is that a <code>%c</code> conversion specifier
+ will not eat whitespace and will instead return the next character
+whether it is whitespace or not. Non-whitespace characters that are not
+part of conversion specifications must match exactly. To detect if <code class="backtick">scanf</code> parsed everything successfully, look at its return value; it returns the number of values it filled in, or <code class="backtick">EOF</code> if it hits end-of-file before filling in any values.</p>
+<p>The <code class="backtick">printf</code> and <code class="backtick">scanf</code> routines are wrappers for <code class="backtick">fprintf</code> and <code class="backtick">fscanf</code>, which take a stream as their first argument, e.g.:</p>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"> fprintf(stderr, <span class="st">"BUILDING ON FIRE, %d%% BURNT!!!</span><span class="ch">\n</span><span class="st">"</span>, percentage);</code></pre></div>
+<p>This sends the output the the standard error output handle <code>stderr</code>. Note the use of "%%" to print a single percent in the output.</p>
+<h3 id="Rolling_your_own_I.2FO_routines"><span class="header-section-number">4.6.4</span> Rolling your own I/O routines</h3>
+<p>Since we can write our own functions in C, if we don't like what the
+standard routines do, we can build our own on top of them. For example,
+here's a function that reads in integer values without leading minus
+signs and returns the result. It uses the <code class="backtick">peekchar</code> routine we defined above, as well as the <code class="backtick">isdigit</code> routine declared in <code class="backtick">ctype.h</code>.</p>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"><span class="co">/* read an integer written in decimal notation from stdin until the first</span>
+<span class="co"> * non-digit and return it. Returns 0 if there are no digits. */</span>
+<span class="dt">int</span>
+readNumber(<span class="dt">void</span>)
+{
+ <span class="dt">int</span> accumulator; <span class="co">/* the number so far */</span>
+ <span class="dt">int</span> c; <span class="co">/* next character */</span>
+
+ accumulator = <span class="dv">0</span>;
+
+ <span class="kw">while</span>((c = peekchar()) != EOF &amp;&amp; isdigit(c)) {
+ c = getchar(); <span class="co">/* consume it */</span>
+ accumulator *= <span class="dv">10</span>; <span class="co">/* shift previous digits over */</span>
+ accumulator += (c - '<span class="dv">0</span>'); <span class="co">/* add decimal value of new digit */</span>
+ }
+
+ <span class="kw">return</span> accumulator;
+}</code></pre></div>
+<p>Here's another implementation that does <em>almost</em> the same thing:</p>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"><span class="dt">int</span>
+readNumber2(<span class="dt">void</span>)
+{
+ <span class="dt">int</span> n;
+
+ <span class="kw">if</span>(scanf(<span class="st">"%u"</span>, &amp;n) == <span class="dv">1</span>) {
+ <span class="kw">return</span> n;
+ } <span class="kw">else</span> {
+ <span class="kw">return</span> <span class="dv">0</span>;
+ }
+}</code></pre></div>
+<p>The difference is that <code class="backtick">readNumber2</code> will consume any whitespace before the first digit, which may or may not be what we want.</p>
+<p>More complex routines can be used to parse more complex input. For example, here's a routine that uses <code class="backtick">readNumber</code> to parse simple arithmetic expressions, where each expression is either a number or of the form <code class="backtick">(</code><em>expression</em><code class="backtick">+</code><em>expression</em><code class="backtick">)</code> or <code class="backtick">(</code><em>expression</em><code class="backtick">*</code><em>expression</em><code class="backtick">)</code>.
+ The return value is the value of the expression after adding together
+or multiplying all of its subexpressions. (A complete program including
+this routine and the others defined earlier that it uses can be found <a href="http://cs.yale.edu/homes/aspnes/classes/223/examples/IO/calc.c" class="uri">examples/IO/calc.c</a>.</p>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"><span class="ot">#define EXPRESSION_ERROR (-1)</span>
+
+<span class="co">/* read an expression from stdin and return its value */</span>
+<span class="co">/* returns EXPRESSION_ERROR on error */</span>
+<span class="dt">int</span>
+readExpression(<span class="dt">void</span>)
+{
+ <span class="dt">int</span> e1; <span class="co">/* value of first sub-expression */</span>
+ <span class="dt">int</span> e2; <span class="co">/* value of second sub-expression */</span>
+ <span class="dt">int</span> c;
+ <span class="dt">int</span> op; <span class="co">/* operation: '+' or '*' */</span>
+
+ c = peekchar();
+
+ <span class="kw">if</span>(c == '(') {
+ c = getchar();
+
+ e1 = readExpression();
+ op = getchar();
+ e2 = readExpression();
+
+ c = getchar(); <span class="co">/* this had better be ')' */</span>
+ <span class="kw">if</span>(c != ')') <span class="kw">return</span> EXPRESSION_ERROR;
+
+ <span class="co">/* else */</span>
+ <span class="kw">switch</span>(op) {
+ <span class="kw">case</span> '*':
+ <span class="kw">return</span> e1*e2;
+ <span class="kw">break</span>;
+ <span class="kw">case</span> '+':
+ <span class="kw">return</span> e1+e2;
+ <span class="kw">break</span>;
+ <span class="kw">default</span>:
+ <span class="kw">return</span> EXPRESSION_ERROR;
+ <span class="kw">break</span>;
+ }
+ } <span class="kw">else</span> <span class="kw">if</span>(isdigit(c)) {
+ <span class="kw">return</span> readNumber();
+ } <span class="kw">else</span> {
+ <span class="kw">return</span> EXPRESSION_ERROR;
+ }
+}</code></pre></div>
+<p>Because this routine calls itself recursively as it works its way down through the input, it is an example of a <a href="http://en.wikipedia.org/wiki/Recursive_descent_parser" title="WikiPedia">recursive descent parser</a>.
+ Parsers for more complicated languages like C are usually not written
+by hand like this, but are instead constructed mechanically using a <a href="http://en.wikipedia.org/wiki/Parser_generator" title="WikiPedia">Parser generator</a>.</p>
+<h3 id="File_I.2FO"><span class="header-section-number">4.6.5</span> File I/O</h3>
+<p>Reading and writing files is done by creating new streams attached to the files. The function that does this is <code class="backtick">fopen</code>.
+ It takes two arguments: a filename, and a flag that controls whether
+the file is opened for reading or writing. The return value of <code class="backtick">fopen</code> has type <code class="backtick">FILE&nbsp;*</code> and can be used in <code class="backtick">putc</code>, <code class="backtick">getc</code>, <code class="backtick">fprintf</code>, etc. just like <code class="backtick">stdin</code>, <code class="backtick">stdout</code>, or <code class="backtick">stderr</code>. When you are done using a stream, you should close it using <code class="backtick">fclose</code>.</p>
+<p>Here's a program that reads a list of numbers from a file whose name is given as <code class="backtick">argv[1]</code> and prints their sum:</p>
+<div>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"><span class="ot">#include &lt;stdio.h&gt;</span>
+<span class="ot">#include &lt;stdlib.h&gt;</span>
+
+<span class="dt">int</span>
+main(<span class="dt">int</span> argc, <span class="dt">char</span> **argv)
+{
+ FILE *f;
+ <span class="dt">int</span> x;
+ <span class="dt">int</span> sum;
+
+ <span class="kw">if</span>(argc &lt; <span class="dv">2</span>) {
+ fprintf(stderr, <span class="st">"Usage: %s filename</span><span class="ch">\n</span><span class="st">"</span>, argv[<span class="dv">0</span>]);
+ exit(<span class="dv">1</span>);
+ }
+
+ f = fopen(argv[<span class="dv">1</span>], <span class="st">"r"</span>);
+ <span class="kw">if</span>(f == <span class="dv">0</span>) {
+ <span class="co">/* perror is a standard C library routine */</span>
+ <span class="co">/* that prints a message about the last failed library routine */</span>
+ <span class="co">/* prepended by its argument */</span>
+ perror(filename);
+ exit(<span class="dv">2</span>);
+ }
+
+ <span class="co">/* else everything is ok */</span>
+ sum = <span class="dv">0</span>;
+ <span class="kw">while</span>(fscanf(<span class="st">"%d"</span>, &amp;x) == <span class="dv">1</span>) {
+ sum += x;
+ }
+
+ printf(<span class="st">"%d</span><span class="ch">\n</span><span class="st">"</span>, sum);
+
+ <span class="co">/* not strictly necessary but it's polite */</span>
+ fclose(f);
+
+ <span class="kw">return</span> <span class="dv">0</span>;
+}</code></pre></div>
+<a href="http://cs.yale.edu/homes/aspnes/classes/223/examples/IO/sum.c" class="uri">examples/IO/sum.c</a>
+</div>
+<p>To write to a file, open it with <code class="backtick">fopen(filename,&nbsp;"w")</code>. Note that as soon as you call <code class="backtick">fopen</code> with the <code class="backtick">"w"</code> flag, any previous contents of the file are erased. If you want to append to the end of an existing file, use <code class="backtick">"a"</code> instead. You can also add <code class="backtick">+</code> onto the flag if you want to read and write the same file (this will probably involve using <code class="backtick">fseek</code>).</p>
+<p>Some operating systems (Windows) make a distinction between text and
+binary files. For text files, use the same arguments as above. For
+binary files, add a <code class="backtick">b</code>, e.g. <code class="backtick">fopen(filename,&nbsp;"wb")</code> to write a binary file.</p>
+<div>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"><span class="co">/* leave a greeting in the current directory */</span>
+
+<span class="ot">#include &lt;stdio.h&gt;</span>
+<span class="ot">#include &lt;stdlib.h&gt;</span>
+
+<span class="ot">#define FILENAME "hello.txt"</span>
+<span class="ot">#define MESSAGE "hello world"</span>
+
+<span class="dt">int</span>
+main(<span class="dt">int</span> argc, <span class="dt">char</span> **argv)
+{
+ FILE *f;
+
+ f = fopen(FILENAME, <span class="st">"w"</span>);
+ <span class="kw">if</span>(f == <span class="dv">0</span>) {
+ perror(FILENAME);
+ exit(<span class="dv">1</span>);
+ }
+
+ <span class="co">/* unlike puts, fputs doesn't add a newline */</span>
+ fputs(MESSAGE, f);
+ putc(<span class="ch">'\n'</span>, f);
+
+ fclose(f);
+
+ <span class="kw">return</span> <span class="dv">0</span>;
+}</code></pre></div>
+<a href="http://cs.yale.edu/homes/aspnes/classes/223/examples/IO/helloFile.c" class="uri">examples/IO/helloFile.c</a>
+</div>
+<h2 id="statements"><span class="header-section-number">4.7</span> Statements and control structures</h2>
+<p>The bodies of C functions (including the <code class="backtick">main</code> function) are made up of <strong>statements</strong>. These can either be <strong>simple statements</strong> that do not contain other statements, or <strong>compound statements</strong> that have other statements inside them. <strong>Control structures</strong>
+ are compound statements like if/then/else, while, for, and do..while
+that control how or whether their component statements are executed.</p>
+<h3 id="Simple_statements"><span class="header-section-number">4.7.1</span> Simple statements</h3>
+<p>The simplest kind of statement in C is an expression (followed by a
+semicolon, the terminator for all simple statements). Its value is
+computed and discarded. Examples:</p>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"> x = <span class="dv">2</span>; <span class="co">/* an assignment statement */</span>
+ x = <span class="dv">2+3</span>; <span class="co">/* another assignment statement */</span>
+ <span class="dv">2+3</span>; <span class="co">/* has no effect---will be discarded by smart compilers */</span>
+ puts(<span class="st">"hi"</span>); <span class="co">/* a statement containing a function call */</span>
+ root2 = sqrt(<span class="dv">2</span>); <span class="co">/* an assignment statement with a function call */</span></code></pre></div>
+<p>Most statements in a typical C program are simple statements of this form.</p>
+<p>Other examples of simple statements are the jump statements <code class="backtick">return</code>, <code class="backtick">break</code>, <code class="backtick">continue</code>, and <code class="backtick">goto</code>. A <code class="backtick">return</code>
+ statement specifies the return value for a function (if there is one),
+and when executed it causes the function to exit immediately. The <code class="backtick">break</code> and <code class="backtick">continue</code> statements jump immediately to the end of a loop (or <code class="backtick">switch</code>; see below) or the next iteration of a loop; we'll talk about these more when we talk about loops. The <code class="backtick">goto</code>
+ statement jumps to another location in the same function, and exists
+for the rare occasions when it is needed. Using it in most circumstances
+ is a sin.</p>
+<h3 id="Compound_statements"><span class="header-section-number">4.7.2</span> Compound statements</h3>
+<p>Compound statements come in two varieties: conditionals and loops.</p>
+<h4 id="conditionals"><span class="header-section-number">4.7.2.1</span> Conditionals</h4>
+<p>These are compound statements that test some condition and execute
+one or another block depending on the outcome of the condition. The
+simplest is the <code class="backtick">if</code> statement:</p>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"> <span class="kw">if</span>(houseIsOnFire) {
+ <span class="co">/* ouch! */</span>
+ scream();
+ runAway();
+ }</code></pre></div>
+<p>The <strong>body</strong> of the <code class="backtick">if</code>
+statement is executed only if the expression in parentheses at the top
+evaluates to true (which in C means any value that is not 0).</p>
+<p>The braces are not strictly required, and are used only to group one
+or more statements into a single statement. If there is only one
+statement in the body, the braces can be omitted:</p>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"> <span class="kw">if</span>(programmerIsLazy) omitBraces();</code></pre></div>
+<p>This style is recommended only for very simple bodies. Omitting the
+braces makes it harder to add more statements later without errors.</p>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"> <span class="kw">if</span>(underAttack)
+ launchCounterAttack(); <span class="co">/* executed only when attacked */</span>
+ hideInBunker(); <span class="co">/* ### DO NOT INDENT LIKE THIS ### executed always */</span></code></pre></div>
+<p>In the example above, the lack of braces means that the <code class="backtick">hideInBunker()</code> statement is <em>not</em> part of the <code class="backtick">if</code> statement, despite the misleading indentation. This sort of thing is why I generally always put in braces in an <code class="backtick">if</code>.</p>
+<p>An <code class="backtick">if</code> statement may have an <code class="backtick">else</code> clause, whose body is executed if the test is false (i.e. equal to 0).</p>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"> <span class="kw">if</span>(happy) {
+ smile();
+ } <span class="kw">else</span> {
+ frown();
+ }</code></pre></div>
+<p>A common idiom is to have a chain of <code class="backtick">if</code> and <code class="backtick">else&nbsp;if</code> branches that test several conditions:</p>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"> <span class="kw">if</span>(temperature &lt; <span class="dv">0</span>) {
+ puts(<span class="st">"brrr"</span>);
+ } <span class="kw">else</span> <span class="kw">if</span>(temperature &lt; <span class="dv">100</span>) {
+ puts(<span class="st">"hooray"</span>);
+ } <span class="kw">else</span> {
+ puts(<span class="st">"ouch!"</span>);
+ }</code></pre></div>
+<p>This can be inefficient if there are a lot of cases, since the tests are applied sequentially. For tests of the form <em>&lt;expression&gt;</em> <code class="backtick">==</code> <em>&lt;small constant&gt;</em>, the <code class="backtick">switch</code> statement may provide a faster alternative. Here's a typical <code class="backtick">switch</code> statement:</p>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"> <span class="co">/* print plural of cow, maybe using the obsolete dual number construction */</span>
+ <span class="kw">switch</span>(numberOfCows) {
+ <span class="kw">case</span> <span class="dv">1</span>:
+ puts(<span class="st">"cow"</span>);
+ <span class="kw">break</span>;
+ <span class="kw">case</span> <span class="dv">2</span>:
+ puts(<span class="st">"cowen"</span>);
+ <span class="kw">break</span>;
+ <span class="kw">default</span>:
+ puts(<span class="st">"cows"</span>);
+ <span class="kw">break</span>;
+ }</code></pre></div>
+<p>This prints the string "cow" if there is one cow, "cowen" if there
+are two cowen, and "cows" if there are any other number of cows. The <code class="backtick">switch</code> statement evaluates its argument and jumps to the matching <code class="backtick">case</code> label, or to the <code class="backtick">default</code> label if none of the cases match. Cases must be constant integer values.</p>
+<p>The <code class="backtick">break</code> statements inside the block jump to the end of the block. Without them, executing the <code class="backtick">switch</code> with <code class="backtick">numberOfCows</code>
+ equal to 1 would print all three lines. This can be useful in some
+circumstances where the same code should be used for more than one case:</p>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"> <span class="kw">switch</span>(c) {
+ <span class="kw">case</span> 'a':
+ <span class="kw">case</span> 'e':
+ <span class="kw">case</span> 'i':
+ <span class="kw">case</span> 'o':
+ <span class="kw">case</span> 'u':
+ type = VOWEL;
+ <span class="kw">break</span>;
+ <span class="kw">default</span>:
+ type = CONSONANT;
+ <span class="kw">break</span>;
+ }</code></pre></div>
+<p>or when a case "falls through" to the next:</p>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"> <span class="kw">switch</span>(countdownStart) {
+ <span class="kw">case</span> <span class="dv">3</span>:
+ puts(<span class="st">"3"</span>);
+ <span class="kw">case</span> <span class="dv">2</span>:
+ puts(<span class="st">"2"</span>);
+ <span class="kw">case</span> <span class="dv">1</span>:
+ puts(<span class="st">"1"</span>)
+ <span class="kw">case</span> <span class="dv">0</span>:
+ puts(<span class="st">"KABLOOIE!"</span>);
+ <span class="kw">break</span>;
+ <span class="kw">default</span>:
+ puts(<span class="st">"I can't count that high!"</span>);
+ <span class="kw">break</span>;
+ }</code></pre></div>
+<p>Note that it is customary to include a <code class="backtick">break</code>
+ on the last case even though it has no effect; this avoids problems
+later if a new case is added. It is also customary to include a <code class="backtick">default</code> case even if the other cases supposedly exhaust all the possible values, as a check against bad or unanticipated inputs.</p>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"> <span class="kw">switch</span>(oliveSize) {
+ <span class="kw">case</span> JUMBO:
+ eatOlives(SLOWLY);
+ <span class="kw">break</span>;
+ <span class="kw">case</span> COLLOSSAL:
+ eatOlives(QUICKLY);
+ <span class="kw">break</span>;
+ <span class="kw">case</span> SUPER_COLLOSSAL:
+ eatOlives(ABSURDLY);
+ <span class="kw">break</span>;
+ <span class="kw">default</span>:
+ <span class="co">/* unknown size! */</span>
+ abort();
+ <span class="kw">break</span>;
+ }</code></pre></div>
+<p>Though <code class="backtick">switch</code> statements are better
+than deeply nested if/else-if constructions, it is often even better to
+organize the different cases as data rather than code. We'll see
+examples of this when we talk about <a href="#functionPointers">function pointers</a>.</p>
+<p>Nothing in the C standards prevents the <code class="backtick">case</code> labels from being buried inside other compound statements. One rather hideous application of this fact is <a href="http://en.wikipedia.org/wiki/Duff%27s_device" title="WikiPedia">Duff's device</a>.</p>
+<h4 id="Loops"><span class="header-section-number">4.7.2.2</span> Loops</h4>
+<p>There are three kinds of loops in C.</p>
+<h5 id="The_while_loop"><span class="header-section-number">4.7.2.2.1</span> The while loop</h5>
+<p>A <code class="backtick">while</code> loop tests if a condition is
+true, and if so, executes its body. It then tests the condition is true
+again, and keeps executing the body as long as it is. Here's a program
+that deletes every occurence of the letter <code class="backtick">e</code> from its input.</p>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"><span class="ot">#include &lt;stdio.h&gt;</span>
+
+<span class="dt">int</span>
+main(<span class="dt">int</span> argc, <span class="dt">char</span> **argv)
+{
+ <span class="dt">int</span> c;
+
+ <span class="kw">while</span>((c = getchar()) != EOF) {
+ <span class="kw">switch</span>(c) {
+ <span class="kw">case</span> 'e':
+ <span class="kw">case</span> 'E':
+ <span class="kw">break</span>;
+ <span class="kw">default</span>:
+ putchar(c);
+ <span class="kw">break</span>;
+ }
+ }
+
+ <span class="kw">return</span> <span class="dv">0</span>;
+}</code></pre></div>
+<p>Note that the expression inside the <code class="backtick">while</code> argument both assigns the return value of <code class="backtick">getchar</code> to <code class="backtick">c</code> and tests to see if it is equal to <code class="backtick">EOF</code>
+ (which is returned when no more input characters are available). This
+is a very common idiom in C programs. Note also that even though <code class="backtick">c</code> holds a single character, it is declared as an <code class="backtick">int</code>. The reason is that <code class="backtick">EOF</code> (a constant defined in <code class="backtick">stdio.h</code>) is outside the normal character range, and if you assign it to a variable of type <code class="backtick">char</code>
+ it will be quietly truncated into something else. Because C doesn't
+provide any sort of exception mechanism for signalling unusual outcomes
+of function calls, designers of library functions often have to resort
+to extending the output of a function to include an extra value or two
+to signal failure; we'll see this a lot when the null pointer shows up
+in the chapter on <a href="#pointers">pointers</a>.</p>
+<h5 id="The_do..while_loop"><span class="header-section-number">4.7.2.2.2</span> The do..while loop</h5>
+<p>The <code class="backtick">do</code>..<code class="backtick">while</code> statement is like the <code class="backtick">while</code>
+ statement except the test is done at the end of the loop instead of the
+ beginning. This means that the body of the loop is always executed at
+least once.</p>
+<p>Here's a loop that does a random walk until it gets back to 0 (if ever). If we changed the <code class="backtick">do</code>..<code class="backtick">while</code> loop to a <code class="backtick">while</code> loop, it would never take the first step, because <code class="backtick">pos</code> starts at 0.</p>
+<div>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"><span class="ot">#include &lt;stdio.h&gt;</span>
+<span class="ot">#include &lt;stdlib.h&gt;</span>
+<span class="ot">#include &lt;time.h&gt;</span>
+
+<span class="dt">int</span>
+main(<span class="dt">int</span> argc, <span class="dt">char</span> **argv)
+{
+ <span class="dt">int</span> pos = <span class="dv">0</span>; <span class="co">/* position of random walk */</span>
+
+ srandom(time(<span class="dv">0</span>)); <span class="co">/* initialize random number generator */</span>
+
+ <span class="kw">do</span> {
+ pos += random() &amp; <span class="bn">0x1</span> ? +<span class="dv">1</span> : -<span class="dv">1</span>;
+ printf(<span class="st">"%d</span><span class="ch">\n</span><span class="st">"</span>, pos);
+ } <span class="kw">while</span>(pos != <span class="dv">0</span>);
+
+ <span class="kw">return</span> <span class="dv">0</span>;
+}</code></pre></div>
+<a href="http://cs.yale.edu/homes/aspnes/classes/223/examples/statements/randomWalk.c" class="uri">examples/statements/randomWalk.c</a>
+</div>
+<p>The <code class="backtick">do</code>..<code class="backtick">while</code> loop is used much less often in practice than the <code class="backtick">while</code> loop.</p>
+<p>It is theoretically possible to convert a <code class="backtick">do</code>..<code class="backtick">while</code> loop to a <code class="backtick">while</code>
+ loop by making an extra copy of the body in front of the loop, but this
+ is not recommended since it's almost always a bad idea to duplicate
+code.</p>
+<h5 id="forLoop"><span class="header-section-number">4.7.2.2.3</span> The for loop</h5>
+<p>The <code class="backtick">for</code> loop is a form of <a href="http://en.wikipedia.org/wiki/Syntactic_sugar">syntactic sugar</a>
+ that is used when a loop iterates over a sequence of values stored in
+some variable (or variables). Its argument consists of three
+expressions: the first initializes the variable and is called once when
+the statement is first reached. The second is the test to see if the
+body of the loop should be executed; it has the same function as the
+test in a <code class="backtick">while</code> loop. The third sets the variable to its next value. Some examples:</p>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"> <span class="co">/* count from 0 to 9 */</span>
+ <span class="kw">for</span>(i = <span class="dv">0</span>; i &lt; <span class="dv">10</span>; i++) {
+ printf(<span class="st">"%d</span><span class="ch">\n</span><span class="st">"</span>, i);
+ }
+
+ <span class="co">/* and back from 10 to 0 */</span>
+ <span class="kw">for</span>(i = <span class="dv">10</span>; i &gt;= <span class="dv">0</span>; i--) {
+ printf(<span class="st">"%d</span><span class="ch">\n</span><span class="st">"</span>, i);
+ }
+
+ <span class="co">/* this loop uses some functions to move around */</span>
+ <span class="kw">for</span>(c = firstCustomer(); c != END_OF_CUSTOMERS; c = customerAfter(c)) {
+ helpCustomer(c);
+ }
+
+ <span class="co">/* this loop prints powers of 2 that are less than n*/</span>
+ <span class="kw">for</span>(i = <span class="dv">1</span>; i &lt; n; i *= <span class="dv">2</span>) {
+ printf(<span class="st">"%d</span><span class="ch">\n</span><span class="st">"</span>, i);
+ }
+
+ <span class="co">/* this loop does the same thing with two variables by using the comma operator */</span>
+ <span class="kw">for</span>(i = <span class="dv">0</span>, power = <span class="dv">1</span>; power &lt; n; i++, power *= <span class="dv">2</span>) {
+ printf(<span class="st">"2^%d = %d</span><span class="ch">\n</span><span class="st">"</span>, i, power);
+ }
+
+ <span class="co">/* Here are some nested loops that print a times table */</span>
+ <span class="kw">for</span>(i = <span class="dv">0</span>; i &lt; n; i++) {
+ <span class="kw">for</span>(j = <span class="dv">0</span>; j &lt; n; j++) {
+ printf(<span class="st">"%d*%d=%d "</span>, i, j, i*j);
+ }
+ putchar(<span class="ch">'\n'</span>);
+ }</code></pre></div>
+<p>A <code class="backtick">for</code> loop can always be rewritten as a <code class="backtick">while</code> loop.</p>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"> <span class="kw">for</span>(i = <span class="dv">0</span>; i &lt; <span class="dv">10</span>; i++) {
+ printf(<span class="st">"%d</span><span class="ch">\n</span><span class="st">"</span>, i);
+ }
+
+ <span class="co">/* is exactly the same as */</span>
+
+ i = <span class="dv">0</span>;
+ <span class="kw">while</span>(i &lt; <span class="dv">10</span>) {
+ printf(<span class="st">"%d</span><span class="ch">\n</span><span class="st">"</span>, i);
+ i++;
+ }</code></pre></div>
+<h5 id="Loops_with_break.2C_continue.2C_and_goto"><span class="header-section-number">4.7.2.2.4</span> Loops with break, continue, and goto</h5>
+<p>The <code class="backtick">break</code> statement immediately exits the innermmost enclosing loop or <code class="backtick">switch</code> statement.</p>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"> <span class="kw">for</span>(i = <span class="dv">0</span>; i &lt; n; i++) {
+ openDoorNumber(i);
+ <span class="kw">if</span>(boobyTrapped()) {
+ <span class="kw">break</span>;
+ }
+ }</code></pre></div>
+<p>The <code class="backtick">continue</code> statement skips to the
+next iteration. Here is a program with a loop that iterates through all
+the integers from -10 through 10, skipping 0:</p>
+<div>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"><span class="ot">#include &lt;stdio.h&gt;</span>
+
+<span class="co">/* print a table of inverses */</span>
+<span class="ot">#define MAXN (10)</span>
+
+<span class="dt">int</span>
+main(<span class="dt">int</span> argc, <span class="dt">char</span> **argv)
+{
+ <span class="dt">int</span> n;
+
+ <span class="kw">for</span>(n = -MAXN; n &lt;= MAXN; n++) {
+ <span class="kw">if</span>(n == <span class="dv">0</span>) <span class="kw">continue</span>;
+ printf(<span class="st">"1.0/%3d = %+f</span><span class="ch">\n</span><span class="st">"</span>, n, <span class="fl">1.0</span>/n);
+ }
+
+ <span class="kw">return</span> <span class="dv">0</span>;
+}</code></pre></div>
+<a href="http://cs.yale.edu/homes/aspnes/classes/223/examples/statements/inverses.c" class="uri">examples/statements/inverses.c</a>
+</div>
+<p>Occasionally, one would like to break out of more than one nested loop. The way to do this is with a <code class="backtick">goto</code> statement.</p>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"> <span class="kw">for</span>(i = <span class="dv">0</span>; i &lt; n; i++) {
+ <span class="kw">for</span>(j = <span class="dv">0</span>; j &lt; n; j++) {
+ doSomethingTimeConsumingWith(i, j);
+ <span class="kw">if</span>(checkWatch() == OUT_OF_TIME) {
+ <span class="kw">goto</span> giveUp;
+ }
+ }
+ }
+giveUp:
+ puts(<span class="st">"done"</span>);</code></pre></div>
+<p>The target for the <code class="backtick">goto</code> is a <strong>label</strong>, which is just an identifier followed by a colon and a statement (the empty statement <code class="backtick">;</code> is ok).</p>
+<p>The <code class="backtick">goto</code> statement can be used to jump
+anywhere within the same function body, but breaking out of nested loops
+ is widely considered to be its only genuinely acceptable use in normal
+code.</p>
+<h4 id="Choosing_where_to_put_a_loop_exit"><span class="header-section-number">4.7.2.3</span> Choosing where to put a loop exit</h4>
+<p>Choosing where to put a loop exit is usually pretty obvious: you want
+ it after any code that you want to execute at least once, and before
+any code that you want to execute only if the termination test fails.</p>
+<p>If you know in advance what values you are going to be iterating over, you will most likely be using a <code class="backtick">for</code> loop:</p>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"><span class="kw">for</span>(i = <span class="dv">0</span>; i &lt; n; i++) {
+ a[i] = <span class="dv">0</span>;
+}</code></pre></div>
+<p>Most of the rest of the time, you will want a <code class="backtick">while</code> loop:</p>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"><span class="kw">while</span>(!done()) {
+ doSomething();
+}</code></pre></div>
+<p>The <code class="backtick">do</code>..<code class="backtick">while</code> loop comes up mostly when you want to try something, then try again if it failed:</p>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"><span class="kw">do</span> {
+ result = fetchWebPage(url);
+} <span class="kw">while</span>(result == <span class="dv">0</span>);</code></pre></div>
+<p>Finally, leaving a loop in the middle using <code class="backtick">break</code> can be handy if you have something extra to do before trying again:</p>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"><span class="kw">for</span>(;;) {
+ result = fetchWebPage(url);
+ <span class="kw">if</span>(result != <span class="dv">0</span>) {
+ <span class="kw">break</span>;
+ }
+ <span class="co">/* else */</span>
+ fprintf(stderr, <span class="st">"fetchWebPage failed with error code %03d</span><span class="ch">\n</span><span class="st">"</span>, result);
+ sleep(retryDelay); <span class="co">/* wait before trying again */</span>
+}</code></pre></div>
+<p>(Note the empty <code class="backtick">for</code> loop header means to loop forever; <code class="backtick">while(1)</code> also works.)</p>
+<h2 id="functions"><span class="header-section-number">4.8</span> Functions</h2>
+<p>A <strong>function</strong>, <strong>procedure</strong>, or <strong>subroutine</strong> encapsulates some complex computation as a single operation. Typically, when we <strong>call</strong> a function, we pass as <strong>arguments</strong> all the information this function needs, and any effect it has will be reflected in either its <strong>return value</strong>
+ or (in some cases) in changes to values pointed to by the arguments.
+Inside the function, the arguments are copied into local variables,
+which can be used just like any other local variable—they can even be
+assigned to without affecting the original argument.</p>
+<h3 id="functionDefinitions"><span class="header-section-number">4.8.1</span> Function definitions</h3>
+<p>A typical function definition looks like this:</p>
+<div>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"><span class="co">/* Returns the square of the distance between two points separated by </span>
+<span class="co"> dx in the x direction and dy in the y direction. */</span>
+<span class="dt">int</span>
+distSquared(<span class="dt">int</span> dx, <span class="dt">int</span> dy)
+{
+ <span class="kw">return</span> dx*dx + dy*dy;
+}</code></pre></div>
+<a href="http://cs.yale.edu/homes/aspnes/classes/223/examples/functions/distSquaredNoHeader.c" class="uri">examples/functions/distSquaredNoHeader.c</a>
+</div>
+<p>The part outside the braces is called the <strong>function declaration</strong>; the braces and their contents is the <strong>function body</strong>.</p>
+<p>Like most complex declarations in C, once you delete the type names
+the declaration looks like how the function is used: the name of the
+function comes before the parentheses and the arguments inside. The <code class="backtick">int</code>s
+ scattered about specify the type of the return value of the function
+(before the function name) and of the parameters (inside the parentheses
+ after the function name); these are used by the compiler to determine
+how to pass values in and out of the function and (usually for more
+complex types, since numerical types will often convert automatically)
+to detect type mismatches.</p>
+<p>If you want to define a function that doesn't return anything, declare its return type as <code class="backtick">void</code>. You should also declare a parameter list of <code class="backtick">void</code> if the function takes no arguments.</p>
+<div>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"><span class="co">/* Prints "hi" to stdout */</span>
+<span class="dt">void</span>
+helloWorld(<span class="dt">void</span>)
+{
+ puts(<span class="st">"hi"</span>);
+}</code></pre></div>
+<a href="http://cs.yale.edu/homes/aspnes/classes/223/examples/functions/helloWorld.c" class="uri">examples/functions/helloWorld.c</a>
+</div>
+<p>It is not strictly speaking an error to omit the second <code class="backtick">void</code> here. Putting <code class="backtick">void</code> in for the parameters tells the compiler to enforce that no arguments are passed in. If we had instead declared <code class="backtick">helloWorld</code> as</p>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"><span class="co">/* Prints "hi" to stdout */</span>
+<span class="dt">void</span>
+helloWorld() <span class="co">/* DANGER! */</span>
+{
+ puts(<span class="st">"hi"</span>);
+}</code></pre></div>
+<p>it would be possible to call it as</p>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"> helloWorld(<span class="st">"this is a bogus argument"</span>);</code></pre></div>
+<p>without causing an error. The reason is that a function declaration
+with no arguments means that the function can take an unspecified number
+ of arguments, and it's up to the user to make sure they pass in the
+right ones. There are good historical reasons for what may seem like
+obvious lack of sense in the design of the language here, and fixing
+this bug would break most C code written before 1989. But you shouldn't
+ever write a function declaration with an empty argument list, since you
+ want the compiler to know when something goes wrong.</p>
+<h3 id="functionIdeology"><span class="header-section-number">4.8.2</span> When to write a function</h3>
+<p>As with any kind of abstraction, there are two goals to making a function:</p>
+<ul>
+<li><strong>Encapsulation:</strong> If you have some task to carry out
+that is simple do describe from the outside but messy to understand from
+ the inside, wrapping it in a function lets somebody carry out this task
+ without having to know the details. This is also useful if you want to
+change the implementation later.</li>
+<li><strong>Code re-use:</strong> If you find yourself writing the same
+lines of code in several places (or worse, are tempted to copy a block
+of code to several places), you should probably put this code in a
+function (or perhaps more than one function, if there is no succinct way
+ to describe what this block of code is doing).</li>
+</ul>
+<p>Both of these goals may be trumped by the goal of making your code
+understandable. If you can't describe what a function is doing in a
+single, simple sentence, this is a sign that maybe you need to
+restructure your code. Having a function that does more than one thing
+(or does different thing depending on its arguments) is likely to lead
+to confusion. So, for example, this is not a good function definition:</p>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"><span class="co">/*** ### UGLY CODE AHEAD ### ***/</span>
+
+<span class="co">/*</span>
+<span class="co"> * If getMaximum is true, return maximum of x and y,</span>
+<span class="co"> * else return minimum.</span>
+<span class="co"> */</span>
+<span class="dt">int</span>
+computeMaximumOrMinimum(<span class="dt">int</span> x, <span class="dt">int</span> y, <span class="dt">int</span> getMaximum)
+{
+ <span class="kw">if</span>(x &gt; y) {
+ <span class="kw">if</span>(getMaximum) {
+ <span class="kw">return</span> x;
+ } <span class="kw">else</span> {
+ <span class="kw">return</span> y;
+ }
+ } <span class="kw">else</span> {
+ <span class="kw">if</span>(getMaximum) {
+ <span class="kw">return</span> y;
+ } <span class="kw">else</span> {
+ <span class="kw">return</span> x;
+ }
+ }
+}</code></pre></div>
+<p>Better would be to write two functions:</p>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"><span class="co">/* return the maximum of x and y */</span>
+<span class="dt">int</span>
+maximum(<span class="dt">int</span> x, <span class="dt">int</span> y)
+{
+ <span class="kw">if</span>(x &gt; y) {
+ <span class="kw">return</span> x;
+ } <span class="kw">else</span> {
+ <span class="kw">return</span> y;
+ }
+}
+
+<span class="co">/* return the minimum of x and y */</span>
+<span class="dt">int</span>
+minimum(<span class="dt">int</span> x, <span class="dt">int</span> y)
+{
+ <span class="kw">if</span>(x &lt; y) {
+ <span class="kw">return</span> x;
+ } <span class="kw">else</span> {
+ <span class="kw">return</span> y;
+ }
+}</code></pre></div>
+<p>At the same time, it's possible for a function to be too simple. Suppose I write the function</p>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"><span class="co">/* print x to stdout followed by a newline */</span>
+<span class="dt">void</span>
+printIntWithNewline(<span class="dt">int</span> x)
+{
+ printf(<span class="st">"%d</span><span class="ch">\n</span><span class="st">"</span>, x);
+}</code></pre></div>
+<p>It's pretty clear from the name what this function does. But since anybody who has been using C for a while has seen <code>printf("%d\n", ...)</code> over and over again, it's usually more clear to expand out the definition:</p>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"> printIntWithNewline(<span class="dv">2+5</span>); <span class="co">/* this could do anything */</span>
+ printf(<span class="st">"%d</span><span class="ch">\n</span><span class="st">"</span>, <span class="dv">2+7</span>); <span class="co">/* this does exactly what it says */</span></code></pre></div>
+<p>As with all caveats, this caveat comes with its own caveat: what
+might justify a function like this is if you want to be able to do some
+kind of specialized formatting that should be consistent for all values
+of a particular form. So you might write a <code>printDistance</code> function like the above as a stub for a fancier function that might use different units at different scales or something.</p>
+<p>A similar issue will come up with <a href="#nonSyntacticMacros">non-syntactic macros</a>,
+ which also tend to fail the "does this make my code more or less
+understandable" test. Usually it is a bad idea to try to replace common C
+ idioms.</p>
+<h3 id="Calling_a_function"><span class="header-section-number">4.8.3</span> Calling a function</h3>
+<p>A function call consists of the function followed by its arguments
+(if any) inside parentheses, separated by comments. For a function with
+no arguments, call it with nothing between the parentheses. A function
+call that returns a value can be used in an expression just like a
+variable. A call to a <code class="backtick">void</code> function can only be used as an expression by itself:</p>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"> totalDistance += distSquared(x1 - x2, y1 - y2);
+ helloWorld();
+ greetings += helloWorld(); <span class="co">/* ERROR */</span></code></pre></div>
+<h3 id="The_return_statement"><span class="header-section-number">4.8.4</span> The return statement</h3>
+<p>To return a value from a function, write a <code class="backtick">return</code> statement, e.g.</p>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"> <span class="kw">return</span> <span class="dv">172</span>;</code></pre></div>
+<p>The argument to <code class="backtick">return</code> can be any expression. Unlike the expression in, say, an <code class="backtick">if</code> statement, you do not need to wrap it in parentheses. If a function is declared <code class="backtick">void</code>, you can do a <code class="backtick">return</code> with no expression, or just let control reach the end of the function.</p>
+<p>Executing a <code class="backtick">return</code> statement immediately terminates the function. This can be used like <code class="backtick">break</code> to get out of loops early.</p>
+<div>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"><span class="co">/* returns 1 if n is prime, 0 otherwise */</span>
+<span class="dt">int</span>
+isPrime(<span class="dt">int</span> n)
+{
+ <span class="dt">int</span> i;
+
+ <span class="kw">if</span> (n &lt; <span class="dv">2</span>) <span class="kw">return</span> <span class="dv">0</span>; <span class="co">/* special case for 0, 1, negative n */</span>
+
+ <span class="kw">for</span>(i = <span class="dv">2</span>; i &lt; n; i++) {
+ <span class="kw">if</span> (n % i == <span class="dv">0</span>) {
+ <span class="co">/* found a factor */</span>
+ <span class="kw">return</span> <span class="dv">0</span>;
+ }
+ }
+
+ <span class="co">/* no factors */</span>
+ <span class="kw">return</span> <span class="dv">1</span>;
+}</code></pre></div>
+<a href="http://cs.yale.edu/homes/aspnes/classes/223/examples/functions/isPrime.c" class="uri">examples/functions/isPrime.c</a>
+</div>
+<h3 id="Function_declarations_and_modules"><span class="header-section-number">4.8.5</span> Function declarations and modules</h3>
+<p>By default, functions have <strong>global scope</strong>: they can be used anywhere in your program, even in other files. If a file doesn't contain a declaration for a function <code class="backtick">someFunc</code> before it is used, the compiler will assume that it is declared like <code class="backtick">int&nbsp;someFunc()</code> (i.e., return type <code class="backtick">int</code>
+ and unknown arguments). This can produce infuriating complaints later
+when the compiler hits the real declaration and insists that your
+function <code class="backtick">someFunc</code> should be returning an <code class="backtick">int</code> and you are a bonehead for declaring it otherwise.</p>
+<p>The solution to such insulting compiler behavior errors is to either
+(a) move the function declaration before any functions that use it; or
+(b) put in a declaration without a body before any functions that use
+it, in addition to the declaration that appears in the function
+definition. (Note that this violates the <strong>no separate but equal</strong>
+ rule, but the compiler should tell you when you make a mistake.) Option
+ (b) is generally preferred, and is the only option when the function is
+ used in a different file.</p>
+<p>To make sure that all declarations of a function are consistent, the
+usual practice is to put them in an include file. For example, if <code class="backtick">distSquared</code> is used in a lot of places, we might put it in its own file <code class="backtick">distSquared.c</code>:</p>
+<div>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"><span class="ot">#include "distSquared.h"</span>
+
+<span class="dt">int</span>
+distSquared(<span class="dt">int</span> dx, <span class="dt">int</span> dy)
+{
+ <span class="kw">return</span> dx*dx + dy*dy;
+}</code></pre></div>
+<a href="http://cs.yale.edu/homes/aspnes/classes/223/examples/functions/distSquared.c" class="uri">examples/functions/distSquared.c</a>
+</div>
+<p>The file <code>distSquared.c</code> above uses <code class="backtick">#include</code> to include a copy of the following header file <code>distSquared.h</code>:</p>
+<div>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"><span class="co">/* Returns the square of the distance between two points separated by </span>
+<span class="co"> dx in the x direction and dy in the y direction. */</span>
+<span class="dt">int</span> distSquared(<span class="dt">int</span> dx, <span class="dt">int</span> dy);</code></pre></div>
+<a href="http://cs.yale.edu/homes/aspnes/classes/223/examples/functions/distSquared.h" class="uri">examples/functions/distSquared.h</a>
+</div>
+<p>Note that the declaration in <code class="backtick">distSquared.h</code>
+ doesn't have a body. Instead, it's terminated by a semicolon, like a
+variable declaration. It's also worth noting that we moved the
+documenting comment to <code class="backtick">distSquared.h</code>: the idea is that <code class="backtick">distSquared.h</code> is the public face of this (very small one-function) module, and so the explanation of how to use the function should be there.</p>
+<p>The reason <code class="backtick">distSquared.c</code> includes <code class="backtick">distSquared.h</code> is to get the compiler to verify that the declarations in the two files match. But to use the <code class="backtick">distSquared</code> function, we also put <code class="backtick">#include&nbsp;"distSquared.h"</code> at the top of the file that uses it:</p>
+<div>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"><span class="ot">#include "distSquared.h"</span>
+
+<span class="ot">#define THRESHOLD (100)</span>
+
+<span class="dt">int</span>
+tooClose(<span class="dt">int</span> x1, <span class="dt">int</span> y1, <span class="dt">int</span> x2, <span class="dt">int</span> y2)
+{
+ <span class="kw">return</span> distSquared(x1 - x2, y1 - y2) &lt; THRESHOLD;
+}</code></pre></div>
+<a href="http://cs.yale.edu/homes/aspnes/classes/223/examples/functions/tooClose.c" class="uri">examples/functions/tooClose.c</a>
+</div>
+<p>The <code class="backtick">#include</code> on line 1 uses double quotes instead of angle brackets; this tells the compiler to look for <code class="backtick">distSquared.h</code> in the current directory instead of the system include directory (typically <code class="backtick">/usr/include</code>).</p>
+<h3 id="Static_functions"><span class="header-section-number">4.8.6</span> Static functions</h3>
+<p>By default, all functions are global; they can be used in any file of
+ your program whether or not a declaration appears in a header file. To
+restrict access to the current file, declare a function <code class="backtick">static</code>, like this:</p>
+<div>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"><span class="dt">static</span> <span class="dt">void</span>
+helloHelper(<span class="dt">void</span>)
+{
+ puts(<span class="st">"hi!"</span>);
+}
+
+<span class="dt">void</span>
+hello(<span class="dt">int</span> repetitions)
+{
+ <span class="dt">int</span> i;
+
+ <span class="kw">for</span>(i = <span class="dv">0</span>; i &lt; repetitions; i++) {
+ helloHelper();
+ }
+}</code></pre></div>
+<a href="http://cs.yale.edu/homes/aspnes/classes/223/examples/functions/staticHello.c" class="uri">examples/functions/staticHello.c</a>
+</div>
+<p>The function <code class="backtick">hello</code> will be visible everywhere. The function <code class="backtick">helloHelper</code> will only be visible in the current file.</p>
+<p>It's generally good practice to declare a function static unless you intend to make it available, since not doing so can cause <strong>namespace conflicts</strong>,
+ where the presence of two functions with the same name either prevent
+the program from linking or—even worse—cause the wrong function to be
+called. The latter can happen with library functions, since C allows the
+ programmer to override library functions by defining a new function
+with the same name. Early on in my career as a C programmer, I once had a
+ program fail in a spectacularly incomprehensible way because I'd
+written a <code class="backtick">select</code> function without realizing that <code class="backtick">select</code> is a core library function in Unix.</p>
+<h3 id="Local_variables"><span class="header-section-number">4.8.7</span> Local variables</h3>
+<p>A function may contain definitions of <strong>local variables</strong>,
+ which are visible only inside the function and which survive only until
+ the function returns. These may be declared at the start of any block
+(group of statements enclosed by braces), but it is conventional to
+declare all of them at the outermost block of the function.</p>
+<div>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"><span class="co">/* Given n, compute n! = 1*2*...*n */</span>
+<span class="co">/* Warning: will overflow on 32-bit machines if n &gt; 12 */</span>
+<span class="dt">int</span>
+factorial(<span class="dt">int</span> n)
+{
+ <span class="dt">int</span> i;
+ <span class="dt">int</span> product;
+
+ <span class="kw">if</span>(n &lt; <span class="dv">2</span>) <span class="kw">return</span> n;
+ <span class="co">/* else */</span>
+
+ product = <span class="dv">1</span>;
+
+ <span class="kw">for</span>(i = <span class="dv">2</span>; i &lt;= n; i++) {
+ product *= i;
+ }
+
+ <span class="kw">return</span> product;
+}</code></pre></div>
+<a href="http://cs.yale.edu/homes/aspnes/classes/223/examples/functions/factorial.c" class="uri">examples/functions/factorial.c</a>
+</div>
+<h3 id="Mechanics_of_function_calls"><span class="header-section-number">4.8.8</span> Mechanics of function calls</h3>
+<p>Several things happen under the hood when a function is called. Since
+ a function can be called from several different places, the CPU needs
+to store its previous state to know where to go back. It also needs to
+allocate space for function arguments and local variables.</p>
+<p>Some of this information will be stored in <strong>registers</strong>, memory locations built into the CPU itself, but most will go on the <strong>stack</strong>,
+ a region of memory that on typical machines grows downward, even though
+ the most recent additions to the stack are called the "top" of the
+stack. The location of the top of the stack is stored in the CPU in a
+special register called the <strong>stack pointer</strong>.</p>
+<p>So a typical function call looks like this internally:</p>
+<ol style="list-style-type: decimal">
+<li>The current <strong>instruction pointer</strong> or <strong>program counter</strong> value, which gives the address of the next line of machine code to be executed, is pushed onto the stack.</li>
+<li>Any arguments to the function are copied either into specially
+designated registers or onto new locations on the stack. The exact rules
+ for how to do this vary from one CPU architecture to the next, but a
+typical convention might be that the first few arguments are copied into
+ registers and the rest (if any) go on the stack.</li>
+<li>The instruction pointer is set to the first instruction in the code for the function.</li>
+<li>The code for the function allocates additional space on the stack to
+ hold its local variables (if any) and to save copies of the values of
+any registers it wants to use (so that it can restore their contents
+before returning to its caller).</li>
+<li>The function body is executed until it hits a <code class="backtick">return</code> statement.</li>
+<li>Returning from the function is the reverse of invoking it: any saved
+ registers are restored from the stack, the return value is copied to a
+standard register, and the values of the instruction pointer and stack
+pointer are restored to what they were before the function call.</li>
+</ol>
+<p>From the programmer's perspective, the important point is that both
+the arguments and the local variables inside a function are stored in
+freshly-allocated locations that are thrown away after the function
+exits. So after a function call the state of the CPU is restored to its
+previous state, except for the return value. Any arguments that are
+passed to a function are passed as copies, so changing the values of the
+ function arguments inside the function has no effect on the caller. Any
+ information stored in local variables is lost.</p>
+<p>Under very rare circumstances, it may be useful to have a variable
+local to a function that persists from one function call to the next.
+You can do so by declaring the variable <code class="backtick">static</code>. For example, here is a function that counts how many times it has been called:</p>
+<div>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"><span class="co">/* return the number of times the function has been called */</span>
+<span class="dt">int</span>
+counter(<span class="dt">void</span>)
+{
+ <span class="dt">static</span> count = <span class="dv">0</span>;
+
+ <span class="kw">return</span> ++count;
+}</code></pre></div>
+<a href="http://cs.yale.edu/homes/aspnes/classes/223/examples/functions/staticCounter.c" class="uri">examples/functions/staticCounter.c</a>
+</div>
+<p>Static local variables are stored outside the stack with global
+variables, and have unbounded extent. But they are only visible inside
+the function that declares them. This makes them slightly less dangerous
+ than global variables—there is no fear that some foolish bit of code
+elsewhere will quietly change their value—but it is still the case that
+they usually aren't what you want. It is also likely that operations on
+static variables will be slightly slower than operations on ordinary
+("automatic") variables, since making them persistent means that they
+have to be stored in (slow) main memory instead of (fast) registers.</p>
+<h2 id="pointers"><span class="header-section-number">4.9</span> Pointers</h2>
+<h3 id="addressSpace"><span class="header-section-number">4.9.1</span> Memory and addresses</h3>
+<p>Memory in a typical modern computer is divided into two classes: a small number of <strong>registers</strong>,
+ which live on the CPU chip and perform specialized functions like
+keeping track of the location of the next machine code instruction to
+execute or the current stack frame, and <strong>main memory</strong>,
+which (mostly) lives outside the CPU chip and which stores the code and
+data of a running program. When the CPU wants to fetch a value from a
+particular location in main memory, it must supply an address: a 32-bit
+or 64-bit unsigned integer on typical current architectures, referring
+to one of up to 2<sup>32</sup> or 2<sup>64</sup> distinct 8-bit locations in the memory. These integers can be manipulated like any other integer; in C, they appear as <strong>pointers</strong>, a family of types that can be passed as arguments, stored in variables, returned from functions, etc.</p>
+<h3 id="Pointer_variables"><span class="header-section-number">4.9.2</span> Pointer variables</h3>
+<p>A <strong>pointer variable</strong> is a variable that holds a pointer, just like an <code>int</code> variable is a variable that holds an <code>int</code>.</p>
+<h4 id="Declaring_a_pointer_variable"><span class="header-section-number">4.9.2.1</span> Declaring a pointer variable</h4>
+<p>The convention is C is that the declaration of a complex type looks
+like its use. To declare a pointer-valued variable, write a declaration
+for the thing that it points to, but include a <code class="backtick">*</code> before the variable name:</p>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"> <span class="dt">int</span> *pointerToInt;
+ <span class="dt">double</span> *pointerToDouble;
+ <span class="dt">char</span> *pointerToChar;
+ <span class="dt">char</span> **pointerToPointerToChar;</code></pre></div>
+<p>These declarations create four pointer variables, named <code>pointerToInt</code>, <code>pointerToDouble</code>, <code>pointerToChar</code>, and <code>pointerToPointerToChar</code>. On a typical 64-bit machine, each will be allocated 8 bytes, enough to represent an address in memory.</p>
+<p>The contents of these variables are initially arbitrary: to use them,
+ you will need to compute the address of something and assign it to the
+variable.</p>
+<h4 id="Assigning_to_pointer_variables"><span class="header-section-number">4.9.2.2</span> Assigning to pointer variables</h4>
+<p>Declaring a pointer-valued variable allocates space to hold the pointer but <em>not</em>
+ to hold anything it points to. Like any other variable in C, a
+pointer-valued variable will initially contain garbage—in this case, the
+ address of a location that might or might not contain something
+important. To initialize a pointer variable, you have to assign to it
+the address of something that already exists. Typically this is done
+using the <code class="backtick">&amp;</code> (<strong>address-of</strong>) operator:</p>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"> <span class="dt">int</span> n; <span class="co">/* an int variable */</span>
+ <span class="dt">int</span> *p; <span class="co">/* a pointer to an int */</span>
+
+ p = &amp;n; <span class="co">/* p now points to n */</span></code></pre></div>
+<h4 id="Using_a_pointer"><span class="header-section-number">4.9.2.3</span> Using a pointer</h4>
+<p>Pointer variables can be used in two ways. The simplest way is to get
+ their value as with any other variable. This value will be an address,
+which can be stored in another pointer variable of the same type.</p>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"> <span class="dt">int</span> n; <span class="co">/* an int variable */</span>
+ <span class="dt">int</span> *p; <span class="co">/* a pointer to an int */</span>
+ <span class="dt">int</span> *q; <span class="co">/* another pointer to an int */</span>
+
+ p = &amp;n; <span class="co">/* p now points to n */</span>
+ q = p; <span class="co">/* q now points to n as well */</span></code></pre></div>
+<p>But more often you will want to work on the value stored at the location pointed to. You can do this by using the <code class="backtick">*</code> (<strong>dereference</strong>) operator, which acts as an inverse of the address-of operator:</p>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"> <span class="dt">int</span> n; <span class="co">/* an int variable */</span>
+ <span class="dt">int</span> *p; <span class="co">/* a pointer to an int */</span>
+
+ p = &amp;n; <span class="co">/* p now points to n */</span>
+
+ *p = <span class="dv">2</span>; <span class="co">/* sets n to 2 */</span>
+ *p = *p + *p; <span class="co">/* sets n to 4 */</span></code></pre></div>
+<p>The <code class="backtick">*</code> operator binds very tightly, so you can usually use <code class="backtick">*p</code> anywhere you could use the variable it points to without worrying about parentheses. However, a few operators, such as the <code class="backtick">--</code> and <code class="backtick">++</code> operators and the <code class="backtick">.</code> operator used to unpack <a href="#structs">structs</a>, bind tighter. These require parentheses if you want the <code class="backtick">*</code> to take precedence.</p>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"> (*p)++; <span class="co">/* increment the value pointed to by p */</span>
+ *p++; <span class="co">/* WARNING: increments p itself */</span></code></pre></div>
+<h4 id="Printing_pointers"><span class="header-section-number">4.9.2.4</span> Printing pointers</h4>
+<p>You can print a pointer value using <code class="backtick">printf</code> with the <code class="backtick">%p</code> format specifier. To do so, you should convert the pointer to type <code class="backtick">void&nbsp;*</code> first using a cast (see below for <code class="backtick">void&nbsp;*</code>
+ pointers), although on machines that don't have different
+representations for different pointer types, this may not be necessary.</p>
+<p>Here is a short program that prints out some pointer values:</p>
+<div>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"><span class="ot">#include &lt;stdio.h&gt;</span>
+<span class="ot">#include &lt;stdlib.h&gt;</span>
+
+<span class="dt">int</span> G = <span class="dv">0</span>; <span class="co">/* a global variable, stored in BSS segment */</span>
+
+<span class="dt">int</span>
+main(<span class="dt">int</span> argc, <span class="dt">char</span> **argv)
+{
+ <span class="dt">static</span> <span class="dt">int</span> s; <span class="co">/* static local variable, stored in BSS segment */</span>
+ <span class="dt">int</span> a; <span class="co">/* automatic variable, stored on stack */</span>
+ <span class="dt">int</span> *p; <span class="co">/* pointer variable for malloc below */</span>
+
+ <span class="co">/* obtain a block big enough for one int from the heap */</span>
+ p = malloc(<span class="kw">sizeof</span>(<span class="dt">int</span>));
+
+ printf(<span class="st">"&amp;G = %p</span><span class="ch">\n</span><span class="st">"</span>, (<span class="dt">void</span> *) &amp;G);
+ printf(<span class="st">"&amp;s = %p</span><span class="ch">\n</span><span class="st">"</span>, (<span class="dt">void</span> *) &amp;s);
+ printf(<span class="st">"&amp;a = %p</span><span class="ch">\n</span><span class="st">"</span>, (<span class="dt">void</span> *) &amp;a);
+ printf(<span class="st">"&amp;p = %p</span><span class="ch">\n</span><span class="st">"</span>, (<span class="dt">void</span> *) &amp;p);
+ printf(<span class="st">"p = %p</span><span class="ch">\n</span><span class="st">"</span>, (<span class="dt">void</span> *) p);
+ printf(<span class="st">"main = %p</span><span class="ch">\n</span><span class="st">"</span>, (<span class="dt">void</span> *) main);
+
+ free(p);
+
+ <span class="kw">return</span> <span class="dv">0</span>;
+}</code></pre></div>
+<a href="http://cs.yale.edu/homes/aspnes/classes/223/examples/pointers/lookingAtPointers.c" class="uri">examples/pointers/lookingAtPointers.c</a>
+</div>
+<p>When I run this on a Mac OS X 10.6 machine after compiling with <code class="backtick">gcc</code>, the output is:</p>
+<pre><code>&amp;G = 0x100001078
+&amp;s = 0x10000107c
+&amp;a = 0x7fff5fbff2bc
+&amp;p = 0x7fff5fbff2b0
+p = 0x100100080
+main = 0x100000e18</code></pre>
+<p>The interesting thing here is that we can see how the compiler
+chooses to allocate space for variables based on their storage classes.
+The global variable <code class="backtick">G</code> and the static local variable <code class="backtick">s</code> both persist between function calls, so they get placed in the BSS segment (see <a href="http://en.wikipedia.org/wiki/.bss" title="WikiPedia">.bss</a>) that starts somewhere around <code class="backtick">0x100000000</code>, typically after the code segment containing the actual code of the program. Local variables <code class="backtick">a</code> and <code class="backtick">p</code> are allocated on the stack, which grows down from somewhere near the top of the address space. The block returned from <code class="backtick">malloc</code> that <code class="backtick">p</code>
+ points to is allocated off the heap, a region of memory that may also
+grow over time and starts after the BSS segment. Finally, <code class="backtick">main</code> appears at 0x100000e18; this is in the code segment, which is a bit lower in memory than all the global variables.</p>
+<h3 id="The_null_pointer"><span class="header-section-number">4.9.3</span> The null pointer</h3>
+<p>The special value <code class="backtick">0</code>, known as the <strong>null pointer</strong>, may be assigned to a pointer of any type. It may or may not be represented by the actual address <code class="backtick">0</code>, but it will act like <code class="backtick">0</code> in all contexts (e.g., it has the value false in an <code class="backtick">if</code> or <code class="backtick">while</code>
+ statement). Null pointers are often used to indicate missing data or
+failed functions. Attempting to dereference a null pointer can have
+catastrophic effects, so it's important to be aware of when you might be
+ supplied with one.</p>
+<h3 id="Pointers_and_functions"><span class="header-section-number">4.9.4</span> Pointers and functions</h3>
+<p>A simple application of pointers is to get around C's limit on having
+ only one return value from a function. Because C arguments are copied,
+assigning a value to an argument inside a function has no effect on the
+outside. So the <code class="backtick">doubler</code> function below doesn't do much:</p>
+<div>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"><span class="ot">#include &lt;stdio.h&gt;</span>
+
+<span class="co">/* doesn't work */</span>
+<span class="dt">void</span>
+doubler(<span class="dt">int</span> x)
+{
+ x *= <span class="dv">2</span>;
+}
+
+<span class="dt">int</span>
+main(<span class="dt">int</span> argc, <span class="dt">char</span> **argv)
+{
+ <span class="dt">int</span> y;
+
+ y = <span class="dv">1</span>;
+
+ doubler(y); <span class="co">/* no effect on y */</span>
+
+ printf(<span class="st">"%d</span><span class="ch">\n</span><span class="st">"</span>, y); <span class="co">/* prints 1 */</span>
+
+ <span class="kw">return</span> <span class="dv">0</span>;
+}</code></pre></div>
+<a href="http://cs.yale.edu/homes/aspnes/classes/223/examples/pointers/badDoubler.c" class="uri">examples/pointers/badDoubler.c</a>
+</div>
+<p>However, if instead of passing the value of <code class="backtick">y</code> into <code class="backtick">doubler</code> we pass a pointer to <code class="backtick">y</code>, then the <code class="backtick">doubler</code> function can reach out of its own stack frame to manipulate <code class="backtick">y</code> itself:</p>
+<div>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"><span class="ot">#include &lt;stdio.h&gt;</span>
+
+<span class="dt">void</span>
+doubler(<span class="dt">int</span> *x)
+{
+ *x *= <span class="dv">2</span>;
+}
+
+<span class="dt">int</span>
+main(<span class="dt">int</span> argc, <span class="dt">char</span> **argv)
+{
+ <span class="dt">int</span> y;
+
+ y = <span class="dv">1</span>;
+
+ doubler(&amp;y); <span class="co">/* sets y to 2 */</span>
+
+ printf(<span class="st">"%d</span><span class="ch">\n</span><span class="st">"</span>, y); <span class="co">/* prints 2 */</span>
+
+ <span class="kw">return</span> <span class="dv">0</span>;
+}</code></pre></div>
+<a href="http://cs.yale.edu/homes/aspnes/classes/223/examples/pointers/goodDoubler.c" class="uri">examples/pointers/goodDoubler.c</a>
+</div>
+<p>Generally, if you pass the value of a variable into a function (with no <code class="backtick">&amp;</code>),
+ you can be assured that the function can't modify your original
+variable. When you pass a pointer, you should assume that the function
+can and will change the variable's value. If you want to write a
+function that takes a pointer argument but promises not to modify the
+target of the pointer, use <code class="backtick">const</code>, like this:</p>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"><span class="dt">void</span>
+printPointerTarget(<span class="dt">const</span> <span class="dt">int</span> *p)
+{
+ printf(<span class="st">"%d</span><span class="ch">\n</span><span class="st">"</span>, *p);
+}</code></pre></div>
+<p>The <code class="backtick">const</code> qualifier tells the compiler
+that the target of the pointer shouldn't be modified. This will cause it
+ to return an error if you try to assign to it anyway:</p>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"><span class="dt">void</span>
+printPointerTarget(<span class="dt">const</span> <span class="dt">int</span> *p)
+{
+ *p = <span class="dv">5</span>; <span class="co">/* produces compile-time error */</span>
+ printf(<span class="st">"%d</span><span class="ch">\n</span><span class="st">"</span>, *p);
+}</code></pre></div>
+<p>Passing <code class="backtick">const</code> pointers is mostly used
+when passing large structures to functions, where copying a 32-bit
+pointer is cheaper than copying the thing it points to.</p>
+<p>If you really want to modify the target anyway, C lets you "cast away <code class="backtick">const</code>":</p>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"><span class="dt">void</span>
+printPointerTarget(<span class="dt">const</span> <span class="dt">int</span> *p)
+{
+ *((<span class="dt">int</span> *) p) = <span class="dv">5</span>; <span class="co">/* no compile-time error */</span>
+ printf(<span class="st">"%d</span><span class="ch">\n</span><span class="st">"</span>, *p);
+}</code></pre></div>
+<p>There is usually no good reason to do this. The one exception might be if the target of the pointer represents an <a href="#abstractDataTypes">abstract data type</a>,
+ and you want to modify its representation during some operation to
+optimize things somehow in a way that will not be visible outside the
+abstraction barrier, making it appear to leave the target constant.</p>
+<p>Note that while it is safe to pass pointers down into functions, it
+is very dangerous to pass pointers up. The reason is that the space used
+ to hold any local variable of the function will be reclaimed when the
+function exits, but the pointer will still point to the same location, <em>even though something else may now be stored there</em>. So this function is very dangerous:</p>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"><span class="dt">int</span> *
+dangerous(<span class="dt">void</span>)
+{
+ <span class="dt">int</span> n;
+
+ <span class="kw">return</span> &amp;n; <span class="co">/* NO! */</span>
+}
+
+...
+
+ *dangerous() = <span class="dv">12</span>; <span class="co">/* writes 12 to some unknown location */</span></code></pre></div>
+<p>An exception is when you can guarantee that the location pointed to
+will survive even after the function exits, e.g. when the location is
+dynamically allocated using <code class="backtick">malloc</code> (see below) or when the local variable is declared <code class="backtick">static</code>:</p>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"><span class="dt">int</span> *
+returnStatic(<span class="dt">void</span>)
+{
+ <span class="dt">static</span> <span class="dt">int</span> n;
+
+ <span class="kw">return</span> &amp;n;
+}
+
+...
+
+ *returnStatic() = <span class="dv">12</span>; <span class="co">/* writes 12 to the hidden static variable */</span></code></pre></div>
+<p>Usually returning a pointer to a <code class="backtick">static</code>
+ local variable is not good practice, since the point of making a
+variable local is to keep outsiders from getting at it. If you find
+yourself tempted to do this, a better approach is to allocate a new
+block using <code class="backtick">malloc</code> (see below) and return a pointer to that. The downside of the <code class="backtick">malloc</code> method is that the caller has to promise to call <code class="backtick">free</code> on the block later, or you will get a storage leak.</p>
+<h3 id="pointerArithmetic"><span class="header-section-number">4.9.5</span> Pointer arithmetic and arrays</h3>
+<p>Because pointers are just numerical values, one can do arithmetic on them. Specifically, it is permitted to</p>
+<ul>
+<li>Add an integer to a pointer or subtract an integer from a pointer. The effect of <code class="backtick">p+n</code> where <code class="backtick">p</code> is a pointer and <code class="backtick">n</code> is an integer is to compute the address equal to <code class="backtick">p</code> plus <code class="backtick">n</code> times the size of whatever <code class="backtick">p</code> points to (this is why <code class="backtick">int&nbsp;*</code> pointers and <code class="backtick">char&nbsp;*</code> pointers aren't the same).</li>
+<li>Subtract one pointer from another. The two pointers must have the same type (e.g. both <code class="backtick">int&nbsp;*</code> or both <code class="backtick">char&nbsp;*</code>). The result is a signed integer value of type <a href="#sizeTypes"><code>ptrdiff_t</code></a>, equal to the numerical difference between the addresses divided by the size of the objects pointed to.</li>
+<li>Compare two pointers using <code class="backtick">==</code>, <code class="backtick">!=</code>, <code class="backtick">&lt;</code>, <code class="backtick">&gt;</code>, <code class="backtick">&lt;=</code>, or <code class="backtick">&gt;=</code>.</li>
+<li>Increment or decrement a pointer using <code class="backtick">++</code> or <code class="backtick">--</code>.</li>
+</ul>
+<h4 id="arrays"><span class="header-section-number">4.9.5.1</span> Arrays</h4>
+<p>The main application of pointer arithmetic in C is in <strong>arrays</strong>.
+ An array is a block of memory that holds one or more objects of a given
+ type. It is declared by giving the type of object the array holds
+followed by the array name and the size in square brackets:</p>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"> <span class="dt">int</span> a[<span class="dv">50</span>]; <span class="co">/* array of 50 ints */</span>
+ <span class="dt">char</span> *cp[<span class="dv">100</span>]; <span class="co">/* array of 100 pointers to char */</span></code></pre></div>
+<p>Declaring an array allocates enough space to hold the specified number of objects (e.g. 200 bytes for <code class="backtick">a</code> above and 400 for <code class="backtick">cp</code>—note that a <code class="backtick">char&nbsp;*</code> is an address, so it is much bigger than a <code class="backtick">char</code>). The number inside the square brackets must be a constant whose value can be determined at compile time.</p>
+<p>The array name acts like a constant pointer to the zeroth element of
+the array. It is thus possible to set or read the zeroth element using <code class="backtick">*a</code>. But because the array name is constant, you can't assign to it:</p>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"> <span class="dv">1</span> *a = <span class="dv">12</span>; <span class="co">/* sets zeroth element to 12 */</span>
+ <span class="dv">2</span>
+ <span class="dv">3</span> a = &amp;n; <span class="co">/* #### DOESN'T WORK #### */</span></code></pre></div>
+<p>More common is to use square brackets to refer to a particular element of the array. The expression <code class="backtick">a[n]</code> is defined to be equivalent to <code class="backtick">*(a+n)</code>; the <strong>index</strong> <code class="backtick">n</code> (an integer) is added to the base of the array (a pointer), to get to the location of the <code class="backtick">n</code>-th element of <code class="backtick">a</code>. The implicit <code class="backtick">*</code>
+ then dereferences this location so that you can read its value (in a
+normal expression) or assign to it (on the left-hand side of an
+assignment operator). The effect is to allow you to use <code class="backtick">a[n]</code> just as you would any other variable of type <code class="backtick">int</code> (or whatever type <code class="backtick">a</code> was declared as).</p>
+<p>Note that C doesn't do any sort of bounds checking. Given the declaration <code class="backtick">int&nbsp;a[50];</code>, only indices from <code class="backtick">a[0]</code> to <code class="backtick">a[49]</code> can be used safely. However, the compiler will not blink at <code class="backtick">a[-12]</code> or <code class="backtick">a[10000]</code>.
+ If you read from such a location you will get garbage data; if you
+write to it, you will overwrite god-knows-what, possibly trashing some
+other variable somewhere else in your program or some critical part of
+the stack (like the location to jump to when you return from a
+function). It is up to you as a programmer to avoid such <strong>buffer overruns</strong>, which can lead to very mysterious (and in the case of code that gets input from a network, security-damaging) bugs. The <a href="#valgrind">valgrind</a> program can help detect such overruns in some cases.</p>
+<p>Another curious feature of the definition of <code class="backtick">a[n]</code> as identical to <code class="backtick">*(a+n)</code> is that it doesn't actually matter which of the array name or the index goes inside the braces. So all of <code class="backtick">a[0]</code>, <code class="backtick">*a</code>, and <code class="backtick">0[a]</code> refer to the zeroth entry in <code class="backtick">a</code>. Unless you are deliberately trying to obfuscate your code, it's best to write what you mean.</p>
+<h4 id="arraysAndFunctions"><span class="header-section-number">4.9.5.2</span> Arrays and functions</h4>
+<p>Because array names act like pointers, they can be passed into
+functions that expect pointers as their arguments. For example, here is a
+ function that computes the sum of all the values in an array <code class="backtick">a</code> of size <code class="backtick">n</code>:</p>
+<div>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"><span class="co">/* compute the sum of the first n elements of array a */</span>
+<span class="dt">int</span>
+sumArray(<span class="dt">int</span> n, <span class="dt">const</span> <span class="dt">int</span> *a)
+{
+ <span class="dt">int</span> i;
+ <span class="dt">int</span> sum;
+
+ sum = <span class="dv">0</span>;
+ <span class="kw">for</span>(i = <span class="dv">0</span>; i &lt; n; i++) {
+ sum += a[i];
+ }
+
+ <span class="kw">return</span> sum;
+}</code></pre></div>
+<a href="http://cs.yale.edu/homes/aspnes/classes/223/examples/pointers/sumArray.c" class="uri">examples/pointers/sumArray.c</a>
+</div>
+<p>Note the use of <code class="backtick">const</code> to promise that <code class="backtick">sumArray</code> won't modify the contents of <code class="backtick">a</code>.</p>
+<p>Another way to write the function header is to declare <code class="backtick">a</code> as an array of unknown size:</p>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"><span class="co">/* return the sum of the values in a, an array of size n */</span>
+<span class="dt">int</span>
+sumArray(<span class="dt">int</span> n, <span class="dt">const</span> <span class="dt">int</span> a[])
+{
+ ...
+}</code></pre></div>
+<p>This has <em>exactly</em> the same meaning to the compiler as the previous definition. Even though normally the declarations <code class="backtick">int&nbsp;a[10]</code> and <code class="backtick">int&nbsp;*a</code> mean very different things (the first one allocates space to hold 10 <code class="backtick">int</code>s, and prevents assigning a new value to <code class="backtick">a</code>), in a function argument <code class="backtick">int&nbsp;a[]</code> is just <a href="http://en.wikipedia.org/wiki/Syntactic_sugar">syntactic sugar</a> for <code class="backtick">int&nbsp;*a</code>. You can even modify what <code class="backtick">a</code> points to inside <code class="backtick">sumArray</code> by assigning to it. This will allow you to do things that you usually don't want to do, like write this hideous routine:</p>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"><span class="co">/* return the sum of the first n values in a */</span>
+<span class="dt">int</span>
+sumArray(<span class="dt">int</span> n, <span class="dt">const</span> <span class="dt">int</span> a[])
+{
+ <span class="dt">const</span> <span class="dt">int</span> *an; <span class="co">/* pointer to first element not in a */</span>
+ <span class="dt">int</span> sum;
+
+ sum = <span class="dv">0</span>;
+ an = a+n;
+
+ <span class="kw">while</span>(a &lt; an) {
+ sum += *a++;
+ }
+
+ <span class="kw">return</span> sum;
+}</code></pre></div>
+<h4 id="multidimensionalArrays"><span class="header-section-number">4.9.5.3</span> Multidimensional arrays</h4>
+<p>Arrays can themselves be members of arrays. The result is a multidimensional array, where a value in row <code class="backtick">i</code> and column <code class="backtick">j</code> is accessed by <code class="backtick">a[i][j]</code>.</p>
+<p>Declaration is similar to one-dimensional arrays:</p>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"> <span class="dt">int</span> a[<span class="dv">6</span>][<span class="dv">4</span>]; <span class="co">/* declares an array of 6 rows of 4 ints each */</span></code></pre></div>
+<p>This declaration produces an array of 24 <code class="backtick">int</code> values, packed contiguously in memory. The interpretation is that <code class="backtick">a</code> is an array of 6 objects, each of which is an array of 4 <code class="backtick">int</code>s.</p>
+<p>If we imagine the array to contain increasing values like this:</p>
+<pre><code> 0 1 2 3 4 5
+ 6 7 8 9 10 11
+12 13 14 15 16 17</code></pre>
+<p>the actual positions in memory will look like this:</p>
+<pre><code> 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
+ ^ ^ ^
+a[0] a[1] a[2]</code></pre>
+<p>To look up a value, we do the usual array-indexing magic. Suppose we want to find <code class="backtick">a[1][4]</code>. The name <code class="backtick">a</code> acts as a pointer to the base of the array.The name <code class="backtick">a[1]</code> says to skip ahead 1 times the size of the things pointed to by <code class="backtick">a</code>, which are arrays of 6 <code class="backtick">int</code>s each, for a total size of 24 bytes assuming 4-byte <code class="backtick">int</code>s. For <code class="backtick">a[1][4]</code>, we start at <code class="backtick">a[1]</code> and move forward 4 times the size of the thing pointed to by <code class="backtick">a[1]</code>, which is an <code class="backtick">int</code>; this puts us 24+16 bytes from <code class="backtick">a</code>, the position of 10 in the picture above.</p>
+<p>Like other array declarations, the size must be specified at compile
+time in pre-C99 C. If this is not desirable, a similar effect can be
+obtained by allocating each row separately using <code class="backtick">malloc</code> and building a master list of pointers to rows, of type <code class="backtick">int&nbsp;**</code>.
+ The downside of this approach is that the array is no longer contiguous
+ (which may affect cache performance) and it requires reading a pointer
+to find the location of a particular value, instead of just doing
+address arithmetic starting from the base address of the array. But
+elements can still be accessed using the <code class="backtick">a[i][j]</code> syntax. An example of this approach is given below:</p>
+<div>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"><span class="co">/* Demo program for malloc'd two-dimensional arrays */</span>
+
+<span class="ot">#include &lt;stdio.h&gt;</span>
+<span class="ot">#include &lt;stdlib.h&gt;</span>
+
+<span class="co">/* frees a 2d array created by malloc2d */</span>
+<span class="dt">void</span>
+free2d(<span class="dt">void</span> **a)
+{
+ <span class="dt">void</span> **row;
+
+ <span class="co">/* first free rows */</span>
+ <span class="kw">for</span>(row = a; *row != <span class="dv">0</span>; row++) {
+ free(*row);
+ }
+
+ <span class="co">/* then free array of rows */</span>
+ free(a);
+}
+
+<span class="co">/* returns a two-dimensional array with numRows rows and </span>
+<span class="co"> * rowSize bytes per row, or 0 on allocation failure.</span>
+<span class="co"> * The caller is responsible for freeing the result with free2d. */</span>
+<span class="dt">void</span> **
+malloc2d(size_t numRows, size_t rowSize)
+{
+ <span class="dt">void</span> **a;
+ size_t i;
+
+ <span class="co">/* a is an array of void * pointers that point to the rows */</span>
+ <span class="co">/* The last element is 0, so free2d can detect the last row */</span>
+ a = malloc(<span class="kw">sizeof</span>(<span class="dt">void</span> *) * (numRows + <span class="dv">1</span>)); <span class="co">/* one extra for sentinel */</span>
+ <span class="kw">if</span>(a == <span class="dv">0</span>) {
+ <span class="co">/* malloc failed */</span>
+ <span class="kw">return</span> <span class="dv">0</span>;
+ }
+
+ <span class="co">/* now allocate the actual rows */</span>
+ <span class="kw">for</span>(i = <span class="dv">0</span>; i &lt; numRows; i++) {
+ a[i] = malloc(rowSize);
+ <span class="kw">if</span>(a[i] == <span class="dv">0</span>) {
+ <span class="co">/* note that 0 in a[i] will stop freed2d after it frees previous rows */</span>
+ free2d(a);
+ <span class="kw">return</span> <span class="dv">0</span>;
+ }
+ }
+
+ <span class="co">/* initialize the sentinel value */</span>
+ a[numRows] = <span class="dv">0</span>;
+
+ <span class="kw">return</span> a;
+}
+
+<span class="dt">int</span>
+main(<span class="dt">int</span> argc, <span class="dt">char</span> **argv)
+{
+ <span class="dt">int</span> rows;
+ <span class="dt">int</span> cols;
+ <span class="dt">int</span> **a;
+ <span class="dt">int</span> i;
+ <span class="dt">int</span> j;
+
+ <span class="kw">if</span>(argc != <span class="dv">3</span>) {
+ fprintf(stderr, <span class="st">"Usage: %s rows cols</span><span class="ch">\n</span><span class="st">"</span>, argv[<span class="dv">0</span>]);
+ <span class="kw">return</span> <span class="dv">1</span>;
+ }
+ <span class="co">/* else */</span>
+
+ rows = atoi(argv[<span class="dv">1</span>]);
+ cols = atoi(argv[<span class="dv">2</span>]);
+
+ <span class="co">/* note that void ** is not converted automatically,</span>
+<span class="co"> * so we need an explicit cast */</span>
+ a = (<span class="dt">int</span> **) malloc2d(rows, cols * <span class="kw">sizeof</span>(<span class="dt">int</span>));
+ <span class="kw">if</span>(a == <span class="dv">0</span>) {
+ fprintf(stderr, <span class="st">"malloc2d failed, exiting</span><span class="ch">\n</span><span class="st">"</span>);
+ <span class="kw">return</span> <span class="dv">2</span>;
+ }
+
+ <span class="kw">for</span>(i = <span class="dv">0</span>; i &lt; rows; i++) {
+ <span class="kw">for</span>(j = <span class="dv">0</span>; j &lt; cols; j++) {
+ a[i][j] = i - j;
+ }
+ }
+
+ <span class="kw">for</span>(i = <span class="dv">0</span>; i &lt; rows; i++) {
+ <span class="kw">for</span>(j = <span class="dv">0</span>; j &lt; cols; j++) {
+ printf(<span class="st">"%4d"</span>, a[i][j]);
+ }
+ putchar(<span class="ch">'\n'</span>);
+ }
+
+ free2d((<span class="dt">void</span> **) a); <span class="co">/* always clean up */</span>
+
+ <span class="kw">return</span> <span class="dv">0</span>;
+}</code></pre></div>
+<a href="http://cs.yale.edu/homes/aspnes/classes/223/examples/pointers/malloc2d.c" class="uri">examples/pointers/malloc2d.c</a>
+</div>
+<h4 id="variableLengthArrays"><span class="header-section-number">4.9.5.4</span> Variable-length arrays</h4>
+<p>C99 adds the feature of <strong>variable-length arrays</strong>, where the size of the array is determined at run-time. These can only appear as local variables in procedures (<em>automatic variables</em>)
+ or in argument lists. In the case of variable-length arrays in argument
+ lists, it is also necessary that the length of the array be computable
+from previous arguments.</p>
+<p>For example, we could make the length of the array explicit in our <code class="backtick">sumArray</code> function:</p>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"><span class="co">/* return the sum of the values in a, an array of size n */</span>
+<span class="dt">int</span>
+sumArray(<span class="dt">int</span> n, <span class="dt">const</span> <span class="dt">int</span> a[n])
+{
+ <span class="dt">int</span> i;
+ <span class="dt">int</span> sum;
+
+ sum = <span class="dv">0</span>;
+ <span class="kw">for</span>(i = <span class="dv">0</span>; i &lt; n; i++) {
+ sum += a[i];
+ }
+
+ <span class="kw">return</span> sum;
+}</code></pre></div>
+<p>This doesn't accomplish much, because the length of the array is not
+used. However, it does become useful if we have a two-dimensional array,
+ as otherwise there is no way to compute the length of each row:</p>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"><span class="dt">int</span>
+sumMatrix(<span class="dt">int</span> rows, <span class="dt">int</span> cols, <span class="dt">const</span> <span class="dt">int</span> m[rows][cols])
+{
+ <span class="dt">int</span> i;
+ <span class="dt">int</span> j;
+ <span class="dt">int</span> sum;
+
+ sum = <span class="dv">0</span>;
+ <span class="kw">for</span>(i = <span class="dv">0</span>; i &lt; rows; i++) {
+ <span class="kw">for</span>(j = <span class="dv">0</span>; j &lt; cols; j++) {
+ sum += a[i][j];
+ }
+ }
+
+ <span class="kw">return</span> sum;
+}</code></pre></div>
+<p>Here the fact that each row of <code class="backtick">m</code> is known to be an array of <code class="backtick">cols</code> many <code class="backtick">int</code>s makes the implicit pointer computation in <code class="backtick">a[i][j]</code> actually work. It is considerably more difficult to to this in ANSI C; the simplest approach is to pack <code class="backtick">m</code> into a one-dimensional array and do the address computation explicitly:</p>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"><span class="dt">int</span>
+sumMatrix(<span class="dt">int</span> rows, <span class="dt">int</span> cols, <span class="dt">const</span> <span class="dt">int</span> a[])
+{
+ <span class="dt">int</span> i;
+ <span class="dt">int</span> j;
+ <span class="dt">int</span> sum;
+
+ sum = <span class="dv">0</span>;
+ <span class="kw">for</span>(i = <span class="dv">0</span>; i &lt; rows; i++) {
+ <span class="kw">for</span>(j = <span class="dv">0</span>; j &lt; cols; j++) {
+ sum += a[i*cols + j];
+ }
+ }
+
+ <span class="kw">return</span> sum;
+}</code></pre></div>
+<p>Variable-length arrays can sometimes be used for run-time storage allocation, as an alternative to <code class="backtick">malloc</code> and <code class="backtick">free</code>
+ (see below). A variable-length array allocated as a local variable will
+ be deallocated when the containing scope (usually a function body, but
+maybe just a compound statement marked off by braces) exits. One
+consequence of this is that you can't return a variable-length array
+from a function.</p>
+<p>Here is an example of code using this feature:</p>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"><span class="co">/* reverse an array in place */</span>
+<span class="dt">void</span>
+reverseArray(<span class="dt">int</span> n, <span class="dt">int</span> a[n])
+{
+ <span class="co">/* algorithm: copy to a new array in reverse order */</span>
+ <span class="co">/* then copy back */</span>
+
+ <span class="dt">int</span> i;
+ <span class="dt">int</span> copy[n];
+
+ <span class="kw">for</span>(i = <span class="dv">0</span>; i &lt; n; i++) {
+ <span class="co">/* the -1 is needed to that a[0] goes to a[n-1] etc. */</span>
+ copy[n-i<span class="dv">-1</span>] = a[i];
+ }
+
+ <span class="kw">for</span>(i = <span class="dv">0</span>; i &lt; n; i++) {
+ a[i] = copy[i];
+ }
+}</code></pre></div>
+<p>While using variable-length arrays for this purpose can simplify code in some cases, as a general programming practice it is <strong>extremely dangerous</strong>. The reason is that, unlike allocations through <code class="backtick">malloc</code>,
+ variable-length array allocations are typically allocated on the stack
+(which is often more constrainted than the heap) and have no way of
+reporting failure. So if there isn't enough room for your
+variable-length array, odds are you won't find out until a segmentation
+fault occurs somewhere later in your code when you try to use it.</p>
+<p>(As an additional annoyance, <code class="backtick">gdb</code> is confused by two-dimensional variable-length arrays.)</p>
+<p>Here's a safer version of the above routine, using <code class="backtick">malloc</code> and <code class="backtick">free</code>.</p>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"><span class="co">/* reverse an array in place */</span>
+<span class="dt">void</span>
+reverseArray(<span class="dt">int</span> n, <span class="dt">int</span> a[n])
+{
+ <span class="co">/* algorithm: copy to a new array in reverse order */</span>
+ <span class="co">/* then copy back */</span>
+
+ <span class="dt">int</span> i;
+ <span class="dt">int</span> *copy;
+
+ copy = (<span class="dt">int</span> *) malloc(n * <span class="kw">sizeof</span>(<span class="dt">int</span>));
+ assert(copy); <span class="co">/* or some other error check */</span>
+
+ <span class="kw">for</span>(i = <span class="dv">0</span>; i &lt; n; i++) {
+ <span class="co">/* the -1 is needed to that a[0] goes to a[n-1] etc. */</span>
+ copy[n-i<span class="dv">-1</span>] = a[i];
+ }
+
+ <span class="kw">for</span>(i = <span class="dv">0</span>; i &lt; n; i++) {
+ a[i] = copy[i];
+ }
+
+ free(copy);
+}</code></pre></div>
+<h3 id="Void_pointers"><span class="header-section-number">4.9.6</span> Void pointers</h3>
+<p>A special pointer type is <code class="backtick">void&nbsp;*</code>, a "pointer to <code class="backtick">void</code>". Such pointers are declared in the usual way:</p>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"> <span class="dt">void</span> *nothing; <span class="co">/* pointer to nothing */</span></code></pre></div>
+<p>Unlike ordinary pointers, you can't dereference a <code class="backtick">void&nbsp;*</code> pointer or do arithmetic on it, because the compiler doesn't know what type it points to. However, you are allowed to use a <code class="backtick">void&nbsp;*</code> as a kind of "raw address" pointer value that you can store arbitrary pointers in. It is permitted to assign to a <code class="backtick">void&nbsp;*</code> variable from an expression of any pointer type; conversely, a <code class="backtick">void&nbsp;*</code> pointer value can be assigned to a pointer variable of any type. An example is the return value of <code>malloc</code> or the argument to <code>free</code>, both of which are declared as <code>void *</code>. (Note that K&amp;R suggests using an explicit cast for the return value of <code>malloc</code>.
+ This is now acknowledged by the authors to be an error, which arose
+from the need for a cast prior to the standardization of void * in ANSI
+C. See <a href="http://cm.bell-labs.com/cm/cs/cbook/2ediffs.html" class="uri">http://cm.bell-labs.com/cm/cs/cbook/2ediffs.html</a>.)</p>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"> <span class="dt">int</span> *block;
+
+ block = malloc(sizoef(<span class="dt">int</span>) * <span class="dv">12</span>); <span class="co">/* void * converted to int * before assignment */</span>
+ free(block); <span class="co">/* int * converted to void * before passing to free */</span></code></pre></div>
+<p>If you need to use a <code class="backtick">void&nbsp;*</code> pointer as a pointer of a particular type in an expression, you can <strong>cast</strong> it to the appropriate type by prefixing it with a type name in parentheses, like this:</p>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"> <span class="dt">int</span> a[<span class="dv">50</span>]; <span class="co">/* typical array of ints */</span>
+ <span class="dt">void</span> *p; <span class="co">/* dangerous void pointer */</span>
+
+ a[<span class="dv">12</span>] = <span class="dv">17</span>; <span class="co">/* save that valuable 17 */</span>
+ p = a; <span class="co">/* p now holds base address of a */</span>
+
+ printf(<span class="st">"%d</span><span class="ch">\n</span><span class="st">"</span>, ((<span class="dt">int</span> *) p)[<span class="dv">12</span>]); <span class="co">/* get 17 back */</span></code></pre></div>
+<p>Usually if you have to start writing casts, it's a sign that you are doing something wrong, and you run the danger of <strong>violating the type system</strong>—say, by tricking the compiler into treating a block of bits that are supposed to be an <code class="backtick">int</code> as four <code class="backtick">char</code>s.
+ But violating the type system like this will be necessary for some
+applications, because even the weak type system in C turns out to be too
+ restrictive for writing certain kinds of "generic" code that work on
+values of arbitrary types.</p>
+<h4 id="alignment"><span class="header-section-number">4.9.6.1</span> Alignment</h4>
+<p>One issue with casting pointers to and from <code>void *</code> is that you may violate the <strong>alignment restrictions</strong> for a particular kind of pointer on some architectures.</p>
+<p>Back in the 8-bit era of the 1970s, a single load or store operation
+would access a single byte of memory, and because some data (<code>char</code>s)
+ are still only one byte wide, C pointers retain the ability to address
+individual bytes. But present-day memory architectures typically have a
+wider data path, and the CPU may load or store as much as 8 bytes (64
+bits) in a single operation. This makes it natural to organize memory
+into 4-byte or 8-byte words even though addresses still refer to
+individual bytes. The effect of the memory architecture is that the
+address of memory words must be <strong>aligned</strong> to a multiple of the word size: so with 4-byte words, the address <code>0x1037ef44</code> (a multiple of 4) could refer to a full word, but <code>0x1037ef45</code> (one more than a multiple of 4) could only be used to refer to a byte within a word.</p>
+<p>What this means for a C program depends on your particular CPU and compiler. If you try to use someting like <code>0x1037ef45</code> as an <code>int *</code>, one of three things might happen:</p>
+<ol style="list-style-type: decimal">
+<li>The CPU might load the 4 bytes starting at this address, using two accesses to memory to piece together the full <code>int</code> out of fragments of words. This is done on Intel architectures, but costs performance.</li>
+<li>The CPU might quietly zero out the last two bits of the address, loading from <code>0x1037ef44</code> even though you asked for <code>0x1037ef45</code>. This happens on some other architectures, notably ARM.</li>
+<li>The CPU might issue a run-time exception.</li>
+</ol>
+<p>All of these outcomes are bad, and the C standard does not specify
+what happens if you try to dereference a pointer value that does not
+satisfy the alignment restrictions of its target type. Fortunately,
+unless you are doing very nasty things with casts, this is unlikely to
+come up, because any pointer value you will see in a typical program is
+likely to arise in one of three ways:</p>
+<ol style="list-style-type: decimal">
+<li>By taking the address of some variable. This pointer will be
+appropriately aligned, because the compiler allocates space for each
+variable (including fields within <code>struct</code>s) with appropriate alignment.</li>
+<li>By computing an offset address using pointer arithmetic either explicitly (<code>p + n</code>) or implicilty (<code>p[n]</code>). In either case, as long as the base pointer is correctly aligned, the computed pointer will also be correctly aligned.</li>
+<li>By obtaining a pointer to an allocated block of memory using <code>malloc</code> or a similar function. Here <code>malloc</code>
+ is designed to always return blocks with the maximum possible required
+alignment, just to avoid problems when you use the results elsewhere.</li>
+</ol>
+<p>On many compilers, you can use <code>__alignof(</code><em>type</em><code>)</code> to get the alignment restriction for a particular type. This was formalized in C11 (with a different name!).</p>
+<p>The other place where alignment can create issues is that if you make a <a href="#structs"><code>struct</code></a>
+ with components with different alignment restrictions, you may end up
+with some empty space. For example, on a machine that enforces 4-byte
+alignment for <code>int</code>s, building a <code>struct</code> that contains a <code>char</code> and an <code>int</code> will give you something bigger than you might expect:</p>
+<div>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"><span class="ot">#include &lt;stdio.h&gt;</span>
+
+<span class="kw">struct</span> ci {
+ <span class="dt">char</span> c; <span class="co">/* offset 0 */</span>
+ <span class="co">/* 3 unused bytes go here */</span>
+ <span class="dt">int</span> i; <span class="co">/* offset 4 */</span>
+};
+
+<span class="kw">struct</span> ic {
+ <span class="dt">int</span> i; <span class="co">/* offset 0 */</span>
+ <span class="dt">char</span> c; <span class="co">/* offset 4 */</span>
+ <span class="co">/* 3 unused bytes go here */</span>
+};
+
+<span class="dt">int</span>
+main(<span class="dt">int</span> argc, <span class="dt">char</span> **argv)
+{
+ printf(<span class="st">"sizeof(struct ci) == %lu</span><span class="ch">\n</span><span class="st">"</span>, <span class="kw">sizeof</span>(<span class="kw">struct</span> ci));
+ printf(<span class="st">"sizeof(struct ic) == %lu</span><span class="ch">\n</span><span class="st">"</span>, <span class="kw">sizeof</span>(<span class="kw">struct</span> ic));
+
+ <span class="kw">return</span> <span class="dv">0</span>;
+}</code></pre></div>
+<a href="http://cs.yale.edu/homes/aspnes/classes/223/examples/alignment/structPacking.c" class="uri">examples/alignment/structPacking.c</a>
+</div>
+<pre><code>$ c99 -Wall -o structPacking structPacking.c
+$ ./structPacking
+sizeof(struct ci) == 8
+sizeof(struct ic) == 8</code></pre>
+<p>In both cases, the compiler packs in an extra 3 bytes to make the
+size of the struct a multiple of the worst alignment of any of its
+components. If it didn't do this, you would have trouble as soon as you
+tried to make an array of these things.</p>
+<h3 id="malloc"><span class="header-section-number">4.9.7</span> Run-time storage allocation using <code>malloc</code></h3>
+<p>C does not generally permit arrays to be declared with variable
+sizes. C also doesn't let local variables outlive the function they are
+declared in. Both features can be awkward if you want to build data
+structures at run time that have unpredictable (perhaps even changing)
+sizes and that are intended to persist longer than the functions that
+create them. To build such structures, the standard C library provides
+the <code class="backtick">malloc</code> routine, which asks the
+operating system for a block of space of a given size (in bytes). With a
+ bit of pushing and shoving, this can be used to obtain a block of space
+ that for all practical purposes acts just like an array.</p>
+<p>To use <code class="backtick">malloc</code>, you must include <code class="backtick">stdlib.h</code> at the top of your program. The declaration for <code class="backtick">malloc</code> is</p>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"><span class="dt">void</span> *malloc(size_t);</code></pre></div>
+<p>where <code class="backtick">size_t</code> is an integer type (often <code class="backtick">unsigned&nbsp;long</code>). Calling <code class="backtick">malloc</code> with an argument of <span class="math inline"><em>n</em></span> allocates and returns a pointer to the start of a block of <span class="math inline"><em>n</em></span> bytes if possible. If the system can't give you the space you asked for (maybe you asked for more space than it has), <code class="backtick">malloc</code> returns a null pointer. It is good practice to test the return value of <code class="backtick">malloc</code> whenever you call it.</p>
+<p>Because the return type of <code class="backtick">malloc</code> is <code class="backtick">void&nbsp;*</code>,
+ its return value can be assigned to any variable with a pointer type.
+Computing the size of the block you need is your responsibility---and
+you will be punished for any mistakes with difficult-to-diagnose buffer
+overrun errors---but this task is made slightly easier by the built-in <code class="backtick">sizeof</code> operator that allows you to compute the size in bytes of any particular data type. A typical call to <code class="backtick">malloc</code> might thus look something like this:</p>
+<div>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"><span class="ot">#include &lt;stdlib.h&gt;</span>
+
+<span class="co">/* allocate and return a new integer array with n elements */</span>
+<span class="co">/* calls abort() if there isn't enough space */</span>
+<span class="dt">int</span> *
+makeIntArray(<span class="dt">int</span> n)
+{
+ <span class="dt">int</span> *a;
+
+ a = malloc(<span class="kw">sizeof</span>(<span class="dt">int</span>) * n);
+
+ <span class="kw">if</span>(a == <span class="dv">0</span>) abort(); <span class="co">/* die on failure */</span>
+
+ <span class="kw">return</span> a;
+}</code></pre></div>
+<a href="http://cs.yale.edu/homes/aspnes/classes/223/examples/pointers/makeIntArray.c" class="uri">examples/pointers/makeIntArray.c</a>
+</div>
+<p>When you are done with a <code class="backtick">malloc</code>'d region, you should return the space to the system using the <code class="backtick">free</code> routine, also defined in <code class="backtick">stdlib.h</code>. If you don't do this, your program will quickly run out of space. The <code class="backtick">free</code> routine takes a <code class="backtick">void&nbsp;*</code> as its argument and returns nothing. It is good practice to write a matching <strong>destructor</strong> that de-allocates an object for each <strong>constructor</strong> (like <code class="backtick">makeIntArray</code>) that makes one.</p>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"><span class="dt">void</span>
+destroyIntArray(<span class="dt">int</span> *a)
+{
+ free(a);
+}</code></pre></div>
+<p>It is a serious error to do anything at all with a block after it has been <code class="backtick">free</code>d. This is not necessarily because <code>free</code>
+ modifies the contents of the block (although it might), but because
+when you free a block you are granting the storage allocator permission
+to hand the same block out in response to a future call to <code>malloc</code>, and you don't want to step on whatever other part of your program is now trying to use that space.</p>
+<p>It is also possible to grow or shrink a previously allocated block. This is done using the <code class="backtick">realloc</code> function, which is declared as</p>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"><span class="dt">void</span> *realloc(<span class="dt">void</span> *oldBlock, size_t newSize);</code></pre></div>
+<p>The <code class="backtick">realloc</code> function returns a pointer
+to the resized block. It may or may not allocate a new block. If there
+is room, it may leave the old block in place and return its argument.
+But it may allocate a new block and copy the contents of the old block,
+so you should assume that the old pointer has been <code class="backtick">free</code>d.</p>
+<p>Here's a typical use of <code class="backtick">realloc</code> to build an array that grows as large as it needs to be:</p>
+<div>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"><span class="co">/* read numbers from stdin until there aren't any more */</span>
+<span class="co">/* returns an array of all numbers read, or null on error */</span>
+<span class="co">/* returns the count of numbers read in *count */</span>
+<span class="dt">int</span> *
+readNumbers(<span class="dt">int</span> *count <span class="co">/* RETVAL */</span>)
+{
+ <span class="dt">int</span> mycount; <span class="co">/* number of numbers read */</span>
+ <span class="dt">int</span> size; <span class="co">/* size of block allocated so far */</span>
+ <span class="dt">int</span> *a; <span class="co">/* block */</span>
+ <span class="dt">int</span> n; <span class="co">/* number read */</span>
+
+ mycount = <span class="dv">0</span>;
+ size = <span class="dv">1</span>;
+
+ a = malloc(<span class="kw">sizeof</span>(<span class="dt">int</span>) * size); <span class="co">/* allocating zero bytes is tricky */</span>
+ <span class="kw">if</span>(a == <span class="dv">0</span>) <span class="kw">return</span> <span class="dv">0</span>;
+
+ <span class="kw">while</span>(scanf(<span class="st">"%d"</span>, &amp;n) == <span class="dv">1</span>) {
+ <span class="co">/* is there room? */</span>
+ <span class="kw">while</span>(mycount &gt;= size) {
+ <span class="co">/* double the size to avoid calling realloc for every number read */</span>
+ size *= <span class="dv">2</span>;
+ a = realloc(a, <span class="kw">sizeof</span>(<span class="dt">int</span>) * size);
+ <span class="kw">if</span>(a == <span class="dv">0</span>) <span class="kw">return</span> <span class="dv">0</span>;
+ }
+
+ <span class="co">/* put the new number in */</span>
+ a[mycount++] = n;
+ }
+
+ <span class="co">/* now trim off any excess space */</span>
+ a = realloc(a, <span class="kw">sizeof</span>(<span class="dt">int</span>) * mycount);
+ <span class="co">/* note: if a == 0 at this point we'll just return it anyway */</span>
+
+ <span class="co">/* save out mycount */</span>
+ *count = mycount;
+
+ <span class="kw">return</span> a;
+}</code></pre></div>
+<a href="http://cs.yale.edu/homes/aspnes/classes/223/examples/pointers/readNumbers.c" class="uri">examples/pointers/readNumbers.c</a>
+</div>
+<p>Because errors involving <code class="backtick">malloc</code> and its friends can be very difficult to spot, it is recommended to test any program that uses <code class="backtick">malloc</code> using <a href="#valgrind">valgrind</a>.</p>
+<h3 id="functionPointers"><span class="header-section-number">4.9.8</span> Function pointers</h3>
+<p>A <strong>function pointer</strong>, internally, is just the
+numerical address for the code for a function. When a function name is
+used by itself without parentheses, the value is a pointer to the
+function, just as the name of an array by itself is a pointer to its
+zeroth element. Function pointers can be stored in variables, <code class="backtick">struct</code>s, <code class="backtick">union</code>s,
+ and arrays and passed to and from functions just like any other pointer
+ type. They can also be called: a variable of type function pointer can
+be used in place of a function name.</p>
+<p>Function pointers are not used as much in C as in functional languages, but there are many common uses even in C code.</p>
+<h4 id="Function_pointer_declarations"><span class="header-section-number">4.9.8.1</span> Function pointer declarations</h4>
+<p>A function pointer declaration looks like a function declaration,
+except that the function name is wrapped in parentheses and preceded by
+an asterisk. For example:</p>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"><span class="co">/* a function taking two int arguments and returning an int */</span>
+<span class="dt">int</span> function(<span class="dt">int</span> x, <span class="dt">int</span> y);
+
+<span class="co">/* a pointer to such a function */</span>
+<span class="dt">int</span> (*pointer)(<span class="dt">int</span> x, <span class="dt">int</span> y);</code></pre></div>
+<p>As with function declarations, the names of the arguments can be omitted.</p>
+<p>Here's a short program that uses function pointers:</p>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"><span class="co">/* Functional "hello world" program */</span>
+
+<span class="ot">#include &lt;stdio.h&gt;</span>
+
+<span class="dt">int</span>
+main(<span class="dt">int</span> argc, <span class="dt">char</span> **argv)
+{
+ <span class="co">/* function for emitting text */</span>
+ <span class="dt">int</span> (*say)(<span class="dt">const</span> <span class="dt">char</span> *);
+
+ say = puts;
+
+ say(<span class="st">"hello world"</span>);
+
+ <span class="kw">return</span> <span class="dv">0</span>;
+}</code></pre></div>
+<h4 id="Callbacks"><span class="header-section-number">4.9.8.2</span> Callbacks</h4>
+<p>A <strong>callback</strong> is when we pass a function pointer into a
+ function so that that function can call our function when some event
+happens or it needs to compute something.</p>
+<p>A classic example is the comparison argument to <code class="backtick">qsort</code>, from the standard library:</p>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"><span class="co">/* defined in stdlib.h */</span>
+<span class="dt">void</span>
+qsort(
+ <span class="dt">void</span> *base,
+ size_t n,
+ size_t size,
+ <span class="dt">int</span> (*cmp)(<span class="dt">const</span> <span class="dt">void</span> *key1, <span class="dt">const</span> <span class="dt">void</span> *key2)
+);</code></pre></div>
+<p>This is a generic sorting routine that will sort any array in place.
+It needs to know (a) the base address of the array; (b) how many
+elements there are; (c) how big each element is; and (d) how to compare
+two elements. The only tricky part is supplying the comparison, which
+could involve arbitrarily-complex code. So we supply this code as a
+function with an interface similar to <code class="backtick">strcmp</code>.</p>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"><span class="dt">static</span> <span class="dt">int</span>
+compare_ints(<span class="dt">void</span> *key1, <span class="dt">void</span> *key2)
+{
+ <span class="kw">return</span> *((<span class="dt">int</span> *) key1) - *((<span class="dt">int</span> *) key2);
+}
+
+<span class="dt">int</span>
+sort_int_array(<span class="dt">int</span> *a, <span class="dt">int</span> n)
+{
+ qsort(a, n, <span class="kw">sizeof</span>(*a), compare_ints);
+}</code></pre></div>
+<p>Other examples might include things like registering an error handler for a library, instead of just having it call <code class="backtick">abort()</code> or something equally catastrophic, or providing a cleanup function for freeing data passed into a data structure.</p>
+<h4 id="Dispatch_tables"><span class="header-section-number">4.9.8.3</span> Dispatch tables</h4>
+<p>Alternative to gigantic <code class="backtick">if/else&nbsp;if</code> or <code class="backtick">switch</code> statements. The idea is to build an array of function pointers (or, more generally, some sort of <a href="#dictionaries">dictionary data structure</a>), and use the value we might otherwise be feeding to <code>switch</code>
+ as an index into this array. Here is a simple example, which echoes
+most of the characters in its input intact, except for echoing every
+lowercase vowel twice:</p>
+<div>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"><span class="ot">#include &lt;stdio.h&gt;</span>
+<span class="ot">#include &lt;stdlib.h&gt;</span>
+<span class="ot">#include &lt;assert.h&gt;</span>
+<span class="ot">#include &lt;limits.h&gt;</span>
+
+<span class="co">/*</span>
+<span class="co"> * Demonstrate use of dispatch tables.</span>
+<span class="co"> */</span>
+
+<span class="co">/* print a character twice */</span>
+<span class="co">/* like putchar, returns character if successful or EOF on error */</span>
+<span class="dt">int</span>
+putcharTwice(<span class="dt">int</span> c)
+{
+ <span class="kw">if</span>(putchar(c) == EOF || putchar(c) == EOF) {
+ <span class="kw">return</span> EOF;
+ } <span class="kw">else</span> {
+ <span class="kw">return</span> c;
+ }
+}
+
+<span class="ot">#define NUM_CHARS (UCHAR_MAX + 1) </span><span class="co">/* UCHAR_MAX is in limits.h */</span>
+
+<span class="dt">int</span>
+main(<span class="dt">int</span> argc, <span class="dt">char</span> **argv)
+{
+ <span class="co">/* this declares table as an array of function pointers */</span>
+ <span class="dt">int</span> (*table[UCHAR_MAX<span class="dv">+1</span>])(<span class="dt">int</span>);
+ <span class="dt">int</span> i;
+ <span class="dt">int</span> c;
+
+ <span class="kw">for</span>(i = <span class="dv">0</span>; i &lt; UCHAR_MAX; i++) {
+ <span class="co">/* default is to call putchar */</span>
+ table[i] = putchar;
+ }
+
+ <span class="co">/* but lower-case vowels show up twice */</span>
+ table['a'] = putcharTwice;
+ table['e'] = putcharTwice;
+ table['i'] = putcharTwice;
+ table['o'] = putcharTwice;
+ table['u'] = putcharTwice;
+
+ <span class="kw">while</span>((c = getchar()) != EOF) {
+ table[c](c);
+ }
+
+ <span class="kw">return</span> <span class="dv">0</span>;
+}</code></pre></div>
+<a href="http://cs.yale.edu/homes/aspnes/classes/223/examples/pointers/dispatchTable.c" class="uri">examples/pointers/dispatchTable.c</a>
+</div>
+<p>And here is the program translating Shakespeare into mock-Swedish:</p>
+<pre><code>$ c99 -Wall -pedantic -g3 -o dispatchTable dispatchTable.c
+$ echo Now is the winter of our discontent made glorious summer by this sun of York. | ./dispatchTable
+Noow iis thee wiinteer oof oouur diiscoonteent maadee glooriioouus suummeer by thiis suun oof Yoork.</code></pre>
+<p>In this particular case, we did a lot of work to avoid just writing a <code>switch</code>
+ statement. But being able to build a dispatch table dynamically can be
+very useful sometimes. An example might be a graphical user interface
+where each button has an associated function. If buttons can be added by
+ different parts of the program, using a table mapping buttons to
+functions allows a single dispatch routine to figure out where to route
+button presses.</p>
+<p>(For some applications, we might want to pass additional information
+in to the function to change its behavior. This can be done by replacing
+ the function pointers with <a href="#closures">closures</a>.)</p>
+<h3 id="The_restrict_keyword"><span class="header-section-number">4.9.9</span> The restrict keyword</h3>
+<p>In C99, it is possible to declare that a pointer variable is the only
+ way to reach its target as long as it is in scope. This is not enforced
+ by the compiler; instead, it is a promise from the programmer <em>to</em>
+ the compiler that any data reached through this point will not be
+changed by other parts of the code, which allows the compiler to
+optimize code in ways that are not possible if pointers might point to
+the same place (a phenomenon called <strong>pointer aliasing</strong>). For example, consider the following short function:</p>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"><span class="co">// write 1 + *src to *dst and return *src</span>
+<span class="dt">int</span>
+copyPlusOne(<span class="dt">int</span> * <span class="dt">restrict</span> dst, <span class="dt">int</span> * <span class="dt">restrict</span> src)
+{
+ *dst = *src + <span class="dv">1</span>;
+ <span class="kw">return</span> *src;
+}</code></pre></div>
+<p>For this function, the output of <code class="backtick">c99&nbsp;-O3&nbsp;-S</code> includes one more instruction if the <code class="backtick">restrict</code> qualifiers are removed. The reason is that if <code class="backtick">dst</code> and <code class="backtick">src</code> may point to the same location, <code class="backtick">src</code> needs to be re-read for the <code class="backtick">return</code>
+ statement, in case it changed. But if they are guaranteed to point to
+different locations, the compiler can re-use the previous value it
+already has in one of the CPU registers.</p>
+<p>For most code, this feature is useless, and potentially dangerous if
+someone calls your routine with aliased pointers. However, it may
+sometimes be possible to increase performance of time-critical code by
+adding a <code class="backtick">restrict</code> keyword. The cost is that the code might no longer work if called with aliased pointers.</p>
+<p>Curiously, C assumes that two pointers are never aliases if you have
+two arguments with different pointer types, neither of which is <code>char *</code> or <code>void *</code>.<a href="#fn10" class="footnoteRef" id="fnref10"><sup>10</sup></a> This is known as the <strong>strict aliasing rule</strong> and cannot be overridden from within the program source code: there is no <code>unrestrict</code>
+ keyword. You probably only need to worry about this if you are casting
+pointers to different types and then passing the cast pointers around in
+ the same context as the original pointers.</p>
+<h2 id="strings"><span class="header-section-number">4.10</span> Strings</h2>
+<p>Processing strings of characters is one of the oldest application of
+mechanical computers, arguably predating numerical computation by at
+least fifty years. Assuming you've already solved the problem of how to
+represent characters in memory (e.g. as the C <code class="backtick">char</code> type encoded in <a href="http://en.wikipedia.org/wiki/ASCII" title="WikiPedia">ASCII</a>), there are two standard ways to represent strings:</p>
+<ul>
+<li>As a <strong>delimited string</strong>, where the end of a string is
+ marked by a special character. The advantages of this method are that
+only one extra byte is needed to indicate the length of an arbitrarily
+long string, that strings can be manipulated by simple pointer
+operations, and in some cases that common string operations that involve
+ processing the entire string can be performed very quickly. The
+disadvantage is that the delimiter can't appear inside any string, which
+ limits what kind of data you can store in a string.</li>
+<li>As a <strong>counted string</strong>, where the string data is
+prefixed or supplemented with an explicit count of the number of
+characters in the string. The advantage of this representation is that a
+ string can hold arbitrary data (including delimiter characters) and
+that one can quickly jump to the end of the string without having to
+scan its entire length. The disadvantage is that maintaining a separate
+count typically requires more space than adding a one-byte delimiter
+(unless you limit your string length to 255 characters) and that more
+care needs to be taken to make sure that the count is correct.</li>
+</ul>
+<h3 id="C_strings"><span class="header-section-number">4.10.1</span> C strings</h3>
+<p>Because delimited strings are simpler and take less space, C went for
+ delimited strings. A string is a sequence of characters terminated by a
+ null character <code class="backtick">'\0'</code>. Looking back from almost half a century later, this choice <a href="http://queue.acm.org/detail.cfm?id=2010365">may have been a mistake in the long run</a>, but we are pretty much stuck with it.</p>
+<p>Note that the null character is <em>not</em> the same as a null pointer, although both appear to have the value <code class="backtick">0</code> when used in integer contexts. A string is represented by a variable of type <code class="backtick">char&nbsp;*</code>,
+ which points to the zeroth character of the string. The programmer is
+responsible for allocating and managing space to store strings, except
+for explicit <strong>string constants</strong>, which are stored in a special non-writable string space by the compiler.</p>
+<p>If you want to use counted strings instead, you can build your own using a <a href="#structs"><code>struct</code></a>. Most scripting languages written in C (e.g. <a href="http://en.wikipedia.org/wiki/Perl" title="WikiPedia">Perl</a>, <a href="http://en.wikipedia.org/wiki/Python_programming_language" title="WikiPedia">Python_programming_language</a>, <a href="http://en.wikipedia.org/wiki/PHP" title="WikiPedia">PHP</a>, etc.) use this approach internally. (<a href="http://en.wikipedia.org/wiki/Tcl" title="WikiPedia">Tcl</a> is an exception, which is one of many good reasons not to use Tcl).</p>
+<h3 id="String_constants"><span class="header-section-number">4.10.2</span> String constants</h3>
+<p>A string constant in C is represented by a sequence of characters
+within double quotes. Standard C character escape sequences like <code class="backtick">\n</code> (newline), <code class="backtick">\r</code> (carriage return), <code class="backtick">\a</code> (bell), <code class="backtick">\0x17</code> (character with hexadecimal code <code class="backtick">0x17</code>), <code class="backtick">\\</code> (backslash), and <code class="backtick">\"</code> (double quote) can all be used inside string constants. The value of a string constant has type <code class="backtick">const&nbsp;char&nbsp;*</code>, and can be assigned to variables and passed as function arguments or return values of this type.</p>
+<p>Two string constants separated only by whitespace will be concatenated by the compiler as a single constant: <code class="backtick">"foo"&nbsp;"bar"</code> is the same as <code class="backtick">"foobar"</code>. This feature is not much used in normal code, but shows up sometimes in <a href="#macros">macros</a>.</p>
+<h3 id="String_buffers"><span class="header-section-number">4.10.3</span> String buffers</h3>
+<p>The problem with string constants is that you can't modify them. If
+you want to build strings on the fly, you will need to allocate space
+for them. The traditional approach is to use a <strong>buffer</strong>, an array of <code class="backtick">char</code>s. Here is a particularly painful hello-world program that builds a string by hand:</p>
+<div>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"><span class="ot">#include &lt;stdio.h&gt;</span>
+
+<span class="dt">int</span>
+main(<span class="dt">int</span> argc, <span class="dt">char</span> **argv)
+{
+ <span class="dt">char</span> hi[<span class="dv">3</span>];
+
+ hi[<span class="dv">0</span>] = 'h';
+ hi[<span class="dv">1</span>] = 'i';
+ hi[<span class="dv">2</span>] = '\<span class="dv">0</span>';
+
+ puts(hi);
+
+ <span class="kw">return</span> <span class="dv">0</span>;
+}</code></pre></div>
+<a href="http://cs.yale.edu/homes/aspnes/classes/223/examples/strings/hi.c" class="uri">examples/strings/hi.c</a>
+</div>
+<p>Note that the buffer needs to have size at least 3 in order to hold
+all three characters. A common error in programming with C strings is to
+ forget to leave space for the null at the end (or to forget to add the
+null, which can have comical results depending on what you are using
+your surprisingly long string for).</p>
+<h4 id="string-buffers-and-the-perils-of-gets"><span class="header-section-number">4.10.3.1</span> String buffers and the perils of <code>gets</code></h4>
+<p>Fixed-size buffers are a common source of errors in older C programs, particularly ones written with the library routine <code>gets</code>. The problem is that if you do something like</p>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"> strcpy(smallBuffer, bigString);</code></pre></div>
+<p>the <code>strcpy</code> function will happily keep copying characters across memory long after it has passed the end of <code>smallBuffer</code>. While you can avoid this to a certain extent when you control where <code>bigString</code>
+ is coming from, the situation becomes particularly fraught if the
+string you are trying to store comes from the input, where it might be
+supplied by anybody, including somebody who is trying to execute a <strong>buffer overrun attack</strong> to seize control of your program.</p>
+<p>If you do need to read a string from the input, you should allocate the receiving buffer using <code>malloc</code> and expand it using <code>realloc</code> as needed. Below is a program that shows how to do this, with some bad alternatives commented out:</p>
+<div>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"><span class="ot">#include &lt;stdio.h&gt;</span>
+<span class="ot">#include &lt;stdlib.h&gt;</span>
+<span class="ot">#include &lt;assert.h&gt;</span>
+
+<span class="ot">#define NAME_LENGTH (2)</span>
+
+<span class="ot">#define INITIAL_LINE_LENGTH (2)</span>
+
+<span class="co">/* return a freshly-malloc'd line with next line of input from stdin */</span>
+<span class="dt">char</span> *
+getLine(<span class="dt">void</span>)
+{
+ <span class="dt">char</span> *line;
+ <span class="dt">int</span> size; <span class="co">/* how much space do I have in line? */</span>
+ <span class="dt">int</span> length; <span class="co">/* how many characters have I used */</span>
+ <span class="dt">int</span> c;
+
+ size = INITIAL_LINE_LENGTH;
+ line = malloc(size);
+ assert(line);
+
+ length = <span class="dv">0</span>;
+
+ <span class="kw">while</span>((c = getchar()) != EOF &amp;&amp; c != <span class="ch">'\n'</span>) {
+ <span class="kw">if</span>(length &gt;= size<span class="dv">-1</span>) {
+ <span class="co">/* need more space! */</span>
+ size *= <span class="dv">2</span>;
+
+ <span class="co">/* make length equal to new size */</span>
+ <span class="co">/* copy contents if necessary */</span>
+ line = realloc(line, size);
+ }
+
+ line[length++] = c;
+ }
+
+ line[length] = '\<span class="dv">0</span>';
+
+ <span class="kw">return</span> line;
+}
+
+<span class="dt">int</span>
+main(<span class="dt">int</span> argc, <span class="dt">char</span> **argv)
+{
+ <span class="dt">int</span> x = <span class="dv">12</span>;
+ <span class="co">/* char name[NAME_LENGTH]; */</span>
+ <span class="dt">char</span> *line;
+ <span class="dt">int</span> y = <span class="dv">17</span>;
+
+ puts(<span class="st">"What is your name?"</span>);
+
+ <span class="co">/* gets(name); */</span> <span class="co">/* may overrun buffer */</span>
+ <span class="co">/* scanf("%s\n", name); */</span> <span class="co">/* may overrun buffer */</span>
+ <span class="co">/* fgets(name, NAME_LENGTH, stdin); */</span> <span class="co">/* may truncate input */</span>
+ line = getLine(); <span class="co">/* has none of these problems */</span>
+
+ printf(<span class="st">"Hi %s! Did you know that x == %d and y == %d?</span><span class="ch">\n</span><span class="st">"</span>, line, x, y);
+
+ free(line); <span class="co">/* but we do have to free line when we are done with it */</span>
+
+ <span class="kw">return</span> <span class="dv">0</span>;
+}</code></pre></div>
+<a href="http://cs.yale.edu/homes/aspnes/classes/223/examples/strings/getLine.c" class="uri">examples/strings/getLine.c</a>
+</div>
+<h3 id="Operations_on_strings"><span class="header-section-number">4.10.4</span> Operations on strings</h3>
+<p>Unlike many programming languages, C provides only a rudimentary
+string-processing library. The reason is that many common
+string-processing tasks in C can be done very quickly by hand.</p>
+<p>For example, suppose we want to copy a string from one buffer to another. The library function <code class="backtick">strcpy</code> declared in <code class="backtick">string.h</code>
+ will do this for us (and is usually the right thing to use), but if it
+didn't exist we could write something very close to it using a famous C
+idiom.</p>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"><span class="dt">void</span>
+strcpy2(<span class="dt">char</span> *dest, <span class="dt">const</span> <span class="dt">char</span> *src)
+{
+ <span class="co">/* This line copies characters one at a time from *src to *dest. */</span>
+ <span class="co">/* The postincrements increment the pointers (++ binds tighter than *) */</span>
+ <span class="co">/* to get to the next locations on the next iteration through the loop. */</span>
+ <span class="co">/* The loop terminates when *src == '\0' == 0. */</span>
+ <span class="co">/* There is no loop body because there is nothing to do there. */</span>
+ <span class="kw">while</span>(*dest++ = *src++);
+}</code></pre></div>
+<p>The externally visible difference between <code class="backtick">strcpy2</code> and the original <code class="backtick">strcpy</code> is that <code class="backtick">strcpy</code> returns a <code class="backtick">char&nbsp;*</code> equal to its first argument. It is also likely that any implementation of <code class="backtick">strcpy</code> found in a recent C library takes advantage of the width of the memory data path to copy more than one character at a time.</p>
+<p>Most C programmers will recognize the <code class="backtick">while(*dest++&nbsp;=&nbsp;*src++);</code>
+ from having seen it before, although experienced C programmers will
+generally be able to figure out what such highly abbreviated
+constructions mean. Exposure to such constructions is arguably a form of
+ hazing.</p>
+<p>Because C pointers act exactly like array names, you can also write <code class="backtick">strcpy2</code> using explicit array indices. The result is longer but may be more readable if you aren't a C fanatic.</p>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"><span class="dt">char</span> *
+strcpy2a(<span class="dt">char</span> *dest, <span class="dt">const</span> <span class="dt">char</span> *src)
+{
+ <span class="dt">int</span> ;
+
+ i = <span class="dv">0</span>;
+ <span class="kw">for</span>(i = <span class="dv">0</span>; src[i] != '\<span class="dv">0</span>'; i++) {
+ dest[i] = src[i];
+ }
+
+ <span class="co">/* note that the final null in src is not copied by the loop */</span>
+ dest[i] = '\<span class="dv">0</span>';
+
+ <span class="kw">return</span> dest;
+}</code></pre></div>
+<p>An advantage of using a separate index in <code class="backtick">strcpy2a</code> is that we don't trash <code class="backtick">dest</code>, so we can return it just like <code class="backtick">strcpy</code> does. (In fairness, <code class="backtick">strcpy2</code> could have saved a copy of the original location of <code class="backtick">dest</code> and done the same thing.)</p>
+<p>Note that nothing in <code class="backtick">strcpy2</code>, <code class="backtick">strcpy2a</code>, or the original <code class="backtick">strcpy</code> will save you if <code class="backtick">dest</code> points to a region of memory that isn't big enough to hold the string at <code class="backtick">src</code>, or if somebody forget to tack a null on the end of <code class="backtick">src</code> (in which case <code class="backtick">strcpy</code>
+ will just keep going until it finds a null character somewhere). As
+elsewhere, it's your job as a programmer to make sure there is enough
+room. Since the compiler has no idea what <code class="backtick">dest</code> points to, this means that you have to remember how much room is available there yourself.</p>
+<p>If you are worried about overrunning <code class="backtick">dest</code>, you could use <code class="backtick">strncpy</code> instead. The <code class="backtick">strncpy</code> function takes a third argument that gives the maximum number of characters to copy; however, if <code class="backtick">src</code> doesn't contain a null character in this range, the resulting string in <code class="backtick">dest</code> won't either. Usually the only practical application to <code class="backtick">strncpy</code> is to extract the first <code class="backtick">k</code> characters of a string, as in</p>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"><span class="co">/* copy the substring of src consisting of characters at positions</span>
+<span class="co"> start..end-1 (inclusive) into dest */</span>
+<span class="co">/* If end-1 is past the end of src, copies only as many characters as </span>
+<span class="co"> available. */</span>
+<span class="co">/* If start is past the end of src, the results are unpredictable. */</span>
+<span class="co">/* Returns a pointer to dest */</span>
+<span class="dt">char</span> *
+copySubstring(<span class="dt">char</span> *dest, <span class="dt">const</span> <span class="dt">char</span> *src, <span class="dt">int</span> start, <span class="dt">int</span> end)
+{
+ <span class="co">/* copy the substring */</span>
+ strncpy(dest, src + start, end - start);
+
+ <span class="co">/* add null since strncpy probably didn't */</span>
+ dest[end - start] = '\<span class="dv">0</span>';
+
+ <span class="kw">return</span> dest;
+}</code></pre></div>
+<p>Another quick and dirty way to extract a substring of a string you
+don't care about (and can write to) is to just drop a null character in
+the middle of the sacrificial string. This is generally a bad idea
+unless you are certain you aren't going to need the original string
+again, but it's a surprisingly common practice among C programmers of a
+certain age.</p>
+<p>A similar operation to <code class="backtick">strcpy</code> is <code class="backtick">strcat</code>. The difference is that <code class="backtick">strcat</code> concatenates <code class="backtick">src</code> on to the end of <code class="backtick">dest</code>; so that if <code class="backtick">dest</code> previous pointed to <code class="backtick">"abc"</code> and <code class="backtick">src</code> to <code class="backtick">"def"</code>, <code class="backtick">dest</code> will now point to <code class="backtick">"abcdef"</code>. Like <code class="backtick">strcpy</code>, <code class="backtick">strcat</code> returns its first argument. A no-return-value version of <code class="backtick">strcat</code> is given below.</p>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"><span class="dt">void</span>
+strcat2(<span class="dt">char</span> *dest, <span class="dt">const</span> <span class="dt">char</span> *src)
+{
+ <span class="kw">while</span>(*dest) dest++;
+ <span class="kw">while</span>(*dest++ = *src++);
+}</code></pre></div>
+<p>Decoding this abomination is left as an exercise for the reader. There is also a function <code class="backtick">strncat</code> which has the same relationship to <code class="backtick">strcat</code> that <code class="backtick">strncpy</code> has to <code class="backtick">strcpy</code>.</p>
+<p>As with <code class="backtick">strcpy</code>, the actual implementation of <code class="backtick">strcat</code> may be much more subtle, and is likely to be faster than rolling your own.</p>
+<h3 id="Finding_the_length_of_a_string"><span class="header-section-number">4.10.5</span> Finding the length of a string</h3>
+<p>Because the length of a string is of fundamental importance in C
+(e.g., when deciding if you can safely copy it somewhere else), the
+standard C library provides a function <code class="backtick">strlen</code>
+ that counts the number of non-null characters in a string. Note that if
+ you are allocating space for a copy of a string, you will need to add
+one to the value returned by <code>strlen</code> to account for the null.</p>
+<p>Here's a possible implementation:</p>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"><span class="dt">int</span>
+strlen(<span class="dt">const</span> <span class="dt">char</span> *s)
+{
+ <span class="dt">int</span> i;
+
+ <span class="kw">for</span>(i = <span class="dv">0</span>; *s; i++, s++);
+
+ <span class="kw">return</span> i;
+}</code></pre></div>
+<p>Note the use of the comma operator in the increment step. The comma
+operator applied to two expressions evaluates both of them and discards
+the value of the first; it is usually used only in <code class="backtick">for</code> loops where you want to initialize or advance more than one variable at once.</p>
+<p>Like the other string routines, using <code class="backtick">strlen</code> requires including <code class="backtick">string.h</code>.</p>
+<h4 id="The_strlen_tarpit"><span class="header-section-number">4.10.5.1</span> The strlen tarpit</h4>
+<p>A common mistake is to put a call to <code class="backtick">strlen</code> in the header of a loop; for example:</p>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"><span class="co">/* like strcpy, but only copies characters at indices 0, 2, 4, ...</span>
+<span class="co"> from src to dest */</span>
+<span class="dt">char</span> *
+copyEvenCharactersBadVersion(<span class="dt">char</span> *dest, <span class="dt">const</span> <span class="dt">char</span> *src)
+{
+ <span class="dt">int</span> i;
+ <span class="dt">int</span> j;
+
+ <span class="co">/* BAD: Calls strlen on every pass through the loop */</span>
+ <span class="kw">for</span>(i = <span class="dv">0</span>, j = <span class="dv">0</span>; i &lt; strlen(src); i += <span class="dv">2</span>, j++) {
+ dest[j] = src[i];
+ }
+
+ dest[j] = '\<span class="dv">0</span>';
+
+ <span class="kw">return</span> dest;
+}</code></pre></div>
+<p>The problem is that <code class="backtick">strlen</code> has to scan all of <code class="backtick">src</code> every time the test is done, which adds time proportional to the length of <code class="backtick">src</code> to each iteration of the loop. So <code class="backtick">copyEvenCharactersBadVersion</code> takes time proportional to the <em>square</em> of the length of <code class="backtick">src</code>.</p>
+<p>Here's a faster version:</p>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"><span class="co">/* like strcpy, but only copies characters at indices 0, 2, 4, ...</span>
+<span class="co"> from src to dest */</span>
+<span class="dt">char</span> *
+copyEvenCharacters(<span class="dt">char</span> *dest, <span class="dt">const</span> <span class="dt">char</span> *src)
+{
+ <span class="dt">int</span> i;
+ <span class="dt">int</span> j;
+ <span class="dt">int</span> len; <span class="co">/* length of src */</span>
+
+ len = strlen(src);
+
+ <span class="co">/* GOOD: uses cached value of strlen(src) */</span>
+ <span class="kw">for</span>(i = <span class="dv">0</span>, j = <span class="dv">0</span>; i &lt; len; i += <span class="dv">2</span>, j++) {
+ dest[j] = src[i];
+ }
+
+ dest[j] = '\<span class="dv">0</span>';
+
+ <span class="kw">return</span> dest;
+}</code></pre></div>
+<p>Because it doesn't call <code class="backtick">strlen</code> all the time, this version of <code class="backtick">copyEvenCharacters</code> will run much faster than the original even on small strings, and several million times faster if <code class="backtick">src</code> is megabytes long.</p>
+<h3 id="Comparing_strings"><span class="header-section-number">4.10.6</span> Comparing strings</h3>
+<p>If you want to test if strings <code class="backtick">s1</code> and <code class="backtick">s2</code> contain the same characters, writing <code class="backtick">s1&nbsp;==&nbsp;s2</code> won't work, since this tests instead whether <code class="backtick">s1</code> and <code class="backtick">s2</code> point to the same address. Instead, you should use <code class="backtick">strcmp</code>, declared in <code class="backtick">string.h</code>. The <code class="backtick">strcmp</code>
+ function walks along both of its arguments until it either hits a null
+on both and returns 0, or hits two different characters, and returns a
+positive integer if the first string's character is bigger and a
+negative integer if the second string's character is bigger (a typical
+implementation will just subtract the two characters). A straightforward
+ implementation might look like this:</p>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"><span class="dt">int</span>
+strcmp(<span class="dt">const</span> <span class="dt">char</span> *s1, <span class="dt">const</span> <span class="dt">char</span> *s2)
+{
+ <span class="kw">while</span>(*s1 &amp;&amp; *s2 &amp;&amp; *s1 == *s2) {
+ s1++;
+ s2++;
+ }
+
+ <span class="kw">return</span> *s1 - *s2;
+}</code></pre></div>
+<p>To use <code class="backtick">strcmp</code> to test equality, test if the return value is <code class="backtick">0</code>:</p>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"> <span class="kw">if</span>(strcmp(s1, s2) == <span class="dv">0</span>) {
+ <span class="co">/* strings are equal */</span>
+ ...
+ }</code></pre></div>
+<p>You may sometimes see this idiom instead:</p>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"> <span class="kw">if</span>(!strcmp(s1, s2)) {
+ <span class="co">/* strings are equal */</span>
+ ...
+ }</code></pre></div>
+<p>My own feeling is that the first version is more clear, since <code class="backtick">!strcmp</code> always suggested to me that you were testing for the negation of some property (e.g. not equal). But if you think of <code class="backtick">strcmp</code> as telling you when two strings are different rather than when they are equal, this may not be so confusing.</p>
+<h3 id="Formatted_output_to_strings"><span class="header-section-number">4.10.7</span> Formatted output to strings</h3>
+<p>You can write formatted output to a string buffer with <code class="backtick">sprintf</code> just like you can write it to <code class="backtick">stdout</code> with <code class="backtick">printf</code> or to a file with <code class="backtick">fprintf</code>. Make sure when you do so that there is enough room in the buffer you are writing to, or the usual bad things will happen.</p>
+<h3 id="Dynamic_allocation_of_strings"><span class="header-section-number">4.10.8</span> Dynamic allocation of strings</h3>
+<p>When allocating space for a copy of a string <code class="backtick">s</code> using <code class="backtick">malloc</code>, the required space is <code class="backtick">strlen(s)+1</code>. Don't forget the <code class="backtick">+1</code>, or bad things may happen.<a href="#fn11" class="footnoteRef" id="fnref11"><sup>11</sup></a></p>
+<p>Because allocating space for a copy of a string is such a common operation, many C libraries provide a <code class="backtick">strdup</code> function that does exactly this. If you don't have one (it's not required by the C standard), you can write your own like this:</p>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"><span class="co">/* return a freshly-malloc'd copy of s */</span>
+<span class="co">/* or 0 if malloc fails */</span>
+<span class="co">/* It is the caller's responsibility to free the returned string when done. */</span>
+<span class="dt">char</span> *
+strdup(<span class="dt">const</span> <span class="dt">char</span> *s)
+{
+ <span class="dt">char</span> *s2;
+
+ s2 = malloc(strlen(s)+<span class="dv">1</span>);
+
+ <span class="kw">if</span>(s2 != <span class="dv">0</span>) {
+ strcpy(s2, s);
+ }
+
+ <span class="kw">return</span> s2;
+}</code></pre></div>
+<p>Exercise: Write a function <code class="backtick">strcatAlloc</code> that returns a freshly-malloc'd string that concatenates its two arguments. Exactly how many bytes do you need to allocate?</p>
+<h3 id="argv"><span class="header-section-number">4.10.9</span> Command-line arguments</h3>
+<p>Now that we know about strings, we can finally do something with <code>argc</code> and <code class="backtick">argv</code>.</p>
+<p>Recall that <code class="backtick">argv</code> in <code class="backtick">main</code> is declared as <code class="backtick">char&nbsp;**</code>; this means that it is a pointer to a pointer to a <code class="backtick">char</code>, or in this case the base address of an array of pointers to <code class="backtick">char</code>,
+ where each such pointer references a string. These strings correspond
+to the command-line arguments to your program, with the program name
+itself appearing in <code class="backtick">argv[0]</code><a href="#fn12" class="footnoteRef" id="fnref12"><sup>12</sup></a></p>
+<p>The count <code class="backtick">argc</code> counts all arguments including <code class="backtick">argv[0]</code>; it is <code class="backtick">1</code> if your program is called with no arguments and larger otherwise.</p>
+<p>Here is a program that prints its arguments. If you get confused about what <code class="backtick">argc</code> and <code class="backtick">argv</code> do, feel free to compile this and play with it:</p>
+<div>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"><span class="ot">#include &lt;stdio.h&gt;</span>
+
+<span class="dt">int</span>
+main(<span class="dt">int</span> argc, <span class="dt">char</span> **argv)
+{
+ <span class="dt">int</span> i;
+
+ printf(<span class="st">"argc = %d</span><span class="ch">\n\n</span><span class="st">"</span>, argc);
+
+ <span class="kw">for</span>(i = <span class="dv">0</span>; i &lt; argc; i++) {
+ printf(<span class="st">"argv[%d] = %s</span><span class="ch">\n</span><span class="st">"</span>, i, argv[i]);
+ }
+
+ <span class="kw">return</span> <span class="dv">0</span>;
+}</code></pre></div>
+<a href="http://cs.yale.edu/homes/aspnes/classes/223/examples/strings/printArgs.c" class="uri">examples/strings/printArgs.c</a>
+</div>
+<p>Like strings, C terminates <code class="backtick">argv</code> with a null: the value of <code class="backtick">argv[argc]</code> is always 0 (a null pointer to <code class="backtick">char</code>). In principle this allows you to recover <code class="backtick">argc</code> if you lose it.</p>
+<h2 id="structuredDataTypes"><span class="header-section-number">4.11</span> Structured data types</h2>
+<p>C has two kinds of structured data types: <code>struct</code>s and <code>union</code>s. A <code>struct</code> holds multiple values in consecutive memory locations, called <strong>fields</strong>, and implements what in type theory is called a <strong>product type</strong>: the set of possible values is the Cartesian product of the sets of possible values for its fields. In contrast, a <code>union</code>
+ has multiple fields but they are all stored in the same location:
+effectively, this means that only one field at a time can hold a value,
+making a <code>union</code> a <strong>sum type</strong> whose set of
+possible values is the union of the sets of possible values for each of
+its fields. Unlike what happens in more sensible programming languages, <code>union</code>s
+ are not tagged: unless you keep track of this somewhere else, you can't
+ tell which field in a union is being used, and you can store a value of
+ one type in a <code>union</code> and try to read it back as a different type, and C won't complain.<a href="#fn13" class="footnoteRef" id="fnref13"><sup>13</sup></a></p>
+<h3 id="structs"><span class="header-section-number">4.11.1</span> Structs</h3>
+<p>A <code class="backtick">struct</code> is a way to define a type that consists of one or more other types pasted together. Here's a typical <code class="backtick">struct</code> definition:</p>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"><span class="kw">struct</span> string {
+ <span class="dt">int</span> length;
+ <span class="dt">char</span> *data;
+};</code></pre></div>
+<p>This defines a new type <code class="backtick">struct&nbsp;string</code> that can be used anywhere you would use a simple type like <code class="backtick">int</code> or <code class="backtick">float</code>. When you declare a variable with type <code class="backtick">struct&nbsp;string</code>, the compiler allocates enough space to hold both an <code class="backtick">int</code> and a <code class="backtick">char&nbsp;*</code> (8 bytes on a typical 32-bit machine). You can get at the individual components using the <code class="backtick">.</code> operator, like this:</p>
+<div>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"><span class="kw">struct</span> string {
+ <span class="dt">int</span> length;
+ <span class="dt">char</span> *data;
+};
+
+<span class="dt">int</span>
+main(<span class="dt">int</span> argc, <span class="dt">char</span> **argv)
+{
+ <span class="kw">struct</span> string s;
+
+ s.length = <span class="dv">4</span>;
+ s.data = <span class="st">"this string is a lot longer than you think"</span>;
+
+ puts(s.data);
+
+ <span class="kw">return</span> <span class="dv">0</span>;
+}</code></pre></div>
+<a href="http://cs.yale.edu/homes/aspnes/classes/223/examples/structs/structExample.c" class="uri">examples/structs/structExample.c</a>
+</div>
+<p>Variables of type <code class="backtick">struct</code> can be
+assigned to, passed into functions, returned from functions, and tested
+for equality, just like any other type. Each such operation is applied
+componentwise; for example, <code class="backtick">s1&nbsp;=&nbsp;s2;</code> is equivalent to <code class="backtick">s1.length&nbsp;=&nbsp;s2.length;&nbsp;s1.data&nbsp;=&nbsp;s2.data;</code> and <code class="backtick">s1&nbsp;==&nbsp;s2</code> is equivalent to <code class="backtick">s1.length&nbsp;==&nbsp;s2.length&nbsp;&amp;&amp;&nbsp;s1.data&nbsp;=&nbsp;s2.data</code>.</p>
+<p>These operations are not used as often as you might think: typically,
+ instead of copying around entire structures, C programs pass around
+pointers, as is done with arrays. Pointers to <code class="backtick">struct</code>s are common enough in C that a special syntax is provided for dereferencing them.<a href="#fn14" class="footnoteRef" id="fnref14"><sup>14</sup></a> Suppose we have:</p>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"> <span class="kw">struct</span> string s; <span class="co">/* a struct */</span>
+ <span class="kw">struct</span> string *sp; <span class="co">/* a pointer to a struct */</span>
+
+ s.length = <span class="dv">4</span>;
+ s.data = <span class="st">"another overly long string"</span>;
+
+ sp = &amp;s; <span class="co">/* sp now points to s */</span></code></pre></div>
+<p>We can then refer to elements of the <code class="backtick">struct&nbsp;string</code> that <code class="backtick">sp</code> points to (i.e. <code class="backtick">s</code>) in either of two ways:</p>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"> puts((*sp).data);
+ puts(sp-&gt;data);</code></pre></div>
+<p>The second is more common, since it involves typing fewer parentheses. It is an error to write <code class="backtick">*sp.data</code> in this case; since <code class="backtick">.</code> binds tighter than <code class="backtick">*</code>, the compiler will attempt to evaluate <code class="backtick">sp.data</code> first and generate an error, since <code class="backtick">sp</code> doesn't have a <code class="backtick">data</code> field.</p>
+<p>Pointers to <code class="backtick">struct</code>s are commonly used in defining <a href="#abstractDataTypes">abstract data data</a>, since it is possible to declare that a function returns e.g. a <code class="backtick">struct&nbsp;string&nbsp;*</code> without specifying the components of a <code class="backtick">struct&nbsp;string</code>. (All pointers to <code class="backtick">struct</code>s
+ in C have the same size and structure, so the compiler doesn't need to
+know the components to pass around the address.) Hiding the components
+discourages code that shouldn't look at them from doing so, and can be
+used, for example, to enforce consistency between fields.</p>
+<p>For example, suppose we wanted to define a <code class="backtick">struct&nbsp;string&nbsp;*</code>
+ type that held counted strings that could only be accessed through a
+restricted interface that prevented (for example) the user from changing
+ the string or its length. We might create a file <code class="backtick">myString.h</code> that contained the declarations:</p>
+<div>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"><span class="co">/* make a struct string * that holds a copy of s */</span>
+<span class="co">/* returns 0 if malloc fails */</span>
+<span class="kw">struct</span> string *makeString(<span class="dt">const</span> <span class="dt">char</span> *s);
+
+<span class="co">/* destroy a struct string * */</span>
+<span class="dt">void</span> destroyString(<span class="kw">struct</span> string *);
+
+<span class="co">/* return the length of a struct string * */</span>
+<span class="dt">int</span> stringLength(<span class="kw">struct</span> string *);
+
+<span class="co">/* return the character at position index in the struct string * */</span>
+<span class="co">/* or returns -1 if index is out of bounds */</span>
+<span class="dt">int</span> stringCharAt(<span class="kw">struct</span> string *s, <span class="dt">int</span> index);</code></pre></div>
+<a href="http://cs.yale.edu/homes/aspnes/classes/223/examples/myString/myString.h" class="uri">examples/myString/myString.h</a>
+</div>
+<p>and then the actual implementation in <code class="backtick">myString.c</code> would be the only place where the components of a <code class="backtick">struct&nbsp;string</code> were defined:</p>
+<div>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"><span class="ot">#include &lt;stdlib.h&gt;</span>
+<span class="ot">#include &lt;string.h&gt;</span>
+
+<span class="ot">#include "myString.h"</span>
+
+<span class="kw">struct</span> string {
+ <span class="dt">int</span> length;
+ <span class="dt">char</span> *data;
+};
+
+<span class="kw">struct</span> string *
+makeString(<span class="dt">const</span> <span class="dt">char</span> *s)
+{
+ <span class="kw">struct</span> string *s2;
+
+ s2 = malloc(<span class="kw">sizeof</span>(<span class="kw">struct</span> string));
+ <span class="kw">if</span>(s2 == <span class="dv">0</span>) { <span class="kw">return</span> <span class="dv">0</span>; } <span class="co">/* let caller worry about malloc failures */</span>
+
+ s2-&gt;length = strlen(s);
+
+ s2-&gt;data = malloc(s2-&gt;length);
+ <span class="kw">if</span>(s2-&gt;data == <span class="dv">0</span>) {
+ free(s2);
+ <span class="kw">return</span> <span class="dv">0</span>;
+ }
+
+ strncpy(s2-&gt;data, s, s2-&gt;length);
+
+ <span class="kw">return</span> s2;
+}
+
+<span class="dt">void</span>
+destroyString(<span class="kw">struct</span> string *s)
+{
+ free(s-&gt;data);
+ free(s);
+}
+
+<span class="dt">int</span>
+stringLength(<span class="kw">struct</span> string *s)
+{
+ <span class="kw">return</span> s-&gt;length;
+}
+
+<span class="dt">int</span>
+stringCharAt(<span class="kw">struct</span> string *s, <span class="dt">int</span> index)
+{
+ <span class="kw">if</span>(index &lt; <span class="dv">0</span> || index &gt;= s-&gt;length) {
+ <span class="kw">return</span> -<span class="dv">1</span>;
+ } <span class="kw">else</span> {
+ <span class="kw">return</span> s-&gt;data[index];
+ }
+}</code></pre></div>
+<a href="http://cs.yale.edu/homes/aspnes/classes/223/examples/myString/myString.c" class="uri">examples/myString/myString.c</a>
+</div>
+<p>In practice, we would probably go even further and replace all the <code class="backtick">struct&nbsp;string&nbsp;*</code> types with a new name declared with <code class="backtick">typedef</code>.</p>
+<h4 id="operations-on-structs"><span class="header-section-number">4.11.1.1</span> Operations on structs</h4>
+<p>What you can do to structs is pretty limited: you can look up or set
+individual components in a struct, you can pass structs to functions or
+as return values from functions (which makes a copy of the original
+struct), and you can assign the contents of one struct to another using <code>s1 = s2</code> (which is equivalent to copying each component separately).</p>
+<p>One thing that you <em>can't</em> do is test two structs for equality using <code>==</code>;
+ this is because structs may contain extra space holding junk data. If
+you want to test for equality, you will need to do it componenti by
+component.</p>
+<h4 id="structLayout"><span class="header-section-number">4.11.1.2</span> Layout in memory</h4>
+<p>The C99 standard guarantees that the components of a <code>struct</code>
+ are stored in memory in the same order that they are defined in: that
+is, later components are placed at higher address. This allows sneaky
+tricks like truncating a structure if you don't use all of its
+components. Because of <a href="#alignment">alignment restrictions</a>, the compiler may add padding between components to put each component on its prefered alignment boundary.</p>
+<p>You can find the position of a component within a <code>struct</code> using the <code>offsetof</code> macro, which is defined in <code>stddef.h</code>.
+ This returns the number of bytes from the base of the struct that the
+component starts at, and can be used to do various terrifying
+non-semantic things with pointers.</p>
+<div>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"><span class="ot">#include &lt;stdio.h&gt;</span>
+<span class="ot">#include &lt;stdlib.h&gt;</span>
+<span class="ot">#include &lt;stddef.h&gt;</span>
+<span class="ot">#include &lt;assert.h&gt;</span>
+
+<span class="dt">int</span>
+main(<span class="dt">int</span> argc, <span class="dt">char</span> **argv)
+{
+ <span class="kw">struct</span> foo {
+ <span class="dt">int</span> i;
+ <span class="dt">char</span> c;
+ <span class="dt">double</span> d;
+ <span class="dt">float</span> f;
+ <span class="dt">char</span> *s;
+ };
+
+ printf(<span class="st">"i is at %lu</span><span class="ch">\n</span><span class="st">"</span>, offsetof(<span class="kw">struct</span> foo, i));
+ printf(<span class="st">"c is at %lu</span><span class="ch">\n</span><span class="st">"</span>, offsetof(<span class="kw">struct</span> foo, c));
+ printf(<span class="st">"d is at %lu</span><span class="ch">\n</span><span class="st">"</span>, offsetof(<span class="kw">struct</span> foo, d));
+ printf(<span class="st">"f is at %lu</span><span class="ch">\n</span><span class="st">"</span>, offsetof(<span class="kw">struct</span> foo, f));
+ printf(<span class="st">"s is at %lu</span><span class="ch">\n</span><span class="st">"</span>, offsetof(<span class="kw">struct</span> foo, s));
+
+ <span class="kw">return</span> <span class="dv">0</span>;
+}</code></pre></div>
+<a href="http://cs.yale.edu/homes/aspnes/classes/223/examples/structs/offsetof.c" class="uri">examples/structs/offsetof.c</a>
+</div>
+<h4 id="Bit_fields"><span class="header-section-number">4.11.1.3</span> Bit fields</h4>
+<p>It is possible to specify the exact number of bits taken up by a member of a <code>struct</code>
+ of integer type. This is seldom useful, but may in principle let you
+pack more information in less space. Bit fields are sometimes used to
+unpack data from an external source that uses this trick, but this is
+dangerous, because there is no guarantee that the compiler will order
+the bit fields in your <code>struct</code> in any particular order (at the very least, you will need to worry about <a href="http://en.wikipedia.org/wiki/Endianness">endianness</a>.</p>
+<p>Example:</p>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"><span class="kw">struct</span> color {
+ <span class="dt">unsigned</span> <span class="dt">int</span> red : <span class="dv">2</span>;
+ <span class="dt">unsigned</span> <span class="dt">int</span> green : <span class="dv">2</span>;
+ <span class="dt">unsigned</span> <span class="dt">int</span> blue : <span class="dv">2</span>;
+ <span class="dt">unsigned</span> <span class="dt">int</span> alpha : <span class="dv">2</span>;
+};</code></pre></div>
+<p>This defines a <code>struct</code> that (probably) occupies only one byte, and supplies four 2-bit fields, each of which can hold values in the range 0-3.</p>
+<h3 id="unions"><span class="header-section-number">4.11.2</span> Unions</h3>
+<p>A <code class="backtick">union</code> is just like a <code class="backtick">struct</code>,
+ except that instead of allocating space to store all the components,
+the compiler only allocates space to store the largest one, and makes
+all the components refer to the same address. This can be used to save
+space if you know that only one of several components will be meaningful
+ for a particular object. An example might be a type representing an
+object in a LISP-like language like Scheme:</p>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"><span class="kw">struct</span> lispObject {
+ <span class="dt">int</span> type; <span class="co">/* type code */</span>
+ <span class="kw">union</span> {
+ <span class="dt">int</span> intVal;
+ <span class="dt">double</span> floatVal;
+ <span class="dt">char</span> * stringVal;
+ <span class="kw">struct</span> {
+ <span class="kw">struct</span> lispObject *car;
+ <span class="kw">struct</span> lispObject *cdr;
+ } consVal;
+ } u;
+};</code></pre></div>
+<p>Now if you wanted to make a <code class="backtick">struct&nbsp;lispObject</code> that held an integer value, you might write</p>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"> lispObject o;
+
+ o.type = TYPE_INT;
+ o.u.intVal = <span class="dv">27</span>;</code></pre></div>
+<p>Here <code class="backtick">TYPE_INT</code> has presumably been defined somewhere. Note that nothing then prevents you from writing</p>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"> x = <span class="fl">2.7</span> * o.u.floatVal; <span class="co">/* BAD */</span></code></pre></div>
+<p>The effects of this will be strange, since it's likely that the bit pattern representing 27 as an <code class="backtick">int</code> represents something very different as a <code class="backtick">double</code>. Avoiding such mistakes is your responsibility, which is why most uses of <code class="backtick">union</code> occur inside larger <code class="backtick">struct</code>s that contain enough information to figure out which variant of the <code class="backtick">union</code> applies.</p>
+<h3 id="enums"><span class="header-section-number">4.11.3</span> Enums</h3>
+<p>C provides the <code class="backtick">enum</code> construction for the special case where you want to have a sequence of named constants of type <code>int</code>, but you don't care what their actual values are, as in</p>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"><span class="kw">enum</span> color { RED, BLUE, GREEN, MAUVE, TURQUOISE };</code></pre></div>
+<p>This will assign the value <code class="backtick">0</code> to <code class="backtick">RED</code>, <code class="backtick">1</code> to <code class="backtick">BLUE</code>, and so on. These values are effectively of type <code class="backtick">int</code>, although you can declare variables, arguments, and return values as type <code class="backtick">enum&nbsp;color</code> to indicate their intended interpretation.</p>
+<p>Despite declaring a variable <code class="backtick">enum&nbsp;color&nbsp;c</code> (say), the compiler will still allow <code class="backtick">c</code> to hold arbitrary values of type <code class="backtick">int</code>.<br>
+So the following ridiculous code works just fine:</p>
+<div>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"><span class="ot">#include &lt;stdio.h&gt;</span>
+<span class="ot">#include &lt;stdlib.h&gt;</span>
+
+<span class="kw">enum</span> foo { FOO };
+<span class="kw">enum</span> apple { MACINTOSH, CORTLAND, RED_DELICIOUS };
+<span class="kw">enum</span> orange { NAVEL, CLEMENTINE, TANGERINE };
+
+<span class="dt">int</span>
+main(<span class="dt">int</span> argc, <span class="dt">char</span> **argv)
+{
+ <span class="kw">enum</span> foo x;
+
+ <span class="kw">if</span>(argc != <span class="dv">1</span>) {
+ fprintf(stderr, <span class="st">"Usage: %s</span><span class="ch">\n</span><span class="st">"</span>, argv[<span class="dv">0</span>]);
+ <span class="kw">return</span> <span class="dv">1</span>;
+ }
+
+ printf(<span class="st">"FOO = %d</span><span class="ch">\n</span><span class="st">"</span>, FOO);
+ printf(<span class="st">"sizeof(enum foo) = %d</span><span class="ch">\n</span><span class="st">"</span>, <span class="kw">sizeof</span>(<span class="kw">enum</span> foo));
+
+ x = <span class="dv">127</span>;
+
+ printf(<span class="st">"x = %d</span><span class="ch">\n</span><span class="st">"</span>, x);
+
+ <span class="co">/* note we can add apples and oranges */</span>
+ printf(<span class="st">"%d</span><span class="ch">\n</span><span class="st">"</span>, RED_DELICIOUS + TANGERINE);
+
+ <span class="kw">return</span> <span class="dv">0</span>;
+}</code></pre></div>
+<a href="http://cs.yale.edu/homes/aspnes/classes/223/examples/definitions/enumsAreInts.c" class="uri">examples/definitions/enumsAreInts.c</a>
+</div>
+<h4 id="specifying-particular-values"><span class="header-section-number">4.11.3.1</span> Specifying particular values</h4>
+<p>It is also possible to specify particular values for particular enumerated constants, as in</p>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"><span class="kw">enum</span> color { RED = <span class="dv">37</span>, BLUE = <span class="dv">12</span>, GREEN = <span class="dv">66</span>, MAUVE = <span class="dv">5</span>, TURQUOISE };</code></pre></div>
+<p>Anything that doesn't get a value starts with one plus the previous value; so the above definition would set <code class="backtick">TURQUOISE</code> to <code class="backtick">6</code>. This may result in two names mapping to the same value.</p>
+<h4 id="what-most-people-do"><span class="header-section-number">4.11.3.2</span> What most people do</h4>
+<p>In practice, <code class="backtick">enum</code>s are seldom used, and you will more commonly see a stack of <code class="backtick">#define</code>s:</p>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"><span class="ot">#define RED (0)</span>
+<span class="ot">#define BLUE (1)</span>
+<span class="ot">#define GREEN (2)</span>
+<span class="ot">#define MAUVE (3)</span>
+<span class="ot">#define TURQUOISE (4)</span></code></pre></div>
+<p>The reason for this is partly historical—<code class="backtick">enum</code> arrived late in the evolution of C—but partly practical: a table of <code class="backtick">#define</code>s
+ makes it much easier to figure out which color is represented by 3,
+without having to count through a list. But if you never plan to use the
+ numerical values, <code class="backtick">enum</code> may be a better choice, because it guarantees that all the values will be distinct.</p>
+<h4 id="enumTagsForUnion"><span class="header-section-number">4.11.3.3</span> Using <code>enum</code> with <code>union</code></h4>
+<p>A natural place to use an <code>enum</code> is to tag a <code>union</code> with the type being used. For example, a Lisp-like language might implement the following multi-purpose data type:</p>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"><span class="kw">enum</span> TypeCode { TYPE_INT, TYPE_DOUBLE, TYPE_STRING };
+
+<span class="kw">struct</span> LispValue {
+ <span class="kw">enum</span> TypeCode typeCode;
+ <span class="kw">union</span> {
+ <span class="dt">int</span> i;
+ <span class="dt">double</span> d;
+ <span class="dt">char</span> *s;
+ } value;
+};</code></pre></div>
+<p>Here we don't care what the numeric values of <code>TYPE_INT</code>, <code>TYPE_DOUBLE</code>, and <code>TYPE_STRING</code> are, as long as we can apply <code>switch</code> to <code>typeCode</code> to figure out what to do with one of these things.</p>
+<h2 id="typedef"><span class="header-section-number">4.12</span> Type aliases using <code>typedef</code></h2>
+<p>Suppose that you want to represent character strings as</p>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"><span class="kw">struct</span> string {
+ <span class="dt">int</span> length;
+ <span class="dt">char</span> *data; <span class="co">/* malloc'd block */</span>
+};
+
+<span class="dt">int</span> stringLength(<span class="dt">const</span> <span class="kw">struct</span> string *s);</code></pre></div>
+<p>If you later change the representation to, say, traditional null-terminated <code class="backtick">char&nbsp;*</code> strings or some even more complicated type (<code class="backtick">union&nbsp;string&nbsp;**some_string[2];</code>), you will need to go back and replace ever occurrence of <code class="backtick">struct&nbsp;string&nbsp;*</code>
+ in every program that uses it with the new type. Even if you don't
+expect to change the type, you may still get tired of typing <code class="backtick">struct&nbsp;string&nbsp;*</code> all the time, especially if your fingers slip and give you <code class="backtick">struct&nbsp;string</code> sometimes.</p>
+<p>The solution is to use a <code class="backtick">typedef</code>, which defines a new type name:</p>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"><span class="kw">typedef</span> <span class="kw">struct</span> string *String;
+
+<span class="dt">int</span> stringLength(String s);</code></pre></div>
+<p>The syntax for <code class="backtick">typedef</code> looks like a variable declaration preceded by <code class="backtick">typedef</code>,
+ except that the variable is replaced by the new type name that acts
+like whatever type the defined variable would have had. You can use a
+name defined with <code class="backtick">typedef</code> anywhere you could use a normal type name, as long as it is later in the source file than the <code class="backtick">typedef</code> definition. Typically <code class="backtick">typedef</code>s are placed in a header file (<code class="backtick">.h</code> file) that is then included anywhere that needs them.</p>
+<p>You are not limited to using <code class="backtick">typedef</code>s
+only for complex types. For example, if you were writing numerical code
+and wanted to declare overtly that a certain quantity was not just any <code class="backtick">double</code> but actually a length in meters, you could write</p>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"><span class="kw">typedef</span> <span class="dt">double</span> LengthInMeters;
+<span class="kw">typedef</span> <span class="dt">double</span> AreaInSquareMeters;
+
+AreaInSquareMeters rectangleArea(LengthInMeters height, LengthInMeters width);</code></pre></div>
+<p>Unfortunately, C does not do type enforcement on <code class="backtick">typedef</code>'d types: it is perfectly acceptable to the compiler if you pass a value of type <code class="backtick">AreaInSquareMeters</code> as the first argument to <code class="backtick">rectangleArea</code>, since by the time it checks it has replaced by <code class="backtick">AreaInSquareMeters</code> and <code class="backtick">LengthInMeters</code> by <code class="backtick">double</code>. So this feature is not as useful as it might be, although it does mean that you can write <code class="backtick">rectangleArea(2.0,&nbsp;3.0)</code> without having to do anything to convert <code class="backtick">2.0</code> and <code class="backtick">3.0</code> to type <code class="backtick">LengthInMeters</code>.</p>
+<h3 id="opaqueStructs"><span class="header-section-number">4.12.1</span> Opaque structs</h3>
+<p>There are certain cases where the compiler needs to know the definition of a <code>struct</code>:</p>
+<ol style="list-style-type: decimal">
+<li>When the program accesses its components.</li>
+<li>When the compiler needs to know its size. This may be because you are building an array of these <code>struct</code>s, because they appear in a larger <code>struct</code>, when you are passing the <code>struct</code> as an argument or assigning it to a variable, or just because you applied <code>sizeof</code> to the <code>struct</code>.</li>
+</ol>
+<p>But the compile does <em>not</em> need to know the definition of a <code>struct</code> to know how create a pointer to it. This is because all <code>struct</code> pointers have the same size and structure.</p>
+<p>This allows a trick called an <strong>opaque struct</strong>, which can be used for <strong>information hiding</strong>, where one part of your program is allowed to see the definition of a <code>struct</code> but other parts are not.</p>
+<p>The idea is to create a header file that defines all the functions that might be used to access the <code>struct</code>, but does not define the <code>struct</code> itself. For example, suppose we want to create a counter, where the user can call a function <code>increment</code> that acts like <code>++</code>
+ in the sense that it increments the counter and returns the new value,
+but we don't want to allow the user to change the value of the counter
+in any other way. This header file defines the <strong>interface</strong> to the counter.</p>
+<p>Here is the header file:</p>
+<div>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"><span class="co">/* Create a new counter, initialized to 0. Call counterDestroy to get rid of it. */</span>
+<span class="kw">struct</span> counter * counterCreate(<span class="dt">void</span>);
+
+<span class="co">/* Free space used by a counter. */</span>
+<span class="dt">void</span> counterDestroy(<span class="kw">struct</span> counter *);
+
+<span class="co">/* Increment a counter and return new value. */</span>
+<span class="dt">int</span> counterIncrement(<span class="kw">struct</span> counter *);</code></pre></div>
+<a href="http://cs.yale.edu/homes/aspnes/classes/223/examples/structs/opaqueStructs/counter.h" class="uri">examples/structs/opaqueStructs/counter.h</a>
+</div>
+<p>We can now write code that uses the <code>struct counter *</code> type without knowing what it is actually pointing to:</p>
+<div>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"><span class="ot">#include &lt;stdio.h&gt;</span>
+<span class="ot">#include &lt;stdlib.h&gt;</span>
+<span class="ot">#include &lt;assert.h&gt;</span>
+
+<span class="ot">#include "counter.h"</span>
+
+<span class="dt">int</span>
+main(<span class="dt">int</span> argc, <span class="dt">char</span> **argv)
+{
+ <span class="kw">struct</span> counter *c;
+ <span class="dt">int</span> value;
+
+ c = counterCreate();
+
+ <span class="kw">while</span>((value = counterIncrement(c)) &lt; <span class="dv">10</span>) {
+ printf(<span class="st">"%d</span><span class="ch">\n</span><span class="st">"</span>, value);
+ }
+
+ counterDestroy(c);
+
+ <span class="kw">return</span> <span class="dv">0</span>;
+}</code></pre></div>
+<a href="http://cs.yale.edu/homes/aspnes/classes/223/examples/structs/opaqueStructs/testCounter.c" class="uri">examples/structs/opaqueStructs/testCounter.c</a>
+</div>
+<p>To make this work, we do have to provide an <strong>implementation</strong>. The obvious way to do it is have a <code>struct counter</code> store the counter value in an <code>int</code>,
+ but one could imagine other (probably bad) implementations that did
+other things, as long as from the outside they acted like we expect.</p>
+<p>We only put the definition of a <code>struct counter</code> in this
+file. This means that only functions in this file can access a counter's
+ components, compute the size of a counter, and so forth. While we can't
+ absolutely prevent some other function from extracting or modifying the
+ contents of a counter (C doesn't provide that kind of memory
+protection), we can at least hint very strongly that the programmer
+shouldn't be doing this.</p>
+<div>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"><span class="ot">#include &lt;stdlib.h&gt;</span>
+<span class="ot">#include &lt;assert.h&gt;</span>
+
+<span class="ot">#include "counter.h"</span>
+
+<span class="kw">struct</span> counter {
+ <span class="dt">int</span> value;
+};
+
+<span class="kw">struct</span> counter *
+counterCreate(<span class="dt">void</span>)
+{
+ <span class="kw">struct</span> counter *c;
+
+ c = malloc(<span class="kw">sizeof</span>(<span class="kw">struct</span> counter));
+ assert(c);
+
+ c-&gt;value = <span class="dv">0</span>;
+
+ <span class="kw">return</span> c;
+}
+
+<span class="dt">void</span>
+counterDestroy(<span class="kw">struct</span> counter *c)
+{
+ free(c);
+}
+
+<span class="dt">int</span>
+counterIncrement(<span class="kw">struct</span> counter *c)
+{
+ <span class="kw">return</span> ++(c-&gt;value);
+}</code></pre></div>
+<a href="http://cs.yale.edu/homes/aspnes/classes/223/examples/structs/opaqueStructs/counter.c" class="uri">examples/structs/opaqueStructs/counter.c</a>
+</div>
+<p>We will see this trick used over and over again when we build <a href="#abstractDataTypes">abstract data types</a>.</p>
+<h2 id="macros"><span class="header-section-number">4.13</span> Macros</h2>
+<p>See K&amp;R Appendix A12.3 for full details on macro expansion in ANSI C and <a href="http://gcc.gnu.org/onlinedocs/cpp/Macros.html" class="uri">http://gcc.gnu.org/onlinedocs/cpp/Macros.html</a> for documentation on what <code>gcc</code> supports.</p>
+<p>The short version: the command</p>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"><span class="ot">#define FOO (12)</span></code></pre></div>
+<p>causes any occurrence of the word <code class="backtick">FOO</code> in your source file to be replaced by <code class="backtick">(12)</code> by the preprocessor. To count as a word, <code class="backtick">FOO</code> can't be adjacent to other alphanumeric characters, so for example <code class="backtick">FOOD</code> will <em>not</em> expand to <code class="backtick">(12)D</code>.</p>
+<h3 id="Macros_with_arguments"><span class="header-section-number">4.13.1</span> Macros with arguments</h3>
+<p>To create a macro with arguments, put them in parentheses separated by commas after the macro name, e.g.</p>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"><span class="ot">#define Square(x) ((x)*(x))</span></code></pre></div>
+<p>Now if you write <code class="backtick">Square(foo)</code> it will expand as <code class="backtick">((foo)*(foo))</code>.
+ Note the heavy use of parentheses inside the macro definition to avoid
+trouble with operator precedence; if instead we had written</p>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"><span class="ot">#define BadSquare(x) x*x</span></code></pre></div>
+<p>then <code class="backtick">BadSquare(3+4)</code> would give <code class="backtick">3+4*3+4</code>, which evaluates to <code class="backtick">19</code>,
+ which is probably not what we intended. The general rule is that macro
+arguments should always be put in parentheses if you are using them in
+an expression where precedence might be an issue.</p>
+<h4 id="Multiple_arguments"><span class="header-section-number">4.13.1.1</span> Multiple arguments</h4>
+<p>You can have multiple arguments to a macro, e.g.</p>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"><span class="ot">#define Average(x,y) (((x)+(y))/2.0)</span></code></pre></div>
+<p>The usual caveats about using lots of parentheses apply.</p>
+<h4 id="Perils_of_repeating_arguments"><span class="header-section-number">4.13.1.2</span> Perils of repeating arguments</h4>
+<p>Macros can have odd effects if their arguments perform side-effects. For example, <code class="backtick">Square(++x)</code> expands to <code class="backtick">((++x)*(++x))</code>; if <code class="backtick">x</code> starts out equal to <code class="backtick">1</code>, this expression may evaluate to any of <code class="backtick">2</code>, <code class="backtick">6</code>, or <code class="backtick">9</code> depending on when the <code class="backtick">++</code> operators are evaluated, and will definitely leave <code class="backtick">3</code> in <code class="backtick">x</code> instead of the <code class="backtick">2</code>
+ the programmer probably expects. For this reason it is generally best
+to avoid side-effects in macro arguments, and to mark macro names (e.g.
+by capitalization) to clearly distinguish them from function names,
+where this issue doesn't come up.</p>
+<h4 id="Variable-length_argument_lists"><span class="header-section-number">4.13.1.3</span> Variable-length argument lists</h4>
+<p>C99 added <strong>variadic macros</strong> that may have a variable number of arguments; these are mostly useful for dealing with variadic functions (like <code>printf</code>) that also take a variable number of arguments.</p>
+<p>To define a variadic macro, define a macro with arguments where the last argument is three periods: <code>...</code> . The macro <code>__VA_ARGS__</code> then expands to whatever arguments matched this ellipsis in the macro call.</p>
+<p>For example:</p>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"><span class="ot">#include &lt;stdio.h&gt;</span>
+
+<span class="ot">#define Warning(...) fprintf(stderr, __VA_ARGS__)</span>
+
+<span class="dt">int</span>
+main(<span class="dt">int</span> argc, <span class="dt">char</span> **argv)
+{
+ Warning(<span class="st">"%s: this program contains no useful code</span><span class="ch">\n</span><span class="st">"</span>, argv[<span class="dv">0</span>]);
+
+ <span class="kw">return</span> <span class="dv">1</span>;
+}</code></pre></div>
+<p>It is possible to mix regular arguments with <code>...</code>, as long as <code>...</code> comes last:</p>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"><span class="ot">#define Useless(format, ...) printf(format, __VA_ARGS__)</span></code></pre></div>
+<h4 id="macros-vs.-inline-functions"><span class="header-section-number">4.13.1.4</span> Macros vs. inline functions</h4>
+<p>It is sometimes tempting to use a macro to avoid having to retype
+some small piece of code that does not seem big enough to justify a
+full-blown function, especially if the cost of the body of the function
+is small relative to the cost of a function call. <strong>Inline functions</strong>
+ are a mechanism that is standard in C99 (and found in some compilers
+for older variants of C) that give you the ability to write a function
+that will never pay this function call overhead; instead, any call to an
+ inline function is effectively replaced by the body of the function.
+Unlike parameterized macros, inline functions do not suffer from issues
+with duplicated parameters or weird text-substitution oddities.</p>
+<p>To take a simple example, the <code>distSquared</code> function that we used to illustrate <a href="#functionDefinitions">function definitions</a> doesn't do very much: just two multiplications and an addition. If we are doing a lot of <code>distSquared</code>
+ computations, we could easily double the cost of each computation with
+function call overhead. One alternative might be to use a macro:</p>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"><span class="ot">#define DistSquared(x,y) ((x)*(x)+(y)*(y))</span></code></pre></div>
+<p>but this suffers from the parameter-duplication problem, which could be particularly unfortunate if we compute <code>DistSquared(expensiveFunctionWithManySideEffects(), 12)</code>. A better alternative is to use an inline function.</p>
+<p>Like macros, inline functions should be defined in header files.
+Ordinary functions always go in C files because (a) we only want to
+compile them once, and (b) the linker will find them in whatever <code>.o</code> file they end up in anyway. But inline functions generally don't get compiled independently, so this doesn't apply.</p>
+<p>Here is a header file for an inline version of <code>distSquared</code>:</p>
+<div>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"><span class="co">/* Returns the square of the distance between two points separated by </span>
+<span class="co"> dx in the x direction and dy in the y direction. */</span>
+<span class="dt">static</span> <span class="kw">inline</span> <span class="dt">int</span>
+distSquared(<span class="dt">int</span> dx, <span class="dt">int</span> dy)
+{
+ <span class="kw">return</span> dx*dx + dy*dy;
+}</code></pre></div>
+<a href="http://cs.yale.edu/homes/aspnes/classes/223/examples/functions/distSquaredInline.h" class="uri">examples/functions/distSquaredInline.h</a>
+</div>
+<p>This looks exactly like the original <code>distSquared</code>, except that we added <code>static inline</code>. We want this function to be declared <code>static</code>
+ because otherwise some compilers will try to emit a non-inline
+definition for it in ever C file this header is included in, which could
+ have bad results.<a href="#fn15" class="footnoteRef" id="fnref15"><sup>15</sup></a></p>
+<p>The nice thing about this approach is that if we do decide to make <code>distSquared</code>
+ an ordinary function (maybe it will make debugging easier, or we
+realize we want to be able to take its address), then we can just move
+the definition into a <code>.c</code> file and take the <code>static inline</code>
+ off. Indeed, this is probably the safest thing to start with, since we
+can also do the reverse if we find that function call overhead on this
+particular function really does account for a non-trivial part of our
+running time (see <a href="#profiling">profiling</a>).</p>
+<h3 id="Multiple_macros"><span class="header-section-number">4.13.2</span> Macros that include other macros</h3>
+<p>One macro can expand to another; for example, after defining</p>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"><span class="ot">#define FOO BAR</span>
+<span class="ot">#define BAR (12)</span></code></pre></div>
+<p>it will be the case that <code class="backtick">FOO</code> will expand to <code class="backtick">BAR</code> which will then expand to <code class="backtick">(12)</code>. For obvious reasons, it is a bad idea to have a macro expansion contain the original macro name.</p>
+<h3 id="Macro_tricks"><span class="header-section-number">4.13.3</span> More specialized macros</h3>
+<p>Some standard idioms have evolved over the years to deal with issues
+that come up in defining complex macros. Usually, having a complex macro
+ is a sign of bad design, but these tools can be useful in some
+situations.</p>
+<h4 id="Multiple_expressions_in_a_macro"><span class="header-section-number">4.13.3.1</span> Multiple expressions in a macro</h4>
+<p>Use the comma operator, e.g.</p>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"><span class="ot">#define NoisyInc(x) (puts("incrementing"), (x)++)</span></code></pre></div>
+<p>The comma operator evaluates both of its operands and returns the value of the one on the right-hand side.</p>
+<p>You can also choose between alternatives using the ternary <code class="backtick">?:</code> operator, as in</p>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"><span class="ot">#define Max(a,b) ((a) &gt; (b) ? (a) : (b))</span></code></pre></div>
+<p>(but see the warning about repeated parameters above).</p>
+<h4 id="nonSyntacticMacros"><span class="header-section-number">4.13.3.2</span> Non-syntactic macros</h4>
+<p>Suppose you get tired of writing</p>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"> <span class="kw">for</span>(i = <span class="dv">0</span>; i &lt; n; i++) ...</code></pre></div>
+<p>all the time. In principle, you can write a macro</p>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"><span class="ot">#define UpTo(i, n) for((i) = 0; (i) &lt; (n); (i)++)</span></code></pre></div>
+<p>and then write</p>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"> UpTo(i, <span class="dv">10</span>) ...</code></pre></div>
+<p>in place of your former <code class="backtick">for</code> loop headers. This is generally a good way to make your code completely unreadable. Such macros are called <strong>non-syntactic</strong> because they allow code that doesn't look like syntactically correct C.</p>
+<p>Sometimes, however, it makes sense to use non-syntactic macros when
+you want something that writes to a variable without having to pass it
+to a function as a pointer. An example might be something like this <code class="backtick">malloc</code> wrapper:</p>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"><span class="ot">#define TestMalloc(x) ((x) = malloc(sizeof(*x)), assert(x))</span></code></pre></div>
+<p>(Strictly speaking, this is probably more of a "non-semantic" macro.)</p>
+<p>Whether the confusion of having a non-syntactic macro is worth the
+gain in safety or code-writing speed is a judgment call that can only be
+ made after long and painful experience. If in doubt, it's probably best
+ not to do it.</p>
+<h4 id="Multiple_statements_in_one_macro"><span class="header-section-number">4.13.3.3</span> Multiple statements in one macro</h4>
+<p>If you want to write a macro that looks like a function call but contains multiple statements, the correct way to do it is like</p>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"><span class="ot">#define HiHi() do { puts("hi"); puts("hi"); } while(0)</span></code></pre></div>
+<p>This can safely be used in place of single statements, like this:<a href="#fn16" class="footnoteRef" id="fnref16"><sup>16</sup></a></p>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"> <span class="kw">if</span>(friendly)
+ HiHi();
+ <span class="kw">else</span>
+ snarl();</code></pre></div>
+<p>Note that no construct except <code class="backtick">do..while</code> will work here. Just using braces will cause trouble with the semicolon before the <code class="backtick">else</code>, and no other compound statement besides <code class="backtick">do..while</code> expects to be followed by a semicolon in this way.</p>
+<h4 id="String_expansion"><span class="header-section-number">4.13.3.4</span> String expansion</h4>
+<p>Let's rewrite <code class="backtick">NoisyInc</code> to include the variable name:</p>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"><span class="ot">#define BadNoisyInc2(x) (puts("Incrementing x"), x++)</span></code></pre></div>
+<p>Will this do what we want? No. The C preprocessor is smart enough not to expand macro parameters inside strings, so <code class="backtick">BadNoisyInc2(y)</code> will expand to <code class="backtick">(puts("Incrementing&nbsp;x"),&nbsp;y++)</code>. Instead, we have to write</p>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"><span class="ot">#define NoisyInc2(x) (puts("Incrementing " #x), x++)</span></code></pre></div>
+<p>Here <code class="backtick">#x</code> expands to whatever the value of <code class="backtick">x</code>
+ is wrapped in double quotes. The resulting string constant is then
+concatenated with the adjacent string constant according to standard C
+string constant concatenation rules.</p>
+<p>To concatenate things that aren't strings, use the <code class="backtick">##</code> operator, as in</p>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"><span class="ot">#define FakeArray(n) fakeArrayVariableNumber ## n</span></code></pre></div>
+<p>This lets you write <code class="backtick">FakeArray(12)</code> instead of <code class="backtick">fakeArrayVariableNumber12</code>. Note that there is generally no good reason to ever do this.</p>
+<p>Where this feature does become useful is if you want to be able to
+refer to part of the source code of your program. For example, here is
+short program that includes a macro that prints the source code and
+value of an expression:</p>
+<div>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"><span class="ot">#include &lt;stdio.h&gt;</span>
+
+<span class="ot">#define PrintExpr(x) (printf("%s = %d\n", #x, (x)))</span>
+
+<span class="dt">int</span>
+main(<span class="dt">int</span> argc, <span class="dt">char</span> **argv)
+{
+ PrintExpr(<span class="dv">2+2</span>);
+ <span class="kw">return</span> <span class="dv">0</span>;
+}</code></pre></div>
+<a href="http://cs.yale.edu/homes/aspnes/classes/223/examples/macros/printExpr.c" class="uri">examples/macros/printExpr.c</a>
+</div>
+<p>When run, this program prints</p>
+<pre><code>2+2 = 4</code></pre>
+<p>Without using a macro, there is no way to capture the text string <code class="backtick">"2+2"</code> so we can print it.</p>
+<p>This sort of trickery is mostly used in debugging. The <code class="backtick">assert</code> macro is a more sophisticated version, which uses the built-in macros <code class="backtick">__FILE__</code> (which expands to the current source file as a quoted string) and <code class="backtick">__LINE__</code>
+ (which expands to the current source line number, not quoted) to not
+only print out an offending expression, but also the location of it in
+the source.</p>
+<h4 id="Big_macros"><span class="header-section-number">4.13.3.5</span> Big macros</h4>
+<p>Nothing restricts a macro expansion to a single line, although you
+must put a backslash at the end of each line to keep it going. Here is a
+ macro that declares a specialized sorting routine for any type that
+supports <code class="backtick">&lt;</code>:</p>
+<div>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"><span class="ot">#define DeclareSort(prefix, type) \</span>
+<span class="ot">static int \</span>
+<span class="ot">_DeclareSort_ ## prefix ## _Compare(const void *a, const void *b) \</span>
+<span class="ot">{ \</span>
+<span class="ot"> const type *aa; const type *bb; \</span>
+<span class="ot"> aa = a; bb = b; \</span>
+<span class="ot"> if(*aa &lt; *bb) return -1; \</span>
+<span class="ot"> else if(*bb &lt; *aa) return 1; \</span>
+<span class="ot"> else return 0; \</span>
+<span class="ot">} \</span>
+<span class="ot">\</span>
+<span class="ot">void \</span>
+<span class="ot">prefix ## _sort(type *a, int n)\</span>
+<span class="ot">{ \</span>
+<span class="ot"> qsort(a, n, sizeof(type), _DeclareSort_ ## prefix ## _Compare); \</span>
+<span class="ot">}</span></code></pre></div>
+<a href="http://cs.yale.edu/homes/aspnes/classes/223/examples/macros/declareSort.h" class="uri">examples/macros/declareSort.h</a>
+</div>
+<p>A typical use might be</p>
+<div>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"><span class="ot">#include &lt;stdio.h&gt;</span>
+<span class="ot">#include &lt;stdlib.h&gt;</span>
+
+<span class="ot">#include "declareSort.h"</span>
+
+<span class="co">/* note: must appear outside of any function, and has no trailing semicolon */</span>
+DeclareSort(<span class="dt">int</span>, <span class="dt">int</span>)
+
+<span class="ot">#define N (50)</span>
+
+<span class="dt">int</span>
+main(<span class="dt">int</span> argc, <span class="dt">char</span> **argv)
+{
+ <span class="dt">int</span> a[N];
+ <span class="dt">int</span> i;
+
+ <span class="kw">for</span>(i=<span class="dv">0</span>; i &lt; N; i++) {
+ a[i] = N-i;
+ }
+
+ int_sort(a, N);
+
+ <span class="kw">for</span>(i=<span class="dv">0</span>; i &lt; N; i++) {
+ printf(<span class="st">"%d "</span>, a[i]);
+ }
+ putchar(<span class="ch">'\n'</span>);
+
+ <span class="kw">return</span> <span class="dv">0</span>;
+}</code></pre></div>
+<a href="http://cs.yale.edu/homes/aspnes/classes/223/examples/macros/useDeclareSort.c" class="uri">examples/macros/useDeclareSort.c</a>
+</div>
+<p>Do this too much and you will end up reinventing C++ templates, which
+ are a more or less equivalent mechanism for generating polymorphic code
+ that improve on C macros like the one above by letting you omit the
+backslashes.</p>
+<h3 id="ifdef"><span class="header-section-number">4.13.4</span> Conditional compilation</h3>
+<p>In addition to generating code, macros can be used for <strong>conditional compiliation</strong>, where a section of the source code is included only if a particular macro is defined. This is done using the <code>#ifdef</code> and <code>#ifndef</code> preprocessor directives. In its simplest form, writing <code>#ifdef NAME</code> includes all code up to the next <code>#endif</code> if and only if <code>NAME</code> is defined. Similarly, <code>#ifndef NAME</code> includes all code up to the next <code>#endif</code> if and only if <code>NAME</code> is <em>not</em> defined.</p>
+<p>Like regular C <code>if</code> statements, <code>#ifdef</code> and <code>#ifndef</code> directives can be nested, and can include else cases, which are separated by an <code>#else</code> directive.</p>
+<div>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"><span class="ot">#include &lt;stdio.h&gt;</span>
+<span class="ot">#include &lt;assert.h&gt;</span>
+
+<span class="dt">int</span>
+main(<span class="dt">int</span> argc, <span class="dt">char</span> **argv)
+{
+<span class="ot">#ifdef SAY_HI</span>
+ puts(<span class="st">"Hi."</span>);
+<span class="ot">#else </span><span class="co">/* matches #ifdef SAY_HI */</span>
+<span class="ot">#ifndef BE_POLITE</span>
+ puts(<span class="st">"Go away!"</span>);
+<span class="ot">#else </span><span class="co">/* matches #ifndef BE_POLITE */</span>
+ puts(<span class="st">"I'm sorry, I don't feel like talking today."</span>);
+<span class="ot">#endif </span><span class="co">/* matches #ifndef BE_POLITE */</span>
+<span class="ot">#endif </span><span class="co">/* matches #ifdfe SAY_HI */</span>
+
+<span class="ot">#ifdef DEBUG_ARITHMETIC</span>
+ assert(<span class="dv">2+2</span> == <span class="dv">5</span>);
+<span class="ot">#endif</span>
+
+ <span class="kw">return</span> <span class="dv">0</span>;
+}</code></pre></div>
+<a href="http://cs.yale.edu/homes/aspnes/classes/223/examples/macros/ifdef.c" class="uri">examples/macros/ifdef.c</a>
+</div>
+<h3 id="defining-macros-on-the-command-line"><span class="header-section-number">4.13.5</span> Defining macros on the command line</h3>
+<p>You can turn these conditional compilation directives on and off at compile time by passing the <code>-D</code> flag to <code>gcc</code>. Here is the program above, running after compiling with different choices of options:</p>
+<pre><code>$ gcc -DSAY_HI -o ifdef ifdef.c
+$ ./ifdef
+Hi.
+$ gcc -DBE_POLITE -DDEBUG_ARITHMETIC -o ifdef ifdef.c
+$ ./ifdef
+I'm sorry, I don't feel like talking today.
+ifdef: ifdef.c:18: main: Assertion `2+2 == 5' failed.
+Aborted</code></pre>
+<p>An example of how this mechanism can be useful is the <code>NDEBUG</code> macro: if you define this before including <code>assert.h</code>, it turns every <code>assert</code>
+ in your code into a no-op. This can be handy if you are pretty sure
+your code works and you want to speed it up in its final shipped
+version, or if you are pretty sure your code doesn't work but you want
+to hide the evidence. (It also means you should not perform side-effects
+ inside an <code>assert</code> unless you are happy with them not happening.)</p>
+<p>Using the flag <code>-DNAME</code> defines <code>NAME</code> to be <code>1</code>. If you want something else, use <code>-DNAME=VALUE</code>.
+ This can be used to bake useful information into your program at
+compile time, and is often used to specify filenames. Below is a simple
+example.</p>
+<div>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"><span class="ot">#include &lt;stdio.h&gt;</span>
+
+<span class="dt">int</span>
+main(<span class="dt">int</span> argc, <span class="dt">char</span> **argv)
+{
+<span class="ot">#ifdef MESSAGE</span>
+ puts(MESSAGE);
+<span class="ot">#endif</span>
+
+ <span class="kw">return</span> <span class="dv">0</span>;
+}</code></pre></div>
+<a href="http://cs.yale.edu/homes/aspnes/classes/223/examples/macros/message.c" class="uri">examples/macros/message.c</a>
+</div>
+<pre><code>$ gcc -DMESSAGE='"Hi there!"' -o message message.c
+$ ./message
+Hi there!</code></pre>
+<p>Note that we had to put an extra layer of single quotes in the
+command line to keep the shell from stripping off the double quotes.
+This is unavoidable: had we written <code>puts("MESSAGE")</code> in the code, the preprocessor would have recognized that <code>MESSAGE</code> appeared inside a string and would not have replaced it.<a href="#fn17" class="footnoteRef" id="fnref17"><sup>17</sup></a></p>
+<h3 id="the-if-directive"><span class="header-section-number">4.13.6</span> The <code>#if</code> directive</h3>
+<p>The preprocessor also includes a more general <code>#if</code>
+directive that evaluates simple arithmetic expressions. The limitations
+are that it can only do integer arithmetic (using the widest signed
+integer type available to the compiler) and can only do it to integer
+and character constants and the special operator <code>defined(NAME)</code>, which evaluates to 1 if <code>NAME</code> is defined and 0 otherwise. The most common use of this is to combine several <code>#ifdef</code>-like tests into one:</p>
+<div>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"><span class="ot">#include &lt;stdio.h&gt;</span>
+
+<span class="dt">int</span>
+main(<span class="dt">int</span> argc, <span class="dt">char</span> **argv)
+{
+<span class="ot">#if VERBOSITY &gt;= 3 &amp;&amp; defined(SAY_HI)</span>
+ puts(<span class="st">"Hi!"</span>);
+<span class="ot">#endif</span>
+
+ <span class="kw">return</span> <span class="dv">0</span>;
+}</code></pre></div>
+<a href="http://cs.yale.edu/homes/aspnes/classes/223/examples/macros/if.c" class="uri">examples/macros/if.c</a>
+</div>
+<h3 id="Debugging_macro_expansions"><span class="header-section-number">4.13.7</span> Debugging macro expansions</h3>
+<p>One problem with using a lot of macros is that you can end up with no
+ idea what input is actually fed to the compiler after the preprocessor
+is done with it. You can tell <code class="backtick">gcc</code> to tell you how everything expands using <code class="backtick">gcc&nbsp;-E&nbsp;source_file.c</code>. If your source file contains any <code class="backtick">#include</code> statements it is probably a good idea to send the output of <code class="backtick">gcc&nbsp;-E</code> to a file so you can scroll down past the thousands of lines of text they may generate.</p>
+<h3 id="Can_a_macro_call_a_preprocessor_command.3F"><span class="header-section-number">4.13.8</span> Can a macro call a preprocessor command?</h3>
+<p>E.g., can you write something like</p>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"><span class="ot">#define DefinePlus1(x, y) #define x ((y)+1)</span>
+<span class="ot">#define IncludeLib(x) #include "lib/" #x</span></code></pre></div>
+<p>The answer is <strong>no</strong>. C preprocessor commands are only
+recognized in unexpanded text. If you want self-modifying macros you
+will need to use a fancier macro processor like <a href="http://en.wikipedia.org/wiki/M4_%28computer_language%29">m4</a>.</p>
+<h1 id="dataStructuresAndProgrammingTechniques"><span class="header-section-number">5</span> Data structures and programming techniques</h1>
+<p>Up until this point we have mostly concentrated on the details of the
+ C programming language. In this part of the notes, we will be looking
+more at how to construct data structures and how to organize a program.
+In principle, these techniques can be applied to any programming
+language that supports the appropriate low-level data types, but we will
+ continue to emphasize issues involved with implementation in C.</p>
+<h2 id="asymptoticNotation"><span class="header-section-number">5.1</span> Asymptotic notation</h2>
+<p><strong>Asymptotic notation</strong> is a tool for measuring the
+growth rate of functions, which for program design usually means the way
+ in which the time or space costs of a program scale with the size of
+the input. We'll start with an example of why this is important.</p>
+<h3 id="two-sorting-algorithms"><span class="header-section-number">5.1.1</span> Two sorting algorithms</h3>
+<p>Suppose we want to sort in increasing order a deck of <span class="math inline"><em>n</em></span> cards, numbered <span class="math inline">1</span> through <span class="math inline"><em>n</em></span>. Here are two algorithms for doing this.</p>
+<p>In the '''mergesort''' algorithm, we start with <span class="math inline"><em>n</em></span>
+ piles of one card each. We then take pairs of piles and merge them
+together, by repeatedly pulling the smaller of the two smallest cards
+off the top of the pile and putting it on the bottom of our output pile.
+ After the first round of this, we have <span class="math inline"><em>n</em>/2</span> piles of two cards each. After another round, <span class="math inline"><em>n</em>/4</span> piles of four cards each, and so on until we get one pile with <span class="math inline"><em>n</em></span> cards after roughly <span class="math inline">log<sub>2</sub><em>n</em></span> rounds of merging.</p>
+<p>Here's a picture of this algorithm in action on 8 cards:</p>
+<pre><code>5 7 1 2 3 4 8 6
+
+57 12 34 68
+
+1257 3468
+
+12345678</code></pre>
+<p>Suppose that we want to estimate the cost of this algorithm without
+actually coding it up. We might observe that each time a card is merged
+into a new pile, we need to do some small, fixed number of operations to
+ decide that it's the smaller card, and then do an additional small,
+fixed number of operations to physically move it to a new place. If we
+are really clever, we might notice that since the size of the pile a
+card is in doubles with each round, there can be at most <span class="math inline">⌈log<sub>2</sub><em>n</em>⌉</span> rounds until all cards are in the same pile. So the cost of getting a single card in the right place will be at most <span class="math inline"><em>c</em>log<em>n</em></span> where <span class="math inline"><em>c</em></span>
+ counts the "small, fixed" number of operations that we keep mentioning,
+ and the cost of getting every card in the right place will be at most <span class="math inline"><em>c</em><em>n</em>log<em>n</em></span>.</p>
+<p>In the '''selection sort''' algorithm, we look through all the cards
+to find the smallest one, swap it to the beginning of the list, then
+look through the remaining cards for the second smallest, swap it to the
+ next position, and so on.</p>
+<p>Here's a picture of this algorithm in action on 8 cards:</p>
+<pre><code>57123486
+
+17523486
+
+12573486
+
+12375486
+
+12345786
+
+12345786
+
+12345687
+
+12345678</code></pre>
+<p>This is a simpler algorithm to implement that mergesort, but it is
+usually slower on large inputs. We can formalize this by arguing that
+each time we scan <span class="math inline"><em>k</em></span> cards to
+find the smallest, it's going to take some small, fixed number of
+operations to test each card against the best one we found so far, and
+an additional small, fixed number of operations to swap the smallest
+card to the right place. To compute the total cost we have to add these
+costs for all cards, which will give us a total cost that looks
+something like <span class="math inline">$(c_1 n + c_2) + (c_1 (n-1) + c_2) + (c_1 (n-2) + c_2) + \ldots + (c1 \dot 1 + c_2) = c_1 n(n+1)/2 + c_2 n$</span>.</p>
+<p>For large <span class="math inline"><em>n</em></span>, it looks like
+this is going to cost more than mergesort. But how can we make this
+claim cleanly, particularly if we don't know the exact values of <span class="math inline"><em>c</em></span>, <span class="math inline"><em>c</em><sub>1</sub></span>, and <span class="math inline"><em>c</em><sub>2</sub></span>?</p>
+<h3 id="big-o-to-the-rescue"><span class="header-section-number">5.1.2</span> Big-O to the rescue</h3>
+<p>The idea is to replace complex running time formulae like <span class="math inline"><em>c</em><em>n</em>log<em>n</em></span> or <span class="math inline"><em>c</em><sub>1</sub><em>n</em>(<em>n</em> + 1)/2 + <em>c</em><sub>2</sub><em>n</em></span> with an asymptotic growth rate <span class="math inline"><em>O</em>(<em>n</em>log<em>n</em>)</span> or <span class="math inline"><em>O</em>(<em>n</em><sup>2</sup>)</span>.
+ These asymptotic growth rates omit the specific details of exactly how
+fast our algorithms run (which we don't necessarily know without
+actually coding them up) and concentrate solely on how the cost scales
+as the size of the input <span class="math inline"><em>n</em></span> becomes large.</p>
+<p>This avoids two issues:</p>
+<ol style="list-style-type: decimal">
+<li>Different computers run at different speeds, and we'd like to be
+able to say that one algorithm is better than another without having to
+measure its running time on specific hardware.</li>
+<li>Performance on large inputs is more important than performance on
+small inputs, since programs running on small inputs are usually pretty
+fast.</li>
+</ol>
+<p>The idea of '''asymptotic notation''' is to consider the shape of the worst-case cost <span class="math inline"><em>T</em>(<em>n</em>)</span> to process an input of size <span class="math inline"><em>n</em></span>.
+ Here, worst-case means we consider the input that gives the greatest
+cost, where cost is usually time, but may be something else like space.
+To formalize the notion of shape, we define classes of functions that
+behave like particular interesting functions for large inputs. The
+definition looks much like a limit in calculus:</p>
+<dl>
+<dt><span class="math inline"><em>O</em>(<em>n</em>)</span></dt>
+<dd>A function <span class="math inline"><em>f</em>(<em>n</em>)</span> is in the class <span class="math inline"><em>O</em>(<em>g</em>(<em>n</em>))</span> if there exist constants <span class="math inline"><em>N</em></span> and <span class="math inline"><em>c</em></span> such that <span class="math inline"><em>f</em>(<em>n</em>)&lt;<em>c</em> ⋅ <em>g</em>(<em>n</em>)</span> when <span class="math inline"><em>n</em> &gt; <em>N</em></span>.
+</dd>
+</dl>
+<p>If <span class="math inline"><em>f</em>(<em>n</em>)</span> is in <span class="math inline"><em>O</em>(<em>g</em>(<em>n</em>))</span> we say <span class="math inline"><em>f</em>(<em>n</em>)</span> is '''big-O''' of <span class="math inline"><em>g</em>(<em>n</em>)</span> or just <span class="math inline"><em>f</em>(<em>n</em>)=<em>O</em>(<em>g</em>(<em>n</em>))</span>.<a href="#fn18" class="footnoteRef" id="fnref18"><sup>18</sup></a></p>
+<p>Unpacked, this definition says that <span class="math inline"><em>f</em>(<em>n</em>)</span> is less than a constant times <span class="math inline"><em>g</em>(<em>n</em>)</span> when <span class="math inline"><em>n</em></span> is large enough.</p>
+<p>Some examples:</p>
+<ul>
+<li>Let <span class="math inline"><em>f</em>(<em>n</em>)=3<em>n</em> + 12</span>, and let <span class="math inline"><em>g</em>(<em>n</em>)=<em>n</em></span>. To show that <span class="math inline"><em>f</em>(<em>n</em>)</span> is in <span class="math inline"><em>O</em>(<em>g</em>(<em>n</em>)) = <em>O</em>(<em>n</em>)</span>, we can pick whatever constants we want for <span class="math inline"><em>c</em></span> and <span class="math inline"><em>N</em></span> (as long as they work). So let's make <span class="math inline"><em>N</em></span> be <span class="math inline">100</span> and <span class="math inline"><em>c</em></span> be <span class="math inline">4</span>. Then we need to show that if <span class="math inline"><em>n</em> &gt; 100</span>, <span class="math inline">3<em>n</em> + 12 &lt; 4<em>n</em></span>. But <span class="math inline">3<em>n</em> + 12 &lt; 4<em>n</em></span> holds precisely when <span class="math inline">12 &lt; <em>n</em></span>, which is implied by our assumption that <span class="math inline"><em>n</em> &gt; 100</span>.</li>
+<li>Let <span class="math inline"><em>f</em>(<em>n</em>)=4<em>n</em><sup>2</sup> + 23<em>n</em> + 15</span>, and let <span class="math inline"><em>g</em>(<em>n</em>)=<em>n</em><sup>2</sup></span>. Now let <span class="math inline"><em>N</em></span> be <span class="math inline">100</span> again and <span class="math inline"><em>c</em></span> be <span class="math inline">5</span>. So we need <span class="math inline">4<em>n</em><sup>2</sup> + 23<em>n</em> + 15 &lt; 5<em>n</em><sup>2</sup></span>, or <span class="math inline">23<em>n</em> + 15 &lt; <em>n</em><sup>2</sup></span>. But <span class="math inline"><em>n</em> &gt; 100</span> means that <span class="math inline"><em>n</em><sup>2</sup> &gt; 100<em>n</em> = 50<em>n</em> + 50<em>n</em> &gt; 50<em>n</em> + 5000 &gt; 23<em>n</em> + 15</span>, which proves that <span class="math inline"><em>f</em>(<em>n</em>)</span> is in <span class="math inline"><em>O</em>(<em>n</em><sup>2</sup>)</span>.</li>
+<li>Let <span class="math inline"><em>f</em>(<em>n</em>)&lt;146</span> for all <span class="math inline"><em>n</em></span>, and let <span class="math inline"><em>g</em>(<em>n</em>)=1</span>. Then for <span class="math inline"><em>N</em> = 0</span> and <span class="math inline"><em>c</em> = 146</span>, <span class="math inline"><em>f</em>(<em>n</em>)&lt;146 = 146<em>g</em>(<em>n</em>)</span>, and <span class="math inline"><em>f</em>(<em>n</em>)</span> is in <span class="math inline"><em>O</em>(1)</span>.</li>
+</ul>
+<p>Writing proofs like this over and over again is a nuisance, so we can use some basic rules of thumb to reduce messy functions <span class="math inline"><em>f</em>(<em>n</em>)</span> to their asymptotic forms:</p>
+<ul>
+<li>If <span class="math inline"><em>c</em></span> is a constant (doesn't depend on <span class="math inline"><em>n</em></span>), then <span class="math inline"><em>c</em> ⋅ <em>f</em>(<em>n</em>)=<em>O</em>(<em>f</em>(<em>n</em>))</span>. This follows immediately from being able to pick <span class="math inline"><em>c</em></span> in the definition. So we can always get rid of constant factors: <span class="math inline">137<em>n</em><sup>5</sup> = <em>O</em>(<em>n</em><sup>5</sup>)</span>.</li>
+<li>If <span class="math inline"><em>f</em>(<em>n</em>)=<em>g</em>(<em>n</em>)+<em>h</em>(<em>n</em>)</span>, then the bigger of <span class="math inline"><em>g</em>(<em>n</em>)</span> or <span class="math inline"><em>h</em>(<em>n</em>)</span> wins. This is because if <span class="math inline"><em>g</em>(<em>n</em>)≤<em>h</em>(<em>n</em>)</span>, then <span class="math inline"><em>g</em>(<em>n</em>)+<em>h</em>(<em>n</em>)≤2<em>g</em>(<em>n</em>)</span>, and then big-O eats the 2. So <span class="math inline">12<em>n</em><sup>2</sup> + 52<em>n</em> + 3 = <em>O</em>(<em>n</em><sup>2</sup>)</span> because <span class="math inline"><em>n</em><sup>2</sup></span> dominates all the other terms.</li>
+<li>To figure out which of two terms dominates, the rule is
+<ul>
+<li>Bigger exponents win: If <span class="math inline"><em>a</em> &lt; <em>b</em></span>, then <span class="math inline"><em>O</em>(<em>n</em><sup><em>a</em></sup>)+<em>O</em>(<em>n</em><sup><em>b</em></sup>)=<em>O</em>(<em>n</em><sup><em>b</em></sup>)</span>.</li>
+<li>Polynomials beat logarithms: For any <span class="math inline"><em>a</em></span> and any <span class="math inline"><em>b</em> &gt; 0</span>, <span class="math inline"><em>O</em>(log<sup><em>a</em></sup><em>n</em>)+<em>O</em>(<em>n</em><sup><em>b</em></sup>)=<em>O</em>(<em>n</em><sup><em>b</em></sup>)</span>.</li>
+<li>Exponentials beat polynomials: For any <span class="math inline"><em>a</em></span> and any <span class="math inline"><em>b</em> &gt; 1</span>, <span class="math inline"><em>O</em>(<em>n</em><sup><em>a</em></sup>)+<em>O</em>(<em>b</em><sup><em>n</em></sup>)=<em>O</em>(<em>b</em><sup><em>n</em></sup>)</span>.</li>
+<li>The distributive law works: Because <span class="math inline"><em>O</em>(log<em>n</em>)</span> dominates <span class="math inline"><em>O</em>(1)</span>, <span class="math inline"><em>O</em>(<em>n</em>log<em>n</em>)</span> dominates <span class="math inline"><em>O</em>(<em>n</em>)</span>.</li>
+</ul></li>
+</ul>
+<p>This means that almost any asymptotic bound can be reduced down to
+one of a very small list of common bounds. Ones that you will typically
+see in practical algorithms, listed in increasing order, are <span class="math inline"><em>O</em>(1)</span>, <span class="math inline"><em>O</em>(log<em>n</em>)</span>, <span class="math inline"><em>O</em>(<em>n</em>)</span>, <span class="math inline"><em>O</em>(<em>n</em>log<em>n</em>)</span>, or <span class="math inline"><em>O</em>(<em>n</em><sup>2</sup>)</span>.</p>
+<p>Applying these rules to mergesort and selection sort gives us asymptotic bounds of <span class="math inline"><em>c</em><em>n</em>log<em>n</em> = <em>O</em>(<em>n</em>log<em>n</em>)</span> (the constant vanishes) and <span class="math inline"><em>c</em><sub>1</sub><em>n</em>(<em>n</em> + 1)/2 + <em>c</em><sub>2</sub><em>n</em> = <em>c</em><sub>1</sub><em>n</em><sup>2</sup>/2 + <em>c</em><sub>1</sub><em>n</em>/2 + <em>c</em><sub>2</sub><em>n</em> = <em>O</em>(<em>n</em><sup>2</sup>)+<em>O</em>(<em>n</em>)+<em>O</em>(<em>n</em>)=<em>O</em>(<em>n</em><sup>2</sup>)</span> (the constants vanish and then <span class="math inline"><em>O</em>(<em>n</em><sup>2</sup>)</span>
+ dominates). Here we see that no matter how fast our machine is at
+different low-level operations, for large enough inputs mergesort will
+beat selection sort.</p>
+<h3 id="asymptotic-cost-of-programs"><span class="header-section-number">5.1.3</span> Asymptotic cost of programs</h3>
+<p>To compute the asymptotic cost of a program, the rule of thumb is that any simple statement costs <span class="math inline"><em>O</em>(1)</span>
+ time to evaluate, and larger costs are the result of loops or calls to
+expensive functions, where a loop multiplies the cost by the number of
+iterations in the loop. When adding costs together, the biggest cost
+wins:</p>
+<p>So this function takes <span class="math inline"><em>O</em>(1)</span> time:</p>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"><span class="co">/* return the sum of the integers i with 0 &lt;= i and i &lt; n */</span>
+<span class="dt">int</span>
+sumTo(<span class="dt">int</span> n)
+{
+ <span class="kw">return</span> n*(n<span class="dv">-1</span>)/<span class="dv">2</span>;
+}</code></pre></div>
+<p>But this function, which computes exactly the same value, takes <span class="math inline"><em>O</em>(<em>n</em>)</span> time:</p>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"><span class="co">/* return the sum of the integers i with 0 &lt;= i and i &lt; n */</span>
+<span class="dt">int</span>
+sumTo(<span class="dt">int</span> n)
+{
+ <span class="dt">int</span> i;
+ <span class="dt">int</span> sum = <span class="dv">0</span>;
+
+ <span class="kw">for</span>(i = <span class="dv">0</span>; i &lt; n; i++) {
+ sum += i;
+ }
+
+ <span class="kw">return</span> sum;
+}</code></pre></div>
+<p>The reason it takes so long is that each iteration of the loop takes only <span class="math inline"><em>O</em>(1)</span> time, but we execute the loop <span class="math inline"><em>n</em></span> times, and <span class="math inline"><em>n</em> ⋅ <em>O</em>(1)=<em>O</em>(<em>n</em>)</span>.</p>
+<p>Here's an even worse version that takes <span class="math inline"><em>O</em>(<em>n</em><sup>2</sup>)</span> time:</p>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"><span class="co">/* return the sum of the integers i with 0 &lt;= i and i &lt; n */</span>
+<span class="dt">int</span>
+sumTo(<span class="dt">int</span> n)
+{
+ <span class="dt">int</span> i;
+ <span class="dt">int</span> j;
+ <span class="dt">int</span> sum = <span class="dv">0</span>;
+
+ <span class="kw">for</span>(i = <span class="dv">0</span>; i &lt; n; i++) {
+ <span class="kw">for</span>(j = <span class="dv">0</span>; j &lt; i; j++) {
+ sum++;
+ }
+ }
+
+ <span class="kw">return</span> sum;
+}</code></pre></div>
+<p>Here we have two nested loops. The outer loop iterates exactly <span class="math inline"><em>n</em></span> times, and for each iteration the inner loop iterates at most <span class="math inline"><em>n</em></span> times, and the innermost iteration costs <span class="math inline"><em>O</em>(1)</span> each time, so the total is at most <span class="math inline"><em>O</em>(<em>n</em><sup>2</sup>)</span>. (In fact, it's no better than this, because at least <span class="math inline"><em>n</em>/2</span> times we execute the inner loop, we do at least <span class="math inline"><em>n</em>/2</span> iterations.)</p>
+<p>So even if we knew that the constant on the first implementation was
+really large (maybe our CPU is bad at dividing by 2?), for big values of
+ <span class="math inline"><em>n</em></span> it's still likely to be faster than the other two.</p>
+<p>(This example is a little misleading, because <span class="math inline"><em>n</em></span> is not the size of the input but the actual input value. More typical might be a statement that the cost of <code>strlen</code> is <span class="math inline"><em>O</em>(<em>n</em>)</span> where <span class="math inline"><em>n</em></span> is the length of the string.)</p>
+<h3 id="other-variants-of-asymptotic-notation"><span class="header-section-number">5.1.4</span> Other variants of asymptotic notation</h3>
+<p>Big-O notation is good for upper bounds, but the inequality in the
+definition means that it can't be used for anything else: it is the case
+ that <span class="math inline">12 = <em>O</em>(<em>n</em><sup>67</sup>)</span> just because <span class="math inline">12 &lt; <em>n</em><sup>67</sup></span> when <span class="math inline"><em>n</em></span> is large enough. There is an alternative definition, called '''big-Omega''', that works in the other direction:</p>
+<dl>
+<dt><span class="math inline"><em>Ω</em>(<em>n</em>)</span></dt>
+<dd>A function <span class="math inline"><em>f</em>(<em>n</em>)</span> is in the class <span class="math inline"><em>Ω</em>(<em>g</em>(<em>n</em>))</span> if there exist constants <span class="math inline"><em>N</em></span> and <span class="math inline"><em>c</em></span> such that <span class="math inline"><em>f</em>(<em>n</em>)&gt;<em>c</em> ⋅ <em>g</em>(<em>n</em>)</span> when <span class="math inline"><em>n</em> &gt; <em>N</em></span>.
+</dd>
+</dl>
+<p>This is exactly the same as the definition of <span class="math inline"><em>O</em>(<em>g</em>(<em>n</em>))</span>
+ except that the inequality goes in the other direction. So if we want
+to express that some algorithm is very expensive, we might write that
+it's <span class="math inline"><em>Ω</em>(<em>n</em><sup>2</sup>)</span>, which says that once the size of the input is big enough, then the cost grows at least as fast as <span class="math inline"><em>n</em><sup>2</sup></span>.</p>
+<p>If you want to claim that your bound is <strong>tight</strong>—both an upper and a lower bound—use <strong>big-Theta</strong>: <span class="math inline"><em>f</em>(<em>n</em>)</span> is <span class="math inline"><em>Θ</em>(<em>g</em>(<em>n</em>))</span> if it is both <span class="math inline"><em>O</em>(<em>f</em>(<em>n</em>))</span> and <span class="math inline"><em>Ω</em>(<em>g</em>(<em>n</em>))</span>.</p>
+<p>Mostly we will just use big-O, with the understanding that when we say that a particular algorithm is <span class="math inline"><em>O</em>(<em>n</em>)</span>, that's the best bound we could come up with.</p>
+<h2 id="linkedLists"><span class="header-section-number">5.2</span> Linked lists</h2>
+<p>Linked lists are about the simplest data structure beyond arrays.
+They aren't very efficient for many purposes, but have very good
+performance for certain specialized applications.</p>
+<p>The basic idea is that instead of storing <span class="math inline"><em>n</em></span> items in one big array, we store each item in its own <code>struct</code>, and each of these <code>structs</code> includes a pointer to the next <code>struct</code>
+ in the list (with a null pointer to indicate that there are no more
+elements). If we follow the pointers we can eventually reach all of the
+elements.</p>
+<p>For example, if we declare the struct holding each element like this:</p>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"><span class="kw">struct</span> elt {
+ <span class="kw">struct</span> elt *next; <span class="co">/* pointer to next element in the list */</span>
+ <span class="dt">int</span> contents; <span class="co">/* contents of this element */</span>
+};</code></pre></div>
+<p>We can build a structure like this:</p>
+<p><img src="data:image/png;base64,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" alt="Basic linked list"><br>
+The box on the far left is not a <code>struct elt</code>, but a <code>struct elt *</code>;
+ in order to keep track of the list we need a pointer to the first
+element. As usual in C, we will have to do all the work of allocating
+these elements and assigning the right pointer values in the right
+places ourselves.</p>
+<h3 id="stacks"><span class="header-section-number">5.2.1</span> Stacks</h3>
+<p>The selling point of linked lists in comparison to arrays is that
+inserting or removing elements can be cheap: at the front of the list,
+inserting a new element just requires allocating another <code>struct</code>
+ and hooking up a few pointers, while removing an element just requires
+moving the pointer to the first element to point to the second element
+instead, and then freeing the first element.</p>
+<p>For example here's what happens the linked list above looks like after we insert a new element at the front:</p>
+<p><img src="data:image/png;base64,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" alt="Linked list after insertion"><br>
+To make this work, we need to change two pointers: the head pointer and the <code>next</code> pointer in the new element holding 0. These operations aren't affected by the size of the rest of the list and so take <span class="math inline"><em>O</em>(1)</span> time.</p>
+<p>Removal is the reverse of installation: We patch out the first
+element by shifting the head pointer to the second element, then
+deallocate it with <code>free</code>. (We do have to be careful to get any data we need out of it before calling free). This is also an <span class="math inline"><em>O</em>(1)</span> operation.</p>
+<p>The fact that we can add and remove elements at the start of linked
+lists for cheap makes them particularly useful for implementing a <strong>stack</strong>, an abstract data type that supports operations <strong>push</strong> (insert a new element on the top of the stack) and <strong>pop</strong>
+ (remove and return the element at the top of the stack. Here is an
+example of a simple linked-list implementation of a stack, together with
+ some test code:</p>
+<div>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"><span class="ot">#include &lt;stdio.h&gt;</span>
+<span class="ot">#include &lt;stdlib.h&gt;</span>
+<span class="ot">#include &lt;assert.h&gt;</span>
+
+<span class="kw">struct</span> elt {
+ <span class="kw">struct</span> elt *next;
+ <span class="dt">int</span> value;
+};
+
+<span class="co">/* </span>
+<span class="co"> * We could make a struct for this,</span>
+<span class="co"> * but it would have only one component,</span>
+<span class="co"> * so this is quicker.</span>
+<span class="co"> */</span>
+<span class="kw">typedef</span> <span class="kw">struct</span> elt *Stack;
+
+<span class="ot">#define STACK_EMPTY (0)</span>
+
+<span class="co">/* push a new value onto top of stack */</span>
+<span class="dt">void</span>
+stackPush(Stack *s, <span class="dt">int</span> value)
+{
+ <span class="kw">struct</span> elt *e;
+
+ e = malloc(<span class="kw">sizeof</span>(<span class="kw">struct</span> elt));
+ assert(e);
+
+ e-&gt;value = value;
+ e-&gt;next = *s;
+ *s = e;
+}
+
+<span class="dt">int</span>
+stackEmpty(<span class="dt">const</span> Stack *s)
+{
+ <span class="kw">return</span> (*s == <span class="dv">0</span>);
+}
+
+<span class="dt">int</span>
+stackPop(Stack *s)
+{
+ <span class="dt">int</span> ret;
+ <span class="kw">struct</span> elt *e;
+
+ assert(!stackEmpty(s));
+
+ ret = (*s)-&gt;value;
+
+ <span class="co">/* patch out first element */</span>
+ e = *s;
+ *s = e-&gt;next;
+
+ free(e);
+
+ <span class="kw">return</span> ret;
+}
+
+<span class="co">/* print contents of stack on a single line */</span>
+<span class="dt">void</span>
+stackPrint(<span class="dt">const</span> Stack *s)
+{
+ <span class="kw">struct</span> elt *e;
+
+ <span class="kw">for</span>(e = *s; e != <span class="dv">0</span>; e = e-&gt;next) {
+ printf(<span class="st">"%d "</span>, e-&gt;value);
+ }
+
+ putchar(<span class="ch">'\n'</span>);
+}
+
+<span class="dt">int</span>
+main(<span class="dt">int</span> argc, <span class="dt">char</span> **argv)
+{
+ <span class="dt">int</span> i;
+ Stack s;
+
+ s = STACK_EMPTY;
+
+ <span class="kw">for</span>(i = <span class="dv">0</span>; i &lt; <span class="dv">5</span>; i++) {
+ printf(<span class="st">"push %d</span><span class="ch">\n</span><span class="st">"</span>, i);
+ stackPush(&amp;s, i);
+ stackPrint(&amp;s);
+ }
+
+ <span class="kw">while</span>(!stackEmpty(&amp;s)) {
+ printf(<span class="st">"pop gets %d</span><span class="ch">\n</span><span class="st">"</span>, stackPop(&amp;s));
+ stackPrint(&amp;s);
+ }
+
+ <span class="kw">return</span> <span class="dv">0</span>;
+}</code></pre></div>
+<a href="http://cs.yale.edu/homes/aspnes/classes/223/examples/linkedLists/stack.c" class="uri">examples/linkedLists/stack.c</a>
+</div>
+<p>Unlike most of our abstract data types, we do not include a <code>struct</code>
+ representing the linked list itself. This is because the only thing we
+need to keep track of a linked list is the head pointer, and it feels a
+little silly to have a <code>struct</code> with just one component. But
+we might choose to do this if we wanted to make the linked list
+implementation opaque or allow for including more information later.</p>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"><span class="kw">struct</span> stack {
+ <span class="kw">struct</span> elt *head;
+};</code></pre></div>
+<h4 id="Building_a_stack_out_of_an_array"><span class="header-section-number">5.2.1.1</span> Building a stack out of an array</h4>
+<p>When the elements of a stack are small, or when a maximum number of
+elements is known in advance, it often makes sense to build a stack from
+ an array (with a variable storing the index of the top element) instead
+ of a linked list. The reason is that pushes and pops only require
+updating the stack pointer instead of calling <code class="backtick">malloc</code> or <code class="backtick">free</code>
+ to allocate space, and pre-allocating is almost always faster than
+allocating as needed. This is the strategy used to store the function
+call stack in almost all programs (the exception is in languages like
+Scheme, where the call stack is allocated on the heap because stack
+frames may outlive the function call that creates them).</p>
+<h3 id="queues"><span class="header-section-number">5.2.2</span> Queues</h3>
+<p>Stacks are last-in-first-out (LIFO) data structures: when we pop, we
+get the last item we pushed. What if we want a first-in-first-out (FIFO)
+ data structure? Such a data structure is called a <strong>queue</strong> and can also be implemented by a linked list. The difference is that if we want <span class="math inline"><em>O</em>(1)</span> time for both the <strong>enqueue</strong> (push) and <strong>dequeue</strong> (pop) operations, we must keep around pointers to both ends of the linked list.</p>
+<p>So now we get something that looks like this:</p>
+<p><img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAXAAAABTCAYAAACGVlwTAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAN1wAADdcBQiibeAAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAA4FSURBVHic7d1/kJ1Vfcfx92ezkCAJCYGEIBIE5UcD4TctGsDWaEdwEKdM6VAjMG1QtLVo23HoZAp0WhSmQBFaFdHBlB8NhcEqaKGi4m9Awi/bDogtKQiG2hAwQSSQfPvH97lks+y9e/c+53nO43O/r5md3bv77Dlnz9797rnPOed7BBxDs71kZndXXYmk7wNHV11PSZ8zs+VVFS7ps8AfVlV+IneZ2ZuqKlzScuCqqspPZK2Z7V5V4ZL2AtZUVX4im8xsepUVSNoMjFRZR1mjwLeBl3M3pAsVb9Nqqu92M3tHTXVNiaQf11TVf5nZG2uqa0ok3QbMrqGqjWY2q4Z6pkzSx4EzaqjKzKyRwUvSCcAXaqruEDN7qKa6JlX8c70W2Ai8YxTAzLbL2qouJB0M3J+7HSGEkJukU4HLgI8BlwNbRvM2KYQQQi+SdgL+ATgMeHvnFYGkZt/fCSGEYSbpTfhdiOeAI8ffzokReAghNIykacAK4CzgTDP78kTXRQAPIYQGkfR6fKJyA3CYmT3d7dq4hRJCCA0h6feBu4EbgRN6BW+IEXgIIWRXTFR+EjiUMROVk4kReAghZCTpzcADwLNMMFHZS4zAQwghg2Ki8i+B99FjorKXCOAhhFAzSXvjE5U/Z5KJyl7iFsqQkjQq6TW525Fbce9xqEUf1NsHkpYBdwH/TB8Tlb0MXQCXtFBSI1MH1GwzcK+kz0k6TpJyNyiTVZJuknSipGF9Rfo3kr4qadkQ/1M/TdI9kj4oaW4VFUiaLek64Bx8ovITZmZlyhzGJ+yRwKclXQ+sNLPkuVYkHQPMTFzsa4DXSUqZbOtR4A+Kt7V4gpztUxQs6TBgtxRljbErsGPiPvhv4I+Ak/FJpDUkSp4maT9gnxRljbEPMD1xHzwJfAh4G/AZ4AcAklQ2wEjaA1hcuoXbOgIYSdwHz+Kx4SjgE5LuImEiPUlLgGuAr+ATlb9MUW6yAF4sPk+dyW8PL1pnJSxze2AOcDZwtqQngVuBlKPy04E9E5YHnoXvQODDCct8/ZiPFwBbgI2S5prZMyXLPhF4c8kyxtsLf86m7IN5Yz6eAxwMmKS9zeyxkmUvAX6vZBnj7Yf/M0/ZB2NH3TsAx+LB6wjg3pJlLyJtW8F/ZyOJyx3Bn//T8OdYJ812Zyv7QIqJynOBMxlworJn+XjayNIvnyUdAnygfJO2sQs+MvpMwjJHgNOATi7hl4F78D/eJxqeTvbOlPnAJX0Tz4H+ZWAlcBJwXNPTyabMBy7pSvyP6xt4H8wCLmx6OtmU+cAlfQS4FFiN98G3gfuank42ZT5wScfjo+NH8T64BngMn2AcKJ1sMVF5HZ7H5Iwy97q7lG/JRuBm9iC+bz+ZIp3s75hZsnIlvQ0/tOAO4B+Bm83s+eJAh6FRzAOswvt3XfG5E/O2KosfABeY2ePwyoEOw+Yp4CAz+w94Jef0sDFgiZl9r/OJMtNCkt4LXAJcAFxe9lZUN8N4D3wdsNDMnszdkJzM7CXgU7nbkZuZfTZ3G3IzsxtytyE3M7stRTmSZuN/VwcDS83shynK7aaRL5GqZGb3D3vwDiGkVyxeeAAfJB5ZdfCG4RyBhxBCMsXy03OB5VQwUdnL0I3AQwihQ9IMSV+QdKqkHQb4/n3wSd+j8AnP2oI3RAAPIbSYpJEiSE/4Vlw2Dbge+Gmxse23+iz7NHxH5SpK7qgcVNxCCSG02bH4EtFNPa7pbNaZTbGxTdKN3S6WNAefqFxMDROVvcQIPITQdt8ysxnd3oB/K677CXAhsMjMTpmoIEnH4hOV/0dNE5W9xAg8hNBmPddfF7dRnsLTCHzDzLZ0uW4UOA/fQ1LrRGUvEcBDCG3XdUdOkZPkzJ7fLL0B31G5nhKpX6sQt1BCCG1Wdgfku/CJyuvJNFHZS4zAQwhtN+U98ZJmFt93BvDW3Pe6u4kAvtUc4LAiO2ETzcfTqVZpV2CvBvfBLniCoSrNxVPWNrUPdsJzuVdpOp4FtKl9MJ3+07waAwRwoJPudTZwW1PT5Y8CSEqSm7YCYrDOH8RP8AC2sab6pmom8ETFdTwB/ILm9sH2+O+pSmuBF2luH4D/jqr0AkVq4YrrGdQm0qZ/fhUze1nSi/iRZy9XWVcZnRH4nTkb0cP2wK/XVNdq4GtmdmFN9U2JpM/jbazSamCWmZ1RcT0DkXQO/kqpSj8CHjSzoyuuZyCS3o2/rK/SBmCDme1fcT0DkXQA8C99Xj7oCBw8DewSM1s74PdX6pV0sg3Ogb0AX3MZQghhnFiFEkJoszIj8MaLAB5CaLNKDlJoiliFUoFid1fnXu0zZtYrD0OrSJoF/Bp+3qaAHwOPmFlTJ8SSK5L6L8ZXDs3GDw1+zMwezdqwjOTLODqHXFvN66lrH4FL2pmtxzZ287yZbShTTwTwBCTNx8/uPBI/CPZAtvbtW/FkOq0m6T3AqcDbefXJ9s9LugS4uOwTtskkHQpci/8De9WrW0n3Aec2ZRt2zc4CPll8vInJg1squUbg1wHHT3LN5fjh6gOLAJ7G0Wx9cg6rvwV2x5dcPQI8jK+lPRzYF094v1TSb5pZY5dllTQf/+f9S+BBfOS9AViIn1B/OHCLpJPM7JZsrayZpD2Bi3I2IWPdG+i+7PPnZQuPAJ7Gi8D38ANy7wH+B/hO1hbV7xngauCKscuuJI0AH8YPeF0CrAD+KksLq/cwnhTpu0WOjVdIei1wCx7Er5Y0v1vipBa6EpgF3Aj8bs11574Hfp6Z/V1VhUcAT8DMbgdu7zwubqkMm8MnutdfBKlLizSc7wZOoKUBvDjZ/vEuX3tK0h/j/+h3ARYB/15j87KQtAy/lbAS/9nrDuAQq1BC6K2Pido7i/eLKm5Kk42dxJyXrRU1KQYylwE/A/4sUzNavYwwRuChLvsU79fkbERmxxbvXwQeytmQmlyBv9pYZmbrmppPpGqSpgM7A0+bWdJbOjECD5WTtB3wzuLh93O2JQdJ20k6GT+GC+DjZrYuZ5uqJukk4BTgdjO7LmNTco/A/wJ4HvgpvhrrAUnnDXKA8kQigIc6XAS8AZ+R/+vMbamFpJslrZH0FL4q5SY8t8b7zKyVcwAdY86M/AXwgczNyW0eHsDXAzsAhwDnAw9LOqRs4RHAQ6UkvQv4SPFwhZlVnVGxKRYAe+FLKzt/ZyPATsXKnDa7GP+5zzOzqtP/TibXCPwOfMJ2ZzObbWZz8VTF5+BZHhcC10oav2diStr+RAoZSToOWFU8vBr4+4zNqdtv4/c9d8f3CVwC7IkHt2sztqtSkpbi50beB1S2fG4KsiwjNLNLzewmM3t2zOfWm9lF+IY3gIOA95epJ0kAlzQiqfWz6qF/ko4CbsVfNt4ALE89gdNkZrbRzJ41s7VmdreZ/Tk+IjPgVEknZG5icpJ2BK7CD5w408yqPniiX42aPTWzW4HvFg9/o0xZqVahzAfux0cbYchJWgzchm/e+CK+CmFYNq10ZWa3FNvpj8Andb+SuUmpLQH2xg/F+JMJVp3sV7wfLfLbA9xYcWqBpg4aVuP9dVCZQlIFcNHcjgo1krQIv/83Fw9Qp7R46/wg1uABfLdJrvtVtgA4vcfXR8Z8/RGg6twwjRqBF2YV758rU0gE8JCMpP2Br+GvyO4ATh6mTIx96qw8+M+srajGQ2y9vzuRpcByPF/Oe4vPPVhxmxoXlySNAscUD0v9/KkC+AgN7KhQH0n7Al/HR1/fBE4anw+k7STt2ytlrKSzgTcWD++qp1X1KXLgrOr2dUk74QF8i5l1va4CtY7Ai7w3PzOzl7pccj6e4A3gX8vUFSPwRCStYOtBqzuO+dLpkt4y5vFlY2em20DSNDx4vxYfXd0LfLTHzruLW5offGWRD/16/GzNNcAMfMnYMjwPDMA/mVnb7n83VY5lhMuAP5W0Ep8bfBw/JPoAfIVOZ/R9jZlFAG+IFfiKi/HG3wtcCbQqgAPTgNcVH48yed6LK2nuiedlHQR8rMvXNuN5oj9YX3NCJrsBH+3ytc34strS+WEigKdzAVtH4L2sr7ohGWxmahkG23qow/H4fd6l+GqMBcALeHrhNcDnzexH2VqX32r8eVLnpHaOEfhV+ElUx+Arb+ax9XSqR4EbzCzJHEgE8ETM7ILcbcilWO97fu525GZmzwE3F29hHDNbjQfxVjOz9dT0PEi1E3PoA3gIoZFyJ7OqVKoAHlvyQwhN1OqBZYzAQwht19oReNwD39ZMSQtyN6KLJPmD+6mnwX0ws6Z6tmtwH8ypqR41uA92ncK1ZePSvCYfRDEKIOnokuUsBKYnKGe8uYnL62UD8CF8o0FTVT0p8gLwFuCBiusp44qKy98E7EGz+6DU2uE+bMGfC03ug64bpiYwaAT+X+CrA35vHZ4WaXaEzQD2p5ptsevM7J2TXxZCCNuSdCCwyswW525LFUbNrPSoWdIBwJdSlBVCCIk19x5ISTGJGUJos1hG2Gc5EcBDCKFGMQIPIbRZjMD7EAE8hBBqFgE8hNBmMQLvQwTwEEITtTouRQAPIbRdjMD7KCcCeAihaVodl2IEHkJouxiBT6K1HRRC+JXW6oFljMBDCG3X2gFmBPAQQpvFMsI+RAAPIYSaRQAPIbRZjMD7LCcCeAgh1ChG4CGENosReB8igIcQmqjVcSkCeAih7WIEPokI4CGEJmp1XBpNVI6AQyU9hndYp9Oswsd11BFtaG4bhvXnjjZM7XtEi0fgMrPJr5qsEGkGsKDzkG07TZN8rurHbaljWOps6881LHU28edaY2Z700L/D0rI1dY5wot9AAAAAElFTkSuQmCC" alt="Queue as a linked list"><br>
+Enqueuing a new element typically requires (a) allocating a new <code>struct</code> to hold it; (b) making the old tail <code>struct</code> point at the new <code>struct</code>; and (c) updating the <code>tail</code> pointer to also point to the new <code>struct</code>. There is a minor complication when the stack is empty; in this case instead of updating <code>tail-&gt;next</code> we must put a pointer to the new <code>struct</code> in <code>head</code>. Dequeuing an element involves updating the head pointer and freeing the removed <code>struct</code>, exactly like a stack pop.</p>
+<p>Here is the queue above after enqueuing a new element 6. The updated pointers are indicated by dotted lines:</p>
+<p><img src="data:image/png;base64,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" alt="Queue after enqueuing a new element"><br>
+Because we are only changing two pointers, each of which we can reach by following a constant number of pointers from the main <code>struct</code>, we can do this in <span class="math inline"><em>O</em>(1)</span> time.</p>
+<p>There is a slight complication when we enqueue the very first
+element, because we need to update the head pointer instead of the
+pointer in the previous tail (which doesn't yet exist). This requires
+testing for an empty queue in the enqueue routine, which we'll do in the
+ sample code below.</p>
+<p>Dequeuing is easier because it requires updating only one pointer:</p>
+<p><img src="data:image/png;base64,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" alt="Queue after dequeuing first element"><br>
+If we adopt the convention that a null in <code>head</code> means an empty queue, and use this property to check if the queue is empty when enqueuing, we don't even have to clear out <code>tail</code> when we dequeue the last element.</p>
+<p>Here is a simple implementation of a queue holding <code class="backtick">int</code>s, together with some test code showing how its behavior differs from a stack:</p>
+<div>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"><span class="ot">#include &lt;stdio.h&gt;</span>
+<span class="ot">#include &lt;stdlib.h&gt;</span>
+<span class="ot">#include &lt;assert.h&gt;</span>
+
+
+
+<span class="kw">struct</span> elt {
+ <span class="kw">struct</span> elt *next;
+ <span class="dt">int</span> value;
+};
+
+<span class="kw">struct</span> queue {
+ <span class="kw">struct</span> elt *head;
+ <span class="kw">struct</span> elt *tail;
+};
+
+<span class="kw">typedef</span> <span class="kw">struct</span> queue *q;
+
+<span class="kw">struct</span> queue *
+queueCreate(<span class="dt">void</span>)
+{
+ <span class="kw">struct</span> queue *q;
+
+ q = malloc(<span class="kw">sizeof</span>(<span class="kw">struct</span> queue));
+
+ q-&gt;head = q-&gt;tail = <span class="dv">0</span>;
+
+ <span class="kw">return</span> q;
+}
+
+<span class="co">/* push a new value onto top of Queue */</span>
+<span class="dt">void</span>
+enq(<span class="kw">struct</span> queue *q, <span class="dt">int</span> value)
+{
+ <span class="kw">struct</span> elt *e;
+
+ e = malloc(<span class="kw">sizeof</span>(<span class="kw">struct</span> elt));
+ assert(e);
+
+ e-&gt;value = value;
+
+ <span class="co">/* Because I will be the tail, nobody is behind me */</span>
+ e-&gt;next = <span class="dv">0</span>;
+
+ <span class="kw">if</span>(q-&gt;head == <span class="dv">0</span>) {
+ <span class="co">/* If the queue was empty, I become the head */</span>
+ q-&gt;head = e;
+ } <span class="kw">else</span> {
+ <span class="co">/* Otherwise I get in line after the old tail */</span>
+ q-&gt;tail-&gt;next = e;
+ }
+
+ <span class="co">/* I become the new tail */</span>
+ q-&gt;tail = e;
+}
+
+<span class="dt">int</span>
+queueEmpty(<span class="dt">const</span> <span class="kw">struct</span> queue *q)
+{
+ <span class="kw">return</span> (q-&gt;head == <span class="dv">0</span>);
+}
+
+<span class="dt">int</span>
+deq(<span class="kw">struct</span> queue *q)
+{
+ <span class="dt">int</span> ret;
+ <span class="kw">struct</span> elt *e;
+
+ assert(!queueEmpty(q));
+
+ ret = q-&gt;head-&gt;value;
+
+ <span class="co">/* patch out first element */</span>
+ e = q-&gt;head;
+ q-&gt;head = e-&gt;next;
+
+ free(e);
+
+ <span class="kw">return</span> ret;
+}
+
+<span class="co">/* print contents of queue on a single line, head first */</span>
+<span class="dt">void</span>
+queuePrint(<span class="kw">struct</span> queue *q)
+{
+ <span class="kw">struct</span> elt *e;
+
+ <span class="kw">for</span>(e = q-&gt;head; e != <span class="dv">0</span>; e = e-&gt;next) {
+ printf(<span class="st">"%d "</span>, e-&gt;value);
+ }
+
+ putchar(<span class="ch">'\n'</span>);
+}
+
+<span class="co">/* free a queue and all of its elements */</span>
+<span class="dt">void</span>
+queueDestroy(<span class="kw">struct</span> queue *q)
+{
+ <span class="kw">while</span>(!queueEmpty(q)) {
+ deq(q);
+ }
+
+ free(q);
+}
+
+<span class="dt">int</span>
+main(<span class="dt">int</span> argc, <span class="dt">char</span> **argv)
+{
+ <span class="dt">int</span> i;
+ <span class="kw">struct</span> queue *q;
+
+ q = queueCreate();
+
+ <span class="kw">for</span>(i = <span class="dv">0</span>; i &lt; <span class="dv">5</span>; i++) {
+ printf(<span class="st">"enq %d</span><span class="ch">\n</span><span class="st">"</span>, i);
+ enq(q, i);
+ queuePrint(q);
+ }
+
+ <span class="kw">while</span>(!queueEmpty(q)) {
+ printf(<span class="st">"deq gets %d</span><span class="ch">\n</span><span class="st">"</span>, deq(q));
+ queuePrint(q);
+ }
+
+ queueDestroy(q);
+
+ <span class="kw">return</span> <span class="dv">0</span>;
+}</code></pre></div>
+<a href="http://cs.yale.edu/homes/aspnes/classes/223/examples/linkedLists/queue.c" class="uri">examples/linkedLists/queue.c</a>
+</div>
+<p>It is a bit trickier to build a queue out of an array than to build a
+ stack. The difference is that while a stack pointer can move up and
+down, leaving the base of the stack in the same place, a naive
+implementation of a queue would have head and tail pointers both
+marching ever onward across the array leaving nothing but empty cells in
+ their wake. While it is possible to have the pointers wrap around to
+the beginning of the array when they hit the end, if the queue size is
+unbounded the tail pointer will eventually catch up to the head pointer.
+ At this point (as in a stack that overflows), it is necessary to
+allocate more space and copy the old elements over. See the section on <a href="#ringBuffers">ring buffers</a> for an example of how to do this.</p>
+<h3 id="Looping_over_a_linked_list"><span class="header-section-number">5.2.3</span> Looping over a linked list</h3>
+<p>Looping over a linked list is not hard if you have access to the <code class="backtick">next</code> pointers. (For a more abstract way to do this see <a href="#iterators">iterators</a>.)</p>
+<p>Let's imagine somebody gave us a pointer to the first <code class="backtick">struct&nbsp;stack</code> in a list; call this pointer <code class="backtick">first</code>. Then we can write a loop like this that prints the contents of the stack:</p>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"><span class="dt">void</span>
+stackPrint(<span class="kw">struct</span> stack *first)
+{
+ <span class="kw">struct</span> stack *elt;
+
+ <span class="kw">for</span>(elt = first; elt != <span class="dv">0</span>; elt = elt-&gt;next) {
+ puts(elt-&gt;book);
+ }
+}</code></pre></div>
+<p>There's not a whole lot to notice here except that <code class="backtick">for</code>
+ is perfectly happy to iterate over something that isn't a range of
+integers. The running time is linear in the length of the list (<span class="math inline"><em>O</em>(<em>n</em>)</span>).</p>
+<h3 id="Looping_over_a_linked_list_backwards"><span class="header-section-number">5.2.4</span> Looping over a linked list backwards</h3>
+<p>What if we want to loop over a linked list backwards? The <code class="backtick">next</code>
+ pointers all go the wrong way, so we have to save a trail of
+breadcrumbs to get back. The safest way to do this is to reverse the
+original list into an auxiliary list:</p>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"><span class="dt">void</span>
+stackPrintReversed(<span class="kw">struct</span> stack *first)
+{
+ <span class="kw">struct</span> stack *elt;
+ Stack s2; <span class="co">/* uses imperative implementation */</span>
+
+ s2 = stackCreate();
+
+ <span class="kw">for</span>(elt = first; elt != <span class="dv">0</span>; elt = elt-&gt;next) {
+ s2 = stackPush(s2, elt-&gt;book);
+ }
+
+ stackPrint(s2);
+ stackDestroy(s2);
+}</code></pre></div>
+<p>Pushing all the elements from the first list onto <code class="backtick">s2</code> puts the first element on the bottom, so when we print <code class="backtick">s2</code> out, it's in the reverse order of the original stack.</p>
+<p>We can also write a recursive function that prints the elements
+backwards. This function effectively uses the function call stack in
+place of the extra stack <code class="backtick">s2</code> above.</p>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"><span class="dt">void</span>
+stackPrintReversedRecursive(<span class="kw">struct</span> stack *first)
+{
+ <span class="kw">if</span>(first != <span class="dv">0</span>) {
+ <span class="co">/* print the rest of the stack */</span>
+ stackPrintReversedRecursive(first-&gt;next);
+
+ <span class="co">/* then print the first element */</span>
+ puts(first-&gt;book);
+ }
+}</code></pre></div>
+<p>The code in <code class="backtick">stackPrintReversedRecursive</code> is shorter than the code in <code class="backtick">stackPrintReversed</code>,
+ and it is likely to be faster since it doesn't require allocating a
+second stack and copying all the elements. But it will only work for
+small stacks: because the function call stack is really a fixed-size
+array, if the input to <code class="backtick">stackPrintReversedRecursive</code> is too big the recursion will go too deep cause a <em>stack overflow</em>.</p>
+<p>If we want to do this sort of thing a lot, we should build a <strong>doubly-linked list</strong>,
+ with a pointer in each element both to the next element and the
+previous element instead of a singly-linked list (see below for more).</p>
+<h3 id="deques"><span class="header-section-number">5.2.5</span> Deques and doubly-linked lists</h3>
+<p>Suppose we want a data structure that represents a line of elements
+where we can push or pop elements at either end. Such a data structure
+is known as a <strong>deque</strong> (pronounced like "deck"), and can be implemented with all operations taking <span class="math inline"><em>O</em>(1)</span> time by a <strong>doubly-linked list</strong>, where each element has a pointer to both its successor and its predecessor.</p>
+<p>An ordinary singly-linked list is not good enough. The reason is that
+ even if we keep a pointer to both ends as in a queue, when it comes
+time to pop an element off the tail, we have no pointer to its
+predecessor ready to hand; the best we can do is scan from the head
+until we get to an element whose successor is the tail, which takes <span class="math inline"><em>O</em>(<em>n</em>)</span> time.</p>
+<p>So instead we need a doubly-linked list, where each node points to
+both its successor and predecessor. The most straightforward way to
+build this is to make it circular, and use a dummy node to represent the
+ head of the list. The resulting data structure might look something
+like this:</p>
+<p><img src="data:image/png;base64,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" alt="Circular doubly-linked list"><br>
+Below is an implementation of this structure. We have separated the interface in <code>deque.h</code> from the implementation in <code>deque.c</code>. This will allow us to change the implementation if we decide we don't like it, without affecting any other code in the system.</p>
+<p>A nice feature of this data structure is that we don't need to use
+null pointers to mark the ends of the deque. Instead, each end is marked
+ by a pointer to the dummy head element. For an empty deque, this just
+means that the head points to itself. The cost of this is that to detect
+ an empty deque we have to test for equality with the head (which might
+be slightly more expensive that just testing for null) and the head may
+contain some wasted space for its missing value if we allocate it like
+any other element.<a href="#fn19" class="footnoteRef" id="fnref19"><sup>19</sup></a></p>
+<p>To keep things symmetric, we implement the pointers as an array, indexed by the directions <code>DEQUE_FRONT</code> and <code>DEQUE_BACK</code> (defined in <code>deque.h</code>). This means we can use the same code to push or pop on either end of the deque.</p>
+<div>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"><span class="kw">typedef</span> <span class="kw">struct</span> deque Deque;
+
+<span class="ot">#define DEQUE_FRONT (0)</span>
+<span class="ot">#define DEQUE_BACK (1)</span>
+
+<span class="ot">#define DEQUE_EMPTY (-1) </span><span class="co">/* returned by dequePop if deque is empty */</span>
+
+<span class="co">/* return a new empty deque */</span>
+Deque *dequeCreate(<span class="dt">void</span>);
+
+<span class="co">/* push new value onto direction side of deque d */</span>
+<span class="dt">void</span> dequePush(Deque *d, <span class="dt">int</span> direction, <span class="dt">int</span> value);
+
+<span class="co">/* pop and return first value on direction side of deque d */</span>
+<span class="co">/* returns DEQUE_EMPTY if deque is empty */</span>
+<span class="dt">int</span> dequePop(Deque *d, <span class="dt">int</span> direction);
+
+<span class="co">/* return 1 if deque contains no elements, 0 otherwise */</span>
+<span class="dt">int</span> dequeIsEmpty(<span class="dt">const</span> Deque *d);
+
+<span class="co">/* free space used by a deque */</span>
+<span class="dt">void</span> dequeDestroy(Deque *d);</code></pre></div>
+<a href="http://cs.yale.edu/homes/aspnes/classes/223/examples/linkedLists/deque/deque.h" class="uri">examples/linkedLists/deque/deque.h</a>
+</div>
+<div>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"><span class="ot">#include &lt;stdlib.h&gt;</span>
+<span class="ot">#include &lt;assert.h&gt;</span>
+<span class="ot">#include &lt;stddef.h&gt; </span><span class="co">/* for offsetof */</span>
+
+<span class="ot">#include "deque.h"</span>
+
+<span class="ot">#define NUM_DIRECTIONS (2)</span>
+
+<span class="kw">struct</span> deque {
+ <span class="kw">struct</span> deque *next[NUM_DIRECTIONS];
+ <span class="dt">int</span> value;
+};
+
+Deque *
+dequeCreate(<span class="dt">void</span>)
+{
+ Deque *d;
+
+ <span class="co">/*</span>
+<span class="co"> * We don't allocate the full space for this object</span>
+<span class="co"> * because we don't use the value field in the dummy head.</span>
+<span class="co"> *</span>
+<span class="co"> * Saving these 4 bytes doesn't make a lot of sense here,</span>
+<span class="co"> * but it might be more significant if value where larger.</span>
+<span class="co"> */</span>
+ d = malloc(offsetof(<span class="kw">struct</span> deque, value));
+
+ <span class="co">/* test is to deal with malloc failure */</span>
+ <span class="kw">if</span>(d) {
+ d-&gt;next[DEQUE_FRONT] = d-&gt;next[DEQUE_BACK] = d;
+ }
+
+ <span class="kw">return</span> d;
+}
+
+<span class="dt">void</span>
+dequePush(Deque *d, <span class="dt">int</span> direction, <span class="dt">int</span> value)
+{
+ <span class="kw">struct</span> deque *e; <span class="co">/* new element */</span>
+
+ assert(direction == DEQUE_FRONT || direction == DEQUE_BACK);
+
+ e = malloc(<span class="kw">sizeof</span>(<span class="kw">struct</span> deque));
+ assert(e);
+
+ e-&gt;next[direction] = d-&gt;next[direction];
+ e-&gt;next[!direction] = d;
+ e-&gt;value = value;
+
+ d-&gt;next[direction] = e;
+ e-&gt;next[direction]-&gt;next[!direction] = e; <span class="co">/* preserves invariant */</span>
+}
+
+<span class="dt">int</span>
+dequePop(Deque *d, <span class="dt">int</span> direction)
+{
+ <span class="kw">struct</span> deque *e;
+ <span class="dt">int</span> retval;
+
+ assert(direction == DEQUE_FRONT || direction == DEQUE_BACK);
+
+ e = d-&gt;next[direction];
+
+ <span class="kw">if</span>(e == d) {
+ <span class="kw">return</span> DEQUE_EMPTY;
+ }
+
+ <span class="co">/* else remove it */</span>
+ d-&gt;next[direction] = e-&gt;next[direction];
+ e-&gt;next[direction]-&gt;next[!direction] = d;
+
+ retval = e-&gt;value;
+
+ free(e);
+
+ <span class="kw">return</span> retval;
+}
+
+<span class="dt">int</span>
+dequeIsEmpty(<span class="dt">const</span> Deque *d)
+{
+ <span class="kw">return</span> d-&gt;next[DEQUE_FRONT] == d;
+}
+
+<span class="dt">void</span>
+dequeDestroy(Deque *d)
+{
+ <span class="kw">while</span>(!dequeIsEmpty(d)) {
+ dequePop(d, DEQUE_FRONT);
+ }
+
+ free(d);
+}</code></pre></div>
+<a href="http://cs.yale.edu/homes/aspnes/classes/223/examples/linkedLists/deque/deque.c" class="uri">examples/linkedLists/deque/deque.c</a>
+</div>
+<p>And here is some test code:</p>
+<p><a href="http://cs.yale.edu/homes/aspnes/classes/223/examples/linkedLists/deque/testDeque.c">testDeque.c</a>.</p>
+<h4 id="ringBuffers"><span class="header-section-number">5.2.5.1</span> Alternate implementation using a ring buffer</h4>
+<p>The <code>deque.h</code> file carefully avoids revealing any details
+of the implementation of a deque. This allows us to replace the
+implementation with a different implementation that is more efficient in
+ its use of both time and space, at the cost of additional code
+complexity. Below is a replacement for <code>deque.c</code> that uses a <strong>ring buffer</strong> in place of the circular linked list.</p>
+<p>The idea of a ring buffer is to store the deque elements in an array,
+ with a pointer to the first element and a length field that says how
+many elements are in the deque. The information needed to manage the
+array (which is allocated using <code>malloc</code>) is stored in a <code>struct</code>.</p>
+<p>The sequence of elements wraps around the endpoints of the array,
+leaving a gap somewhere in the middle. Deque pushes extend the sequence
+into this gap from one side or another, while pops increase the size of
+the gap. If the user wants to do a push and the array is full, we build a
+ new, larger deque, move all the elements there, and then transplant all
+ the bits of the new <code>struct deque</code> into the old one. This transplant trick avoids changing the address of the <code>struct deque</code> that the user needs to access it.</p>
+<div>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"><span class="ot">#include &lt;stdlib.h&gt;</span>
+<span class="ot">#include &lt;assert.h&gt;</span>
+
+<span class="ot">#include "deque.h"</span>
+
+<span class="co">/*</span>
+<span class="co"> * Alternative implementation of a deque using a ring buffer.</span>
+<span class="co"> *</span>
+<span class="co"> * Conceptually, this is an array whose indices wrap around at</span>
+<span class="co"> * the endpoints. </span>
+<span class="co"> *</span>
+<span class="co"> * The region in use is specified by a base index pointing</span>
+<span class="co"> * to the first element, and a length count giving the number</span>
+<span class="co"> * of elements. A size field specifies the number of slots</span>
+<span class="co"> * in the block.</span>
+<span class="co"> *</span>
+<span class="co"> * Picture:</span>
+<span class="co"> *</span>
+<span class="co"> * ---------------------------------------------------</span>
+<span class="co"> * |7|8|9| | | | | | | | | | | | | | | | |1|2|3|4|5|6|</span>
+<span class="co"> * ---------------------------------------------------</span>
+<span class="co"> * ^ ^</span>
+<span class="co"> * | |</span>
+<span class="co"> * base + length - 1 base</span>
+<span class="co"> *</span>
+<span class="co"> */</span>
+
+<span class="kw">struct</span> deque {
+ size_t base; <span class="co">/* location of front element */</span>
+ size_t length; <span class="co">/* length of region in use */</span>
+ size_t size; <span class="co">/* total number of positions in contents */</span>
+ <span class="dt">int</span> *contents;
+};
+
+<span class="ot">#define INITIAL_SIZE (8)</span>
+
+<span class="co">/* create a new deque of the given size */</span>
+<span class="dt">static</span> Deque *
+dequeCreateInternal(size_t size)
+{
+ <span class="kw">struct</span> deque *d;
+
+ d = malloc(<span class="kw">sizeof</span>(<span class="kw">struct</span> deque));
+ assert(d);
+
+ d-&gt;base = <span class="dv">0</span>;
+ d-&gt;length = <span class="dv">0</span>;
+ d-&gt;size = size;
+
+ d-&gt;contents = malloc(<span class="kw">sizeof</span>(<span class="dt">int</span>) * d-&gt;size);
+ assert(d-&gt;contents);
+
+ <span class="kw">return</span> d;
+}
+
+<span class="co">/* return a new empty deque */</span>
+Deque *
+dequeCreate(<span class="dt">void</span>)
+{
+ <span class="kw">return</span> dequeCreateInternal(INITIAL_SIZE);
+}
+
+<span class="dt">void</span>
+dequePush(Deque *d, <span class="dt">int</span> direction, <span class="dt">int</span> value)
+{
+ <span class="kw">struct</span> deque *d2; <span class="co">/* replacement deque if we grow */</span>
+ <span class="dt">int</span> *oldContents; <span class="co">/* old contents of d */</span>
+
+ <span class="co">/*</span>
+<span class="co"> * First make sure we have space.</span>
+<span class="co"> */</span>
+
+ <span class="kw">if</span>(d-&gt;length == d-&gt;size) {
+ <span class="co">/* nope */</span>
+ d2 = dequeCreateInternal(d-&gt;size * <span class="dv">2</span>);
+
+ <span class="co">/* evacuate d */</span>
+ <span class="kw">while</span>(!dequeIsEmpty(d)) {
+ dequePush(d2, DEQUE_BACK, dequePop(d, DEQUE_FRONT));
+ }
+
+ <span class="co">/* do a transplant from d2 to d */</span>
+ <span class="co">/* but save old contents so we can free them */</span>
+ oldContents = d-&gt;contents;
+ *d = *d2; <span class="co">/* this is equivalent to copying the components one by one */</span>
+
+ <span class="co">/* these are the pieces we don't need any more */</span>
+ free(oldContents);
+ free(d2);
+ }
+
+ <span class="co">/*</span>
+<span class="co"> * This requires completely different code </span>
+<span class="co"> * depending on the direction, which is </span>
+<span class="co"> * annoying.</span>
+<span class="co"> */</span>
+ <span class="kw">if</span>(direction == DEQUE_FRONT) {
+ <span class="co">/* d-&gt;base is unsigned, so we have to check for zero first */</span>
+ <span class="kw">if</span>(d-&gt;base == <span class="dv">0</span>) {
+ d-&gt;base = d-&gt;size - <span class="dv">1</span>;
+ } <span class="kw">else</span> {
+ d-&gt;base--;
+ }
+
+ d-&gt;length++;
+
+ d-&gt;contents[d-&gt;base] = value;
+ } <span class="kw">else</span> {
+ d-&gt;contents[(d-&gt;base + d-&gt;length++) % d-&gt;size] = value;
+ }
+}
+
+<span class="co">/* pop and return first value on direction side of deque d */</span>
+<span class="co">/* returns DEQUE_EMPTY if deque is empty */</span>
+<span class="dt">int</span>
+dequePop(Deque *d, <span class="dt">int</span> direction)
+{
+ <span class="dt">int</span> retval;
+
+ <span class="kw">if</span>(dequeIsEmpty(d)) {
+ <span class="kw">return</span> DEQUE_EMPTY;
+ }
+
+ <span class="co">/* else */</span>
+ <span class="kw">if</span>(direction == DEQUE_FRONT) {
+ <span class="co">/* base goes up by one, length goes down by one */</span>
+ retval = d-&gt;contents[d-&gt;base];
+
+ d-&gt;base = (d-&gt;base<span class="dv">+1</span>) % d-&gt;size;
+ d-&gt;length--;
+
+ <span class="kw">return</span> retval;
+ } <span class="kw">else</span> {
+ <span class="co">/* length goes down by one */</span>
+ <span class="kw">return</span> d-&gt;contents[(d-&gt;base + --d-&gt;length) % d-&gt;size];
+ }
+}
+
+<span class="dt">int</span>
+dequeIsEmpty(<span class="dt">const</span> Deque *d)
+{
+ <span class="kw">return</span> d-&gt;length == <span class="dv">0</span>;
+}
+
+<span class="dt">void</span>
+dequeDestroy(Deque *d)
+{
+ free(d-&gt;contents);
+ free(d);
+}</code></pre></div>
+<a href="http://cs.yale.edu/homes/aspnes/classes/223/examples/linkedLists/deque/ringBuffer.c" class="uri">examples/linkedLists/deque/ringBuffer.c</a>
+</div>
+<p>Here is a <code>Makefile</code> that compiles <code>testDeque.c</code> against both the linked list and the ring buffer implementations. You can do <code>make time</code> to race them against each other.</p>
+<div>
+<div class="sourceCode"><pre class="sourceCode makefile"><code class="sourceCode makefile"><span class="dt">CC</span><span class="ch">=</span><span class="st">gcc</span>
+<span class="dt">CFLAGS=-std</span><span class="ch">=</span><span class="st">c99 -Wall -pedantic -O3 -g3</span>
+
+<span class="co"># how many iterations for test</span>
+<span class="dt">ITERATIONS</span><span class="ch">=</span><span class="st">10000000</span>
+<span class="dt">VALGRIND_ITERATIONS</span><span class="ch">=</span><span class="st">100</span>
+
+<span class="dv">all:</span><span class="dt"> testDeque testRingBuffer</span>
+
+<span class="dv">test:</span><span class="dt"> all</span>
+ ./testDeque <span class="ch">$(</span><span class="dt">ITERATIONS</span><span class="ch">)</span>
+ valgrind -q --leak-check=yes ./testDeque <span class="ch">$(</span><span class="dt">VALGRIND_ITERATIONS</span><span class="ch">)</span>
+ ./testRingBuffer <span class="ch">$(</span><span class="dt">ITERATIONS</span><span class="ch">)</span>
+ valgrind -q --leak-check=yes ./testRingBuffer <span class="ch">$(</span><span class="dt">VALGRIND_ITERATIONS</span><span class="ch">)</span>
+
+<span class="dv">time:</span><span class="dt"> all</span>
+ time ./testDeque <span class="ch">$(</span><span class="dt">ITERATIONS</span><span class="ch">)</span>
+ time ./testRingBuffer <span class="ch">$(</span><span class="dt">ITERATIONS</span><span class="ch">)</span>
+
+<span class="dv">testDeque:</span><span class="dt"> testDeque.o deque.o</span>
+ <span class="ch">$(</span><span class="dt">CC</span><span class="ch">)</span> <span class="ch">$(</span><span class="dt">CFLAGS</span><span class="ch">)</span> -o <span class="ch">$@</span> <span class="ch">$^</span>
+
+<span class="dv">testRingBuffer:</span><span class="dt"> testDeque.o ringBuffer.o</span>
+ <span class="ch">$(</span><span class="dt">CC</span><span class="ch">)</span> <span class="ch">$(</span><span class="dt">CFLAGS</span><span class="ch">)</span> -o <span class="ch">$@</span> <span class="ch">$^</span>
+
+
+<span class="dv">clean:</span>
+ <span class="ch">$(</span><span class="dt">RM</span><span class="ch">)</span> testDeque testRingBuffer *.o</code></pre></div>
+<a href="http://cs.yale.edu/homes/aspnes/classes/223/examples/linkedLists/deque/Makefile" class="uri">examples/linkedLists/deque/Makefile</a>
+</div>
+<h3 id="Circular_linked_lists"><span class="header-section-number">5.2.6</span> Circular linked lists</h3>
+<p>For some applications, there is no obvious starting or ending point
+to a list, and a circular list (where the last element points back to
+the first) may be appropriate. Circular doubly-linked lists can also be
+used to build deques; a single pointer into the list tracks the head of
+the deque, with some convention adopted for whether the head is an
+actual element of the list (at the front, say, with its left neighbor at
+ the back) or a dummy element that is not considered to be part of the
+list.</p>
+<p>The selling point of circular doubly-linked lists as a concrete data
+structure is that insertions and deletions can be done anywhere in the
+list with only local information. For example, here are some routines
+for manipulating a doubly-linked list directly. We'll make our lives
+easy and assume (for the moment) that the list has no actual contents to
+ keep track of.</p>
+<div>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"><span class="ot">#include &lt;stdlib.h&gt;</span>
+
+<span class="co">/* directions for doubly-linked list next pointers */</span>
+<span class="ot">#define RIGHT (0)</span>
+<span class="ot">#define LEFT (1)</span>
+
+<span class="kw">struct</span> elt {
+ <span class="kw">struct</span> elt *next[<span class="dv">2</span>];
+};
+
+<span class="kw">typedef</span> <span class="kw">struct</span> elt *Elt;
+
+<span class="co">/* create a new circular doubly-linked list with 1 element */</span>
+<span class="co">/* returns 0 on allocation error */</span>
+Elt
+listCreate(<span class="dt">void</span>)
+{
+ Elt e;
+
+ e = malloc(<span class="kw">sizeof</span>(*e));
+ <span class="kw">if</span>(e) {
+ e-&gt;next[LEFT] = e-&gt;next[RIGHT] = e;
+ }
+
+ <span class="kw">return</span> e;
+}
+
+<span class="co">/* remove an element from a list */</span>
+<span class="co">/* Make sure you keep a pointer to some other element! */</span>
+<span class="co">/* does not free the removed element */</span>
+<span class="dt">void</span>
+listRemove(Elt e)
+{
+ <span class="co">/* splice e out */</span>
+ e-&gt;next[RIGHT]-&gt;next[LEFT] = e-&gt;next[LEFT];
+ e-&gt;next[LEFT]-&gt;next[RIGHT] = e-&gt;next[RIGHT];
+}
+
+<span class="co">/* insert an element e into list in direction dir from head */</span>
+<span class="dt">void</span>
+listInsert(Elt head, <span class="dt">int</span> dir, Elt e)
+{
+ <span class="co">/* fill in e's new neighbors */</span>
+ e-&gt;next[dir] = head-&gt;next[dir];
+ e-&gt;next[!dir] = head;
+
+ <span class="co">/* make neigbhors point back at e */</span>
+ e-&gt;next[dir]-&gt;next[!dir] = e;
+ e-&gt;next[!dir]-&gt;next[dir] = e;
+}
+
+<span class="co">/* split a list, removing all elements between e1 and e2 */</span>
+<span class="co">/* e1 is the leftmost node of the removed subsequence, e2 rightmost */</span>
+<span class="co">/* the removed elements are formed into their own linked list */</span>
+<span class="co">/* comment: listRemove could be implemented as listSplit(e,e) */</span>
+<span class="dt">void</span>
+listSplit(Elt e1, Elt e2)
+{
+ <span class="co">/* splice out the new list */</span>
+ e2-&gt;next[RIGHT]-&gt;next[LEFT] = e1-&gt;next[LEFT];
+ e1-&gt;next[LEFT]-&gt;next[RIGHT] = e2-&gt;next[RIGHT];
+
+ <span class="co">/* fix up the ends */</span>
+ e2-&gt;next[RIGHT] = e1;
+ e1-&gt;next[LEFT] = e2;
+}
+
+<span class="co">/* splice a list starting at e2 after e1 */</span>
+<span class="co">/* e2 becomes e1's right neighbor */</span>
+<span class="co">/* e2's left neighbor becomes left neighbor of e1's old right neighbor */</span>
+<span class="dt">void</span>
+listSplice(Elt e1, Elt e2)
+{
+ <span class="co">/* fix up tail end */</span>
+ e2-&gt;next[LEFT]-&gt;next[RIGHT] = e1-&gt;next[RIGHT];
+ e1-&gt;next[RIGHT]-&gt;next[LEFT] = e2-&gt;next[LEFT];
+
+ <span class="co">/* fix up e1 and e2 */</span>
+ e1-&gt;next[RIGHT] = e2;
+ e2-&gt;next[LEFT] = e1;
+}
+
+<span class="co">/* free all elements of the list containing e */</span>
+<span class="dt">void</span>
+listDestroy(Elt e)
+{
+ Elt target;
+ Elt next;
+
+ <span class="co">/* we'll free elements until we get back to e, then free e */</span>
+ <span class="co">/* note use of pointer address comparison to detect end of loop */</span>
+ <span class="kw">for</span>(target = e-&gt;next[RIGHT]; target != e; target = next) {
+ next = target-&gt;next[RIGHT];
+ free(target);
+ }
+
+ free(e);
+}</code></pre></div>
+<a href="http://cs.yale.edu/homes/aspnes/classes/223/examples/linkedLists/circular.c" class="uri">examples/linkedLists/circular.c</a>
+</div>
+<p>The above code might or might not actually work. What if it doesn't?
+It may make sense to include some sanity-checking code that we can run
+to see if our pointers are all going to the right place:</p>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"><span class="co">/* assert many things about correctness of the list */</span>
+<span class="co">/* Amazingly, this is guaranteed to abort or return no matter</span>
+<span class="co"> how badly screwed up the list is. */</span>
+<span class="dt">void</span>
+listSanityCheck(Elt e)
+{
+ Elt check;
+
+ assert(e != <span class="dv">0</span>);
+
+ check = e;
+
+ <span class="kw">do</span> {
+
+ <span class="co">/* are our pointers consistent with our neighbors? */</span>
+ assert(check-&gt;next[RIGHT]-&gt;next[LEFT] == check);
+ assert(check-&gt;next[LEFT]-&gt;next[RIGHT] == check);
+
+ <span class="co">/* on to the next */</span>
+ check = check-&gt;next[RIGHT];
+
+ } <span class="kw">while</span>(check != e);
+}</code></pre></div>
+<p>What if we want to store something in this list? The simplest approach is to extend the definition of <code class="backtick">struct&nbsp;elt</code>:</p>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"><span class="kw">struct</span> elt {
+ <span class="kw">struct</span> elt *next[<span class="dv">2</span>];
+ <span class="dt">char</span> *name;
+ <span class="dt">int</span> socialSecurityNumber;
+ <span class="dt">int</span> gullibility;
+};</code></pre></div>
+<p>But then we can only use the code for one particular type of data. An alternative approach is to define a new <code class="backtick">Elt</code>-plus struct:</p>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"><span class="kw">struct</span> fancyElt {
+ <span class="kw">struct</span> elt *next[<span class="dv">2</span>];
+ <span class="dt">char</span> *name;
+ <span class="dt">int</span> socialSecurityNumber;
+ <span class="dt">int</span> gullibility;
+};</code></pre></div>
+<p>and then use pointer casts to convert the fancy structs into <code class="backtick">Elt</code>s:</p>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"> <span class="kw">struct</span> fancyElt *e;
+
+ e = malloc(<span class="kw">sizeof</span>(*e));
+
+ <span class="co">/* fill in fields on e */</span>
+
+ listInsert(someList, (Elt) e);</code></pre></div>
+<p>The trick here is that as long as the initial part of the <code class="backtick">struct&nbsp;fancyElt</code> looks like a <code class="backtick">struct&nbsp;elt</code>, any code that expects a <code class="backtick">struct&nbsp;elt</code> will happily work with it and ignore the fields that happen to be sitting later in memory. (This trick is how <a href="#cplusplus">C++</a> inheritance works.)</p>
+<p>The downside is that if something needs to be done with the other fields (e.g freeing <code class="backtick">e-&gt;name</code> if <code class="backtick">e</code> is freed), then the <code class="backtick">Elt</code> functions won't know to do this. So if you use this trick you should be careful.</p>
+<p>A similar technique using <code class="backtick">void&nbsp;*</code> pointers can be used to implement <a href="#genericContainers">generic containers</a>.</p>
+<h3 id="What_linked_lists_are_and_are_not_good_for"><span class="header-section-number">5.2.7</span> What linked lists are and are not good for</h3>
+<p>Linked lists are good for any task that involves inserting or
+deleting elements next to an element you already have a pointer to; such
+ operations can usually be done in <span class="math inline"><em>O</em>(1)</span>
+ time. They generally beat arrays (even resizeable arrays) if you need
+to insert or delete in the middle of a list, since an array has to copy
+any elements above the insertion point to make room; if inserts or
+deletes always happen at the end, an array may be better.</p>
+<p>Linked lists are not good for any operation that requires random
+access, since reaching an arbitrary element of a linked list takes as
+much as <span class="math inline"><em>O</em>(<em>n</em>)</span> time.
+For such applications, arrays are better if you don't need to insert in
+the middle; if you do, you should use some sort of <a href="#binaryTrees">tree</a>.</p>
+<h3 id="Further_reading"><span class="header-section-number">5.2.8</span> Further reading</h3>
+<p>A description of many different kinds of linked lists with pictures can be found in <a href="http://en.wikipedia.org/wiki/Linked_list">the WikiPedia article on the subject</a>.</p>
+<p>Animated versions can be found at <a href="http://www.cs.usfca.edu/%7Egalles/visualization/Algorithms.html" class="uri">http://www.cs.usfca.edu/~galles/visualization/Algorithms.html</a>.</p>
+<h2 id="abstractDataTypes"><span class="header-section-number">5.3</span> Abstract data types</h2>
+<p>One of the hard parts about computer programming is that, in general, <em>programs are bigger than brains</em>.
+ Unless you have an unusally capacious brain, it is unlikely that you
+will be able to understand even a modestly large program in its
+entirety. So in order to be able to write and debug large programs, it
+is important to be able to break it up into pieces, where each piece can
+ be treated as a tool whose use and description is simpler (and therefor
+ fits in your brain better) than its actual code. Then you can forget
+about what is happening inside that piece, and just treat it as an
+easily-understood black box from the outside.</p>
+<p>This process of wrapping functionality up in a box and forgetting about its internals is called <strong>abstraction</strong>,
+ and it is the single most important concept in computer science. In
+these notes we will describe a particular kind of abstraction, the
+construction of <strong>abstract data types</strong> or ADTs. Abstract
+data types are data types whose implementation is not visible to their
+user; from the outside, all the user knows about an ADT is what
+operations can be performed on it and what those operations are supposed
+ to do.</p>
+<p>ADTs have an outside and an inside. The outside is called the <strong>interface</strong>; it consists of the minimal set of type and function declarations needed to use the ADT. The inside is called the <strong>implementation</strong>; it consists of type and function definitions, and sometime auxiliary data or helper functions, that are <em>not</em> visible to users of the ADT. This separation between interface and implementation is called the <strong>abstraction barrier</strong>, and allows the implementation to change without affecting the rest of the program.</p>
+<p>What joins the implementation to the interface is an <strong>abstraction function</strong>.
+ This is a function (in the mathematical sense) that takes any state of
+the implementation and trims off any irrelevant details to leave behind
+an idealized pictures of what the data type is doing. For example, a
+linked list implementation translates to a sequence abstract data type
+by forgetting about the pointers used to hook up the elements and just
+keeping the sequence of elements themselves. To exclude bad states of
+the implementation (for example, a singly-linked list that loops back on
+ itself instead of having a terminating null pointer), we may have a <strong>representation invariant</strong>,
+ which is just some property of the implementation that is always true.
+Representation invariants are also useful for detecting when we've
+bungled our implementation, and a good debugging strategy for
+misbehaving abstract data type implementations is often to look for the
+first point at which they violated some property that we thought was an
+invariant.</p>
+<p>Some programming language include very strong mechanisms for
+enforcing abstraction barriers. C relies somewhat more on politeness,
+and as a programmer you violate an abstraction barrier (by using details
+ of an implementation that are supposed to be hidden) at your peril. In
+C, the interface will typically consist of function and type
+declarations contained in a header file, with implementation made up of
+the corresponding function definitions (and possibly a few extra <code>static</code> functions) in one or more <code>.c</code> files. The <a href="#opaqueStructs">opaque struct</a> technique can be used to hide implementation details of the type.</p>
+<h3 id="abstractDataTypeExample"><span class="header-section-number">5.3.1</span> A sequence type</h3>
+<p>Too much abstraction at once can be hard to take, so let's look at a
+concrete example of an abstract data type. This ADT will represent an
+infinite sequence of <code>int</code>s. Each <strong>instance</strong> of the <code>Sequence</code> type supports a single operation <code>seq_next</code> that returns the next <code>int</code> in the sequence. We will also need to provide one or more <strong>constructor</strong> functions to generate new <code>Sequence</code>s, and a <strong>destructor</strong> function to tear them down.</p>
+<p>Here is an example of a typical use of a <code>Sequence</code>:</p>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"><span class="dt">void</span>
+seq_print(Sequence s, <span class="dt">int</span> limit)
+{
+ <span class="dt">int</span> i;
+
+ <span class="kw">for</span>(i = seq_next(s); i &lt; limit; i = seq_next(s)) {
+ printf(<span class="st">"%d</span><span class="ch">\n</span><span class="st">"</span>, i);
+ }
+}</code></pre></div>
+<p>Note that <code>seq_print</code> doesn't need to know anything at all about what a <code>Sequence</code> is or how <code>seq_next</code>
+ works in order to print out all the values in the sequence until it
+hits one greater than or equal to limit. This is a good thing--- it
+means that we can use with any implementation of <code>Sequence</code> we like, and we don't have to change it if <code>Sequence</code> or <code>seq_next</code> changes.</p>
+<h4 id="Interface"><span class="header-section-number">5.3.1.1</span> Interface</h4>
+<p>In C, the interface of an abstract data type will usually be declared
+ in a header file, which is included both in the file that implements
+the ADT (so that the compiler can check that the declarations match up
+with the actual definitions in the implementation. Here's a header file
+for sequences:</p>
+<div>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"><span class="co">/* opaque struct: hides actual components of struct sequence,</span>
+<span class="co"> * which are defined in sequence.c */</span>
+<span class="kw">typedef</span> <span class="kw">struct</span> sequence *Sequence;
+
+<span class="co">/* constructors */</span>
+<span class="co">/* all our constructors return a null pointer on allocation failure */</span>
+
+<span class="co">/* returns a Sequence representing init, init+1, init+2, ... */</span>
+Sequence seq_create(<span class="dt">int</span> init);
+
+<span class="co">/* returns a Sequence representing init, init+step, init+2*step, ... */</span>
+Sequence seq_create_step(<span class="dt">int</span> init, <span class="dt">int</span> step);
+
+<span class="co">/* destructor */</span>
+<span class="co">/* destroys a Sequence, recovering all interally-allocated data */</span>
+<span class="dt">void</span> seq_destroy(Sequence);
+
+<span class="co">/* accessor */</span>
+<span class="co">/* returns the first element in a sequence not previously returned */</span>
+<span class="dt">int</span> seq_next(Sequence);</code></pre></div>
+<a href="http://cs.yale.edu/homes/aspnes/classes/223/examples/ADT/sequence/sequence.h" class="uri">examples/ADT/sequence/sequence.h</a>
+</div>
+<p>Here we have defined two different constructors for <code>Sequence</code>s,
+ one of which gives slightly more control over the sequence than the
+other. If we were willing to put more work into the implementation, we
+could imagine building a very complicated <code>Sequence</code> type
+that supported a much wider variety of sequences (for example, sequences
+ generated by functions or sequences read from files); but we'll try to
+keep things simple for now. We can always add more functionality later,
+since the users won't notice if the <code>Sequence</code> type changes internally.</p>
+<h4 id="adtImplementation"><span class="header-section-number">5.3.1.2</span> Implementation</h4>
+<p>The implementation of an ADT in C is typically contained in one (or sometimes more than one) <code>.c</code> file. This file can be compiled and linked into any program that needs to use the ADT. Here is our implementation of <code>Sequence</code>:</p>
+<div>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"><span class="ot">#include &lt;stdlib.h&gt;</span>
+
+<span class="ot">#include "sequence.h"</span>
+
+<span class="kw">struct</span> sequence {
+ <span class="dt">int</span> next; <span class="co">/* next value to return */</span>
+ <span class="dt">int</span> step; <span class="co">/* how much to increment next by */</span>
+};
+
+Sequence
+seq_create(<span class="dt">int</span> init)
+{
+ <span class="kw">return</span> seq_create_step(init, <span class="dv">1</span>);
+}
+
+Sequence
+seq_create_step(<span class="dt">int</span> init, <span class="dt">int</span> step)
+{
+ Sequence s;
+
+ s = malloc(<span class="kw">sizeof</span>(*s));
+ <span class="kw">if</span>(s == <span class="dv">0</span>) <span class="kw">return</span> <span class="dv">0</span>;
+ s-&gt;next = init;
+ s-&gt;step = step;
+ <span class="kw">return</span> s;
+}
+
+<span class="dt">void</span>
+seq_destroy(Sequence s)
+{
+ free(s);
+}
+
+<span class="dt">int</span>
+seq_next(Sequence s)
+{
+ <span class="dt">int</span> ret; <span class="co">/* saves the old value before we increment it */</span>
+
+ ret = s-&gt;next;
+ s-&gt;next += s-&gt;step;
+
+ <span class="kw">return</span> ret;
+}</code></pre></div>
+<a href="http://cs.yale.edu/homes/aspnes/classes/223/examples/ADT/sequence/sequence.c" class="uri">examples/ADT/sequence/sequence.c</a>
+</div>
+<p>Things to note here: the definition of <code>struct&nbsp;sequence</code> appears only in this file; this means that only the functions defined here can (easily) access the <code>next</code> and <code>step</code> components. This protects <code>Sequence</code>s
+ to a limited extent from outside interference, and defends against
+users who might try to "violate the abstraction boundary" by examining
+the components of a <code>Sequence</code> directly. It also means that if we change the components or meaning of the components in <code>struct&nbsp;sequence</code>, we only have to fix the functions defined in <code>sequence.c</code>.</p>
+<h4 id="Compiling_and_linking"><span class="header-section-number">5.3.1.3</span> Compiling and linking</h4>
+<p>Now that we have <code>sequence.h</code> and <code>sequence.c</code>, how do we use them? Let's suppose we have a simple main program:</p>
+<div>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"><span class="ot">#include &lt;stdio.h&gt;</span>
+
+<span class="ot">#include "sequence.h"</span>
+
+
+<span class="dt">void</span>
+seq_print(Sequence s, <span class="dt">int</span> limit)
+{
+ <span class="dt">int</span> i;
+
+ <span class="kw">for</span>(i = seq_next(s); i &lt; limit; i = seq_next(s)) {
+ printf(<span class="st">"%d</span><span class="ch">\n</span><span class="st">"</span>, i);
+ }
+}
+
+
+<span class="dt">int</span>
+main(<span class="dt">int</span> argc, <span class="dt">char</span> **argv)
+{
+ Sequence s;
+ Sequence s2;
+
+ puts(<span class="st">"Stepping by 1:"</span>);
+
+ s = seq_create(<span class="dv">0</span>);
+ seq_print(s, <span class="dv">5</span>);
+ seq_destroy(s);
+
+ puts(<span class="st">"Now stepping by 3:"</span>);
+
+ s2 = seq_create_step(<span class="dv">1</span>, <span class="dv">3</span>);
+ seq_print(s2, <span class="dv">20</span>);
+ seq_destroy(s2);
+
+ <span class="kw">return</span> <span class="dv">0</span>;
+}</code></pre></div>
+<a href="http://cs.yale.edu/homes/aspnes/classes/223/examples/ADT/sequence/main.c" class="uri">examples/ADT/sequence/main.c</a>
+</div>
+<p>We can compile <code>main.c</code> and <code>sequence.c</code> together into a single binary with the command <code>c99&nbsp;main.c&nbsp;sequence.c</code>. Or we can build a <code>Makefile</code> which will compile the two files separately and then link them. Using <code>make</code> may be more efficient, especially for large programs consisting of many components, since if we make any changes <code>make</code> will only recompile those files we have changed. So here is our <code>Makefile</code>:</p>
+<div>
+<div class="sourceCode"><pre class="sourceCode makefile"><code class="sourceCode makefile"><span class="dt">CC</span><span class="ch">=</span><span class="st">c99</span>
+<span class="dt">CFLAGS</span><span class="ch">=</span><span class="st">-g3 -pedantic -Wall</span>
+
+<span class="dv">all:</span><span class="dt"> seqprinter</span>
+
+<span class="dv">seqprinter:</span><span class="dt"> main.o sequence.o</span>
+ <span class="ch">$(</span><span class="dt">CC</span><span class="ch">)</span> <span class="ch">$(</span><span class="dt">CFLAGS</span><span class="ch">)</span> -o <span class="ch">$@</span> <span class="ch">$^</span>
+
+<span class="dv">test:</span><span class="dt"> seqprinter</span>
+ ./seqprinter
+
+<span class="co"># these rules say to rebuild main.o and sequence.o if sequence.h changes</span>
+<span class="dv">main.o:</span><span class="dt"> main.c sequence.h</span>
+<span class="dv">sequence.o:</span><span class="dt"> sequence.c sequence.h</span>
+
+<span class="dv">clean:</span>
+ <span class="ch">$(</span><span class="dt">RM</span><span class="ch">)</span> -f seqprinter *.o</code></pre></div>
+<a href="http://cs.yale.edu/homes/aspnes/classes/223/examples/ADT/sequence/Makefile" class="uri">examples/ADT/sequence/Makefile</a>
+</div>
+<p>And now running <code>make&nbsp;test</code> produces this output. Notice how the built-in <code>make</code> variables <code>$@</code> and <code>$^</code> expand out to the left-hand side and right-hand side of the dependency line for building <code>seqprinter</code>.</p>
+<pre><code>$ make test
+c99 -g3 -pedantic -Wall -c -o main.o main.c
+c99 -g3 -pedantic -Wall -c -o sequence.o sequence.c
+c99 -g3 -pedantic -Wall -o seqprinter main.o sequence.o
+./seqprinter
+Stepping by 1:
+0
+1
+2
+3
+4
+Now stepping by 3:
+1
+4
+7
+10
+13
+16
+19</code></pre>
+<h3 id="Designing_abstract_data_types"><span class="header-section-number">5.3.2</span> Designing abstract data types</h3>
+<p>Now we've seen how to implement an abstract data type. How do we
+choose when to use when, and what operations to give it? Let's try
+answering the second question first.</p>
+<h4 id="Parnas.27s_Principle"><span class="header-section-number">5.3.2.1</span> Parnas's Principle</h4>
+<p>Parnas's Principle is a statement of the fundamental idea of <em>information hiding</em>, which says that abstraction boundaries should be as narrow as possible:</p>
+<ul>
+<li>The developer of a software component must provide the intended user
+ with all the information needed to make effective use of the services
+provided by the component, and should provide no other information.</li>
+<li>The developer of a software component must be provided with all the
+information necessary to carry out the given responsibilities assigned
+to the component, and should be provided with no other information.</li>
+</ul>
+<p>(David Parnas, "On the Criteria to Be Used in Decomposing Systems into Modules," <em>Communications of the ACM</em>, 15(12): 1059--1062, 1972.)</p>
+<p>For ADTs, this means we should provide as few functions for accessing and modifying the ADT as we can get away with. The <code>Sequence</code> type we defined early has a particularly narrow interface; the developer of <code>Sequence</code> (whoever is writing <code>sequence.c</code>) needs to know nothing about what its user wants except for the arguments passed in to <code>seq_create</code> or <code>seq_create_step</code>, and the user only needs to be able to call <code>seq_next</code>.
+ More complicated ADTs might provide larger sets of operations, but in
+general we know that an ADT provides a successful abstraction when the
+operations are all "natural" ones given our high-level description. If
+we find ourselves writing a lot of extra operations to let users tinker
+with the guts of our implementation, that may be a sign that either we
+aren't taking our abstraction barrier seriously enough, or that we need
+to put the abstraction barrier in a different place.</p>
+<h4 id="When_to_build_an_abstract_data_type"><span class="header-section-number">5.3.2.2</span> When to build an abstract data type</h4>
+<p>The short answer: Whenever you can.</p>
+<p>A better answer: The best heuristic I know for deciding what ADTs to
+include in a program is to write down a description of how your program
+is going to work. For each noun or noun phrase in the description,
+either identify a built-in data type to implement it or design an
+abstract data type.</p>
+<p>For example: a grade database maintains a list of students, and for
+each student it keeps a list of grades. So here we might want data types
+ to represent:</p>
+<ul>
+<li>A list of students,</li>
+<li>A student,</li>
+<li>A list of grades,</li>
+<li>A grade.</li>
+</ul>
+<p>If grades are simple, we might be able to make them just be <code>int</code>s (or maybe <code>double</code>s); to be on the safe side, we should probably create a <code>Grade</code> type with a <code>typedef</code>.
+ The other types are likely to be more complicated. Each student might
+have in addition to his or her grades a long list of other attributes,
+such as a name, an email address, etc. By wrapping students up as
+abstract data types we can extend these attributes if we need to, or
+allow for very general implementations (say, by allowing a student to
+have an arbitrary list of keyword-attribute pairs). The two kinds of
+lists are likely to be examples of <em>sequence</em> types; we'll be
+seeing a lot of ways to implement these as the course progresses. If we
+want to perform the same kinds of operations on both lists, we might
+want to try to implement them as a single list data type, which then is
+specialized to hold either students or grades; this is not always easy
+to do in C, but we'll see examples of how to do this, too.</p>
+<p>Whether or not this set of four types is the set we will finally use,
+ writing it down gives us a place to start writing our program. We can
+start writing interface files for each of the data types, and then
+evolve their implementations and the main program in parallel, adjusting
+ the interfaces as we find that we have provided too little (or too
+much) data for each component to do what it must.</p>
+<h2 id="hashTables"><span class="header-section-number">5.4</span> Hash tables</h2>
+<p>A <strong>hash table</strong> is a randomized data structure that supports the INSERT, DELETE, and FIND operations in expected <span class="math inline"><em>O</em>(1)</span> time. The core idea behind hash tables is to use a <em>hash function</em>
+ that maps a large keyspace to a smaller domain of array indices, and
+then use constant-time array operations to store and retrieve the data.</p>
+<h3 id="dictionaries"><span class="header-section-number">5.4.1</span> Dictionary data types</h3>
+<p>A hash table is typically used to implement a <strong>dictionary data type</strong>, where keys are mapped to values, but unlike an array, the keys are not conveniently arranged as integers <span class="math inline">0, 1, 2, …</span>. Dictionary data types are a fundamental data structure often found in <a href="http://en.wikipedia.org/wiki/Scripting_language" title="WikiPedia">scripting languages</a> like <a href="http://en.wikipedia.org/wiki/AWK" title="WikiPedia">AWK</a>, <a href="http://en.wikipedia.org/wiki/Perl" title="WikiPedia">Perl</a>, <a href="http://en.wikipedia.org/wiki/Python" title="WikiPedia">Python</a>, <a href="http://en.wikipedia.org/wiki/PHP" title="WikiPedia">PHP</a>, <a href="http://en.wikipedia.org/wiki/Lua" title="WikiPedia">Lua</a>, or <a href="http://en.wikipedia.org/wiki/Ruby" title="WikiPedia">Ruby</a>. For example, here is some Python code that demonstrates use of a dictionary accessed using an array-like syntax:</p>
+<div class="sourceCode"><pre class="sourceCode python"><code class="sourceCode python">title <span class="op">=</span> {} <span class="co"># empty dictionary</span>
+title[<span class="st">"Barack"</span>] <span class="op">=</span> <span class="st">"President"</span>
+user <span class="op">=</span> <span class="st">"Barack"</span>
+<span class="bu">print</span>(<span class="st">"Welcome"</span> <span class="op">+</span> title[user] <span class="op">+</span> <span class="st">" "</span> <span class="op">+</span> user)</code></pre></div>
+<p>In C, we don't have the convenience of reusing <code class="backtick">[]</code> for dictionary lookups (we'd need <a href="#cplusplus">C++</a>
+ for that), but we can still get the same effect with more typing using
+functions. For example, using an abstract dictionary in C might look
+like this:</p>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c">Dict *title;
+<span class="dt">const</span> <span class="dt">char</span> *user;
+
+title = dictCreate();
+dictSet(title, <span class="st">"Barack"</span>, <span class="st">"President"</span>);
+user = <span class="st">"Barack"</span>;
+printf(<span class="st">"Welcome %s %s</span><span class="ch">\n</span><span class="st">"</span>, dictGet(title, user), user);</code></pre></div>
+<p>As with other abstract data types, the idea is that the user of the
+dictionary type doesn't need to know how it is implemented. For example,
+ we could implement the dictionary as an array of <code>struct</code>s that we search through, but that would be expensive: <span class="math inline"><em>O</em>(<em>n</em>)</span> time to find a key in the worst case.</p>
+<p>Closely related to a dictionary is a <strong>set</strong>, which has
+keys but no values. It's usually pretty straightforward to turn an
+implementation of a dictionary into a set (leave out the values) or vice
+ versa (add values to the end of keys but don't use them in searching).</p>
+<h3 id="Basics_of_hashing"><span class="header-section-number">5.4.2</span> Basics of hashing</h3>
+<p>If our keys were conveniently named <span class="math inline">0, 1, 2, …, <em>n</em> − 1</span>,
+ we could simply use an array, and be able to find a record given a key
+in constant time. Unfortunately, naming conventions for most objects are
+ not so convenient, and even enumerations like Social Security numbers
+are likely to span a larger range than we want to allocate. But we would
+ like to get the constant-time performance of an array anyway.</p>
+<p>The solution is to feed the keys through some hash function <span class="math inline"><em>H</em></span>, which maps them down to array indices. So in a database of people, to find "Smith, Wayland", we would first compute <span class="math inline"><em>H</em></span>("Smith, Wayland")$ = 137$ (say), and then look in position <span class="math inline">137</span> in the array. Because we are always using the same function <span class="math inline"><em>H</em></span>, we will always be directed to the same position <span class="math inline">137</span>.</p>
+<h3 id="Resolving_collisions"><span class="header-section-number">5.4.3</span> Resolving collisions</h3>
+<p>But what if <span class="math inline"><em>H</em></span>("Smith, Wayland") and <span class="math inline"><em>H</em></span>("Hephaestos") both equal 137? Now we have a <strong>collision</strong>,
+ and we have to resolve it by finding some way to either (a) effectively
+ store both records in a single array location, or (b) move one of the
+records to a new location that we can still find later. Let's consider
+these two approaches separately.</p>
+<h4 id="Chaining"><span class="header-section-number">5.4.3.1</span> Chaining</h4>
+<p>We can't really store more than one record in an array location, but
+we can fake it by making each array location be a pointer to a linked
+list. Every time we insert a new element in a particular location, we
+simply add it to this list.</p>
+<p>Since the cost of scanning a linked list is linear in its size, this
+means that the worst-case cost of searching for a particular key will be
+ linear in the number of keys in the table that hash to the same
+location. Under the assumption that the hash function is a random
+function (which does not mean that it returns random values every time
+you call it but instead means that we picked one of the many possible
+hash functions uniformly at random), on average we get <span class="math inline"><em>n</em>/<em>m</em></span> elements in each list.<br>
+So on average a failed search takes <span class="math inline"><em>O</em>(<em>n</em>/<em>m</em>)</span> time.</p>
+<p>This quantity <span class="math inline"><em>n</em>/<em>m</em></span> is called the <strong>load factor</strong> of the hash table and is often written as <span class="math inline"><em>α</em></span>.
+ If we want our hash table to be efficient, we will need to keep this
+load factor down. If we can guarantee that it's a constant, then we get
+constant-time searches.</p>
+<h4 id="Open_addressing"><span class="header-section-number">5.4.3.2</span> Open addressing</h4>
+<p>With <em>open addressing</em>, we store only one element per
+location, and handle collisions by storing the extra elements in other
+unused locations in the array. To find these other locations, we fix
+some <em>probe sequence</em> that tells us where to look if <span class="math inline"><em>A</em>[<em>H</em>(<em>x</em>)]</span> contains an element that is not <span class="math inline"><em>x</em></span>. A typical probe sequence (called <em>linear probing</em>) is just <span class="math inline"><em>H</em>(<em>x</em>),<em>H</em>(<em>x</em>)+1, <em>H</em>(<em>x</em>)+2, …, </span>
+ wrapping around at the end of the array. The idea is that if we can't
+put an element in a particular place, we just keep walking up through
+the array until we find an empty slot. As long as we follow the same
+probe sequence when looking for an element, we will be able to find the
+element again. If we are looking for an element and reach an empty
+location, then we know that the element is not present in the table.</p>
+<p>For open addressing, we always have that <span class="math inline"><em>α</em> = <em>n</em>/<em>m</em></span>
+ is less than or equal to 1, since we can't store more elements in the
+table than we have locations. In fact, we must ensure that the load
+factor is strictly less than 1, or some searches will never terminate
+because they never reach an empty location. Assuming <span class="math inline"><em>α</em> &lt; 1</span>
+ and that the hash function is uniform, it is possible to calculate the
+worst-case expected cost of a FIND operation, which as before will occur
+ when we have an unsuccessful FIND. Though we won't do this calculation
+here, the result is bounded by <span class="math inline">1/(1 − <em>n</em>/<em>m</em>)</span>, which gets pretty bad if <span class="math inline"><em>n</em>/<em>m</em></span> is very close to <span class="math inline">1</span>, but is a constant as long as <span class="math inline"><em>n</em>/<em>m</em></span> is bounded by a constant (say <span class="math inline">3/4</span>, which makes the expected number of probes at most <span class="math inline">4</span>).</p>
+<h3 id="Choosing_a_hash_function"><span class="header-section-number">5.4.4</span> Choosing a hash function</h3>
+<p>Here we will describe three methods for generating hash functions.
+The first two are typical methods used in practice. The last has
+additional desirable theoretical properties.</p>
+<h4 id="Division_method"><span class="header-section-number">5.4.4.1</span> Division method</h4>
+<p>We want our hash function to look as close as it can to a random
+function, but random functions are (provably) expensive to store. So in
+practice we do something simpler and hope for the best. If the keys are
+large integers, a typical approach is to just compute the remainder mod <span class="math inline"><em>m</em></span>. This can cause problems if <span class="math inline"><em>m</em></span>
+ is, say, a power of 2, since it may be that the low-order bits of all
+the keys are similar, which will produce lots of collisions. So in
+practice with this method <span class="math inline"><em>m</em></span> is typically chosen to be a large prime.</p>
+<p>What if we want to hash strings instead of integers? The trick is to treat the strings as integers. Given a string <span class="math inline"><em>a</em><sub>1</sub><em>a</em><sub>2</sub><em>a</em><sub>3</sub>…<em>a</em><sub><em>k</em></sub></span>, we represent it as <span class="math inline">∑<sub><em>i</em></sub><em>a</em><sub><em>i</em></sub><em>b</em><sup><em>i</em></sup></span>, where <span class="math inline"><em>b</em></span>
+ is a base chosen to be larger than the number of characters. We can
+then feed this resulting huge integer to our hash function. Typically we
+ do not actually compute the huge integer directly, but instead compute
+its remainder mod <span class="math inline"><em>m</em></span>, as in this short C function:</p>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"><span class="co">/* treat strings as base-256 integers */</span>
+<span class="co">/* with digits in the range 1 to 255 */</span>
+<span class="ot">#define BASE (256)</span>
+
+size_t
+hash(<span class="dt">const</span> <span class="dt">char</span> *s, size_t m)
+{
+ size_t h;
+ <span class="dt">unsigned</span> <span class="dt">const</span> <span class="dt">char</span> *us;
+
+ <span class="co">/* cast s to unsigned const char * */</span>
+ <span class="co">/* this ensures that elements of s will be treated as having values &gt;= 0 */</span>
+ us = (<span class="dt">unsigned</span> <span class="dt">const</span> <span class="dt">char</span> *) s;
+
+ h = <span class="dv">0</span>;
+ <span class="kw">while</span>(*us != '\<span class="dv">0</span>') {
+ h = (h * BASE + *us) % m;
+ us++;
+ }
+
+ <span class="kw">return</span> h;
+}</code></pre></div>
+<p>The division method works best when <span class="math inline"><em>m</em></span>
+ is a prime, as otherwise regularities in the keys can produce
+clustering in the hash values. (Consider, for example, what happens if <span class="math inline"><em>m</em></span>
+ is 256). But this can be awkward for computing hash functions quickly,
+because computing remainders is a relatively slow operation.</p>
+<h4 id="Multiplication_method"><span class="header-section-number">5.4.4.2</span> Multiplication method</h4>
+<p>For this reason, the most commonly-used hash functions replace the modulus <span class="math inline"><em>m</em></span> with something like <span class="math inline">2<sup>32</sup></span> and replace the base with some small prime, relying on the multiplier to break up patterns in the input. This yields the <strong>multiplication method</strong>. Typical code might look something like this:</p>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"><span class="ot">#define MULTIPLIER (37)</span>
+
+size_t
+hash(<span class="dt">const</span> <span class="dt">char</span> *s)
+{
+ size_t h;
+ <span class="dt">unsigned</span> <span class="dt">const</span> <span class="dt">char</span> *us;
+
+ <span class="co">/* cast s to unsigned const char * */</span>
+ <span class="co">/* this ensures that elements of s will be treated as having values &gt;= 0 */</span>
+ us = (<span class="dt">unsigned</span> <span class="dt">const</span> <span class="dt">char</span> *) s;
+
+ h = <span class="dv">0</span>;
+ <span class="kw">while</span>(*us != '\<span class="dv">0</span>') {
+ h = h * MULTIPLIER + *us;
+ us++;
+ }
+
+ <span class="kw">return</span> h;
+}</code></pre></div>
+<p>The only difference between this code and the division method code is that we've renamed <code class="backtick">BASE</code> to <code class="backtick">MULTIPLIER</code> and dropped <span class="math inline"><em>m</em></span>.
+ There is still some remainder-taking happening: since C truncates the
+result of any operation that exceeds the size of the integer type that
+holds it, the <code class="backtick">h&nbsp;=&nbsp;h&nbsp;*&nbsp;MULTIPLIER&nbsp;+&nbsp;*us;</code> line effectively has a hidden mod <span class="math inline">2<sup>32</sup></span> or <span class="math inline">2<sup>64</sup></span> at the end of it (depending on how big your <code>size_t</code> is). Now we can't use, say, <span class="math inline">256</span>, as the multiplier, because then the hash value <code class="backtick">h</code> would be determined by just the last four characters of <code class="backtick">s</code>.</p>
+<p>The choice of <span class="math inline">37</span> is based on folklore. I like <span class="math inline">97</span> myself, and <span class="math inline">31</span> also has supporters. Almost any medium-sized prime should work.</p>
+<h4 id="Universal_hashing"><span class="header-section-number">5.4.4.3</span> Universal hashing</h4>
+<p>The preceding hash functions offer no guarantees that the adversary can't find a set of <span class="math inline"><em>n</em></span> keys that all hash to the same location; indeed, since they're deterministic, as long as the keyspace contains at least <span class="math inline"><em>n</em><em>m</em></span>
+ keys the adversary can always do so. Universal families of hash
+functions avoid this problem by choosing the hash function randomly,
+from some set of possible functions that is small enough that we can
+write our random choice down.</p>
+<p>The property that makes a family of hash functions <span class="math inline">{<em>H</em><sub><em>r</em></sub>}</span> universal is that, for any distinct keys <span class="math inline"><em>x</em></span> and <span class="math inline"><em>y</em></span>, the probability that <span class="math inline"><em>r</em></span> is chosen so that <span class="math inline"><em>H</em><sub><em>r</em></sub>(<em>x</em>)=<em>H</em><sub><em>r</em></sub>(<em>y</em>)</span> is exactly <span class="math inline">1/<em>m</em></span>.</p>
+<p>Why is this important? Recall that for chaining, the expected number of collisions between an element <span class="math inline"><em>x</em></span> and other elements was just the sum over all particular elements <span class="math inline"><em>y</em></span> of the probability that <span class="math inline"><em>x</em></span> collides with that particular element. If <span class="math inline"><em>H</em><sub><em>r</em></sub></span> is drawn from a universal family, this probability is <span class="math inline">1/<em>m</em></span> for each <span class="math inline"><em>y</em></span>, and we get the same <span class="math inline"><em>n</em>/<em>m</em></span> expected collisions as if <span class="math inline"><em>H</em><sub><em>r</em></sub></span> were completely random.</p>
+<p>Several universal families of hash functions are known. Here is a
+simple one that works when the size of the keyspace and the size of the
+output space are both powers of <span class="math inline">2</span>. Let the keyspace consist of <span class="math inline"><em>n</em></span>-bit strings and let <span class="math inline"><em>m</em> = 2<sup><em>k</em></sup></span>. Then the random index <span class="math inline"><em>r</em></span> consists of <span class="math inline"><em>n</em><em>k</em></span> independent random bits organized as <span class="math inline"><em>n</em></span> <span class="math inline"><em>m</em></span>-bit strings <span class="math inline"><em>a</em><sub>1</sub><em>a</em><sub>2</sub>…<em>a</em><sub><em>n</em></sub></span>. To compute the hash function of a particular input <span class="math inline"><em>x</em></span>, compute the bitwise exclusive or of <span class="math inline"><em>a</em><sub><em>i</em></sub></span> for each position <span class="math inline"><em>i</em></span> where the <span class="math inline"><em>i</em></span>-th bit of <span class="math inline"><em>x</em></span> is <span class="math inline">1</span>.</p>
+<p>We can implement this in C as</p>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"><span class="co">/* implements universal hashing using random bit-vectors in x */</span>
+<span class="co">/* assumes number of elements in x is at least BITS_PER_CHAR * MAX_STRING_SIZE */</span>
+
+<span class="ot">#define BITS_PER_CHAR (8) </span><span class="co">/* not true on all machines! */</span>
+<span class="ot">#define MAX_STRING_SIZE (128) </span><span class="co">/* we'll stop hashing after this many */</span>
+<span class="ot">#define MAX_BITS (BITS_PER_CHAR * MAX_STRING_SIZE)</span>
+
+size_t
+hash(<span class="dt">const</span> <span class="dt">char</span> *s, size_t x[])
+{
+ size_t h;
+ <span class="dt">unsigned</span> <span class="dt">const</span> <span class="dt">char</span> *us;
+ <span class="dt">int</span> i;
+ <span class="dt">unsigned</span> <span class="dt">char</span> c;
+ <span class="dt">int</span> shift;
+
+ <span class="co">/* cast s to unsigned const char * */</span>
+ <span class="co">/* this ensures that elements of s will be treated as having values &gt;= 0 */</span>
+ us = (<span class="dt">unsigned</span> <span class="dt">const</span> <span class="dt">char</span> *) s;
+
+ h = <span class="dv">0</span>;
+ <span class="kw">for</span>(i = <span class="dv">0</span>; *us != <span class="dv">0</span> &amp;&amp; i &lt; MAX_BITS; us++) {
+ c = *us;
+ <span class="kw">for</span>(shift = <span class="dv">0</span>; shift &lt; BITS_PER_CHAR; shift++, i++) {
+ <span class="co">/* is low bit of c set? */</span>
+ <span class="kw">if</span>(c &amp; <span class="bn">0x1</span>) {
+ h ^= x[i];
+ }
+
+ <span class="co">/* shift c to get new bit in lowest position */</span>
+ c &gt;&gt;= <span class="dv">1</span>;
+ }
+ }
+
+ <span class="kw">return</span> h;
+}</code></pre></div>
+<p>As you can see, this requires a lot of bit-fiddling. It also fails if we get a lot of strings that are identical for the first <code class="backtick">MAX_STRING_SIZE</code> characters. Conceivably, the latter problem could be dealt with by growing <code class="backtick">x</code> dynamically as needed. But we also haven't addressed the question of where we get these random values from—see the chapter on <a href="#randomization">randomization</a> for some possibilities.</p>
+<p>In practice, universal families of hash functions are seldom used,
+since a reasonable fixed hash function is unlikely to be correlated with
+ any patterns in the actual input. But they are useful for demonstrating
+ provably good performance.</p>
+<h3 id="Maintaining_a_constant_load_factor"><span class="header-section-number">5.4.5</span> Maintaining a constant load factor</h3>
+<p>All of the running time results for hash tables depend on keeping the load factor <span class="math inline"><em>α</em></span>
+ small. But as more elements are inserted into a fixed-size table, the
+load factor grows without bound. The usual solution to this problem is
+rehashing: when the load factor crosses some threshold, we create a new
+hash table of size <span class="math inline">2<em>n</em></span> or thereabouts and migrate all the elements to it.</p>
+<p>This approach raises the worst-case cost of an insertion to <span class="math inline"><em>O</em>(<em>n</em>)</span>. However, we can bring the <em>expected</em> cost down to <span class="math inline"><em>O</em>(1)</span> by rehashing only with probability <span class="math inline"><em>O</em>(1/<em>n</em>)</span> for each insert after the threshold is crossed. Or we can apply <strong>amortized analysis</strong> to argue that the amortized cost (total cost divided by number of operations) is <span class="math inline"><em>O</em>(1)</span>
+ assuming we double the table size on each rehash. Neither the
+expected-cost nor the amortized-cost approaches actually change the
+worst-case cost, but they make it look better by demonstrating that we
+at least don't incur that cost every time.</p>
+<p>With enough machinery, it may be possible to <strong>deamortize</strong>
+ the cost of rehashing by doing a little bit of it with every insertion.
+ The idea is to build the new hash table incrementally, and start moving
+ elements to it once it is fully initialized. This requires keeping
+around two copies of the hash table and searching both, and for most
+purposes is more trouble than it's worth. But a mechanism like this is
+often used for real-time garbage collection, where it's important not to
+ have the garbage collector lock up the entire system while it does its
+work.</p>
+<h3 id="Examples"><span class="header-section-number">5.4.6</span> Examples</h3>
+<h4 id="A_low-overhead_hash_table_using_open_addressing"><span class="header-section-number">5.4.6.1</span> A low-overhead hash table using open addressing</h4>
+<p>Here is a very low-overhead hash table based on open addressing. The
+application is rapidly verifying ID numbers in the range 000000000 to
+999999999 by checking them against a list of known good IDs. Since the
+quantity of valid ID numbers may be very large, a goal of the mechanism
+is to keep the amount of extra storage used as small as possible. This
+implementation uses a tunable overhead parameter. Setting the parameter
+to a high value makes lookups fast but requires more space per ID number
+ in the list. Setting it to a low value can reduce the storage cost
+arbitrarily close to 4 bytes per ID, at the cost of increasing search
+times.</p>
+<p>Here is the header file giving the interface:</p>
+<div>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"><span class="kw">typedef</span> <span class="kw">struct</span> idList *IDList;
+
+<span class="ot">#define MIN_ID (0)</span>
+<span class="ot">#define MAX_ID (999999999)</span>
+
+<span class="co">/* build an IDList out of an unsorted array of n good ids */</span>
+<span class="co">/* returns 0 on allocation failure */</span>
+IDList IDListCreate(<span class="dt">int</span> n, <span class="dt">int</span> unsortedIdList[]);
+
+<span class="co">/* destroy an IDList */</span>
+<span class="dt">void</span> IDListDestroy(IDList list);
+
+<span class="co">/* check an id against the list */</span>
+<span class="co">/* returns nonzero if id is in the list */</span>
+<span class="dt">int</span> IDListContains(IDList list, <span class="dt">int</span> id);</code></pre></div>
+<a href="http://cs.yale.edu/homes/aspnes/classes/223/examples/hashTables/idList/idList.h" class="uri">examples/hashTables/idList/idList.h</a>
+</div>
+<p>And here is the implementation:</p>
+<div>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"><span class="ot">#include &lt;stdlib.h&gt;</span>
+<span class="ot">#include &lt;assert.h&gt;</span>
+
+<span class="ot">#include "idList.h"</span>
+
+<span class="co">/* overhead parameter that determines both space and search costs */</span>
+<span class="co">/* must be strictly greater than 1 */</span>
+<span class="ot">#define OVERHEAD (1.1)</span>
+<span class="ot">#define NULL_ID (-1)</span>
+
+
+<span class="kw">struct</span> idList {
+ <span class="dt">int</span> size;
+ <span class="dt">int</span> ids[<span class="dv">1</span>]; <span class="co">/* we'll actually malloc more space than this */</span>
+};
+
+IDList
+IDListCreate(<span class="dt">int</span> n, <span class="dt">int</span> unsortedIdList[])
+{
+ IDList list;
+ <span class="dt">int</span> size;
+ <span class="dt">int</span> i;
+ <span class="dt">int</span> probe;
+
+ size = (<span class="dt">int</span>) (n * OVERHEAD + <span class="dv">1</span>);
+
+ list = malloc(<span class="kw">sizeof</span>(*list) + <span class="kw">sizeof</span>(<span class="dt">int</span>) * (size<span class="dv">-1</span>));
+ <span class="kw">if</span>(list == <span class="dv">0</span>) <span class="kw">return</span> <span class="dv">0</span>;
+
+ <span class="co">/* else */</span>
+ list-&gt;size = size;
+
+ <span class="co">/* clear the hash table */</span>
+ <span class="kw">for</span>(i = <span class="dv">0</span>; i &lt; size; i++) {
+ list-&gt;ids[i] = NULL_ID;
+ }
+
+ <span class="co">/* load it up */</span>
+ <span class="kw">for</span>(i = <span class="dv">0</span>; i &lt; n; i++) {
+
+ assert(unsortedIdList[i] &gt;= MIN_ID);
+ assert(unsortedIdList[i] &lt;= MAX_ID);
+
+ <span class="co">/* hashing with open addressing by division */</span>
+ <span class="co">/* this MUST be the same pattern as in IDListContains */</span>
+ <span class="kw">for</span>(probe = unsortedIdList[i] % list-&gt;size;
+ list-&gt;ids[probe] != NULL_ID;
+ probe = (probe + <span class="dv">1</span>) % list-&gt;size);
+
+ assert(list-&gt;ids[probe] == NULL_ID);
+
+ list-&gt;ids[probe] = unsortedIdList[i];
+ }
+
+ <span class="kw">return</span> list;
+}
+
+<span class="dt">void</span>
+IDListDestroy(IDList list)
+{
+ free(list);
+}
+
+<span class="dt">int</span>
+IDListContains(IDList list, <span class="dt">int</span> id)
+{
+ <span class="dt">int</span> probe;
+
+ <span class="co">/* this MUST be the same pattern as in IDListCreate */</span>
+ <span class="kw">for</span>(probe = id % size;
+ list-&gt;ids[probe] != NULL_ID;
+ probe = (probe + <span class="dv">1</span>) % size) {
+ <span class="kw">if</span>(list-&gt;ids[probe] == id) {
+ <span class="kw">return</span> <span class="dv">1</span>;
+ }
+ }
+
+ <span class="kw">return</span> <span class="dv">0</span>;
+}</code></pre></div>
+<a href="http://cs.yale.edu/homes/aspnes/classes/223/examples/hashTables/idList/idList.c" class="uri">examples/hashTables/idList/idList.c</a>
+</div>
+<h4 id="A_string_to_string_dictionary_using_chaining"><span class="header-section-number">5.4.6.2</span> A string to string dictionary using chaining</h4>
+<p>Here is a more complicated string to string dictionary based on chaining.</p>
+<div>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"><span class="kw">typedef</span> <span class="kw">struct</span> dict *Dict;
+
+<span class="co">/* create a new empty dictionary */</span>
+Dict DictCreate(<span class="dt">void</span>);
+
+<span class="co">/* destroy a dictionary */</span>
+<span class="dt">void</span> DictDestroy(Dict);
+
+<span class="co">/* insert a new key-value pair into an existing dictionary */</span>
+<span class="dt">void</span> DictInsert(Dict, <span class="dt">const</span> <span class="dt">char</span> *key, <span class="dt">const</span> <span class="dt">char</span> *value);
+
+<span class="co">/* return the most recently inserted value associated with a key */</span>
+<span class="co">/* or 0 if no matching key is present */</span>
+<span class="dt">const</span> <span class="dt">char</span> *DictSearch(Dict, <span class="dt">const</span> <span class="dt">char</span> *key);
+
+<span class="co">/* delete the most recently inserted record with the given key */</span>
+<span class="co">/* if there is no such record, has no effect */</span>
+<span class="dt">void</span> DictDelete(Dict, <span class="dt">const</span> <span class="dt">char</span> *key);</code></pre></div>
+<a href="http://cs.yale.edu/homes/aspnes/classes/223/examples/hashTables/dict/dict.h" class="uri">examples/hashTables/dict/dict.h</a>
+</div>
+<div>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"><span class="ot">#include &lt;stdlib.h&gt;</span>
+<span class="ot">#include &lt;assert.h&gt;</span>
+<span class="ot">#include &lt;string.h&gt;</span>
+
+<span class="ot">#include "dict.h"</span>
+
+<span class="kw">struct</span> elt {
+ <span class="kw">struct</span> elt *next;
+ <span class="dt">char</span> *key;
+ <span class="dt">char</span> *value;
+};
+
+<span class="kw">struct</span> dict {
+ <span class="dt">int</span> size; <span class="co">/* size of the pointer table */</span>
+ <span class="dt">int</span> n; <span class="co">/* number of elements stored */</span>
+ <span class="kw">struct</span> elt **table;
+};
+
+<span class="ot">#define INITIAL_SIZE (1024)</span>
+<span class="ot">#define GROWTH_FACTOR (2)</span>
+<span class="ot">#define MAX_LOAD_FACTOR (1)</span>
+
+<span class="co">/* dictionary initialization code used in both DictCreate and grow */</span>
+Dict
+internalDictCreate(<span class="dt">int</span> size)
+{
+ Dict d;
+ <span class="dt">int</span> i;
+
+ d = malloc(<span class="kw">sizeof</span>(*d));
+
+ assert(d != <span class="dv">0</span>);
+
+ d-&gt;size = size;
+ d-&gt;n = <span class="dv">0</span>;
+ d-&gt;table = malloc(<span class="kw">sizeof</span>(<span class="kw">struct</span> elt *) * d-&gt;size);
+
+ assert(d-&gt;table != <span class="dv">0</span>);
+
+ <span class="kw">for</span>(i = <span class="dv">0</span>; i &lt; d-&gt;size; i++) d-&gt;table[i] = <span class="dv">0</span>;
+
+ <span class="kw">return</span> d;
+}
+
+Dict
+DictCreate(<span class="dt">void</span>)
+{
+ <span class="kw">return</span> internalDictCreate(INITIAL_SIZE);
+}
+
+<span class="dt">void</span>
+DictDestroy(Dict d)
+{
+ <span class="dt">int</span> i;
+ <span class="kw">struct</span> elt *e;
+ <span class="kw">struct</span> elt *next;
+
+ <span class="kw">for</span>(i = <span class="dv">0</span>; i &lt; d-&gt;size; i++) {
+ <span class="kw">for</span>(e = d-&gt;table[i]; e != <span class="dv">0</span>; e = next) {
+ next = e-&gt;next;
+
+ free(e-&gt;key);
+ free(e-&gt;value);
+ free(e);
+ }
+ }
+
+ free(d-&gt;table);
+ free(d);
+}
+
+<span class="ot">#define MULTIPLIER (97)</span>
+
+<span class="dt">static</span> <span class="dt">unsigned</span> <span class="dt">long</span>
+hash_function(<span class="dt">const</span> <span class="dt">char</span> *s)
+{
+ <span class="dt">unsigned</span> <span class="dt">const</span> <span class="dt">char</span> *us;
+ <span class="dt">unsigned</span> <span class="dt">long</span> h;
+
+ h = <span class="dv">0</span>;
+
+ <span class="kw">for</span>(us = (<span class="dt">unsigned</span> <span class="dt">const</span> <span class="dt">char</span> *) s; *us; us++) {
+ h = h * MULTIPLIER + *us;
+ }
+
+ <span class="kw">return</span> h;
+}
+
+<span class="dt">static</span> <span class="dt">void</span>
+grow(Dict d)
+{
+ Dict d2; <span class="co">/* new dictionary we'll create */</span>
+ <span class="kw">struct</span> dict swap; <span class="co">/* temporary structure for brain transplant */</span>
+ <span class="dt">int</span> i;
+ <span class="kw">struct</span> elt *e;
+
+ d2 = internalDictCreate(d-&gt;size * GROWTH_FACTOR);
+
+ <span class="kw">for</span>(i = <span class="dv">0</span>; i &lt; d-&gt;size; i++) {
+ <span class="kw">for</span>(e = d-&gt;table[i]; e != <span class="dv">0</span>; e = e-&gt;next) {
+ <span class="co">/* note: this recopies everything */</span>
+ <span class="co">/* a more efficient implementation would</span>
+<span class="co"> * patch out the strdups inside DictInsert</span>
+<span class="co"> * to avoid this problem */</span>
+ DictInsert(d2, e-&gt;key, e-&gt;value);
+ }
+ }
+
+ <span class="co">/* the hideous part */</span>
+ <span class="co">/* We'll swap the guts of d and d2 */</span>
+ <span class="co">/* then call DictDestroy on d2 */</span>
+ swap = *d;
+ *d = *d2;
+ *d2 = swap;
+
+ DictDestroy(d2);
+}
+
+<span class="co">/* insert a new key-value pair into an existing dictionary */</span>
+<span class="dt">void</span>
+DictInsert(Dict d, <span class="dt">const</span> <span class="dt">char</span> *key, <span class="dt">const</span> <span class="dt">char</span> *value)
+{
+ <span class="kw">struct</span> elt *e;
+ <span class="dt">unsigned</span> <span class="dt">long</span> h;
+
+ assert(key);
+ assert(value);
+
+ e = malloc(<span class="kw">sizeof</span>(*e));
+
+ assert(e);
+
+ e-&gt;key = strdup(key);
+ e-&gt;value = strdup(value);
+
+ h = hash_function(key) % d-&gt;size;
+
+ e-&gt;next = d-&gt;table[h];
+ d-&gt;table[h] = e;
+
+ d-&gt;n++;
+
+ <span class="co">/* grow table if there is not enough room */</span>
+ <span class="kw">if</span>(d-&gt;n &gt;= d-&gt;size * MAX_LOAD_FACTOR) {
+ grow(d);
+ }
+}
+
+<span class="co">/* return the most recently inserted value associated with a key */</span>
+<span class="co">/* or 0 if no matching key is present */</span>
+<span class="dt">const</span> <span class="dt">char</span> *
+DictSearch(Dict d, <span class="dt">const</span> <span class="dt">char</span> *key)
+{
+ <span class="kw">struct</span> elt *e;
+
+ <span class="kw">for</span>(e = d-&gt;table[hash_function(key) % d-&gt;size]; e != <span class="dv">0</span>; e = e-&gt;next) {
+ <span class="kw">if</span>(!strcmp(e-&gt;key, key)) {
+ <span class="co">/* got it */</span>
+ <span class="kw">return</span> e-&gt;value;
+ }
+ }
+
+ <span class="kw">return</span> <span class="dv">0</span>;
+}
+
+<span class="co">/* delete the most recently inserted record with the given key */</span>
+<span class="co">/* if there is no such record, has no effect */</span>
+<span class="dt">void</span>
+DictDelete(Dict d, <span class="dt">const</span> <span class="dt">char</span> *key)
+{
+ <span class="kw">struct</span> elt **prev; <span class="co">/* what to change when elt is deleted */</span>
+ <span class="kw">struct</span> elt *e; <span class="co">/* what to delete */</span>
+
+ <span class="kw">for</span>(prev = &amp;(d-&gt;table[hash_function(key) % d-&gt;size]);
+ *prev != <span class="dv">0</span>;
+ prev = &amp;((*prev)-&gt;next)) {
+ <span class="kw">if</span>(!strcmp((*prev)-&gt;key, key)) {
+ <span class="co">/* got it */</span>
+ e = *prev;
+ *prev = e-&gt;next;
+
+ free(e-&gt;key);
+ free(e-&gt;value);
+ free(e);
+
+ <span class="kw">return</span>;
+ }
+ }
+}</code></pre></div>
+<a href="http://cs.yale.edu/homes/aspnes/classes/223/examples/hashTables/dict/dict.c" class="uri">examples/hashTables/dict/dict.c</a>
+</div>
+<p>And here is some (very minimal) test code.</p>
+<div>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"><span class="ot">#include &lt;stdio.h&gt;</span>
+<span class="ot">#include &lt;assert.h&gt;</span>
+
+<span class="ot">#include "dict.h"</span>
+
+<span class="dt">int</span>
+main()
+{
+ Dict d;
+ <span class="dt">char</span> buf[<span class="dv">512</span>];
+ <span class="dt">int</span> i;
+
+ d = DictCreate();
+
+ DictInsert(d, <span class="st">"foo"</span>, <span class="st">"hello world"</span>);
+ puts(DictSearch(d, <span class="st">"foo"</span>));
+ DictInsert(d, <span class="st">"foo"</span>, <span class="st">"hello world2"</span>);
+ puts(DictSearch(d, <span class="st">"foo"</span>));
+ DictDelete(d, <span class="st">"foo"</span>);
+ puts(DictSearch(d, <span class="st">"foo"</span>));
+ DictDelete(d, <span class="st">"foo"</span>);
+ assert(DictSearch(d, <span class="st">"foo"</span>) == <span class="dv">0</span>);
+ DictDelete(d, <span class="st">"foo"</span>);
+
+ <span class="kw">for</span>(i = <span class="dv">0</span>; i &lt; <span class="dv">10000</span>; i++) {
+ sprintf(buf, <span class="st">"%d"</span>, i);
+ DictInsert(d, buf, buf);
+ }
+
+ DictDestroy(d);
+
+ <span class="kw">return</span> <span class="dv">0</span>;
+}
+
+ </code></pre></div>
+<a href="http://cs.yale.edu/homes/aspnes/classes/223/examples/hashTables/dict/test_dict.c" class="uri">examples/hashTables/dict/test_dict.c</a>
+</div>
+<h2 id="genericContainers"><span class="header-section-number">5.5</span> Generic containers</h2>
+<p>The first rule of programming is that you should never write the same
+ code twice. Suppose that you happen to have lying around a dictionary
+type whose keys are <code>int</code>s and whose values are strings.
+Tomorrow you realize that what you really want is a dictionary type
+whose keys are strings and whose values are <code>int</code>s, or one whose keys are <code>int</code>s but whose values are stacks. If you have <span class="math inline"><em>n</em></span> different types that may appear as keys or values, can you avoid writing <span class="math inline"><em>n</em><sup>2</sup></span> different dictionary implementations to get every possible combination?</p>
+<p>Many languages provide special mechanisms to support <strong>generic types</strong>,
+ ones for which part of the type is not specified. It's as if you could
+declare an array in C to be an array of some type to be specified later,
+ and then write functions that operate on any such array without knowing
+ what the missing type is going to be (<strong>templates</strong> in C++
+ are an example of such a mechanism). Unfortunately, C does not provide
+generic types. But by aggressive use of function pointers and <code>void&nbsp;*</code>, it is possible to fake them.</p>
+<h3 id="Generic_dictionary:_interface"><span class="header-section-number">5.5.1</span> Generic dictionary: interface</h3>
+<p>Below is an example of an interface to a generic dictionary type for storing maps from constant values to constant values. The <code>void&nbsp;*</code> pointers are used to avoid having to declare exactly what kinds of keys and values the dictionary will contain.</p>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"><span class="co">/* Set dict[key] = value. */</span>
+<span class="co">/* Both key and value are copied internally. */</span>
+<span class="co">/* If data is the null pointer, remove dict[key]. */</span>
+<span class="dt">void</span> dictSet(Dict d, <span class="dt">const</span> <span class="dt">void</span> *key, <span class="dt">const</span> <span class="dt">void</span> *value);
+
+<span class="co">/* Return dict[key], or null if dict[key] has not been set. */</span>
+<span class="dt">const</span> <span class="dt">void</span> *dictGet(Dict d, <span class="dt">const</span> <span class="dt">void</span> *key);</code></pre></div>
+<p>We'll also need a constructor and destructor, but we'll get to those in a moment. First we need to think about what <code>dictSet</code> and <code>dictGet</code>
+ are supposed to do, and how we might possibly be able to implement
+them. Suppose we want to build a dictionary with strings as both keys
+and values. Internally, this might be represented as some sort of hash
+table or tree. Suppose it's a hash table. Now, given some <code>void&nbsp;*key</code>, we'd like to be able to compute its hash value. But we don't know what type <code>key</code>
+ points to, and if we guess wrong we are likely to end up with
+segmentation faults or worse. So we need some way to register a hash
+function for our keys, whatever type they might really be behind that <code>void&nbsp;*</code>.</p>
+<p>Similarly, we will want to be able to compare keys for equality
+(since not all keys that hash together will necessarily be the same),
+and we may want to be able to copy keys and values so that the data
+inside the dictionary is not modified if somebody changes a value passed
+ in from the outside. So we need a fair bit of information about keys
+and values. We'll organize all of this information in a struct made up
+of function pointers. (This includes a few extra components that came up
+ while writing the implementation.)</p>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"><span class="co">/* Provides operations for working with keys or values */</span>
+<span class="kw">struct</span> dictContentsOperations {
+ <span class="co">/* hash function */</span>
+ <span class="dt">unsigned</span> <span class="dt">long</span> (*hash)(<span class="dt">const</span> <span class="dt">void</span> *datum, <span class="dt">void</span> *arg);
+
+ <span class="co">/* returns nonzero if *datum1 == *datum2 */</span>
+ <span class="dt">int</span> (*equal)(<span class="dt">const</span> <span class="dt">void</span> *datum1, <span class="dt">const</span> <span class="dt">void</span> *datum2, <span class="dt">void</span> *arg);
+
+ <span class="co">/* make a copy of datum that will survive changes to original */</span>
+ <span class="dt">void</span> *(*copy)(<span class="dt">const</span> <span class="dt">void</span> *datum, <span class="dt">void</span> *arg);
+
+ <span class="co">/* free a copy */</span>
+ <span class="dt">void</span> (*delete)(<span class="dt">void</span> *datum, <span class="dt">void</span> *arg);
+
+ <span class="co">/* extra argument, to allow further specialization */</span>
+ <span class="dt">void</span> *arg;
+};</code></pre></div>
+<p>We could write a similar but smaller struct for values, but to save a little bit of effort in the short run we'll use the same <code>struct</code>
+ for both keys and values. We can now write a constructor for our
+generic dictionary that consumes two such structs that provide
+operations for working on keys and values, respectively:</p>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"><span class="co">/* create a new dictionary with given key and value operations */</span>
+<span class="co">/* Note: valueOps.hash and valueOps.equal are not used. */</span>
+Dict dictCreate(<span class="kw">struct</span> dictContentsOperations keyOps,
+ <span class="kw">struct</span> dictContentsOperations valueOps);</code></pre></div>
+<p>So now to create a dict, we just need to fill in two <code>dictContentsOperations</code> structures. For convenience, it might be nice if <code>dict.c</code> provided some preloaded structures for common types like <code>int</code>s and strings. We can also use the <code>arg</code> field in <code>struct&nbsp;dictContentsOperations</code> to make the keys and values themselves be parameterized types, for example a type of byte-vectors of given length.</p>
+<p>We can declare these various convenience structures in <code>dict.h</code> as</p>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"><span class="co">/* Some predefined dictContentsOperations structures */</span>
+
+<span class="co">/* </span>
+<span class="co"> * DictIntOps supports int's that have been cast to (void *), e.g.:</span>
+<span class="co"> * d = dictCreate(DictIntOps, DictIntOps);</span>
+<span class="co"> * dictSet(d, (void *) 1, (void * 2));</span>
+<span class="co"> * x = (int) dictGet(d, (void * 1));</span>
+<span class="co"> */</span>
+<span class="kw">struct</span> dictContentsOperations DictIntOps;
+
+<span class="co">/*</span>
+<span class="co"> * Supports null-terminated strings, e.g.:</span>
+<span class="co"> * d = dictCreate(DictStringOps, DictStringOps);</span>
+<span class="co"> * dictSet(d, "foo", "bar");</span>
+<span class="co"> * s = dictGet(d, "foo");</span>
+<span class="co"> * Note: no casts are needed since C automatically converts</span>
+<span class="co"> * between (void *) and other pointer types.</span>
+<span class="co"> */</span>
+<span class="kw">struct</span> dictContentsOperations DictStringOps;
+
+<span class="co">/*</span>
+<span class="co"> * Supports fixed-size blocks of memory, e.g.:</span>
+<span class="co"> * int x = 1;</span>
+<span class="co"> * int y = 2;</span>
+<span class="co"> * d = dictCreate(dictMemOps(sizeof(int)), dictMemOps(sizeof(int));</span>
+<span class="co"> * dictSet(d, &amp;x, &amp;y);</span>
+<span class="co"> * printf("%d", *dictGet(d, &amp;x);</span>
+<span class="co"> */</span>
+<span class="kw">struct</span> dictContentsOperations dictMemOps(<span class="dt">int</span> size);</code></pre></div>
+<p>We'll define the operations in <code>DictIntOps</code> to expect <code>int</code>s cast directly to <code>void&nbsp;*</code>, the operations in <code>DictStringOps</code> to expect <code>char&nbsp;*</code> cast to <code>void&nbsp;*</code>, and the operations in <code>dictMemOps(size)</code> will expect <code>void&nbsp;*</code> arguments pointing to blocks of the given size. There is a subtle difference between a dictionary using <code>DictIntOps</code> and <code>dictMemOps(sizeof(int))</code>; in the former case, keys and values are the <code>int</code>s themselves (after being case), which in the latter, keys and values are pointers to <code>int</code>s.</p>
+<p>Implementations of these structures can be found <a href="#genericDictionaryImplementation">below</a>.</p>
+<p>To make a dictionary that maps strings to ints, we just call:</p>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"> d = dictCreate(DictStringOps, DictIntOps);</code></pre></div>
+<p>and then we can do things like:</p>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"> dictSet(d, <span class="st">"foo"</span>, (<span class="dt">void</span> *) <span class="dv">2</span>);
+ v = (<span class="dt">int</span>) dictGet(d, <span class="st">"foo');</span></code></pre></div>
+<p>If we find ourselves working with an integer-valued dictionary a lot,
+ we might want to define a few macros or inline functions to avoid
+having to type casts all the time.</p>
+<h3 id="genericDictionaryImplementation"><span class="header-section-number">5.5.2</span> Generic dictionary: implementation</h3>
+<p>To implement our generic dictionary, we just take our favorite
+non-generic hash table, and replace any calls to fixed hash functions,
+copier, <code>free</code>, etc. with calls to elements of the appropriate structure. The result is shown below.</p>
+<div>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"><span class="kw">typedef</span> <span class="kw">struct</span> dict *Dict;
+
+<span class="co">/* Provides operations for working with keys or values */</span>
+<span class="kw">struct</span> dictContentsOperations {
+ <span class="co">/* hash function */</span>
+ <span class="dt">unsigned</span> <span class="dt">long</span> (*hash)(<span class="dt">const</span> <span class="dt">void</span> *datum, <span class="dt">void</span> *arg);
+
+ <span class="co">/* returns nonzero if *datum1 == *datum2 */</span>
+ <span class="dt">int</span> (*equal)(<span class="dt">const</span> <span class="dt">void</span> *datum1, <span class="dt">const</span> <span class="dt">void</span> *datum2, <span class="dt">void</span> *arg);
+
+ <span class="co">/* make a copy of datum that will survive changes to original */</span>
+ <span class="dt">void</span> *(*copy)(<span class="dt">const</span> <span class="dt">void</span> *datum, <span class="dt">void</span> *arg);
+
+ <span class="co">/* free a copy */</span>
+ <span class="dt">void</span> (*delete)(<span class="dt">void</span> *datum, <span class="dt">void</span> *arg);
+
+ <span class="co">/* extra argument, to allow further specialization */</span>
+ <span class="dt">void</span> *arg;
+};
+
+<span class="co">/* create a new dictionary with given key and value operations */</span>
+<span class="co">/* Note: valueOps.hash and valueOps.equal are not used. */</span>
+Dict dictCreate(<span class="kw">struct</span> dictContentsOperations keyOps,
+ <span class="kw">struct</span> dictContentsOperations valueOps);
+
+<span class="co">/* free a dictionary and all the space it contains */</span>
+<span class="co">/* This will call the appropriate delete function for all keys and */</span>
+<span class="co">/* values. */</span>
+<span class="dt">void</span> dictDestroy(Dict d);
+
+<span class="co">/* Set dict[key] = value. */</span>
+<span class="co">/* Both key and value are copied internally. */</span>
+<span class="co">/* If data is the null pointer, remove dict[key]. */</span>
+<span class="dt">void</span> dictSet(Dict d, <span class="dt">const</span> <span class="dt">void</span> *key, <span class="dt">const</span> <span class="dt">void</span> *value);
+
+<span class="co">/* Return dict[key], or null if dict[key] has not been set. */</span>
+<span class="dt">const</span> <span class="dt">void</span> *dictGet(Dict d, <span class="dt">const</span> <span class="dt">void</span> *key);
+
+<span class="co">/* Some predefined dictContentsOperations structures */</span>
+
+<span class="co">/* </span>
+<span class="co"> * DictIntOps supports int's that have been cast to (void *), e.g.:</span>
+<span class="co"> * d = dictCreate(DictIntOps, DictIntOps);</span>
+<span class="co"> * dictSet(d, (void *) 1, (void * 2));</span>
+<span class="co"> * x = (int) dictGet(d, (void * 1));</span>
+<span class="co"> */</span>
+<span class="kw">struct</span> dictContentsOperations DictIntOps;
+
+<span class="co">/*</span>
+<span class="co"> * Supports null-terminated strings, e.g.:</span>
+<span class="co"> * d = dictCreate(DictStringOps, DictStringOps);</span>
+<span class="co"> * dictSet(d, "foo", "bar");</span>
+<span class="co"> * s = dictGet(d, "foo");</span>
+<span class="co"> * Note: no casts are needed since C automatically converts</span>
+<span class="co"> * between (void *) and other pointer types.</span>
+<span class="co"> */</span>
+<span class="kw">struct</span> dictContentsOperations DictStringOps;
+
+<span class="co">/*</span>
+<span class="co"> * Supports fixed-size blocks of memory, e.g.:</span>
+<span class="co"> * int x = 1;</span>
+<span class="co"> * int y = 2;</span>
+<span class="co"> * d = dictCreate(dictMemOps(sizeof(int)), dictMemOps(sizeof(int));</span>
+<span class="co"> * dictSet(d, &amp;x, &amp;y);</span>
+<span class="co"> * printf("%d", *dictGet(d, &amp;x);</span>
+<span class="co"> */</span>
+<span class="kw">struct</span> dictContentsOperations dictMemOps(<span class="dt">int</span> size);</code></pre></div>
+<a href="http://cs.yale.edu/homes/aspnes/classes/223/examples/generic/dict.h" class="uri">examples/generic/dict.h</a>
+</div>
+<div>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"><span class="ot">#include &lt;stdlib.h&gt;</span>
+<span class="ot">#include &lt;string.h&gt;</span>
+<span class="ot">#include "dict.h"</span>
+
+<span class="kw">struct</span> dictElt {
+ <span class="dt">unsigned</span> <span class="dt">long</span> hash; <span class="co">/* full hash of key */</span>
+ <span class="dt">void</span> *key;
+ <span class="dt">void</span> *value;
+ <span class="kw">struct</span> dictElt *next;
+};
+
+<span class="kw">struct</span> dict {
+ <span class="dt">int</span> tableSize; <span class="co">/* number of slots in table */</span>
+ <span class="dt">int</span> numElements; <span class="co">/* number of elements */</span>
+ <span class="kw">struct</span> dictElt **table; <span class="co">/* linked list heads */</span>
+ <span class="co">/* these save arguments passed at creation */</span>
+ <span class="kw">struct</span> dictContentsOperations keyOps;
+ <span class="kw">struct</span> dictContentsOperations valueOps;
+};
+
+<span class="ot">#define INITIAL_TABLESIZE (16)</span>
+<span class="ot">#define TABLESIZE_MULTIPLIER (2)</span>
+<span class="ot">#define TABLE_GROW_DENSITY (1)</span>
+
+Dict
+dictCreate(<span class="kw">struct</span> dictContentsOperations keyOps,
+ <span class="kw">struct</span> dictContentsOperations valueOps)
+{
+ Dict d;
+ <span class="dt">int</span> i;
+
+ d = malloc(<span class="kw">sizeof</span>(*d));
+ <span class="kw">if</span>(d == <span class="dv">0</span>) <span class="kw">return</span> <span class="dv">0</span>;
+
+ d-&gt;tableSize = INITIAL_TABLESIZE;
+ d-&gt;numElements = <span class="dv">0</span>;
+ d-&gt;keyOps = keyOps;
+ d-&gt;valueOps = valueOps;
+ d-&gt;table = malloc(<span class="kw">sizeof</span>(*(d-&gt;table)) * d-&gt;tableSize);
+ <span class="kw">if</span>(d-&gt;table == <span class="dv">0</span>) {
+ free(d);
+ <span class="kw">return</span> <span class="dv">0</span>;
+ }
+
+ <span class="kw">for</span>(i = <span class="dv">0</span>; i &lt; d-&gt;tableSize; i++) d-&gt;table[i] = <span class="dv">0</span>;
+
+ <span class="kw">return</span> d;
+}
+
+<span class="dt">void</span>
+dictDestroy(Dict d)
+{
+ <span class="dt">int</span> i;
+ <span class="kw">struct</span> dictElt *e;
+ <span class="kw">struct</span> dictElt *next;
+
+ <span class="kw">for</span>(i = <span class="dv">0</span>; i &lt; d-&gt;tableSize; i++) {
+ <span class="kw">for</span>(e = d-&gt;table[i]; e != <span class="dv">0</span>; e = next) {
+ next = e-&gt;next;
+ d-&gt;keyOps.delete(e-&gt;key, d-&gt;keyOps.arg);
+ d-&gt;valueOps.delete(e-&gt;value, d-&gt;valueOps.arg);
+ free(e);
+ }
+ }
+ free(d-&gt;table);
+ free(d);
+}
+
+<span class="co">/* return pointer to element with given key, if any */</span>
+<span class="dt">static</span> <span class="kw">struct</span> dictElt *
+dictFetch(Dict d, <span class="dt">const</span> <span class="dt">void</span> *key)
+{
+ <span class="dt">unsigned</span> <span class="dt">long</span> h;
+ <span class="dt">int</span> i;
+ <span class="kw">struct</span> dictElt *e;
+
+ h = d-&gt;keyOps.hash(key, d-&gt;keyOps.arg);
+ i = h % d-&gt;tableSize;
+ <span class="kw">for</span>(e = d-&gt;table[i]; e != <span class="dv">0</span>; e = e-&gt;next) {
+ <span class="kw">if</span>(e-&gt;hash == h &amp;&amp; d-&gt;keyOps.equal(key, e-&gt;key, d-&gt;keyOps.arg)) {
+ <span class="co">/* found it */</span>
+ <span class="kw">return</span> e;
+ }
+ }
+ <span class="co">/* didn't find it */</span>
+ <span class="kw">return</span> <span class="dv">0</span>;
+}
+
+<span class="co">/* increase the size of the dictionary, rehashing all table elements */</span>
+<span class="dt">static</span> <span class="dt">void</span>
+dictGrow(Dict d)
+{
+ <span class="kw">struct</span> dictElt **old_table;
+ <span class="dt">int</span> old_size;
+ <span class="dt">int</span> i;
+ <span class="kw">struct</span> dictElt *e;
+ <span class="kw">struct</span> dictElt *next;
+ <span class="dt">int</span> new_pos;
+
+ <span class="co">/* save old table */</span>
+ old_table = d-&gt;table;
+ old_size = d-&gt;tableSize;
+
+ <span class="co">/* make new table */</span>
+ d-&gt;tableSize *= TABLESIZE_MULTIPLIER;
+ d-&gt;table = malloc(<span class="kw">sizeof</span>(*(d-&gt;table)) * d-&gt;tableSize);
+ <span class="kw">if</span>(d-&gt;table == <span class="dv">0</span>) {
+ <span class="co">/* put the old one back */</span>
+ d-&gt;table = old_table;
+ d-&gt;tableSize = old_size;
+ <span class="kw">return</span>;
+ }
+ <span class="co">/* else */</span>
+ <span class="co">/* clear new table */</span>
+ <span class="kw">for</span>(i = <span class="dv">0</span>; i &lt; d-&gt;tableSize; i++) d-&gt;table[i] = <span class="dv">0</span>;
+
+ <span class="co">/* move all elements of old table to new table */</span>
+ <span class="kw">for</span>(i = <span class="dv">0</span>; i &lt; old_size; i++) {
+ <span class="kw">for</span>(e = old_table[i]; e != <span class="dv">0</span>; e = next) {
+ next = e-&gt;next;
+ <span class="co">/* find the position in the new table */</span>
+ new_pos = e-&gt;hash % d-&gt;tableSize;
+ e-&gt;next = d-&gt;table[new_pos];
+ d-&gt;table[new_pos] = e;
+ }
+ }
+
+ <span class="co">/* don't need this any more */</span>
+ free(old_table);
+}
+
+<span class="dt">void</span>
+dictSet(Dict d, <span class="dt">const</span> <span class="dt">void</span> *key, <span class="dt">const</span> <span class="dt">void</span> *value)
+{
+ <span class="dt">int</span> tablePosition;
+ <span class="kw">struct</span> dictElt *e;
+
+ e = dictFetch(d, key);
+ <span class="kw">if</span>(e != <span class="dv">0</span>) {
+ <span class="co">/* change existing setting */</span>
+ d-&gt;valueOps.delete(e-&gt;value, d-&gt;valueOps.arg);
+ e-&gt;value = value ? d-&gt;valueOps.copy(value, d-&gt;valueOps.arg) : <span class="dv">0</span>;
+ } <span class="kw">else</span> {
+ <span class="co">/* create new element */</span>
+ e = malloc(<span class="kw">sizeof</span>(*e));
+ <span class="kw">if</span>(e == <span class="dv">0</span>) abort();
+
+ e-&gt;hash = d-&gt;keyOps.hash(key, d-&gt;keyOps.arg);
+ e-&gt;key = d-&gt;keyOps.copy(key, d-&gt;keyOps.arg);
+ e-&gt;value = value ? d-&gt;valueOps.copy(value, d-&gt;valueOps.arg) : <span class="dv">0</span>;
+
+ <span class="co">/* link it in */</span>
+ tablePosition = e-&gt;hash % d-&gt;tableSize;
+ e-&gt;next = d-&gt;table[tablePosition];
+ d-&gt;table[tablePosition] = e;
+
+ d-&gt;numElements++;
+
+ <span class="kw">if</span>(d-&gt;numElements &gt; d-&gt;tableSize * TABLE_GROW_DENSITY) {
+ <span class="co">/* grow and rehash */</span>
+ dictGrow(d);
+ }
+ }
+}
+
+<span class="dt">const</span> <span class="dt">void</span> *
+dictGet(Dict d, <span class="dt">const</span> <span class="dt">void</span> *key)
+{
+ <span class="kw">struct</span> dictElt *e;
+
+ e = dictFetch(d, key);
+ <span class="kw">if</span>(e != <span class="dv">0</span>) {
+ <span class="kw">return</span> e-&gt;value;
+ } <span class="kw">else</span> {
+ <span class="kw">return</span> <span class="dv">0</span>;
+ }
+}
+
+<span class="co">/* int functions */</span>
+<span class="co">/* We assume that int can be cast to void * and back without damage */</span>
+<span class="dt">static</span> <span class="dt">unsigned</span> <span class="dt">long</span> dictIntHash(<span class="dt">const</span> <span class="dt">void</span> *x, <span class="dt">void</span> *arg) { <span class="kw">return</span> (<span class="dt">int</span>) x; }
+<span class="dt">static</span> <span class="dt">int</span> dictIntEqual(<span class="dt">const</span> <span class="dt">void</span> *x, <span class="dt">const</span> <span class="dt">void</span> *y, <span class="dt">void</span> *arg)
+{
+ <span class="kw">return</span> ((<span class="dt">int</span>) x) == ((<span class="dt">int</span>) y);
+}
+<span class="dt">static</span> <span class="dt">void</span> *dictIntCopy(<span class="dt">const</span> <span class="dt">void</span> *x, <span class="dt">void</span> *arg) { <span class="kw">return</span> (<span class="dt">void</span> *) x; }
+<span class="dt">static</span> <span class="dt">void</span> dictIntDelete(<span class="dt">void</span> *x, <span class="dt">void</span> *arg) { ; }
+
+<span class="kw">struct</span> dictContentsOperations DictIntOps = {
+ dictIntHash,
+ dictIntEqual,
+ dictIntCopy,
+ dictIntDelete,
+ <span class="dv">0</span>
+};
+
+<span class="co">/* common utilities for string and mem */</span>
+<span class="dt">static</span> <span class="dt">unsigned</span> <span class="dt">long</span> hashMem(<span class="dt">const</span> <span class="dt">unsigned</span> <span class="dt">char</span> *s, <span class="dt">int</span> len)
+{
+ <span class="dt">unsigned</span> <span class="dt">long</span> h;
+ <span class="dt">int</span> i;
+
+ h = <span class="dv">0</span>;
+ <span class="kw">for</span>(i = <span class="dv">0</span>; i &lt; len; i++) {
+ h = (h &lt;&lt; <span class="dv">13</span>) + (h &gt;&gt; <span class="dv">7</span>) + h + s[i];
+ }
+ <span class="kw">return</span> h;
+}
+
+<span class="dt">static</span> <span class="dt">void</span> dictDeleteFree(<span class="dt">void</span> *x, <span class="dt">void</span> *arg) { free(x); }
+
+<span class="co">/* string functions */</span>
+<span class="dt">static</span> <span class="dt">unsigned</span> <span class="dt">long</span> dictStringHash(<span class="dt">const</span> <span class="dt">void</span> *x, <span class="dt">void</span> *arg)
+{
+ <span class="kw">return</span> hashMem(x, strlen(x));
+}
+
+<span class="dt">static</span> <span class="dt">int</span> dictStringEqual(<span class="dt">const</span> <span class="dt">void</span> *x, <span class="dt">const</span> <span class="dt">void</span> *y, <span class="dt">void</span> *arg)
+{
+ <span class="kw">return</span> !strcmp((<span class="dt">const</span> <span class="dt">char</span> *) x, (<span class="dt">const</span> <span class="dt">char</span> *) y);
+}
+
+<span class="dt">static</span> <span class="dt">void</span> *dictStringCopy(<span class="dt">const</span> <span class="dt">void</span> *x, <span class="dt">void</span> *arg)
+{
+ <span class="dt">const</span> <span class="dt">char</span> *s;
+ <span class="dt">char</span> *s2;
+
+ s = x;
+ s2 = malloc(<span class="kw">sizeof</span>(*s2) * (strlen(s)+<span class="dv">1</span>));
+ strcpy(s2, s);
+ <span class="kw">return</span> s2;
+}
+
+<span class="kw">struct</span> dictContentsOperations DictStringOps = {
+ dictStringHash,
+ dictStringEqual,
+ dictStringCopy,
+ dictDeleteFree,
+ <span class="dv">0</span>
+};
+
+<span class="co">/* mem functions */</span>
+<span class="dt">static</span> <span class="dt">unsigned</span> <span class="dt">long</span> dictMemHash(<span class="dt">const</span> <span class="dt">void</span> *x, <span class="dt">void</span> *arg)
+{
+ <span class="kw">return</span> hashMem(x, (<span class="dt">int</span>) arg);
+}
+
+<span class="dt">static</span> <span class="dt">int</span> dictMemEqual(<span class="dt">const</span> <span class="dt">void</span> *x, <span class="dt">const</span> <span class="dt">void</span> *y, <span class="dt">void</span> *arg)
+{
+ <span class="kw">return</span> !memcmp(x, y, (size_t) arg);
+}
+
+<span class="dt">static</span> <span class="dt">void</span> *dictMemCopy(<span class="dt">const</span> <span class="dt">void</span> *x, <span class="dt">void</span> *arg)
+{
+ <span class="dt">void</span> *x2;
+
+ x2 = malloc((size_t) arg);
+ memcpy(x2, x, (size_t) arg);
+ <span class="kw">return</span> x2;
+}
+
+<span class="kw">struct</span> dictContentsOperations
+dictMemOps(<span class="dt">int</span> len)
+{
+ <span class="kw">struct</span> dictContentsOperations memOps;
+
+ memOps.hash = dictMemHash;
+ memOps.equal = dictMemEqual;
+ memOps.copy = dictMemCopy;
+ memOps.delete = dictDeleteFree;
+ memOps.arg = (<span class="dt">void</span> *) len;
+
+ <span class="kw">return</span> memOps;
+}</code></pre></div>
+<a href="http://cs.yale.edu/homes/aspnes/classes/223/examples/generic/dict.c" class="uri">examples/generic/dict.c</a>
+</div>
+<p>And here is some test code and a Makefile: <a href="http://cs.yale.edu/homes/aspnes/classes/223/examples/generic/test-dict.c">test-dict.c</a>, <a href="http://cs.yale.edu/homes/aspnes/classes/223/examples/generic/tester.h">tester.h</a>, <a href="http://cs.yale.edu/homes/aspnes/classes/223/examples/generic/tester.c">tester.c</a>, <a href="http://cs.yale.edu/homes/aspnes/classes/223/examples/generic/Makefile">Makefile</a>.</p>
+<h2 id="recursion"><span class="header-section-number">5.6</span> Recursion</h2>
+<p><strong>Recursion</strong> is when a function calls itself. Some programming languages (particularly functional programming languages like <a href="http://en.wikipedia.org/wiki/Scheme_%28programming_language%29" title="WikiPedia">Scheme</a>, <a href="http://en.wikipedia.org/wiki/ML_%28programming_language%29" title="WikiPedia">ML</a>, or <a href="http://www.haskell.org/">Haskell</a> use recursion as a basic tool for implementing algorithms that in other languages would typically be expressed using <strong>iteration</strong> (loops). Procedural languages like C tend to emphasize iteration over recursion, but can support recursion as well.</p>
+<h3 id="Example_of_recursion_in_C"><span class="header-section-number">5.6.1</span> Example of recursion in C</h3>
+<p>Here are a bunch of routines that print the numbers from 0 to 9:</p>
+<div>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"><span class="ot">#include &lt;stdio.h&gt;</span>
+<span class="ot">#include &lt;stdlib.h&gt;</span>
+<span class="ot">#include &lt;assert.h&gt;</span>
+
+<span class="co">/* all of these routines print numbers i where start &lt;= i &lt; stop */</span>
+
+<span class="dt">void</span>
+printRangeIterative(<span class="dt">int</span> start, <span class="dt">int</span> stop)
+{
+ <span class="dt">int</span> i;
+
+ <span class="kw">for</span>(i = start; i &lt; stop; i++) {
+ printf(<span class="st">"%d</span><span class="ch">\n</span><span class="st">"</span>, i);
+ }
+}
+
+<span class="dt">void</span>
+printRangeRecursive(<span class="dt">int</span> start, <span class="dt">int</span> stop)
+{
+ <span class="kw">if</span>(start &lt; stop) {
+ printf(<span class="st">"%d</span><span class="ch">\n</span><span class="st">"</span>, start);
+ printRangeRecursive(start<span class="dv">+1</span>, stop);
+ }
+}
+
+<span class="dt">void</span>
+printRangeRecursiveReversed(<span class="dt">int</span> start, <span class="dt">int</span> stop)
+{
+ <span class="kw">if</span>(start &lt; stop) {
+ printRangeRecursiveReversed(start<span class="dv">+1</span>, stop);
+ printf(<span class="st">"%d</span><span class="ch">\n</span><span class="st">"</span>, start);
+ }
+}
+
+<span class="dt">void</span>
+printRangeRecursiveSplit(<span class="dt">int</span> start, <span class="dt">int</span> stop)
+{
+ <span class="dt">int</span> mid;
+
+ <span class="kw">if</span>(start &lt; stop) {
+ mid = (start + stop) / <span class="dv">2</span>;
+
+ printRangeRecursiveSplit(start, mid);
+ printf(<span class="st">"%d</span><span class="ch">\n</span><span class="st">"</span>, mid);
+ printRangeRecursiveSplit(mid<span class="dv">+1</span>, stop);
+ }
+}
+
+<span class="ot">#define Noisy(x) (puts(#x), x)</span>
+
+<span class="dt">int</span>
+main(<span class="dt">int</span> argc, <span class="dt">char</span> **argv)
+{
+
+ <span class="kw">if</span>(argc != <span class="dv">1</span>) {
+ fprintf(stderr, <span class="st">"Usage: %s</span><span class="ch">\n</span><span class="st">"</span>, argv[<span class="dv">0</span>]);
+ <span class="kw">return</span> <span class="dv">1</span>;
+ }
+
+ Noisy(printRangeIterative(<span class="dv">0</span>, <span class="dv">10</span>));
+ Noisy(printRangeRecursive(<span class="dv">0</span>, <span class="dv">10</span>));
+ Noisy(printRangeRecursiveReversed(<span class="dv">0</span>, <span class="dv">10</span>));
+ Noisy(printRangeRecursiveSplit(<span class="dv">0</span>, <span class="dv">10</span>));
+
+ <span class="kw">return</span> <span class="dv">0</span>;
+}</code></pre></div>
+<a href="http://cs.yale.edu/homes/aspnes/classes/223/examples/recursion/recursion.c" class="uri">examples/recursion/recursion.c</a>
+</div>
+<p>And here is the output:</p>
+<pre><code>printRangeIterative(0, 10)
+0
+1
+2
+3
+4
+5
+6
+7
+8
+9
+printRangeRecursive(0, 10)
+0
+1
+2
+3
+4
+5
+6
+7
+8
+9
+printRangeRecursiveReversed(0, 10)
+9
+8
+7
+6
+5
+4
+3
+2
+1
+0
+printRangeRecursiveSplit(0, 10)
+0
+1
+2
+3
+4
+5
+6
+7
+8
+9</code></pre>
+<p>The first function <code class="backtick">printRangeIterative</code> is simple and direct: it's what we've been doing to get loops forever. The others are a bit more mysterious.</p>
+<p>The function <code class="backtick">printRangeRecursive</code> is an example of solving a problem using a <a href="#algorithmDesignTechniquesClassification">divide and conquer</a>
+ approach. If we don't know how to print a range of numbers 0 through 9,
+ maybe we can start by solving a simpler problem of printing the first
+number 0. Having done that, we have a new, smaller problem: print the
+numbers 1 through 9. But then we notice we already have a function <code class="backtick">printRangeRecursive</code> that will do that for us. So we'll call it.</p>
+<p>If you aren't used to this, it has the feeling of trying to make yourself fly by pulling very hard on your shoelaces.<a href="#fn20" class="footnoteRef" id="fnref20"><sup>20</sup></a> But in fact the computer will happily generate the eleven nested instances of <code class="backtick">printRangeRecursive</code> to make this happen. When we hit the bottom, the call stack will look something like this:</p>
+<pre><code>printRangeRecursive(0, 10)
+ printRangeRecursive(1, 10)
+ printRangeRecursive(2, 10)
+ printRangeRecursive(3, 10)
+ printRangeRecursive(4, 10)
+ printRangeRecursive(5, 10)
+ printRangeRecursive(6, 10)
+ printRangeRecursive(7, 10)
+ printRangeRecursive(8, 10)
+ printRangeRecursive(9, 10)
+ printRangeRecursive(10, 10)</code></pre>
+<p>This works because each call to <code class="backtick">printRangeRecursive</code>
+ gets its own parameters and its own variables separate from the others,
+ even the ones that are still in progress. So each will print out <code class="backtick">start</code> and then call another copy in to print <code class="backtick">start+1</code> etc. In the last call, we finally fail the test <code class="backtick">start&nbsp;&lt;&nbsp;stop</code>, so the function exits, then its parent exits, and so on until we unwind all the calls on the stack back to the first one.</p>
+<p>In <code class="backtick">printRangeRecursiveReversed</code>, the calling pattern is exactly the same, but now instead of printing <code class="backtick">start</code> on the way down, we print <code class="backtick">start</code> on the way back up, after making the recursive call. This means that in <code class="backtick">printRangeRecursiveReversed(0,&nbsp;10)</code>, 0 is printed only after the results of <code class="backtick">printRangeRecursiveReversed(1,&nbsp;10)</code>, which gives us the countdown effect.</p>
+<p>So far these procedures all behave very much like ordinary loops,
+with increasing values on the stack standing in for the loop variable.
+More exciting is <code class="backtick">printRangeRecursiveSplit</code>. This function takes a much more aggressive approach to dividing up the problem: it splits a range <span class="math inline">[0, 10)</span> as two ranges <span class="math inline">[0, 5)</span> and <span class="math inline">[6, 10)</span> separated by a midpoint <span class="math inline">5</span>.^[The notation <span class="math inline">[<em>x</em>, <em>y</em>)</span> means all numbers <span class="math inline"><em>z</em></span> such that <span class="math inline"><em>x</em> ≤ <em>z</em> &lt; <em>y</em></span>.] We want to print the midpoint in the middle, of course, and we can use <code class="backtick">printRangeRecursiveSplit</code>
+ recursively to print the two ranges. Following the execution of this
+procedure is more complicated, with the start of the sequence of calls
+looking something like this:</p>
+<pre><code>printRangeRecursiveSplit(0, 10)
+ printRangeRecursiveSplit(0, 5)
+ printRangeRecursiveSplit(0, 2)
+ printRangeRecursiveSplit(0, 1)
+ printRangeRecursiveSplit(0, 0)
+ printRangeRecursiveSplit(1, 1)
+ printRangeRecursiveSplit(2, 2)
+ printRangeRecursiveSplit(3, 5)
+ printRangeRecursiveSplit(3, 4)
+ printRangeRecursiveSplit(3, 3)
+ printRangeRecursiveSplit(4, 4)
+ printRangeRecursiveSplit(5, 5)
+ printRangeRecursiveSplit(6, 10)
+ ... etc.</code></pre>
+<p>Here the computation has the structure of a tree instead of a list,
+so it is not so obvious how one might rewrite this procedure as a loop.</p>
+<h3 id="Common_problems_with_recursion"><span class="header-section-number">5.6.2</span> Common problems with recursion</h3>
+<p>Like iteration, recursion is a powerful tool that can cause your
+program to do much more than expected. While it may seem that errors in
+recursive functions would be harder to track down than errors in loops,
+most of the time there are a few basic causes.</p>
+<h4 id="Omitting_the_base_case"><span class="header-section-number">5.6.2.1</span> Omitting the base case</h4>
+<p>Suppose we leave out the <code class="backtick">if</code> statement in <code class="backtick">printRangeRecursive</code>:</p>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"><span class="dt">void</span>
+printRangeRecursiveBad(<span class="dt">int</span> start, <span class="dt">int</span> stop)
+{
+ printf(<span class="st">"%d</span><span class="ch">\n</span><span class="st">"</span>, start);
+ printRangeRecursiveBad(start<span class="dv">+1</span>, stop);
+}</code></pre></div>
+<p>This will still work, in a sense. When called as <code class="backtick">printRangeRecursiveBad(0,&nbsp;10)</code>, it will print 0, call itself with <code class="backtick">printRangeRecursiveBad(1,&nbsp;10)</code>,
+ print 1, 2, 3, etc., but there is nothing to stop it at 10 (or anywhere
+ else). So our output will be a long string of numbers followed by a
+segmentation fault, when we blow out the stack.</p>
+<p>This is the recursive version of an infinite loop: the same thing happens if we forget a loop test and write</p>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"><span class="dt">void</span>
+printRangeIterativeBad(<span class="dt">int</span> start, <span class="dt">int</span> stop)
+{
+ <span class="kw">for</span>(i = <span class="dv">0</span>; ; i++) {
+ printf(<span class="st">"%d</span><span class="ch">\n</span><span class="st">"</span>, i);
+ }
+}</code></pre></div>
+<p>except that now the program just runs forever, since it never runs
+out of resources. This is an example of how iteration is more efficient
+than recursion, at least in C.</p>
+<h4 id="Blowing_out_the_stack"><span class="header-section-number">5.6.2.2</span> Blowing out the stack</h4>
+<p>Blowing out the stack is what happens when a recursion is too deep.
+Typically, the operating system puts a hard limit on how big the stack
+can grow, on the assumption that any program that grows the stack too
+much has gone insane and needs to be killed before it does more damage.
+One of the ways this can happen is if we forget the base case as above,
+but it can also happen if we just try to use a recursive function to do
+too much. For example, if we call <code class="backtick">printRangeRecursive(0,&nbsp;1000000)</code>, we will probably get a segmentation fault after the first 100,000 numbers or so.</p>
+<p>For this reason, it's best to try to avoid linear recursions like the one in <code class="backtick">printRangeRecursive</code>, where the depth of the recursion is proportional to the number of things we are doing. Much safer are even splits like <code class="backtick">printRangeRecursiveSplit</code>,
+ since the depth of the stack will now be only logarithmic in the number
+ of things we are doing. Fortunately, linear recursions are often <strong>tail-recursive</strong>,
+ where the recursive call is the last thing the recursive function does;
+ in this case, we can use a standard transformation (see <a href="#tailRecursion">below</a>) to convert the tail-recursive function into an iterative function.</p>
+<h4 id="Failure_to_make_progress"><span class="header-section-number">5.6.2.3</span> Failure to make progress</h4>
+<p>Sometimes we end up blowing out the stack because we thought we were
+recursing on a smaller instance of the problem, but in fact we weren't.
+Consider this broken version of <code class="backtick">printRangeRecursiveSplit</code>:</p>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"><span class="dt">void</span>
+printRangeRecursiveSplitBad(<span class="dt">int</span> start, <span class="dt">int</span> stop)
+{
+ <span class="dt">int</span> mid;
+
+ <span class="kw">if</span>(start == stop) {
+ printf(<span class="st">"%d</span><span class="ch">\n</span><span class="st">"</span>, start);
+ } <span class="kw">else</span> {
+ mid = (start + stop) / <span class="dv">2</span>;
+
+ printRangeRecursiveSplitBad(start, mid);
+ printRangeRecursiveSplitBad(mid, stop);
+ }
+}</code></pre></div>
+<p>This will get stuck on as simple a call as <code class="backtick">printRangeRecursiveSplitBad(0,&nbsp;1)</code>; it will set <code class="backtick">mid</code> to 0, and while the recursive call to <code class="backtick">printRangeRecursiveSplitBad(0,&nbsp;0)</code> will work just fine, the recursive call to <code class="backtick">printRangeRecursiveSplitBad(0,&nbsp;1)</code> will put us back where we started, giving an infinite recursion.</p>
+<p>Detecting these errors is usually not too hard (segmentation faults that produce huge piles of stack frames when you type <code class="backtick">where</code> in gdb are a dead give-away). Figuring out how to make sure that you do in fact always make progress can be trickier.</p>
+<h3 id="tailRecursion"><span class="header-section-number">5.6.3</span> Tail-recursion and iteration</h3>
+<p><strong>Tail recursion</strong> is when a recursive function calls itself only once, and as the last thing it does. The <code class="backtick">printRangeRecursive</code> function is an example of a tail-recursive function:</p>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"><span class="dt">void</span>
+printRangeRecursive(<span class="dt">int</span> start, <span class="dt">int</span> stop)
+{
+ <span class="kw">if</span>(start &lt; stop) {
+ printf(<span class="st">"%d</span><span class="ch">\n</span><span class="st">"</span>, start);
+ printRangeRecursive(start<span class="dv">+1</span>, stop);
+ }
+}</code></pre></div>
+<p>The nice thing about tail-recursive functions is that we can always
+translate them directly into iterative functions. The reason is that
+when we do the tail call, we are effectively replacing the current copy
+of the function with a new copy with new arguments. So rather than
+keeping around the old zombie parent copy—which has no purpose other
+than to wait for the child to return and then return itself—we can reuse
+ it by assigning new values to its arguments and jumping back to the top
+ of the function.</p>
+<p>Done literally, this produces this <code class="backtick">goto</code>-considered-harmful monstrosity:</p>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"><span class="dt">void</span>
+printRangeRecursiveGoto(<span class="dt">int</span> start, <span class="dt">int</span> stop)
+{
+ topOfFunction:
+
+ <span class="kw">if</span>(start &lt; stop) {
+ printf(<span class="st">"%d</span><span class="ch">\n</span><span class="st">"</span>, start);
+
+ start = start<span class="dv">+1</span>;
+ <span class="kw">goto</span> topOfFunction;
+ }
+}</code></pre></div>
+<p>But we can almost always remove <code class="backtick">goto</code> statements using less dangerous control structures. In this particular case, the pattern of jumping back to just before an <code class="backtick">if</code> matches up exactly with what we get from a <code class="backtick">while</code> loop:</p>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"><span class="dt">void</span>
+printRangeRecursiveNoMore(<span class="dt">int</span> start, <span class="dt">int</span> stop)
+{
+ <span class="kw">while</span>(start &lt; stop) {
+ printf(<span class="st">"%d</span><span class="ch">\n</span><span class="st">"</span>, start);
+
+ start = start<span class="dv">+1</span>;
+ }
+}</code></pre></div>
+<p>In functional programming languages, this transformation is usually
+done in the other direction, to unroll loops into recursive functions.
+Since C doesn't like recursive functions so much (they blow out the
+stack!), we usually do this transformation got get rid of recursion
+instead of adding it.</p>
+<h4 id="binarySearch"><span class="header-section-number">5.6.3.1</span> Binary search: recursive and iterative versions</h4>
+<p><strong>Binary search</strong> is an algorithm for searching a sorted
+ array for a particular target element, similar to playing Twenty
+Questions when the answer is a number (hopefully in a range that
+includes at most <span class="math inline">2<sup>20</sup></span>
+numbers). The algorithm starts by picking an value in the middle of the
+array. If the target is less than this value, we recurse on the bottom
+half of the array; else we recurse on the top half.</p>
+<p>Here is an interface for binary search on an array of <code>int</code>s:</p>
+<div>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"><span class="co">/* returns 1 if target is present in sorted array */</span>
+<span class="dt">int</span> binarySearch(<span class="dt">int</span> target, <span class="dt">const</span> <span class="dt">int</span> *a, size_t length);</code></pre></div>
+<a href="http://cs.yale.edu/homes/aspnes/classes/223/examples/binarySearch/binarySearch.h" class="uri">examples/binarySearch/binarySearch.h</a>
+</div>
+<p>Written recursively, we might implement the algorithm like this:</p>
+<div>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"><span class="ot">#include &lt;stddef.h&gt;</span>
+
+<span class="ot">#include "binarySearch.h"</span>
+
+<span class="dt">int</span>
+binarySearch(<span class="dt">int</span> target, <span class="dt">const</span> <span class="dt">int</span> *a, size_t length)
+{
+ size_t index;
+
+ index = length/<span class="dv">2</span>;
+
+ <span class="kw">if</span>(length == <span class="dv">0</span>) {
+ <span class="co">/* nothing left */</span>
+ <span class="kw">return</span> <span class="dv">0</span>;
+ } <span class="kw">else</span> <span class="kw">if</span>(target == a[index]) {
+ <span class="co">/* got it */</span>
+ <span class="kw">return</span> <span class="dv">1</span>;
+ } <span class="kw">else</span> <span class="kw">if</span>(target &lt; a[index]) {
+ <span class="co">/* recurse on bottom half */</span>
+ <span class="kw">return</span> binarySearch(target, a, index);
+ } <span class="kw">else</span> {
+ <span class="co">/* recurse on top half */</span>
+ <span class="co">/* we throw away index+1 elements (including a[index]) */</span>
+ <span class="kw">return</span> binarySearch(target, a+index<span class="dv">+1</span>, length-(index<span class="dv">+1</span>));
+ }
+}</code></pre></div>
+<a href="http://cs.yale.edu/homes/aspnes/classes/223/examples/binarySearch/binarySearchRecursive.c" class="uri">examples/binarySearch/binarySearchRecursive.c</a>
+</div>
+<p>This will work just fine, and indeed it finds the target element (or not) in <span class="math inline"><em>O</em>(log<em>n</em>)</span> time, because we can only recurse <span class="math inline"><em>O</em>(log<em>n</em>)</span> times before running out of elements and we only pay <span class="math inline"><em>O</em>(1)</span> cost per recursive call to <code>binarySearch</code>.
+ But we do have to pay function call overhead for call, and there is a
+potential to run into stack overflow if our stack is very constrained.</p>
+<p>Fortunately, we don't do anything with the return value from <code>binarySearch</code>
+ but pass it on up the stack: the function is tail-recursive. This means
+ that we can get rid of the recursion by reusing the stack from from the
+ initial call. The mechanical way to do this is wrap the body of the
+routine in a <code>for(;;)</code> loop (so that we jump back to the top
+whenever we hit the bottom), and replace each recursive call with one or
+ more assignments to update any parameters that change in the recursive
+call. The result looks like this:</p>
+<div>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"><span class="ot">#include &lt;stddef.h&gt;</span>
+
+<span class="ot">#include "binarySearch.h"</span>
+
+<span class="dt">int</span>
+binarySearch(<span class="dt">int</span> target, <span class="dt">const</span> <span class="dt">int</span> *a, size_t length)
+{
+ size_t index;
+
+ <span class="co">/* direct translation of recursive version */</span>
+ <span class="co">/* hence the weird organization of the loop */</span>
+ <span class="kw">for</span>(;;) {
+ index = length/<span class="dv">2</span>;
+
+ <span class="kw">if</span>(length == <span class="dv">0</span>) {
+ <span class="co">/* nothing left */</span>
+ <span class="kw">return</span> <span class="dv">0</span>;
+ } <span class="kw">else</span> <span class="kw">if</span>(target == a[index]) {
+ <span class="co">/* got it */</span>
+ <span class="kw">return</span> <span class="dv">1</span>;
+ } <span class="kw">else</span> <span class="kw">if</span>(target &lt; a[index]) {
+ <span class="co">/* recurse on bottom half */</span>
+ length = index;
+ } <span class="kw">else</span> {
+ <span class="co">/* recurse on top half */</span>
+ <span class="co">/* we throw away index+1 elements (including a[index]) */</span>
+ a = a + index + <span class="dv">1</span>;
+ length = length - (index + <span class="dv">1</span>);
+ }
+ }
+}</code></pre></div>
+<a href="http://cs.yale.edu/homes/aspnes/classes/223/examples/binarySearch/binarySearchIterative.c" class="uri">examples/binarySearch/binarySearchIterative.c</a>
+</div>
+<p>Here's some simple test code to demonstrate that these two implementations in fact do the same thing: <a href="http://cs.yale.edu/homes/aspnes/classes/223/examples/binarySearch/Makefile">Makefile</a>, <a href="http://cs.yale.edu/homes/aspnes/classes/223/examples/binarySearch/testBinarySearch.c">testBinarySearch.c</a>.</p>
+<h3 id="mergesort"><span class="header-section-number">5.6.4</span> Mergesort: a recursive sorting algorithm</h3>
+<p>So far the examples we have given have not been very useful, or have
+involved recursion that we can easily replace with iteration. Here is an
+ example of a recursive procedure that cannot be as easily turned into
+an iterative version.</p>
+<p>We are going to implement the <a href="http://en.wikipedia.org/wiki/Mergesort" title="WikiPedia">mergesort</a> algorithm on arrays. This is a classic <a href="#algorithmDesignTechniquesClassification">divide and conquer</a>
+ sorting algorithm that splits an array into two pieces, sorts each
+piece (recursively!), then merges the results back together. Here is the
+ code, together with a simple test program.</p>
+<div>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"><span class="ot">#include &lt;stdio.h&gt;</span>
+<span class="ot">#include &lt;stdlib.h&gt;</span>
+<span class="ot">#include &lt;string.h&gt;</span>
+
+<span class="co">/* merge sorted arrays a1 and a2, putting result in out */</span>
+<span class="dt">void</span>
+merge(<span class="dt">int</span> n1, <span class="dt">const</span> <span class="dt">int</span> a1[], <span class="dt">int</span> n2, <span class="dt">const</span> <span class="dt">int</span> a2[], <span class="dt">int</span> out[])
+{
+ <span class="dt">int</span> i1;
+ <span class="dt">int</span> i2;
+ <span class="dt">int</span> iout;
+
+ i1 = i2 = iout = <span class="dv">0</span>;
+
+ <span class="kw">while</span>(i1 &lt; n1 || i2 &lt; n2) {
+ <span class="kw">if</span>(i2 &gt;= n2 || ((i1 &lt; n1) &amp;&amp; (a1[i1] &lt; a2[i2]))) {
+ <span class="co">/* a1[i1] exists and is smaller */</span>
+ out[iout++] = a1[i1++];
+ } <span class="kw">else</span> {
+ <span class="co">/* a1[i1] doesn't exist, or is bigger than a2[i2] */</span>
+ out[iout++] = a2[i2++];
+ }
+ }
+}
+
+<span class="co">/* sort a, putting result in out */</span>
+<span class="co">/* we call this mergeSort to avoid conflict with mergesort in libc */</span>
+<span class="dt">void</span>
+mergeSort(<span class="dt">int</span> n, <span class="dt">const</span> <span class="dt">int</span> a[], <span class="dt">int</span> out[])
+{
+ <span class="dt">int</span> *a1;
+ <span class="dt">int</span> *a2;
+
+ <span class="kw">if</span>(n &lt; <span class="dv">2</span>) {
+ <span class="co">/* 0 or 1 elements is already sorted */</span>
+ memcpy(out, a, <span class="kw">sizeof</span>(<span class="dt">int</span>) * n);
+ } <span class="kw">else</span> {
+ <span class="co">/* sort into temp arrays */</span>
+ a1 = malloc(<span class="kw">sizeof</span>(<span class="dt">int</span>) * (n/<span class="dv">2</span>));
+ a2 = malloc(<span class="kw">sizeof</span>(<span class="dt">int</span>) * (n - n/<span class="dv">2</span>));
+
+ mergeSort(n/<span class="dv">2</span>, a, a1);
+ mergeSort(n - n/<span class="dv">2</span>, a + n/<span class="dv">2</span>, a2);
+
+ <span class="co">/* merge results */</span>
+ merge(n/<span class="dv">2</span>, a1, n - n/<span class="dv">2</span>, a2, out);
+
+ <span class="co">/* free the temp arrays */</span>
+ free(a1);
+ free(a2);
+ }
+}
+
+<span class="ot">#define N (20)</span>
+
+<span class="dt">int</span>
+main(<span class="dt">int</span> argc, <span class="dt">char</span> **argv)
+{
+ <span class="dt">int</span> a[N];
+ <span class="dt">int</span> b[N];
+ <span class="dt">int</span> i;
+
+ <span class="kw">for</span>(i = <span class="dv">0</span>; i &lt; N; i++) {
+ a[i] = N-i<span class="dv">-1</span>;
+ }
+
+ <span class="kw">for</span>(i = <span class="dv">0</span>; i &lt; N; i++) {
+ printf(<span class="st">"%d "</span>, a[i]);
+ }
+ putchar(<span class="ch">'\n'</span>);
+
+ mergeSort(N, a, b);
+
+ <span class="kw">for</span>(i = <span class="dv">0</span>; i &lt; N; i++) {
+ printf(<span class="st">"%d "</span>, b[i]);
+ }
+ putchar(<span class="ch">'\n'</span>);
+
+ <span class="kw">return</span> <span class="dv">0</span>;
+}</code></pre></div>
+<a href="http://cs.yale.edu/homes/aspnes/classes/223/examples/sorting/mergesort.c" class="uri">examples/sorting/mergesort.c</a>
+</div>
+<p>The cost of this is pretty cheap: <span class="math inline"><em>O</em>(<em>n</em>log<em>n</em>)</span>, since each element of <code class="backtick">a</code> is processed through <code class="backtick">merge</code> once for each array it gets put in, and the recursion only goes <span class="math inline"><em>O</em>(log<em>n</em>)</span> layers deep before we hit 1-element arrays.</p>
+<p>The reason that we can't easily transform this into an iterative version is that the <code>mergeSort</code>
+ function is not tail-recursive: not only does it call itself twice, but
+ it also needs to free the temporary arrays at the end. Because the
+algorithm has to do these tasks on the way back up the stack, we need to
+ keep the stack around to track them.</p>
+<h3 id="asymptotic-complexity-of-recursive-functions"><span class="header-section-number">5.6.5</span> Asymptotic complexity of recursive functions</h3>
+<p>One issue with a recursive functions is that it becomes harder to
+estimate its asymptotic complexity. Unlike loops, where we can estimate
+the cost by simply multiplying the number of iterations by the cost of
+each iteration, the cost of a recursive function depends on the cost of
+its recursive calls. This would make it seem that we would need to be
+able to compute the cost of the function before we could compute the
+cost of the function.</p>
+<p>Fortunately, for most recursive functions, the size of the input
+drops whenever we recurse. So the cost can be expressed in terms of a <strong>recurrence</strong>, a formula for the cost <span class="math inline"><em>T</em>(<em>n</em>)</span> on an input of size <span class="math inline"><em>n</em></span> in terms of the cost on smaller inputs. Some examples:</p>
+<dl>
+<dt><span class="math inline"><em>T</em>(<em>n</em>)=<em>O</em>(1)+<em>T</em>(<em>n</em>/2)</span></dt>
+<dd>This is the cost of binary search. To search an array of <span class="math inline"><em>n</em></span> elements, look up the middle element (<span class="math inline"><em>O</em>(1)</span> time) and, in the worst case, recurse on an array of <span class="math inline"><em>n</em>/2</span> elements.
+</dd>
+<dt><span class="math inline"><em>T</em>(<em>n</em>)=2<em>T</em>(<em>n</em>/2)+<em>O</em>(<em>n</em>)</span></dt>
+<dd>This is the cost of mergesort. Sort two half-size arrays recursively, then merge them in <span class="math inline"><em>O</em>(<em>n</em>)</span> time.
+</dd>
+<dt><span class="math inline"><em>T</em>(<em>n</em>)=<em>O</em>(1)+<em>T</em>(<em>n</em> − 1)</span></dt>
+<dd>This is the cost of most simple loops, if we think of them as a recursive process. Do <span class="math inline"><em>O</em>(1)</span> work on the first element, then do <span class="math inline"><em>T</em>(<em>n</em> − 1)</span> work on the rest.
+</dd>
+</dl>
+<p>There are <a href="http://en.wikipedia.org/wiki/Master_theorem">standard tools</a>
+ for solving many of the recurrences that arise in common algorithms,
+but these are overkill for our purposes, since there are only a handful
+of recurrences that are likely to come up in practice and we already
+solved most of them. Here is a table of some of the more common
+possibilities:</p>
+<table>
+<thead>
+<tr class="header">
+<th align="left">Recurrence</th>
+<th align="left">Solution</th>
+<th align="left">Example</th>
+</tr>
+</thead>
+<tbody>
+<tr class="odd">
+<td align="left"><span class="math inline"><em>T</em>(<em>n</em>)=<em>T</em>(<em>n</em> − 1)+<em>O</em>(1)</span></td>
+<td align="left"><span class="math inline"><em>T</em>(<em>n</em>)=<em>O</em>(<em>n</em>)</span></td>
+<td align="left">Finding a maximum</td>
+</tr>
+<tr class="even">
+<td align="left"><span class="math inline"><em>T</em>(<em>n</em>)=<em>T</em>(<em>n</em> − 1)+<em>O</em>(<em>n</em>)</span></td>
+<td align="left"><span class="math inline"><em>T</em>(<em>n</em>)=<em>O</em>(<em>n</em><sup>2</sup>)</span></td>
+<td align="left">Selection sort</td>
+</tr>
+<tr class="odd">
+<td align="left"><span class="math inline"><em>T</em>(<em>n</em>)=<em>T</em>(<em>n</em>/2)+<em>O</em>(1)</span></td>
+<td align="left"><span class="math inline"><em>T</em>(<em>n</em>)=<em>O</em>(log<em>n</em>)</span></td>
+<td align="left">Binary search</td>
+</tr>
+<tr class="even">
+<td align="left"><span class="math inline"><em>T</em>(<em>n</em>)=2<em>T</em>(<em>n</em>/2)+<em>O</em>(<em>n</em>)</span></td>
+<td align="left"><span class="math inline"><em>T</em>(<em>n</em>)=<em>O</em>(<em>n</em>log<em>n</em>)</span></td>
+<td align="left">Mergesort</td>
+</tr>
+</tbody>
+</table>
+<h2 id="binaryTrees"><span class="header-section-number">5.7</span> Binary trees</h2>
+<p><a href="#algorithmDesignTechniquesClassification">Divide and conquer</a>
+ yields algorithms whose execution has a tree structure. Sometimes we
+build data structures that are also trees. It is probably not surprising
+ that divide and conquer is the natural way to build algorithms that use
+ such trees as inputs.</p>
+<h3 id="Tree_basics"><span class="header-section-number">5.7.1</span> Tree basics</h3>
+<p>Here is a typical binary tree. It is binary because every node has at most two children. This particular tree is also <strong>complete</strong> because the nodes consist only of <strong>internal nodes</strong> with exactly two children and <strong>leaves</strong> with no children. Not all binary trees will be complete.</p>
+<pre><code> 0
+ / \
+ 1 2
+ / \
+ 3 4
+ / \
+ 5 6
+ / \
+ 7 8</code></pre>
+<p>Structurally, a complete binary tree consists of either a single node (a leaf) or a root node with a left and right <strong>subtree</strong>,
+ each of which is itself either a leaf or a root node with two subtrees.
+ The set of all nodes underneath a particular node x is called the
+subtree rooted at x.</p>
+<p>The <strong>size</strong> of a tree is the number of nodes; a leaf by itself has size 1. The <strong>height</strong> of a tree is the length of the longest path; 0 for a leaf, at least one in any larger tree. The <strong>depth</strong> of a node is the length of the path from the root to that node. The <strong>height</strong>
+ of a node is the height of the subtree of which it is the root, i.e.
+the length of the longest path from that node to some leaf below it. A
+node <span class="math inline"><em>u</em></span> is an <strong>ancestor</strong> of a node <span class="math inline"><em>v</em></span> if <span class="math inline"><em>v</em></span> is contained in the subtree rooted at <span class="math inline"><em>u</em></span>; we may write equivalently that <span class="math inline"><em>v</em></span> is a <strong>descendant</strong> of <span class="math inline"><em>u</em></span>. Note that every node is both and ancestor and descendant of itself; if we wish to exclude the node itself, we refer to a <strong>proper ancestor</strong> or <strong>proper descendant</strong>.</p>
+<h3 id="Binary_tree_implementations"><span class="header-section-number">5.7.2</span> Binary tree implementations</h3>
+<p>In a low-level programming language like C, a binary tree typically
+looks a lot like a linked list with an extra outgoing pointer from each
+element, e.g.</p>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"><span class="kw">struct</span> node {
+ <span class="dt">int</span> key;
+ <span class="kw">struct</span> node *left; <span class="co">/* left child */</span>
+ <span class="kw">struct</span> node *right; <span class="co">/* right child */</span>
+};</code></pre></div>
+<p>Missing children (and the empty tree) are represented by null
+pointers. Typically, individual tree nodes are allocated separately
+using <code class="backtick">malloc</code>; however, for
+high-performance use it is not unusual for tree libraries to do their
+own storage allocation out of large blocks obtained from <code class="backtick">malloc</code>.</p>
+<p>Optionally, the <code class="backtick">struct</code> may be extended to include additional information such as a pointer to the node's parent, hints for <a href="#balancedTrees">balancing</a>,
+ or aggregate information about the subtree rooted at the node such as
+its size or the sum/max/average of the keys of its nodes.</p>
+<p>When it is not important to be able to move large subtrees around
+simply by adjusting pointers, a tree may be represented implicitly by
+packing it into an array. This is a standard approach for implementing <a href="#heaps">heaps</a>, which we will see soon.</p>
+<h3 id="The_canonical_binary_tree_algorithm"><span class="header-section-number">5.7.3</span> The canonical binary tree algorithm</h3>
+<p>Pretty much every <a href="#algorithmDesignTechniquesClassification">divide and conquer</a> algorithm for binary trees looks like this:</p>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"><span class="dt">void</span>
+doSomethingToAllNodes(<span class="kw">struct</span> node *root)
+{
+ <span class="kw">if</span>(root) {
+ doSomethingTo(root);
+ doSomethingToAllNodes(root-&gt;left);
+ doSomethingToAllNodes(root-&gt;right);
+ }
+}</code></pre></div>
+<p>The function processes all nodes in what is called a <strong>preorder traversal</strong>, where the "preorder" part means that the root of any tree is processed first. Moving the call to <code class="backtick">doSomethingTo</code> in between or after the two recursive calls yields an <strong>inorder</strong> or <strong>postorder</strong> traversal, respectively.</p>
+<p>In practice we usually want to extract some information from the tree. For example, this function computes the size of a tree:</p>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"><span class="dt">int</span>
+treeSize(<span class="kw">struct</span> node *root)
+{
+ <span class="kw">if</span>(root == <span class="dv">0</span>) {
+ <span class="kw">return</span> <span class="dv">0</span>;
+ } <span class="kw">else</span> {
+ <span class="kw">return</span> <span class="dv">1</span> + treeSize(root-&gt;left) + treeSize(root-&gt;right);
+ }
+}</code></pre></div>
+<p>and this function computes the height:</p>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"><span class="dt">int</span>
+treeHeight(<span class="kw">struct</span> node *root)
+{
+ <span class="dt">int</span> lh; <span class="co">/* height of left subtree */</span>
+ <span class="dt">int</span> rh; <span class="co">/* height of right subtree */</span>
+
+ <span class="kw">if</span>(root == <span class="dv">0</span>) {
+ <span class="kw">return</span> -<span class="dv">1</span>;
+ } <span class="kw">else</span> {
+ lh = treeHeight(root-&gt;left);
+ rh = treeHeight(root-&gt;right);
+ <span class="kw">return</span> <span class="dv">1</span> + (lh &gt; rh ? lh : rh);
+ }
+}</code></pre></div>
+<p>Since both of these algorithms have the same structure, they both
+have the same asymptotic running time. We can compute this running time
+by observing that each recursive call to <code>treeSize</code> or <code>treeHeight</code> that does not get a null pointer passed to it gets a different node (so there are <span class="math inline"><em>n</em></span>
+ such calls), and each call that does get a null pointer passed to it is
+ called by a routine that doesn't, and that there are at most two such
+calls per node. Since the body of each call itself costs <span class="math inline"><em>O</em>(1)</span> (no loops), this gives a total cost of <span class="math inline"><em>Θ</em>(<em>n</em>)</span>.</p>
+<p>So these are all <span class="math inline"><em>Θ</em>(<em>n</em>)</span> algorithms.</p>
+<h3 id="Nodes_vs_leaves"><span class="header-section-number">5.7.4</span> Nodes vs leaves</h3>
+<p>For some binary trees we don't store anything interesting in the
+internal nodes, using them only to provide a route to the leaves. We
+might reasonably ask if an algorithm that runs in <span class="math inline"><em>O</em>(<em>n</em>)</span> time where <span class="math inline"><em>n</em></span> is the total number of nodes still runs in <span class="math inline"><em>O</em>(<em>m</em>)</span> time, where <span class="math inline"><em>m</em></span> counts only the leaves. For <em>complete</em>
+ binary trees, we can show that we get the same asymptotic performance
+whether we count leaves only, internal nodes only, or both leaves and
+internal nodes.</p>
+<p>Let <span class="math inline"><em>T</em>(<em>n</em>)</span> be the number of internal nodes in a complete binary tree with <span class="math inline"><em>n</em></span> leaves. It is easy to see that <span class="math inline"><em>T</em>(1)=0</span> and <span class="math inline"><em>T</em>(2)=1</span>, but for larger trees there are multiple structures and so it makes sense to write a recurrence: <span class="math inline"><em>T</em>(<em>n</em>)=1 + <em>T</em>(<em>k</em>)+<em>T</em>(<em>n</em> − <em>k</em>)</span>.</p>
+<p>We can show by induction that the solution to this recurrence is exactly <span class="math inline"><em>T</em>(<em>n</em>)=<em>n</em> − 1</span>. We already have the base case <span class="math inline"><em>T</em>(1)=0</span>. For larger <span class="math inline"><em>n</em></span>, we have <span class="math inline"><em>T</em>(<em>n</em>)=1 + <em>T</em>(<em>k</em>)+<em>T</em>(<em>n</em> − <em>k</em>)=1 + (<em>k</em> − 1)+(<em>n</em> − <em>k</em> − 1)=<em>n</em> − 1</span>.</p>
+<p>So a complete binary tree with <span class="math inline"><em>Θ</em>(<em>n</em>)</span> nodes has <span class="math inline"><em>Θ</em>(<em>n</em>)</span> internal nodes and <span class="math inline"><em>Θ</em>(<em>n</em>)</span> leaves; if we don't care about constant factors, we won't care which number we use.</p>
+<h3 id="Special_classes_of_binary_trees"><span class="header-section-number">5.7.5</span> Special classes of binary trees</h3>
+<p>So far we haven't specified where particular nodes are placed in the
+binary tree. Most applications of binary trees put some constraints on
+how nodes relate to one another. Some possibilities:</p>
+<ul>
+<li><a href="#heaps">Heaps</a>: Each node has a key that is less than
+the keys of both of its children. These allow for a very simple
+implementation using arrays, so we will look at these first.</li>
+<li><a href="#binarySearchTrees">BinarySearchTrees</a>: Each node has a
+key, and a node's key must be greater than all keys in the subtree of
+its left-hand child and less than all keys in the subtree of its
+right-hand child.</li>
+</ul>
+<h2 id="heaps"><span class="header-section-number">5.8</span> Heaps</h2>
+<p>A <strong>heap</strong> is a <a href="#binaryTrees">binary tree</a> in which each element has a key (or sometimes <strong>priority</strong>) that is less than the keys of its children. Heaps are used to implement the <strong>priority queue</strong> <a href="#abstractDataTypes">abstract data type</a>, which we'll talk about first.</p>
+<h3 id="priorityQueues"><span class="header-section-number">5.8.1</span> Priority queues</h3>
+<p>In a standard queue, elements leave the queue in the same order as
+they arrive. In a priority queue, elements leave the queue in order of
+decreasing priority: the DEQUEUE operation becomes a DELETE-MIN
+operation (or DELETE-MAX, if higher numbers mean higher priority), which
+ removes and returns the highest-priority element of the priority queue,
+ regardless of when it was inserted. Priority queues are often used in
+operating system schedulers to determine which job to run next: a
+high-priority job (e.g., turn on the fire suppression system) runs
+before a low-priority job (floss the cat) even if the low-priority job
+has been waiting longer.</p>
+<h3 id="Expensive_implementations_of_priority_queues"><span class="header-section-number">5.8.2</span> Expensive implementations of priority queues</h3>
+<p>Implementing a priority queue using an array or linked list is likely
+ to be expensive. If the array or list is unsorted, it takes <span class="math inline"><em>O</em>(<em>n</em>)</span> time to find the minimum element; if it is sorted, it takes <span class="math inline"><em>O</em>(<em>n</em>)</span>
+ time (in the worst case) to add a new element. So such implementations
+are only useful when the numbers of INSERT and DELETE-MIN operations are
+ very different. For example, if DELETE-MIN is called only rarely but
+INSERT is called often, it may actually be cheapest to implement a
+priority queue as an unsorted linked list with <span class="math inline"><em>O</em>(1)</span> INSERTs and <span class="math inline"><em>O</em>(<em>n</em>)</span>
+ DELETE-MINs. But if we expect that every element that is inserted is
+eventually removed, we want something for which both INSERT and
+DELETE-MIN are cheap operations.</p>
+<h3 id="heapStructure"><span class="header-section-number">5.8.3</span> Structure of a heap</h3>
+<p>A heap is a binary tree in which each node has a smaller key than its children; this property is called the <strong>heap property</strong> or <strong>heap invariant</strong>.</p>
+<p>To insert a node in the heap, we add it as a new leaf, which may
+violate the heap property if the new node has a lower key than its
+parent. But we can restore the heap property (at least between this node
+ and its parent) by swapping either the new node or its sibling with the
+ parent, where in either case we move up the node with the smaller key.
+This may still leave a violation of the heap property one level up in
+the tree, but by continuing to swap small nodes with their parents we
+eventually reach the top and have a heap again. The time to complete
+this operation is proportional to the depth of the heap, which will
+typically be <span class="math inline"><em>O</em>(log<em>n</em>)</span> (we will see how to enforce this in a moment).</p>
+<p>To implement DELETE-MIN, we can easily find the value to return at
+the top of the heap. Unfortunately, removing it leaves a vacuum that
+must be filled in by some other element. The easiest way to do this is
+to grab a leaf (which probably has a very high key), and then float it
+down to where it belongs by swapping it with its smaller child at each
+iteration. After time proportional to the depth (again <span class="math inline"><em>O</em>(log<em>n</em>)</span> if we are doing things right), the heap invariant is restored.</p>
+<p>Similar local swapping can be used to restore the heap invariant if
+the priority of some element in the middle changes; we will not discuss
+this in detail.</p>
+<h3 id="Packed_heaps"><span class="header-section-number">5.8.4</span> Packed heaps</h3>
+<p>It is possible to build a heap using <code class="backtick">struct</code>s
+ and pointers, where each element points to its parent and children. In
+practice, heaps are instead stored in arrays, with an implicit pointer
+structure determined by array indices. For zero-based arrays as in C,
+the rule is that a node at position <code class="backtick">i</code> has children at positions <code class="backtick">2*i+1</code> and <code class="backtick">2*i+2</code>; in the other direction, a node at position <code class="backtick">i</code> has a parent at position <code class="backtick">(i-1)/2</code> (which rounds down in C). This is equivalent to storing a heap in an array by reading through the tree in <a href="#graphSearch">breadth-first search</a> order:</p>
+<pre><code> 0
+ / \
+ 1 2
+/ \ / \
+3 4 5 6</code></pre>
+<p>becomes</p>
+<pre><code>0 1 2 3 4 5 6</code></pre>
+<p>This approach works best if there are no gaps in the array. So to
+maximize efficiency we make this "no gaps" policy part of the invariant.
+ We can do so because we don't care which leaf gets added when we do an
+INSERT, so we can make it be the position at the end of the array.
+Similarly, in a DELETE-MIN operation we can promote the last element to
+the root before floating it down. Both these operations change the
+number of elements in the array, and INSERTs in particular might force
+us to reallocate eventually. So in the worst case INSERT can be an
+expensive operation, although as with growing hash tables, the amortized
+ cost may still be small.</p>
+<h3 id="Bottom-up_heapification"><span class="header-section-number">5.8.5</span> Bottom-up heapification</h3>
+<p>If we are presented with an unsorted array, we can turn it into a heap more quickly than the <span class="math inline"><em>O</em>(<em>n</em>log<em>n</em>)</span> time required to do <span class="math inline"><em>n</em></span> INSERTs. The trick is to build the heap from the bottom up (i.e. starting with position <span class="math inline"><em>n</em> − 1</span> and working back to position <span class="math inline">0</span>, so that when it comes time to fix the heap invariant at position <span class="math inline"><em>i</em></span> we have already fixed it at all later positions (this is a form of <a href="#dynamicProgramming">dynamic programming</a>). Unfortunately, it is not quite enough simply to swap <code class="backtick">a[i]</code> with its smaller child when we get there, because we could find that <code class="backtick">a[0]</code> (say) was the largest element in the heap. But the cost of floating <code class="backtick">a[i]</code>
+ down to its proper place will be proportional to its own height rather
+than the height of the entire heap. Since most of the elements of the
+heap are close to the bottom, the total cost will turn out to be <span class="math inline"><em>O</em>(<em>n</em>)</span>.</p>
+<h3 id="heapSort"><span class="header-section-number">5.8.6</span> Heapsort</h3>
+<p>Bottom-up heapification is used in the Heapsort algorithm, which first does bottom-up heapification in <span class="math inline"><em>O</em>(<em>n</em>)</span> time and then repeatedly calls DELETE-MAX to extract the largest remaining element. This is no faster than the <span class="math inline"><em>O</em>(<em>n</em>log<em>n</em>)</span> cost of <a href="#mergesort">mergesort</a> or <a href="#quicksort">quicksort</a>
+ in typical use, but requires very little auxiliary storage since we can
+ maintain the heap in the bottom part of the same array whose top part
+stores the max elements extracted so far.</p>
+<p>Here is a simple implementation of heapsort, that demonstrates how
+both bottom-up heapification and the DELETE-MAX procedure work by
+floating elements down to their proper places:</p>
+<div>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"><span class="ot">#include &lt;stdio.h&gt;</span>
+<span class="ot">#include &lt;stdlib.h&gt;</span>
+<span class="ot">#include &lt;assert.h&gt;</span>
+
+<span class="co">/* max heap implementation */</span>
+
+<span class="co">/* compute child 0 or 1 */</span>
+<span class="ot">#define Child(x, dir) (2*(x)+1+(dir))</span>
+
+<span class="co">/* float value at position pos down */</span>
+<span class="dt">static</span> <span class="dt">void</span>
+floatDown(<span class="dt">int</span> n, <span class="dt">int</span> *a, <span class="dt">int</span> pos)
+{
+ <span class="dt">int</span> x;
+
+ <span class="co">/* save original value once */</span>
+ x = a[pos];
+
+ <span class="kw">for</span>(;;) {
+ <span class="kw">if</span>(Child(pos, <span class="dv">1</span>) &lt; n &amp;&amp; a[Child(pos, <span class="dv">1</span>)] &gt; a[Child(pos, <span class="dv">0</span>)]) {
+ <span class="co">/* maybe swap with Child(pos, 1) */</span>
+ <span class="kw">if</span>(a[Child(pos, <span class="dv">1</span>)] &gt; x) {
+ a[pos] = a[Child(pos, <span class="dv">1</span>)];
+ pos = Child(pos, <span class="dv">1</span>);
+ } <span class="kw">else</span> {
+ <span class="co">/* x is bigger than both kids */</span>
+ <span class="kw">break</span>;
+ }
+ } <span class="kw">else</span> <span class="kw">if</span>(Child(pos, <span class="dv">0</span>) &lt; n &amp;&amp; a[Child(pos, <span class="dv">0</span>)] &gt; x) {
+ <span class="co">/* swap with Child(pos, 0) */</span>
+ a[pos] = a[Child(pos, <span class="dv">0</span>)];
+ pos = Child(pos, <span class="dv">0</span>);
+ } <span class="kw">else</span> {
+ <span class="co">/* done */</span>
+ <span class="kw">break</span>;
+ }
+ }
+
+ a[pos] = x;
+}
+
+<span class="co">/* construct a heap bottom-up */</span>
+<span class="dt">static</span> <span class="dt">void</span>
+heapify(<span class="dt">int</span> n, <span class="dt">int</span> *a)
+{
+ <span class="dt">int</span> i;
+
+ <span class="kw">for</span>(i = n<span class="dv">-1</span>; i &gt;= <span class="dv">0</span>; i--) {
+ floatDown(n, a, i);
+ }
+}
+
+<span class="co">/* sort an array */</span>
+<span class="dt">void</span>
+heapSort(<span class="dt">int</span> n, <span class="dt">int</span> *a)
+{
+ <span class="dt">int</span> i;
+ <span class="dt">int</span> tmp;
+
+ heapify(n, a);
+
+ <span class="kw">for</span>(i = n<span class="dv">-1</span>; i &gt; <span class="dv">0</span>; i--) {
+ <span class="co">/* swap max to a[i] */</span>
+ tmp = a[<span class="dv">0</span>];
+ a[<span class="dv">0</span>] = a[i];
+ a[i] = tmp;
+
+ <span class="co">/* float new a[0] down */</span>
+ floatDown(i, a, <span class="dv">0</span>);
+ }
+}
+
+<span class="ot">#define N (100)</span>
+<span class="ot">#define MULTIPLIER (17)</span>
+
+<span class="dt">int</span>
+main(<span class="dt">int</span> argc, <span class="dt">char</span> **argv)
+{
+ <span class="dt">int</span> a[N];
+ <span class="dt">int</span> i;
+
+ <span class="kw">if</span>(argc != <span class="dv">1</span>) {
+ fprintf(stderr, <span class="st">"Usage: %s</span><span class="ch">\n</span><span class="st">"</span>, argv[<span class="dv">0</span>]);
+ <span class="kw">return</span> <span class="dv">1</span>;
+ }
+
+ <span class="kw">for</span>(i = <span class="dv">0</span>; i &lt; N; i++) { a[i] = (i*MULTIPLIER) % N; }
+
+ <span class="kw">for</span>(i = <span class="dv">0</span>; i &lt; N; i++) { printf(<span class="st">"%d "</span>, a[i]); }
+ putchar(<span class="ch">'\n'</span>);
+
+ heapSort(N, a);
+
+ <span class="kw">for</span>(i = <span class="dv">0</span>; i &lt; N; i++) { printf(<span class="st">"%d "</span>, a[i]); }
+ putchar(<span class="ch">'\n'</span>);
+
+ <span class="kw">return</span> <span class="dv">0</span>;
+}</code></pre></div>
+<a href="http://cs.yale.edu/homes/aspnes/classes/223/examples/sorting/heapsort.c" class="uri">examples/sorting/heapsort.c</a>
+</div>
+<h3 id="heapMoreInformation"><span class="header-section-number">5.8.7</span> More information</h3>
+<ul>
+<li><a href="http://en.wikipedia.org/wiki/Priority_queue" title="WikiPedia">Priority_queue</a></li>
+<li><a href="http://en.wikipedia.org/wiki/Binary_heap" title="WikiPedia">Binary_heap</a></li>
+<li><a href="http://mathworld.wolfram.com/Heap.html" class="uri">http://mathworld.wolfram.com/Heap.html</a></li>
+</ul>
+<h2 id="binarySearchTrees"><span class="header-section-number">5.9</span> Binary search trees</h2>
+<p>A <strong>binary search tree</strong> is a <a href="#binaryTrees">binary tree</a> in which each node has a <strong>key</strong>,
+ and a node's key must be greater than all keys in the subtree of its
+left-hand child and less than all keys in the subtree of its right-hand
+child. This allows a node to be searched for using essentially the same
+binary search algorithm used on sorted arrays.</p>
+<h3 id="Searching_for_a_node"><span class="header-section-number">5.9.1</span> Searching for a node</h3>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"><span class="co">/* returns node with given target key */</span>
+<span class="co">/* or null if no such node exists */</span>
+<span class="kw">struct</span> node *
+treeSearch(<span class="kw">struct</span> node *root, <span class="dt">int</span> target)
+{
+ <span class="kw">if</span>(root-&gt;key == target) {
+ <span class="kw">return</span> root;
+ } <span class="kw">else</span> <span class="kw">if</span>(root-&gt;key &gt; target) {
+ <span class="kw">return</span> treeSearch(root-&gt;left, target);
+ } <span class="kw">else</span> {
+ <span class="kw">return</span> treeSearch(root-&gt;right, target);
+ }
+}</code></pre></div>
+<p>This procedure can be rewritten iteratively, which avoids stack overflow and is likely to be faster:</p>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"><span class="kw">struct</span> node *
+treeSearch(<span class="kw">struct</span> node *root, <span class="dt">int</span> target)
+{
+ <span class="kw">while</span>(root != <span class="dv">0</span> &amp;&amp; root-&gt;key != target) {
+ <span class="kw">if</span>(root-&gt;key &gt; target) {
+ root = root-&gt;left;
+ } <span class="kw">else</span> {
+ root = root-&gt;right;
+ }
+ }
+
+ <span class="kw">return</span> root;
+}</code></pre></div>
+<p>These procedures can be modified in the obvious way to deal with keys that aren't <code class="backtick">int</code>s, as long as they can be compared (e.g., by using <code class="backtick">strcmp</code> on strings).</p>
+<h3 id="Inserting_a_new_node"><span class="header-section-number">5.9.2</span> Inserting a new node</h3>
+<p>As in a <a href="#hashTables">hash table</a>, the insertion procedure
+ mirrors the search procedure. We must be a little careful to avoid
+actually walking all the way down to a null pointer, since a null
+pointer now indicates a missing space for a leaf that we can fill with
+our new node. So the code is a little more complex.</p>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"><span class="dt">void</span>
+treeInsert(<span class="kw">struct</span> tree *root, <span class="dt">int</span> key)
+{
+ <span class="kw">struct</span> tree *newNode;
+
+ newNode = malloc(<span class="kw">sizeof</span>(*newNode));
+ assert(newNode);
+
+ newNode-&gt;key = key;
+ newNode-&gt;left = <span class="dv">0</span>;
+ newNode-&gt;right = <span class="dv">0</span>;
+
+ <span class="kw">for</span>(;;) {
+ <span class="kw">if</span>(root-&gt;key &gt; key) {
+ <span class="co">/* try left child */</span>
+ <span class="kw">if</span>(root-&gt;left) {
+ root = root-&gt;left;
+ } <span class="kw">else</span> {
+ <span class="co">/* put it in */</span>
+ root-&gt;left = newNode;
+ <span class="kw">return</span>;
+ }
+ } <span class="kw">else</span> {
+ <span class="co">/* right child case is symmetric */</span>
+ <span class="kw">if</span>(root-&gt;right) {
+ root = root-&gt;right;
+ } <span class="kw">else</span> {
+ <span class="co">/* put it in */</span>
+ root-&gt;right = newNode;
+ <span class="kw">return</span>;
+ }
+ }
+ }
+}</code></pre></div>
+<p>Note that this code happily inserts duplicate keys. It also makes no
+attempt to keep the tree balanced. This may lead to very long paths if
+new keys are inserted in strictly increasing or strictly decreasing
+order.</p>
+<h3 id="deleting-a-node"><span class="header-section-number">5.9.3</span> Deleting a node</h3>
+<p>Deletion is more complicated. If a node has no children, we can just
+remove it, and the rest of the tree stays the same. A node with one
+child can be spliced out, connecting its parent directly to its child.
+But with two children, we can't do this.</p>
+<p>The trick is to find the leftmost node in our target's right subtree
+(or vice versa). This node exists assuming the target has two children.
+As in a hash table, we can then swap our target node with this more
+convenient node. Because it is the leftmost node, it has no left child,
+so we can delete it using the no-children or one-child case.</p>
+<h3 id="Costs"><span class="header-section-number">5.9.4</span> Costs</h3>
+<p>Searching for or inserting a node in a binary search tree with <span class="math inline"><em>n</em></span> nodes takes time proportional to the depth of the node. In <a href="#balancedTrees">balanced trees</a>, where the nodes in each subtree are divided roughly evenly between the two child subtrees, this will be <span class="math inline"><em>O</em>(log<em>n</em>)</span>, but for a badly unbalanced tree, this might be as much as <span class="math inline"><em>O</em>(<em>n</em>)</span>. So making a binary search tree work efficiently requires keeping it balanced.</p>
+<h2 id="augmentedTrees"><span class="header-section-number">5.10</span> Augmented trees</h2>
+<p>An <strong>augmented</strong> data structure stores additional
+information in each of its nodes that caches values that might otherwise
+ be expensive to compute. For trees, this might include information like
+ the size of a subtree (which can be useful for <strong>ranking</strong>
+ values, where we want to determine how many elements of the tree are
+smaller), the height of a subtree, or other summary information like the
+ sum of all the keys in a subtree.</p>
+<p>Augmented data structures, in a sense, violate the
+no-separate-but-equal rule that says we shouldn't store the same
+information in different places. The reason we try to avoid this is that
+ it's trouble if the two copies diverge, and by not having two copies in
+ the first place there is no possibility that they contradict each
+other. But in this case the reduced cost justifies breaking this rule.</p>
+<p>The idea is that when we insert a new element into an augmented tree,
+ it only changes the height/size/sum/etc. values for nodes on the path
+from the root to the new value. Since each of these aggregate values can
+ be computed for a node in <span class="math inline"><em>O</em>(1)</span>
+ time from the values in its children, we can update all the aggregate
+values on our way back up the stack after doing the insertion at a cost
+of <span class="math inline"><em>O</em>(1)</span> per node. This will give a total cost of <span class="math inline"><em>O</em>(log<em>n</em>)</span> assuming our tree is reasonably balanced.</p>
+<h3 id="applications"><span class="header-section-number">5.10.1</span> Applications</h3>
+<p>Storing the height field can be useful for balancing, as in <a href="#avlTrees">AVL trees</a>.</p>
+<p>Storing the size allows ranking (computing the number of elements
+less than a given target value) and unraking (find an element with a
+particular rank). Sample code for doing this is given in the <a href="#avlTreeImplementation">AVL tree sample implementation</a> below.</p>
+<p>Storing other aggregates like the sum of keys or values allows <strong>range queries</strong>,
+ where we ask, for example, for some aggregate statistic (like the sum
+or average) of all the elements between some goven minimum and maximum.</p>
+<p>Assuming we keep the tree balanced and correctly maintain the
+aggregate data or each subtree, all of these operations can be done in <span class="math inline"><em>O</em>(log<em>n</em>)</span> time.</p>
+<h2 id="balancedTrees"><span class="header-section-number">5.11</span> Balanced trees</h2>
+<p><a href="#binarySearchTrees">Binary search trees</a> are a fine idea, but they only work if they are <strong>balanced</strong>—if
+ moving from a tree to its left or right subtree reduces the size by a
+constant fraction. Balanced binary trees add some extra mechanism to the
+ basic binary search tree to ensure balance. Finding efficient ways to
+balance a tree has been studied for decades, and several good mechanisms
+ are known. We'll try to hit the high points of all of them.</p>
+<h3 id="treeRotations"><span class="header-section-number">5.11.1</span> Tree rotations</h3>
+<p>The problem is that as we insert new nodes, some paths through the
+tree may become very long. So we need to be able to shrink the long
+paths by moving nodes elsewhere in the tree.</p>
+<p>But how do we do this? The idea is to notice that there may be many
+binary search trees that contain the same data, and that we can
+transform one into another by a local modification called a <em>rotation</em>:</p>
+<pre><code> y x
+ / \ &lt;==&gt; / \
+ x C A y
+ / \ / \
+A B B C
+
+Single rotation on x-y edge</code></pre>
+<p>If <span class="math inline"><em>A</em> &lt; <em>x</em> &lt; <em>B</em> &lt; <em>y</em> &lt; <em>C</em></span>, then both versions of this tree have the binary search tree property. By doing the rotation in one direction, we move <span class="math inline"><em>A</em></span> up and <span class="math inline"><em>C</em></span> down; in the other direction, we move <span class="math inline"><em>A</em></span> down and <span class="math inline"><em>C</em></span> up. So rotations can be used to transfer depth from the leftmost grandchild of a node to the rightmost and vice versa.</p>
+<p>But what if it's the middle grandchild <span class="math inline"><em>B</em></span> that's the problem? A single rotation as above doesn't move <span class="math inline"><em>B</em></span> up or down. To move <span class="math inline"><em>B</em></span>, we have to reposition it so that it's on the end of something. We do this by splitting <span class="math inline"><em>B</em></span> into two subtrees <span class="math inline"><em>B</em><sub>1</sub></span> and <span class="math inline"><em>B</em><sub>2</sub></span>, and doing two rotations that split the two subtrees while moving both up. For this we need to do two rotations:</p>
+<pre><code> z z y
+ / \ ===&gt; / \ ===&gt; / \
+ x C y C x z
+ / \ / \ /| |\
+A y x B2 A B1 B2 C
+ / \ / \
+ B1 B2 A B1
+
+Double rotation: rotate xy then zy</code></pre>
+<h3 id="AVLtrees"><span class="header-section-number">5.11.2</span> AVL trees</h3>
+<p>Rotations in principle let us rebalance a tree, but we still need to
+decide when to do them. If we try to keep the tree in perfect balance
+(all paths nearly the same length), we'll spend so much time rotating
+that we won't be able to do anything else.</p>
+<p>AVL trees solve this problem by enforcing the invariant that the
+heights of the two subtrees sitting under each node differ by at most
+one. This does not guarantee perfect balance, but it does get close. Let
+ <span class="math inline"><em>S</em>(<em>k</em>)</span> be the size of the smallest AVL tree with height <span class="math inline"><em>k</em></span>. This tree will have at least one subtree of height <span class="math inline"><em>k</em> − 1</span>, but its other subtree can be of height <span class="math inline"><em>k</em> − 2</span> (and should be, to keep it as small as possible). We thus have the recurrence <span class="math inline"><em>S</em>(<em>k</em>)=1 + <em>S</em>(<em>k</em> − 1)+<em>S</em>(<em>k</em> − 2)</span>, which is very close to the Fibonacci recurrence.</p>
+<p>It is possible to solve this exactly using generating functions. But we can get close by guessing that <span class="math inline"><em>S</em>(<em>k</em>)≥<em>a</em><sup><em>k</em></sup></span> for some constant <span class="math inline"><em>a</em></span>. This clearly works for <span class="math inline"><em>S</em>(0)=<em>a</em><sup>0</sup> = 1</span>. For larger <span class="math inline"><em>k</em></span>, compute</p>
+<ul>
+<li><span class="math inline"><em>S</em>(<em>k</em>)=1 + <em>a</em><sup><em>k</em> − 1</sup> + <em>a</em><sup><em>k</em> − 2</sup> = 1 + <em>a</em><sup><em>k</em></sup>(1/<em>a</em> + 1/<em>a</em><sup>2</sup>)&gt;<em>a</em><sup><em>k</em></sup>(1/<em>a</em> + 1/<em>a</em><sup>2</sup>)</span>.</li>
+</ul>
+<p>This last quantity is at least <span class="math inline"><em>a</em><sup><em>k</em></sup></span> provided <span class="math inline">(1/<em>a</em> + 1/<em>a</em><sup>2</sup>)</span> is at least 1. We can solve exactly for the largest <span class="math inline"><em>a</em></span> that makes this work, but a very quick calculation shows that <span class="math inline"><em>a</em> = 3/2</span> works: <span class="math inline">2/3 + 4/9 = 10/9 &gt; 1</span>. It follows that any AVL tree with height <span class="math inline"><em>k</em></span> has at least <span class="math inline">(3/2)<sup><em>k</em></sup></span> nodes, or conversely that any AVL tree with <span class="math inline">(3/2)<sup><em>k</em></sup></span> nodes has height at most <span class="math inline"><em>k</em></span>. So the height of an arbitrary AVL tree with <span class="math inline"><em>n</em></span> nodes is no greater than <span class="math inline">log<sub>3/2</sub><em>n</em> = <em>O</em>(log<em>n</em>)</span>.</p>
+<p>How do we maintain this invariant? The first thing to do is add extra
+ information to the tree, so that we can tell when the invariant has
+been violated. AVL trees store in each node the difference between the
+heights of its left and right subtrees, which will be one of <span class="math inline">−1</span>, <span class="math inline">0</span>, or <span class="math inline">1</span>. In an ideal world this would require <span class="math inline">log<sub>2</sub>3 ≈ 1.58</span>
+ bits per node, but since fractional bits are difficult to represent on
+modern computers a typical implementation uses two bits. Inserting a new
+ node into an AVL tree involves</p>
+<ol style="list-style-type: decimal">
+<li>Doing a standard binary search tree insertion.</li>
+<li>Updating the balance fields for every node on the insertion path.</li>
+<li>Performing a single or double rotation to restore balance if needed.</li>
+</ol>
+<p>Implementing this correctly is tricky. Intuitively, we can imagine a
+version of an AVL tree in which we stored the height of each node (using
+ <span class="math inline"><em>O</em>(loglog<em>n</em>)</span> bits). When we insert a new node, only the heights of its ancestors change—so step 2 requires updating <span class="math inline"><em>O</em>(log<em>n</em>)</span>
+ height fields. Similarly, it is only these ancestors that can be too
+tall. It turns out that fixing the closest ancestor fixes all the ones
+above it (because it shortens their longest paths by one as well). So
+just one single or double rotation restores balance.</p>
+<p>Deletions are also possible, but are uglier: a deletion in an AVL tree may require as many as <span class="math inline"><em>O</em>(log<em>n</em>)</span> rotations. The basic idea is to use the standard <a href="#binarySearchTrees">binary search tree</a>
+ deletion trick of either splicing out a node if it has no right child,
+or replacing it with the minimum value in its right subtree (the node
+for which is spliced out); we then have to check to see if we need to
+rebalance at every node above whatever node we removed.</p>
+<p>Which rotations we need to do to rebalance depends on how some pair
+of siblings are unbalanced. Below, we show the possible cases.</p>
+<p>Zig-zig case: This can occur after inserting in A or deleting in C. Here we rotate A up:</p>
+<pre><code> y x
+ / \ ===&gt; / \
+ x C A y
+ / \ | / \
+A B # B C
+|
+#</code></pre>
+<p>Zig-zag case: This can occur after inserting in B or deleting in C. This requires a double rotation.</p>
+<pre><code> z z y
+ / \ ===&gt; / \ ===&gt; / \
+ x C y C x z
+ / \ / \ /| |\
+A y x B2 A B1 B2 C
+ / \ / \
+ B1 B2 A B1</code></pre>
+<p>Zig-zag case, again: This last case comes up after deletion if both
+nephews of the short node are too tall. The same double rotation we used
+ in the previous case works here, too. Note that one of the subtrees is
+still one taller than the others, but that's OK.</p>
+<pre><code> z z y
+ / \ ===&gt; / \ ===&gt; / \
+ x C y C x z
+ / \ / \ /| |\
+A y x B2 A B1 B2 C
+| / \ / \ |
+# B1 B2 A B1 #
+ |
+ #</code></pre>
+<h4 id="avlTreeImplementation"><span class="header-section-number">5.11.2.1</span> Sample implementation</h4>
+<p>If we are not fanatical about space optimization, we can just keep
+track of the heights of all nodes explicitly, instead of managing the <span class="math inline">−1, 0, 1</span> balance values. Below, we give a not-very-optimized example implementation that uses this approach to store a set of <code>int</code>s.
+ This is pretty much our standard unbalanced BST (although we have to
+make sure that the insert and delete routines are recursive, so that we
+can fix things up on the way back out), with a layer on top, implemented
+ in the <code>treeFix</code> function, that tracks the height and size
+of each subtree (although we don't use size), and another layer on top
+of that, implemented in the <code>treeBalance</code> function, that fixes any violations of the AVL balance rule.</p>
+<div>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"><span class="co">/*</span>
+<span class="co"> * Basic binary search tree data structure without balancing info.</span>
+<span class="co"> *</span>
+<span class="co"> * Convention: </span>
+<span class="co"> *</span>
+<span class="co"> * Operations that update a tree are passed a struct tree **,</span>
+<span class="co"> * so they can replace the argument with the return value.</span>
+<span class="co"> *</span>
+<span class="co"> * Operations that do not update the tree get a const struct tree *.</span>
+<span class="co"> */</span>
+
+<span class="ot">#define LEFT (0)</span>
+<span class="ot">#define RIGHT (1)</span>
+<span class="ot">#define TREE_NUM_CHILDREN (2)</span>
+
+<span class="kw">struct</span> tree {
+ <span class="co">/* we'll make this an array so that we can make some operations symmetric */</span>
+ <span class="kw">struct</span> tree *child[TREE_NUM_CHILDREN];
+ <span class="dt">int</span> key;
+ <span class="dt">int</span> height; <span class="co">/* height of this node */</span>
+ size_t size; <span class="co">/* size of subtree rooted at this node */</span>
+};
+
+<span class="ot">#define TREE_EMPTY (0)</span>
+<span class="ot">#define TREE_EMPTY_HEIGHT (-1)</span>
+
+<span class="co">/* free all elements of a tree, replacing it with TREE_EMPTY */</span>
+<span class="dt">void</span> treeDestroy(<span class="kw">struct</span> tree **root);
+
+<span class="co">/* insert an element into a tree pointed to by root */</span>
+<span class="dt">void</span> treeInsert(<span class="kw">struct</span> tree **root, <span class="dt">int</span> newElement);
+
+<span class="co">/* return 1 if target is in tree, 0 otherwise */</span>
+<span class="co">/* we allow root to be modified to allow for self-balancing trees */</span>
+<span class="dt">int</span> treeContains(<span class="dt">const</span> <span class="kw">struct</span> tree *root, <span class="dt">int</span> target);
+
+<span class="co">/* delete minimum element from the tree and return its key */</span>
+<span class="co">/* do not call this on an empty tree */</span>
+<span class="dt">int</span> treeDeleteMin(<span class="kw">struct</span> tree **root);
+
+<span class="co">/* delete target from the tree */</span>
+<span class="co">/* has no effect if target is not in tree */</span>
+<span class="dt">void</span> treeDelete(<span class="kw">struct</span> tree **root, <span class="dt">int</span> target);
+
+<span class="co">/* return height of tree */</span>
+<span class="dt">int</span> treeHeight(<span class="dt">const</span> <span class="kw">struct</span> tree *root);
+
+<span class="co">/* return size of tree */</span>
+size_t treeSize(<span class="dt">const</span> <span class="kw">struct</span> tree *root);
+
+<span class="co">/* pretty-print the contents of a tree */</span>
+<span class="dt">void</span> treePrint(<span class="dt">const</span> <span class="kw">struct</span> tree *root);
+
+<span class="co">/* return the number of elements in tree less than target */</span>
+size_t treeRank(<span class="dt">const</span> <span class="kw">struct</span> tree *root, <span class="dt">int</span> target);
+
+<span class="co">/* return an element with the given rank */</span>
+<span class="co">/* rank must be less than treeSize(root) */</span>
+<span class="dt">int</span> treeUnrank(<span class="dt">const</span> <span class="kw">struct</span> tree *root, size_t rank);
+
+<span class="co">/* check that aggregate data is correct throughout the tree */</span>
+<span class="dt">void</span> treeSanityCheck(<span class="dt">const</span> <span class="kw">struct</span> tree *root);</code></pre></div>
+<a href="http://cs.yale.edu/homes/aspnes/classes/223/examples/trees/AVL/tree.h" class="uri">examples/trees/AVL/tree.h</a>
+</div>
+<div>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"><span class="ot">#include &lt;stdio.h&gt;</span>
+<span class="ot">#include &lt;stdlib.h&gt;</span>
+<span class="ot">#include &lt;assert.h&gt;</span>
+<span class="ot">#include &lt;stdint.h&gt;</span>
+<span class="ot">#include &lt;stdlib.h&gt;</span>
+
+<span class="ot">#include "tree.h"</span>
+
+<span class="dt">int</span>
+treeHeight(<span class="dt">const</span> <span class="kw">struct</span> tree *root)
+{
+ <span class="kw">if</span>(root == <span class="dv">0</span>) {
+ <span class="kw">return</span> TREE_EMPTY_HEIGHT;
+ } <span class="kw">else</span> {
+ <span class="kw">return</span> root-&gt;height;
+ }
+}
+
+<span class="co">/* recompute height from height of kids */</span>
+<span class="dt">static</span> <span class="dt">int</span>
+treeComputeHeight(<span class="dt">const</span> <span class="kw">struct</span> tree *root)
+{
+ <span class="dt">int</span> childHeight;
+ <span class="dt">int</span> maxChildHeight;
+ <span class="dt">int</span> i;
+
+ <span class="kw">if</span>(root == <span class="dv">0</span>) {
+ <span class="kw">return</span> TREE_EMPTY_HEIGHT;
+ } <span class="kw">else</span> {
+ maxChildHeight = TREE_EMPTY_HEIGHT;
+
+ <span class="kw">for</span>(i = <span class="dv">0</span>; i &lt; TREE_NUM_CHILDREN; i++) {
+ childHeight = treeHeight(root-&gt;child[i]);
+ <span class="kw">if</span>(childHeight &gt; maxChildHeight) {
+ maxChildHeight = childHeight;
+ }
+ }
+
+ <span class="kw">return</span> maxChildHeight + <span class="dv">1</span>;
+ }
+}
+
+size_t
+treeSize(<span class="dt">const</span> <span class="kw">struct</span> tree *root)
+{
+ <span class="kw">if</span>(root == <span class="dv">0</span>) {
+ <span class="kw">return</span> <span class="dv">0</span>;
+ } <span class="kw">else</span> {
+ <span class="kw">return</span> root-&gt;size;
+ }
+}
+
+<span class="co">/* recompute size from size of kids */</span>
+<span class="dt">static</span> <span class="dt">int</span>
+treeComputeSize(<span class="dt">const</span> <span class="kw">struct</span> tree *root)
+{
+ <span class="dt">int</span> size;
+ <span class="dt">int</span> i;
+
+ <span class="kw">if</span>(root == <span class="dv">0</span>) {
+ <span class="kw">return</span> <span class="dv">0</span>;
+ } <span class="kw">else</span> {
+ size = <span class="dv">1</span>;
+
+ <span class="kw">for</span>(i = <span class="dv">0</span>; i &lt; TREE_NUM_CHILDREN; i++) {
+ size += treeSize(root-&gt;child[i]);
+ }
+
+ <span class="kw">return</span> size;
+ }
+}
+
+<span class="co">/* fix aggregate data in root */</span>
+<span class="co">/* assumes children are correct */</span>
+<span class="dt">static</span> <span class="dt">void</span>
+treeAggregateFix(<span class="kw">struct</span> tree *root)
+{
+ <span class="kw">if</span>(root) {
+ root-&gt;height = treeComputeHeight(root);
+ root-&gt;size = treeComputeSize(root);
+ }
+}
+
+<span class="co">/* rotate child in given direction to root */</span>
+<span class="dt">static</span> <span class="dt">void</span>
+treeRotate(<span class="kw">struct</span> tree **root, <span class="dt">int</span> direction)
+{
+ <span class="kw">struct</span> tree *x;
+ <span class="kw">struct</span> tree *y;
+ <span class="kw">struct</span> tree *b;
+
+ <span class="co">/*</span>
+<span class="co"> * y x </span>
+<span class="co"> * / \ / \</span>
+<span class="co"> * x C &lt;=&gt; A y</span>
+<span class="co"> * / \ / \</span>
+<span class="co"> * A B B C</span>
+<span class="co"> */</span>
+
+ y = *root; assert(y);
+ x = y-&gt;child[direction]; assert(x);
+ b = x-&gt;child[!direction];
+
+ <span class="co">/* do the rotation */</span>
+ *root = x;
+ x-&gt;child[!direction] = y;
+ y-&gt;child[direction] = b;
+
+ <span class="co">/* fix aggregate data for y then x */</span>
+ treeAggregateFix(y);
+ treeAggregateFix(x);
+}
+
+<span class="co">/* restore AVL property at *root after an insertion or deletion */</span>
+<span class="co">/* assumes subtrees already have AVL property */</span>
+<span class="dt">static</span> <span class="dt">void</span>
+treeRebalance(<span class="kw">struct</span> tree **root)
+{
+ <span class="dt">int</span> tallerChild;
+
+ <span class="kw">if</span>(*root) {
+ <span class="kw">for</span>(tallerChild = <span class="dv">0</span>; tallerChild &lt; TREE_NUM_CHILDREN; tallerChild++) {
+ <span class="kw">if</span>(treeHeight((*root)-&gt;child[tallerChild]) &gt;= treeHeight((*root)-&gt;child[!tallerChild]) + <span class="dv">2</span>) {
+
+ <span class="co">/* which grandchild is the problem? */</span>
+ <span class="kw">if</span>(treeHeight((*root)-&gt;child[tallerChild]-&gt;child[!tallerChild])
+ &gt; treeHeight((*root)-&gt;child[tallerChild]-&gt;child[tallerChild])) {
+ <span class="co">/* opposite-direction grandchild is too tall */</span>
+ <span class="co">/* rotation at root will just change its parent but not change height */</span>
+ <span class="co">/* so we rotate it up first */</span>
+ treeRotate(&amp;(*root)-&gt;child[tallerChild], !tallerChild);
+ }
+
+ <span class="co">/* now rotate up the taller child */</span>
+ treeRotate(root, tallerChild);
+
+ <span class="co">/* don't bother with other child */</span>
+ <span class="kw">break</span>;
+ }
+ }
+
+ <span class="co">/* test that we actually fixed it */</span>
+ assert(abs(treeHeight((*root)-&gt;child[LEFT]) - treeHeight((*root)-&gt;child[RIGHT])) &lt;= <span class="dv">1</span>);
+
+<span class="ot">#ifdef PARANOID_REBALANCE</span>
+ treeSanityCheck(*root);
+<span class="ot">#endif</span>
+ }
+}
+
+
+<span class="co">/* free all elements of a tree, replacing it with TREE_EMPTY */</span>
+<span class="dt">void</span>
+treeDestroy(<span class="kw">struct</span> tree **root)
+{
+ <span class="dt">int</span> i;
+
+ <span class="kw">if</span>(*root) {
+ <span class="kw">for</span>(i = <span class="dv">0</span>; i &lt; TREE_NUM_CHILDREN; i++) {
+ treeDestroy(&amp;(*root)-&gt;child[i]);
+ }
+ free(*root);
+ *root = TREE_EMPTY;
+ }
+}
+
+
+
+<span class="co">/* insert an element into a tree pointed to by root */</span>
+<span class="dt">void</span>
+treeInsert(<span class="kw">struct</span> tree **root, <span class="dt">int</span> newElement)
+{
+ <span class="kw">struct</span> tree *e;
+
+ <span class="kw">if</span>(*root == <span class="dv">0</span>) {
+ <span class="co">/* not already there, put it in */</span>
+
+ e = malloc(<span class="kw">sizeof</span>(*e));
+ assert(e);
+
+ e-&gt;key = newElement;
+ e-&gt;child[LEFT] = e-&gt;child[RIGHT] = <span class="dv">0</span>;
+
+ *root = e;
+ } <span class="kw">else</span> <span class="kw">if</span>((*root)-&gt;key == newElement) {
+ <span class="co">/* already there, do nothing */</span>
+ <span class="kw">return</span>;
+ } <span class="kw">else</span> {
+ <span class="co">/* do this recursively so we can fix data on the way back out */</span>
+ treeInsert(&amp;(*root)-&gt;child[(*root)-&gt;key &lt; newElement], newElement);
+ }
+
+ <span class="co">/* fix the aggregate data */</span>
+ treeAggregateFix(*root);
+ treeRebalance(root);
+}
+
+<span class="co">/* return 1 if target is in tree, 0 otherwise */</span>
+<span class="dt">int</span>
+treeContains(<span class="dt">const</span> <span class="kw">struct</span> tree *t, <span class="dt">int</span> target)
+{
+ <span class="kw">while</span>(t &amp;&amp; t-&gt;key != target) {
+ t = t-&gt;child[t-&gt;key &lt; target];
+ }
+
+ <span class="kw">return</span> t != <span class="dv">0</span>;
+}
+
+<span class="co">/* delete minimum element from the tree and return its key */</span>
+<span class="co">/* do not call this on an empty tree */</span>
+<span class="dt">int</span>
+treeDeleteMin(<span class="kw">struct</span> tree **root)
+{
+ <span class="kw">struct</span> tree *toFree;
+ <span class="dt">int</span> retval;
+
+ assert(*root); <span class="co">/* can't delete min from empty tree */</span>
+
+ <span class="kw">if</span>((*root)-&gt;child[LEFT]) {
+ <span class="co">/* recurse on left subtree */</span>
+ retval = treeDeleteMin(&amp;(*root)-&gt;child[LEFT]);
+ } <span class="kw">else</span> {
+ <span class="co">/* delete the root */</span>
+ toFree = *root;
+ retval = toFree-&gt;key;
+ *root = toFree-&gt;child[RIGHT];
+ free(toFree);
+ }
+
+ <span class="co">/* fix the aggregate data */</span>
+ treeAggregateFix(*root);
+ treeRebalance(root);
+
+ <span class="kw">return</span> retval;
+}
+
+<span class="co">/* delete target from the tree */</span>
+<span class="co">/* has no effect if target is not in tree */</span>
+<span class="dt">void</span>
+treeDelete(<span class="kw">struct</span> tree **root, <span class="dt">int</span> target)
+{
+ <span class="kw">struct</span> tree *toFree;
+
+ <span class="co">/* do nothing if target not in tree */</span>
+ <span class="kw">if</span>(*root) {
+ <span class="kw">if</span>((*root)-&gt;key == target) {
+ <span class="kw">if</span>((*root)-&gt;child[RIGHT]) {
+ <span class="co">/* replace root with min value in right subtree */</span>
+ (*root)-&gt;key = treeDeleteMin(&amp;(*root)-&gt;child[RIGHT]);
+ } <span class="kw">else</span> {
+ <span class="co">/* patch out root */</span>
+ toFree = *root;
+ *root = toFree-&gt;child[LEFT];
+ free(toFree);
+ }
+ } <span class="kw">else</span> {
+ treeDelete(&amp;(*root)-&gt;child[(*root)-&gt;key &lt; target], target);
+ }
+
+ <span class="co">/* fix the aggregate data */</span>
+ treeAggregateFix(*root);
+ treeRebalance(root);
+ }
+}
+
+
+<span class="co">/* how far to indent each level of the tree */</span>
+<span class="ot">#define INDENTATION_LEVEL (2)</span>
+
+<span class="co">/* print contents of a tree, indented by depth */</span>
+<span class="dt">static</span> <span class="dt">void</span>
+treePrintIndented(<span class="dt">const</span> <span class="kw">struct</span> tree *root, <span class="dt">int</span> depth)
+{
+ <span class="dt">int</span> i;
+
+ <span class="kw">if</span>(root != <span class="dv">0</span>) {
+ treePrintIndented(root-&gt;child[LEFT], depth<span class="dv">+1</span>);
+
+ <span class="kw">for</span>(i = <span class="dv">0</span>; i &lt; INDENTATION_LEVEL*depth; i++) {
+ putchar(' ');
+ }
+ printf(<span class="st">"%d Height: %d Size: %zu (%p)</span><span class="ch">\n</span><span class="st">"</span>, root-&gt;key, root-&gt;height, root-&gt;size, (<span class="dt">void</span> *) root);
+
+ treePrintIndented(root-&gt;child[RIGHT], depth<span class="dv">+1</span>);
+ }
+}
+
+<span class="co">/* print the contents of a tree */</span>
+<span class="dt">void</span>
+treePrint(<span class="dt">const</span> <span class="kw">struct</span> tree *root)
+{
+ treePrintIndented(root, <span class="dv">0</span>);
+}
+
+size_t
+treeRank(<span class="dt">const</span> <span class="kw">struct</span> tree *t, <span class="dt">int</span> target)
+{
+ size_t rank = <span class="dv">0</span>;
+
+ <span class="kw">while</span>(t &amp;&amp; t-&gt;key != target) {
+ <span class="kw">if</span>(t-&gt;key &lt; target) {
+ <span class="co">/* go right */</span>
+ <span class="co">/* root and left subtree are all less than target */</span>
+ rank += (<span class="dv">1</span> + treeSize(t-&gt;child[LEFT]));
+ t = t-&gt;child[RIGHT];
+ } <span class="kw">else</span> {
+ <span class="co">/* go left */</span>
+ t = t-&gt;child[LEFT];
+ }
+ }
+
+ <span class="co">/* we must also count left subtree */</span>
+ <span class="kw">return</span> rank + treeSize(t-&gt;child[LEFT]);
+}
+
+<span class="dt">int</span>
+treeUnrank(<span class="dt">const</span> <span class="kw">struct</span> tree *t, size_t rank)
+{
+ size_t leftSize;
+
+ <span class="co">/* basic idea: if rank &lt; treeSize(child[LEFT]), recurse in left child */</span>
+ <span class="co">/* if it's equal, return the root */</span>
+ <span class="co">/* else recurse in right child with rank = rank - treeSize(child[LEFT]) - 1 */</span>
+ <span class="kw">while</span>(rank != (leftSize = treeSize(t-&gt;child[LEFT]))) {
+ <span class="kw">if</span>(rank &lt; leftSize) {
+ t = t-&gt;child[LEFT];
+ } <span class="kw">else</span> {
+ t = t-&gt;child[RIGHT];
+ rank -= (leftSize + <span class="dv">1</span>);
+ }
+ }
+
+ <span class="kw">return</span> t-&gt;key;
+}
+
+<span class="co">/* check that aggregate data is correct throughout the tree */</span>
+<span class="dt">void</span>
+treeSanityCheck(<span class="dt">const</span> <span class="kw">struct</span> tree *root)
+{
+ <span class="dt">int</span> i;
+
+ <span class="kw">if</span>(root) {
+ assert(root-&gt;height == treeComputeHeight(root));
+ assert(root-&gt;size == treeComputeSize(root));
+
+ assert(abs(treeHeight(root-&gt;child[LEFT]) - treeHeight(root-&gt;child[RIGHT])) &lt; <span class="dv">2</span>);
+
+ <span class="kw">for</span>(i = <span class="dv">0</span>; i &lt; TREE_NUM_CHILDREN; i++) {
+ treeSanityCheck(root-&gt;child[i]);
+ }
+ }
+}
+
+<span class="ot">#ifdef TEST_MAIN</span>
+<span class="dt">int</span>
+main(<span class="dt">int</span> argc, <span class="dt">char</span> **argv)
+{
+ <span class="dt">int</span> key;
+ <span class="dt">int</span> i;
+ <span class="dt">const</span> <span class="dt">int</span> n = <span class="dv">10</span>;
+ <span class="dt">const</span> <span class="dt">int</span> randRange = <span class="dv">1000</span>;
+ <span class="dt">const</span> <span class="dt">int</span> randTrials = <span class="dv">10000</span>;
+ <span class="kw">struct</span> tree *root = TREE_EMPTY;
+
+ <span class="kw">if</span>(argc != <span class="dv">1</span>) {
+ fprintf(stderr, <span class="st">"Usage: %s</span><span class="ch">\n</span><span class="st">"</span>, argv[<span class="dv">0</span>]);
+ <span class="kw">return</span> <span class="dv">1</span>;
+ }
+
+ <span class="co">/* original test */</span>
+ <span class="kw">for</span>(i = <span class="dv">0</span>; i &lt; n; i++) {
+ assert(!treeContains(root, i));
+ treeInsert(&amp;root, i);
+ assert(treeContains(root, i));
+ treeSanityCheck(root);
+<span class="ot">#ifdef PRINT_AFTER_OPERATIONS</span>
+ treePrint(root);
+ puts(<span class="st">"---"</span>);
+<span class="ot">#endif</span>
+ }
+
+ <span class="co">/* check ranks */</span>
+ <span class="kw">for</span>(i = <span class="dv">0</span>; i &lt; n; i++) {
+ assert(treeRank(root, i) == i);
+ assert(treeUnrank(root, i) == i);
+ }
+
+ treeSanityCheck(root);
+
+ <span class="co">/* now delete everything */</span>
+ <span class="kw">for</span>(i = <span class="dv">0</span>; i &lt; n; i++) {
+ assert(treeContains(root, i));
+ treeDelete(&amp;root, i);
+ assert(!treeContains(root, i));
+ treeSanityCheck(root);
+<span class="ot">#ifdef PRINT_AFTER_OPERATIONS</span>
+ treePrint(root);
+ puts(<span class="st">"---"</span>);
+<span class="ot">#endif</span>
+ }
+
+ treeSanityCheck(root);
+ treeDestroy(&amp;root);
+
+ <span class="co">/* random test */</span>
+ srand(<span class="dv">1</span>);
+
+ <span class="kw">for</span>(i = <span class="dv">0</span>; i &lt; randTrials; i++) {
+ treeInsert(&amp;root, rand() % randRange);
+ treeDelete(&amp;root, rand() % randRange);
+ }
+
+ treeSanityCheck(root);
+ treeDestroy(&amp;root);
+
+<span class="ot">#ifdef TEST_USE_STDIN</span>
+ <span class="kw">while</span>(scanf(<span class="st">"%d"</span>, &amp;key) == <span class="dv">1</span>) {
+ <span class="co">/* insert if positive, delete if negative */</span>
+ <span class="kw">if</span>(key &gt; <span class="dv">0</span>) {
+ treeInsert(&amp;root, key);
+ assert(treeContains(root, key));
+ } <span class="kw">else</span> <span class="kw">if</span>(key &lt; <span class="dv">0</span>) {
+ treeDelete(&amp;root, -key);
+ assert(!treeContains(root, key));
+ }
+ <span class="co">/* else ignore 0 */</span>
+
+<span class="ot">#ifdef PRINT_AFTER_OPERATIONS</span>
+ treePrint(root);
+ puts(<span class="st">"---"</span>);
+<span class="ot">#endif</span>
+ }
+
+ treeSanityCheck(root);
+
+ treeDestroy(&amp;root);
+<span class="ot">#endif </span><span class="co">/* TEST_USE_STDIN */</span>
+ <span class="kw">return</span> <span class="dv">0</span>;
+}
+<span class="ot">#endif </span><span class="co">/* TEST_MAIN */</span></code></pre></div>
+<a href="http://cs.yale.edu/homes/aspnes/classes/223/examples/trees/AVL/tree.c" class="uri">examples/trees/AVL/tree.c</a>
+</div>
+<p>This <a href="http://cs.yale.edu/homes/aspnes/classes/223/examples/trees/AVL/Makefile">Makefile</a> will compile and run some demo code in <code>tree.c</code> if run with <code>make test</code>.</p>
+<p>(An older implementation can be found in the directory <a href="http://cs.yale.edu/homes/aspnes/classes/223/examples/trees/oldAvlTree" class="uri">examples/trees/oldAvlTree</a>.</p>
+<h3 id="A2.2BIBM-3_trees"><span class="header-section-number">5.11.3</span> 2–3 trees</h3>
+<p>An early branch in the evolution of balanced trees was the 2–3 tree.
+Here all paths have the same length, but internal nodes have either 2 or
+ 3 children. So a 2–3 tree with height <span class="math inline"><em>k</em></span> has between <span class="math inline">2<sup><em>k</em></sup></span> and <span class="math inline">3<sup><em>k</em></sup></span> leaves and a comparable number of internal nodes. The maximum path length in a tree with <span class="math inline"><em>n</em></span> nodes is at most <span class="math inline">⌈lg<em>n</em>⌉</span>, as in a perfectly balanced binary tree.</p>
+<p>An internal node in a 2–3 tree holds one key if it has two children
+(including two nil pointers) and two if it has three children. A search
+that reaches a three-child node must compare the target with both keys
+to decide which of the three subtrees to recurse into. As in binary
+trees, these comparisons take constant time, so we can search a 2–3 tree
+ in <span class="math inline"><em>O</em>(log<em>n</em>)</span> time.</p>
+<p>Insertion is done by expanding leaf nodes. This may cause a leaf to
+split when it acquires a third key. When a leaf splits, it becomes two
+one-key nodes and the middle key moves up into its parent. This may
+cause further splits up the ancestor chain; the tree grows in height by
+adding a new root when the old root splits. In practice only a small
+number of splits are needed for most insertions, but even in the worst
+case this entire process takes <span class="math inline"><em>O</em>(log<em>n</em>)</span> time.</p>
+<p>It follows that 2–3 trees have the same performance as AVL trees.
+Conceptually, they are simpler, but having to write separate cases for
+2-child and 3-child nodes doubles the size of most code that works on
+2–3 trees. The real significance of 2–3 trees is as a precursor to two
+other kinds of trees, the <em>red-black tree</em> and the <em>B-tree</em>.</p>
+<h3 id="redBlackTrees"><span class="header-section-number">5.11.4</span> Red-black trees</h3>
+<p>A red-black tree is a 2–3–4 tree (i.e. all nodes have 2, 3, or 4
+children and 1, 2, or 3 internal keys) where each node is represented by
+ a little binary tree with a black root and zero, one, or two red
+extender nodes as follows:</p>
+<div class="figure">
+<img src="data:image/png;base64,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" title="red-black nodes" alt="redblacknodes.png">
+<p class="caption">redblacknodes.png</p>
+</div>
+<p>The invariant for a red-black tree is that</p>
+<ol style="list-style-type: decimal">
+<li>No two red nodes are adjacent.</li>
+<li>Every path contains the same number of black nodes.</li>
+</ol>
+<p>For technical reasons, we include the null pointers at the bottom of
+the tree as black nodes; this has no effect on the invariant, but
+simplifies the description of the rebalancing procedure.</p>
+<p>From the invariant it follows that every path has between <span class="math inline"><em>k</em></span> and <span class="math inline">2<em>k</em></span> nodes, where <span class="math inline"><em>k</em></span> is the <em>black-height</em>, the common number of black nodes on each path. From this we can prove that the height of the tree is <span class="math inline"><em>O</em>(log<em>n</em>)</span>.</p>
+<p>Searching in a red-black tree is identical to searching in any other
+binary search tree; we simply ignore the color bit on each node. So
+search takes <span class="math inline"><em>O</em>(log<em>n</em>)</span>
+time. For insertions, we use the standard binary search tree insertion
+algorithm, and insert the new node as a red node. This may violate the
+first part of the invariant (it doesn't violate the second because it
+doesn't change the number of black nodes on any path). In this case we
+need to fix up the constraint by recoloring nodes and possibly
+performing a single or double rotation.</p>
+<div class="figure">
+<img src="data:image/png;base64,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" title="Rebalancing a red-black tree" alt="redblackrebalance.png">
+<p class="caption">redblackrebalance.png</p>
+</div>
+<p>Which operations we need to do depend on the color of the new node's
+uncle. If the uncle is red, we can recolor the node's parent, uncle, and
+ grandparent and get rid of the double-red edge between the new node and
+ its parent without changing the number of black nodes on any path. In
+this case, the grandparent becomes red, which may create a new
+double-red edge which must be fixed recursively. Thus up to <span class="math inline"><em>O</em>(log<em>n</em>)</span> such recolorings may occur at a total cost of <span class="math inline"><em>O</em>(log<em>n</em>)</span>.</p>
+<p>If the uncle is black (which includes the case where the uncle is a
+null pointer), a rotation (possibly a double rotation) and recoloring is
+ necessary. In this case (depicted at the bottom of the picture above),
+the new grandparent is always black, so there are no more double-red
+edges. So at most two rotations occur after any insertion.</p>
+<p>Deletion is more complicated but can also be done in <span class="math inline"><em>O</em>(log<em>n</em>)</span> recolorings and <span class="math inline"><em>O</em>(1)</span>
+ (in this case up to 3) rotations. Because deletion is simpler in
+red-black trees than in AVL trees, and because operations on red-black
+trees tend to have slightly smaller constants than corresponding
+operation on AVL trees, red-black trees are more often used that AVL
+trees in practice.</p>
+<h3 id="B-trees"><span class="header-section-number">5.11.5</span> B-trees</h3>
+<p>Neither is used as much as a B-tree, a specialized data structure
+optimized for storage systems where the cost of reading or writing a
+large block (of typically 4096 or 8192 bytes) is no greater than the
+cost of reading or writing a single bit. Such systems include typical
+disk drives, where the disk drive has to spend so long finding data on
+disk that it tries to amortize the huge (tens of millions of CPU clock
+cycles) seek cost over many returned bytes.</p>
+<p>A B-tree is a generalization of a 2–3 tree where each node has between <span class="math inline"><em>M</em>/2</span> and <span class="math inline"><em>M</em> − 1</span> children, where <span class="math inline"><em>M</em></span> is some large constant chosen so that a node (including up to <span class="math inline"><em>M</em> − 1</span> pointers and up to <span class="math inline"><em>M</em> − 2</span> keys) will just fit inside a single block. When a node would otherwise end up with <span class="math inline"><em>M</em></span> children, it splits into two nodes with <span class="math inline"><em>M</em>/2</span>
+ children each, and moves its middle key up into its parent. As in 2–3
+trees this may eventually require the root to split and a new root to be
+ created; in practice, <span class="math inline"><em>M</em></span> is often large enough that a small fixed height is enough to span as much data as the storage system is capable of holding.</p>
+<p>Searches in B-trees require looking through <span class="math inline">log<sub><em>M</em></sub><em>n</em></span> nodes, at a cost of <span class="math inline"><em>O</em>(<em>M</em>)</span> time per node. If <span class="math inline"><em>M</em></span> is a constant the total time is asymptotically <span class="math inline"><em>O</em>(log<em>n</em>)</span>. But the reason for using B-trees is that the <span class="math inline"><em>O</em>(<em>M</em>)</span>
+ cost of reading a block is trivial compare to the much larger constant
+time to find the block on the disk; and so it is better to minimize the
+number of disk accesses (by making <span class="math inline"><em>M</em></span> large) than reduce the CPU time.</p>
+<h3 id="splayTrees"><span class="header-section-number">5.11.6</span> Splay trees</h3>
+<p>Yet another approach to balancing is to do it dynamically. Splay trees, described by Sleator and Tarjan in the paper "<a href="https://www.cs.cmu.edu/%7Esleator/papers/self-adjusting.pdf">Self-adjusting binary search trees</a>"
+ (JACM 32(3):652–686, July 1985) are binary search trees in which every
+search operation rotates the target to the root. If this is done
+correctly, the <strong>amortized cost</strong> of each tree operation is <span class="math inline"><em>O</em>(log<em>n</em>)</span>, although particular rare operations might take as much as <span class="math inline"><em>O</em>(<em>n</em>)</span>
+ time. Splay trees require no extra space because they store no
+balancing information; however, the constant factors on searches can be
+larger because every search requires restructuring the tree. For some
+applications this additional cost is balanced by the splay tree's
+ability to adapt to data access patterns; if some elements of the tree
+are hit more often than others, these elements will tend to migrate to
+the top, and the cost of a typical search will drop to <span class="math inline"><em>O</em>(log<em>m</em>)</span>, where <span class="math inline"><em>m</em></span> is the size of the "working set" of frequently-accessed elements.</p>
+<h4 id="how-splaying-works"><span class="header-section-number">5.11.6.1</span> How splaying works</h4>
+<p>The basic idea of a splay operation is that we move some particular
+node to the root of the tree, using a sequence of rotations that tends
+to fix the balance of the tree if the node starts out very deep. So
+while we might occasionally drive the tree into a state that is highly
+unbalanced, as soon as we try to exploit this by searching for a deep
+node, we'll start balancing the tree so that we can't collect too much
+additional cost. In fact, in order to set up the bad state in the first
+place we will have to do a lot of cheap splaying operations: the missing
+ cost of these cheap splays ends up paying for the cost of the later
+expensive search.</p>
+<p>Splaying a node to the root involves performing rotations two layers
+at a time. There are two main cases, depending on whether the node's
+parent and grandparent are in the same direction (zig-zig) or in
+opposite directions (zig-zag), plus a third case when the node is only
+one step away from the root. At each step, we pick one of these cases
+and apply it, until the target node reaches the root of the tree.</p>
+<p>This is probably best understood by looking at a figure from the original paper:</p>
+<p><img src="data:image/png;base64,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" alt="Figure 3 from (Sleator and Tarjan, 1985)"><br>
+The bottom two cases are the ones we will do most of the time.</p>
+<p>Just looking at the picture, it doesn't seem like zig-zig will
+improve balance much. But if we have a long path made up of zig-zig
+cases, each operation will push at least one node off of this path,
+cutting the length of the path in half. So the rebalancing happens as
+much because we are pushing nodes off of the long path as because the
+specific rotation operations improve things locally.</p>
+<h4 id="splayTreeAnalysis"><span class="header-section-number">5.11.6.2</span> Analysis</h4>
+<p>Sleator and Tarjan show that any sequence of <span class="math inline"><em>m</em></span> splay operations on an <span class="math inline"><em>n</em></span>-node splay tree has total cost at most <span class="math inline"><em>O</em>((<em>m</em> + <em>n</em>)log<em>n</em> + <em>m</em>)</span>. For large <span class="math inline"><em>m</em></span> (at least linear in <span class="math inline"><em>n</em></span>), the <span class="math inline"><em>O</em>(<em>m</em>log<em>n</em>)</span> term dominates, giving an amortized cost per operation of <span class="math inline"><em>O</em>(log<em>n</em>)</span>,
+ the same as we get from any balanced binary tree. This immediately
+gives a bound on search costs, because the cost of plunging down the
+tree to find the node we are looking for is proportional to the cost of
+splaying it up to the root.</p>
+<p>Splay trees have a useful "caching" property in that they pull
+frequently-accessed nodes to the to the top and push
+less-frequently-accessed nodes down. The authors show that if only <span class="math inline"><em>k</em></span> of the <span class="math inline"><em>n</em></span> nodes are accessed, the long-run amortized cost per search drops to <span class="math inline"><em>O</em>(log<em>k</em>)</span>.
+ For more general access sequences, it is conjectured that the cost to
+perform a sufficiently long sequence of searches using a splay tree is
+in fact optimal up to a constant factor (the "dynamic optimality
+conjecture"), but no one has yet been able to prove this conjecture (or
+provide a counterexample).<a href="#fn21" class="footnoteRef" id="fnref21"><sup>21</sup></a></p>
+<h4 id="other-operations"><span class="header-section-number">5.11.6.3</span> Other operations</h4>
+<p>A search operation consists of a standard binary tree search followed
+ by splaying the target node to the root (if present) or the last
+non-null node we reached to the root instead (if not).</p>
+<p>Insertion and deletion are built on top of procedures to split and join trees.</p>
+<p>A split divides a single splay tree into two splay trees, consisting of all elements less than or equal to some value <span class="math inline"><em>x</em></span> and all elements greater than <span class="math inline"><em>x</em></span>. This is done by searching for <span class="math inline"><em>x</em></span>, which brings either <span class="math inline"><em>x</em></span> or the first element less than or greater than <span class="math inline"><em>x</em></span>
+ to the root, then breaking the link between the root and its left or
+right child depending on whether the root should go in the right or left
+ tree.</p>
+<p>A join merges two splay trees <span class="math inline"><em>L</em></span> and <span class="math inline"><em>R</em></span>, where every element in <span class="math inline"><em>L</em></span> is less than every element in <span class="math inline"><em>R</em></span>. This involves splaying the largest element in <span class="math inline"><em>L</em></span> to the root, and then making the root of <span class="math inline"><em>R</em></span> the right child of this element.</p>
+<p>To do an insert of <span class="math inline"><em>x</em></span>, we do a split around <span class="math inline"><em>x</em></span>, then make the roots of the two trees the children of a new element holding <span class="math inline"><em>x</em></span> (unless <span class="math inline"><em>x</em></span> is already present in the tree, in which case we stop before breaking the trees apart).</p>
+<p>To do a delete of an element <span class="math inline"><em>x</em></span>, we splay <span class="math inline"><em>x</em></span> to the root, remove it, then join the two orphaned subtrees.</p>
+<p>For each operation, we are doing a constant number of splays (amortized cost <span class="math inline"><em>O</em>(log<em>n</em>)</span> each), plus <span class="math inline"><em>O</em>(1)</span>
+ additional work. A bit of work is needed to ensure that the joins and
+splits don't break the amortized cost analysis, but this is done in the
+paper, so we will sweep it under the carpet with the rest of the
+analysis.</p>
+<h4 id="top-down-splaying"><span class="header-section-number">5.11.6.4</span> Top-down splaying</h4>
+<p>There are a few remaining details that we need to deal with before
+trying to implement a splay trees. Because the splay tree could become
+very deep, we probably don't want to implement a splay recursively in a
+language like C, because we'll blow out our stack. We also have a
+problem if we are trying to rotate our target up from the bottom of
+figuring out what its ancestors are. We could solve both of these
+problems by including parent pointers in our tree, but this would add a
+lot of complexity and negate the space improvement over AVL trees of not
+ having to store heights.</p>
+<p>The solution given in the Sleator-Tarjan paper is to replace the
+bottom-up splay procedure with a top-down splay procedure that
+accomplishes the same task. The idea is that rotating a node up from the
+ bottom effectively splits the tree above it into two new left and right
+ subtrees by pushing ancestors sideways according to the zig-zig and
+zig-zag patters. But we can recognize these zig-zig and zig-zag patterns
+ from the top as well, and so we can construct these same left and right
+ subtrees from the top down instead of the bottom up. When we do this,
+instead of adding new nodes to the tops of the trees, we will be adding
+new nodes to the bottoms, as the right child of the rightmost node in
+the left tree or the left child of the rightmost node in the left tree.</p>
+<p>Here's the picture, from the original paper:</p>
+<p><img src="data:image/png;base64,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TU3J2dmZnJ2dycTEhOzt7WnNmjVUXl5OPM9TfHw8+fn5EcdxNGPGjCZd73l5eRQVFdWg0Kr/+mgHDBhACgoK5OLiQiKRiEaOHEkZGRlCeCTHcbRt2zaSSCS1vnvOnDnEcZxQr6wt0CShjYiIIAsLC/L09KSMjIx6BbaiooKKi4spJiaGDA0NqWfPni2yvPW/Invz5s0G7/v06dNaYquvr0/z58+nZcuW0RdffEHjx48nPz8/+u2335ocoVAtsj/++CO9++675OzsTB999BEFBgYysWU0S/TCRx99RAoKCjRgwADavHkzeXt704QJE+i7776jkydP1ojW8PHxIX19fbK0tGzyUtmioiKKj49vtNCGhISQvLw8ubu70/nz52nMmDGkoKBA165dI57n6eHDh6Svr092dna0detWSk1NpcLCQnr69CkFBweTlZUVmZubt3h2MJlOhhERdu/ejaSkJBgbG2PFihXQ19ev9TmJRAKe51FSUgIlJSXwPI/bt2/j7Nmz+PLLL5stTrXaXXD8+HG4u7tjyZIl6Nmz50v3CwgIQH5+Pu7du4fOnTtDJBJh7ty5ICJ888032Lp1KxQUFKCqqorKykpERUUB+DeG+IcffoCmpmaj+/vHH39g48aNMDU1haGhIe7evYt79+5h6NCh0NXVZc+6DJlw//59+Pj4IDg4GMOGDcPcuXPRu3dvlJSUIDs7W6iw8byLRVtbG56enujTpw+cnJya5H5RV1dvkstNX18fCxcuhLu7O1xdXaGnpye4hADA3Nwc8+fPR0BAANauXYtr165BU1MTubm5ePDgAZKSkuDm5gYzM7O2MydB1Li1ZTzPY8mSJQgMDATP8xCJRILfQklJCZaWlrh//76QRT05ORlisRilpaWwtraGl5cXpk+f3uwiO3To0AaJbPUxubu748mTJ0hKSoKKigqUlJTw+PFjlJWVwdHREZmZmZg4cSL+97//Cdnhz5w5gxMnTuDrr7/G999/36hsW0SE/v374/Hjx9i6dSt0dXWRkpKCY8eOYcuWLcLySwbjVUV2yZIlOHHiBN577z18//336N69+0uF8+nTp5BKpTAwMICCgkKL+rklEglKSkqgpaUlVFvIz8+HhoaGsPAgNzcXwcHBCA4Oxt27dwUtqqysRHp6OszNzbF+/XoMGzYMYrG41f30jRZaIkJiYiJu374t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ALB8+XJGjx5NQkICSUlJtGzZ8ncL7R92OhYWFvLOO+8wb948ZsyYgUqlwsPDQxCj6OhoVq5ciZeXF88//zy9e/dm+PDhyOXy33WdJ1m/f4YvWCKRIJfLhXtqbGxscszU1JT8/Hzef/99unTpwoQJE4iLi2P58uXIZDJOnz7NpUuX6N69OxYWFnz33XdcuXKlicimpqaycOFCAgMDeemll7C1tRWOL168mKKiImbOnImHhwdbt27l3LlzNDQ0cPLkSZRKJUqlkpMnT1JUVER2djb19fXY29sTFRVFVFQUI0eOJDc3l2+++abZMp49e5Zz587RvXt3nJyccHV1JSkpiStXrhAcHEzv3r05evQou3fvbnLe0aNHUalUPP/889y6dYtz587h4+NDXl4eu3btori4mFu3buHj40Pbtm25cOECNTU1ODs7k5OTQ1xcHBMnTqRFixbs3bsXlUrF8uXLMTEx4c033yQiIgKtVvvY/SYnJwt1MGTIEPz8/BgwYAAAkyZN4u7du2zdupUHDx4QFxfHhQsXyMrKQiKRkJuby8svv0xISAhXr17l22+//dVOdunSpbRo0YLTp0+zePFibt68ScuWLTE0NOTy5csUFhYSHR2Nq6sr7dq1o6CggJycHN577z0CAgKIioritdde48033+TmzZtUVlbi6+tLSUkJGRkZzJ8/n27duhEZGcmYMWOYO3cu9+/fp7S0lHPnznH16lViYmLIy8vj2rVrODs74+7ujpmZGZ06dWLQoEEkJibi5eXFunXreOutt4QOMiIigt27dzNs2DDmzJlDv379sLa2fqyc3bt3R6PREBYWRklJCZcvX+aZZ54BoGfPnpibm5Ofn09kZCSOjo5IJBJkMhmff/45CxcuxMDAgPz8fACsrKwYPHgwarWagoICjh8/jp2dHZaWlpSXl7Ns2TI6dOjAjRs3aGxsZPjw4UgkErp3705tbS33798nOjqanj170qZNm8eE6/z58xw9epRp06YxadIkunTpwr59+8jNzcXf3x8vLy+GDh362Hnp6en8+OOPTJgwgQkTJjBu3DhatmyJk5MTXbt2pby8nKysLO7evUtGRgZ5eXmkpaUxcuRILl++zM2bN0lOTqa6upqCggISEhJIT0/nxo0b9OzZ8xc77L/EdaBHqVTi6OiIk5MTiYmJGBgYYGtri62tLQqFgtu3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" alt="Figure 12 from (Sleator and Tarjan, 1985)"><br>
+To implement this, we need to keep track of the roots of the three
+trees, as well as the locations in the left and right trees where we
+will be adding new vertices. The roots we can just keep pointers to. For
+ the lower corners of the trees, it makes sense to store instead a
+pointer to the pointer location, so that we can modify the pointer in
+the tree (and then move the pointer to point to the pointer in the new
+corner). Initially, these corner pointers will just point to the left
+and right tree roots, which will start out empty.</p>
+<p>The last step (shown as Figure 12 from the paper) pastes the tree
+back together by inserting the left and right trees between the new root
+ and its children.</p>
+<h4 id="splayTreeImplementation"><span class="header-section-number">5.11.6.5</span> An implementation</h4>
+<p>Here is an implementation of a splay tree, with an interface similar to the previous <a href="#avlTreeImplementation">AVL tree implementation</a>.</p>
+<div>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"><span class="co">/*</span>
+<span class="co"> * Basic binary search tree data structure without balancing info.</span>
+<span class="co"> *</span>
+<span class="co"> * Convention: </span>
+<span class="co"> *</span>
+<span class="co"> * Operations that update a tree are passed a struct tree **,</span>
+<span class="co"> * so they can replace the argument with the return value.</span>
+<span class="co"> *</span>
+<span class="co"> * Operations that do not update the tree get a const struct tree *.</span>
+<span class="co"> */</span>
+
+<span class="ot">#define LEFT (0)</span>
+<span class="ot">#define RIGHT (1)</span>
+<span class="ot">#define TREE_NUM_CHILDREN (2)</span>
+
+<span class="kw">struct</span> tree {
+ <span class="co">/* we'll make this an array so that we can make some operations symmetric */</span>
+ <span class="kw">struct</span> tree *child[TREE_NUM_CHILDREN];
+ <span class="dt">int</span> key;
+};
+
+<span class="ot">#define TREE_EMPTY (0)</span>
+
+<span class="co">/* free all elements of a tree, replacing it with TREE_EMPTY */</span>
+<span class="dt">void</span> treeDestroy(<span class="kw">struct</span> tree **root);
+
+<span class="co">/* insert an element into a tree pointed to by root */</span>
+<span class="dt">void</span> treeInsert(<span class="kw">struct</span> tree **root, <span class="dt">int</span> newElement);
+
+<span class="co">/* return 1 if target is in tree, 0 otherwise */</span>
+<span class="co">/* we allow root to be modified to allow for self-balancing trees */</span>
+<span class="dt">int</span> treeContains(<span class="kw">struct</span> tree **root, <span class="dt">int</span> target);
+
+<span class="co">/* delete target from the tree */</span>
+<span class="co">/* has no effect if target is not in tree */</span>
+<span class="dt">void</span> treeDelete(<span class="kw">struct</span> tree **root, <span class="dt">int</span> target);
+
+<span class="co">/* pretty-print the contents of a tree */</span>
+<span class="dt">void</span> treePrint(<span class="dt">const</span> <span class="kw">struct</span> tree *root);</code></pre></div>
+<a href="http://cs.yale.edu/homes/aspnes/classes/223/examples/trees/splay/tree.h" class="uri">examples/trees/splay/tree.h</a>
+</div>
+<div>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"><span class="ot">#include &lt;stdio.h&gt;</span>
+<span class="ot">#include &lt;stdlib.h&gt;</span>
+<span class="ot">#include &lt;assert.h&gt;</span>
+<span class="ot">#include &lt;limits.h&gt;</span>
+
+<span class="ot">#include "tree.h"</span>
+
+<span class="co">/* free all elements of a tree, replacing it with TREE_EMPTY */</span>
+<span class="dt">void</span>
+treeDestroy(<span class="kw">struct</span> tree **root)
+{
+ <span class="co">/* we want to avoid doing this recursively, because the tree might be deep */</span>
+ <span class="co">/* so we will repeatedly delete the root until the tree is empty */</span>
+ <span class="kw">while</span>(*root) {
+ treeDelete(root, (*root)-&gt;key);
+ }
+}
+
+<span class="co">/* rotate child in given direction to root */</span>
+<span class="dt">void</span>
+treeRotate(<span class="kw">struct</span> tree **root, <span class="dt">int</span> direction)
+{
+ <span class="kw">struct</span> tree *x;
+ <span class="kw">struct</span> tree *y;
+ <span class="kw">struct</span> tree *b;
+
+ <span class="co">/*</span>
+<span class="co"> * y x </span>
+<span class="co"> * / \ / \</span>
+<span class="co"> * x C &lt;=&gt; A y</span>
+<span class="co"> * / \ / \</span>
+<span class="co"> * A B B C</span>
+<span class="co"> */</span>
+
+ y = *root; assert(y);
+ x = y-&gt;child[direction]; assert(x);
+ b = x-&gt;child[!direction];
+
+ <span class="co">/* do the rotation */</span>
+ *root = x;
+ x-&gt;child[!direction] = y;
+ y-&gt;child[direction] = b;
+}
+
+<span class="co">/* link operations for top-down splay */</span>
+<span class="co">/* this pastes a node in as !d-most node in subtree on side d */</span>
+<span class="dt">static</span> <span class="kw">inline</span> <span class="dt">void</span>
+treeLink(<span class="kw">struct</span> tree ***hook, <span class="dt">int</span> d, <span class="kw">struct</span> tree *node)
+{
+ *hook[d] = node;
+ <span class="co">/* strictly speaking we don't need to do this, but it allows printing the partial trees */</span>
+ node-&gt;child[!d] = <span class="dv">0</span>;
+ hook[d] = &amp;node-&gt;child[!d];
+}
+
+<span class="co">/* splay last element on path to target to root */</span>
+<span class="dt">static</span> <span class="dt">void</span>
+treeSplay(<span class="kw">struct</span> tree **root, <span class="dt">int</span> target)
+{
+ <span class="kw">struct</span> tree *t;
+ <span class="kw">struct</span> tree *child;
+ <span class="kw">struct</span> tree *grandchild;
+ <span class="kw">struct</span> tree *top[TREE_NUM_CHILDREN]; <span class="co">/* accumulator trees that will become subtrees of new root */</span>
+ <span class="kw">struct</span> tree **hook[TREE_NUM_CHILDREN]; <span class="co">/* where to link new elements into accumulator trees */</span>
+ <span class="dt">int</span> d;
+ <span class="dt">int</span> dChild; <span class="co">/* direction of child */</span>
+ <span class="dt">int</span> dGrandchild; <span class="co">/* direction of grandchild */</span>
+
+ <span class="co">/* we don't need to keep following this pointer, we'll just fix it at the end */</span>
+ t = *root;
+
+ <span class="co">/* don't do anything to an empty tree */</span>
+ <span class="kw">if</span>(t == <span class="dv">0</span>) { <span class="kw">return</span>; }
+
+ <span class="co">/* ok, tree is not empty, start chopping it up */</span>
+ <span class="kw">for</span>(d = <span class="dv">0</span>; d &lt; TREE_NUM_CHILDREN; d++) {
+ top[d] = <span class="dv">0</span>;
+ hook[d] = &amp;top[d];
+ }
+
+ <span class="co">/* keep going until we hit the key or we would hit a null pointer in the child */</span>
+ <span class="kw">while</span>(t-&gt;key != target &amp;&amp; (child = t-&gt;child[dChild = t-&gt;key &lt; target]) != <span class="dv">0</span>) {
+ <span class="co">/* child is not null */</span>
+ grandchild = child-&gt;child[dGrandchild = child-&gt;key &lt; target];
+
+<span class="ot">#ifdef DEBUG_SPLAY</span>
+ treePrint(top[<span class="dv">0</span>]);
+ puts(<span class="st">"---"</span>);
+ treePrint(t);
+ puts(<span class="st">"---"</span>);
+ treePrint(top[<span class="dv">1</span>]);
+ puts(<span class="st">"==="</span>);
+<span class="ot">#endif</span>
+
+ <span class="kw">if</span>(grandchild == <span class="dv">0</span> || child-&gt;key == target) {
+ <span class="co">/* zig case; paste root into opposite-side hook */</span>
+ treeLink(hook, !dChild, t);
+ t = child;
+ <span class="co">/* we can break because we know we will hit child == 0 next */</span>
+ <span class="kw">break</span>;
+ } <span class="kw">else</span> <span class="kw">if</span>(dChild == dGrandchild) {
+ <span class="co">/* zig-zig case */</span>
+ <span class="co">/* rotate and then hook up child */</span>
+ <span class="co">/* grandChild becomes new root */</span>
+ treeRotate(&amp;t, dChild);
+ treeLink(hook, !dChild, child);
+ t = grandchild;
+ } <span class="kw">else</span> {
+ <span class="co">/* zig-zag case */</span>
+ <span class="co">/* root goes to !dChild, child goes to dChild, grandchild goes to root */</span>
+ treeLink(hook, !dChild, t);
+ treeLink(hook, dChild, child);
+ t = grandchild;
+ }
+ }
+
+ <span class="co">/* now reassemble the tree */</span>
+ <span class="co">/* t's children go in hooks, top nodes become t's new children */</span>
+ <span class="kw">for</span>(d = <span class="dv">0</span>; d &lt; TREE_NUM_CHILDREN; d++) {
+ *hook[d] = t-&gt;child[d];
+ t-&gt;child[d] = top[d];
+ }
+
+ <span class="co">/* and put t back in *root */</span>
+ *root = t;
+}
+
+<span class="co">/* return 1 if target is in tree, 0 otherwise */</span>
+<span class="dt">int</span>
+treeContains(<span class="kw">struct</span> tree **root, <span class="dt">int</span> target)
+{
+ treeSplay(root, target);
+ <span class="kw">return</span> *root != <span class="dv">0</span> &amp;&amp; (*root)-&gt;key == target;
+}
+
+
+<span class="co">/* insert an element into a tree pointed to by root */</span>
+<span class="dt">void</span>
+treeInsert(<span class="kw">struct</span> tree **root, <span class="dt">int</span> newElement)
+{
+ <span class="kw">struct</span> tree *e;
+ <span class="kw">struct</span> tree *t;
+ <span class="dt">int</span> d; <span class="co">/* which side of e to put old root on */</span>
+
+ treeSplay(root, newElement);
+
+ t = *root;
+
+ <span class="co">/* skip if already present */</span>
+ <span class="kw">if</span>(t &amp;&amp; t-&gt;key == newElement) { <span class="kw">return</span>; }
+
+ <span class="co">/* otherwise split the tree */</span>
+ e = malloc(<span class="kw">sizeof</span>(*e));
+ assert(e);
+
+ e-&gt;key = newElement;
+
+ <span class="kw">if</span>(t == <span class="dv">0</span>) {
+ e-&gt;child[LEFT] = e-&gt;child[RIGHT] = <span class="dv">0</span>;
+ } <span class="kw">else</span> {
+ <span class="co">/* split tree and put e on top */</span>
+ <span class="co">/* we know t is closest to e, so we don't have to move anything else */</span>
+ d = (*root)-&gt;key &gt; newElement;
+ e-&gt;child[d] = t;
+ e-&gt;child[!d] = t-&gt;child[!d];
+ t-&gt;child[!d] = <span class="dv">0</span>;
+ }
+
+ <span class="co">/* either way we stuff e in *root */</span>
+ *root = e;
+}
+
+<span class="co">/* delete target from the tree */</span>
+<span class="co">/* has no effect if target is not in tree */</span>
+<span class="dt">void</span>
+treeDelete(<span class="kw">struct</span> tree **root, <span class="dt">int</span> target)
+{
+ <span class="kw">struct</span> tree *left;
+ <span class="kw">struct</span> tree *right;
+
+ treeSplay(root, target);
+
+ <span class="kw">if</span>(*root &amp;&amp; (*root)-&gt;key == target) {
+ <span class="co">/* save pointers to kids */</span>
+ left = (*root)-&gt;child[LEFT];
+ right = (*root)-&gt;child[RIGHT];
+
+ <span class="co">/* free the old root */</span>
+ free(*root);
+
+ <span class="co">/* if left is empty, just return right */</span>
+ <span class="kw">if</span>(left == <span class="dv">0</span>) {
+ *root = right;
+ } <span class="kw">else</span> {
+ <span class="co">/* first splay max element in left to top */</span>
+ treeSplay(&amp;left, INT_MAX);
+
+ <span class="co">/* now paste in right subtree */</span>
+ left-&gt;child[RIGHT] = right;
+
+ <span class="co">/* return left */</span>
+ *root = left;
+ }
+ }
+}
+
+<span class="co">/* how far to indent each level of the tree */</span>
+<span class="ot">#define INDENTATION_LEVEL (2)</span>
+
+<span class="co">/* print contents of a tree, indented by depth */</span>
+<span class="dt">static</span> <span class="dt">void</span>
+treePrintIndented(<span class="dt">const</span> <span class="kw">struct</span> tree *root, <span class="dt">int</span> depth)
+{
+ <span class="dt">int</span> i;
+
+ <span class="kw">if</span>(root != <span class="dv">0</span>) {
+ treePrintIndented(root-&gt;child[LEFT], depth<span class="dv">+1</span>);
+
+ <span class="kw">for</span>(i = <span class="dv">0</span>; i &lt; INDENTATION_LEVEL*depth; i++) {
+ putchar(' ');
+ }
+ printf(<span class="st">"%d (%p)</span><span class="ch">\n</span><span class="st">"</span>, root-&gt;key, (<span class="dt">void</span> *) root);
+
+ treePrintIndented(root-&gt;child[RIGHT], depth<span class="dv">+1</span>);
+ }
+}
+
+<span class="co">/* print the contents of a tree */</span>
+<span class="dt">void</span>
+treePrint(<span class="dt">const</span> <span class="kw">struct</span> tree *root)
+{
+ treePrintIndented(root, <span class="dv">0</span>);
+}
+
+
+<span class="ot">#ifdef TEST_MAIN</span>
+<span class="dt">int</span>
+main(<span class="dt">int</span> argc, <span class="dt">char</span> **argv)
+{
+ <span class="dt">int</span> i;
+ <span class="dt">const</span> <span class="dt">int</span> n = <span class="dv">10</span>;
+ <span class="kw">struct</span> tree *root = TREE_EMPTY;
+
+ <span class="kw">if</span>(argc != <span class="dv">1</span>) {
+ fprintf(stderr, <span class="st">"Usage: %s</span><span class="ch">\n</span><span class="st">"</span>, argv[<span class="dv">0</span>]);
+ <span class="kw">return</span> <span class="dv">1</span>;
+ }
+
+ <span class="kw">for</span>(i = <span class="dv">0</span>; i &lt; n; i++) {
+ assert(!treeContains(&amp;root, i));
+ treeInsert(&amp;root, i);
+ assert(treeContains(&amp;root, i));
+ treePrint(root);
+ puts(<span class="st">"==="</span>);
+ }
+
+ <span class="co">/* now delete everything */</span>
+ <span class="kw">for</span>(i = <span class="dv">0</span>; i &lt; n; i++) {
+ assert(treeContains(&amp;root, i));
+ treeDelete(&amp;root, i);
+ assert(!treeContains(&amp;root, i));
+ treePrint(root);
+ puts(<span class="st">"==="</span>);
+ }
+
+ treeDestroy(&amp;root);
+
+ <span class="kw">return</span> <span class="dv">0</span>;
+}
+<span class="ot">#endif</span></code></pre></div>
+<a href="http://cs.yale.edu/homes/aspnes/classes/223/examples/trees/splay/tree.c" class="uri">examples/trees/splay/tree.c</a>
+</div>
+<p><a href="http://cs.yale.edu/homes/aspnes/classes/223/examples/trees/splay/Makefile">Makefile</a>. The file <a href="http://cs.yale.edu/homes/aspnes/classes/223/examples/trees/splay/speedTest.c">speedTest.c</a>
+ can be used to do a simple test of the efficiency of inserting many
+random elements. On my machine, the splay tree version is about 10%
+slower than the AVL tree for this test on a million elements. This
+probably indicates a bigger slowdown for <code>treeInsert</code> itself, because some of the time will be spent in <code>rand</code> and <code>treeDestroy</code>, but I was too lazy to actually test this further.</p>
+<h4 id="splayTreesMoreInformation"><span class="header-section-number">5.11.6.6</span> More information</h4>
+<p>For more details on splay trees, see <a href="http://dl.acm.org/citation.cfm?id=3835">the original paper</a>, or any number of demos, animations, and other descriptions that can be found via <a href="http://www.google.com/search?q=splay+trees">Google</a>.</p>
+<h3 id="scapegoatTrees"><span class="header-section-number">5.11.7</span> Scapegoat trees</h3>
+<p><strong>Scapegoat trees</strong> are another amortized balanced tree
+data structure. The idea of a scapegoat tree is that if we ever find
+ourselves doing an insert at the end of a path that is too long, we can
+find some subtree rooted at a node along this path that is particularly
+imbalanced and rebalance it all at once at a cost of <span class="math inline"><em>O</em>(<em>k</em>)</span> where <span class="math inline"><em>k</em></span> is the size of the subtree. These were shown by Galperin and Rivest (SODA 1993) to give <span class="math inline"><em>O</em>(log<em>n</em>)</span> amortized cost for inserts, while guaranteeing <span class="math inline"><em>O</em>(log<em>n</em>)</span> depth, so that inserts also run in <span class="math inline"><em>O</em>(log<em>n</em>)</span>
+ worst-case time; they also came up with the name "scapegoat tree",
+although it turns out the same data structure had previously been
+published by Andersson in 1989. Unlike splay trees, scapegoat trees do
+not require modifying the tree during a search, and unlike AVL trees,
+scapegoat trees do not require tracking any information in nodes
+(although they do require tracking the total size of the tree and, to
+allow for rebalancing after many deletes, the maximum size of the tree
+since the last time the entire tree was rebalanced).</p>
+<p>Unfortunately, scapegoat trees are not very fast, so one is probably better off with an AVL tree.</p>
+<h3 id="skip-lists"><span class="header-section-number">5.11.8</span> Skip lists</h3>
+<p><a href="#skipLists">Skip lists</a> are yet another balanced tree
+data structure, where the tree is disguised as a tower of linked lists.
+Since they use randomization for balance, we describe them with other <a href="#randomizedDataStructures">randomized data structures</a>.</p>
+<h3 id="treeImplementations"><span class="header-section-number">5.11.9</span> Implementations</h3>
+<p>AVL trees and red-black trees have been implemented for every
+reasonable programming language you've ever heard of. For C
+implementations, a good place to start is at <a href="http://adtinfo.org/" class="uri">http://adtinfo.org/</a>.</p>
+<h2 id="graphs"><span class="header-section-number">5.12</span> Graphs</h2>
+<p>These are notes on implementing <strong>graphs</strong> and graph algorithms in C.</p>
+<h3 id="graphDefinitions"><span class="header-section-number">5.12.1</span> Basic definitions</h3>
+<p>A <strong>graph</strong> consists of a set of <strong>nodes</strong> or <strong>vertices</strong> together with a set of <strong>edges</strong> or <strong>arcs</strong> where each edge joins two vertices. Unless otherwise specified, a graph is <strong>undirected</strong>: each edge is an unordered pair <span class="math inline">{<em>u</em>, <em>v</em>}</span>
+ of vertices, and we don't regard either of the two vertices as having a
+ distinct role from the other. However, it is more common in computing
+to consider <strong>directed graphs</strong> or <strong>digraphs</strong> in which edges are <em>ordered</em> pairs <span class="math inline">(<em>u</em>, <em>v</em>)</span>; here the vertex <span class="math inline"><em>u</em></span> is the <strong>source</strong> of the edge and vertex v is the <strong>sink</strong> or <strong>target</strong>
+ of the edge. Directed edges are usually drawn as arrows and undirected
+edges as curves or line segments. It is always possible to represent an
+undirected graph as a directed graph where each undirected edge <span class="math inline">{<em>u</em>, <em>v</em>}</span> becomes two oppositely directed edges <span class="math inline">(<em>u</em>, <em>v</em>)</span> and <span class="math inline">(<em>v</em>, <em>u</em>)</span>.</p>
+<p>Here is an example of a small graph, drawn using <a href="http://cs.yale.edu/homes/aspnes/classes/223/images/graphs/graph.dot">this file</a> using the <code>circo</code> program from the <a href="http://graphviz.org/">GraphViz</a> library:</p>
+<div class="figure">
+<img src="data:image/png;base64,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" alt="A graph">
+<p class="caption">A graph</p>
+</div>
+<p>Here is a similar directed graph, drawn using <a href="http://cs.yale.edu/homes/aspnes/classes/223/images/graphs/digraph.dot">this file</a>:</p>
+<div class="figure">
+<img src="data:image/png;base64,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" alt="A directed graph">
+<p class="caption">A directed graph</p>
+</div>
+<p>Given an edge <span class="math inline">(<em>u</em>, <em>v</em>)</span>, the vertices <span class="math inline"><em>u</em></span> and <span class="math inline"><em>v</em></span> are said to be <strong>incident</strong> to the edge and <strong>adjacent</strong> to each other. The number of vertices adjacent to a given vertex <span class="math inline"><em>u</em></span> is the <strong>degree</strong> of <span class="math inline"><em>u</em></span>; this can be divided into the <strong>out-degree</strong> (number of vertices <span class="math inline"><em>v</em></span> such that <span class="math inline">(<em>u</em>, <em>v</em>)</span> is an edge) and the <strong>in-degree</strong> (number of vertices <span class="math inline"><em>v</em></span> such that <span class="math inline">(<em>v</em>, <em>u</em>)</span> is an edge). A vertex <span class="math inline"><em>v</em></span> adjacent to <span class="math inline"><em>u</em></span> is called a <strong>neighbor</strong> of <span class="math inline"><em>u</em></span>, and (in a directed graph) is a <strong>predecessor</strong> of <span class="math inline"><em>u</em></span> if <span class="math inline">(<em>v</em>, <em>u</em>)</span> is an edge and a <strong>successor</strong> of <span class="math inline"><em>u</em></span> if <span class="math inline">(<em>u</em>, <em>v</em>)</span> is an edge. We will allow a node to be its own predecessor and successor.</p>
+<h3 id="Why_graphs_are_useful"><span class="header-section-number">5.12.2</span> Why graphs are useful</h3>
+<p>Graphs can be used to model any situation where we have things that
+are related to each other in pairs; for example, all of the following
+can be represented by graphs:</p>
+<dl>
+<dt>Family trees</dt>
+<dd>Nodes are members, with an edge from each parent to each of their children.
+</dd>
+<dt>Transportation networks</dt>
+<dd>Nodes are airports, intersections, ports, etc. Edges are airline flights, one-way roads, shipping routes, etc.
+</dd>
+<dt>Assignments</dt>
+<dd>Suppose we are assigning classes to classrooms. Let each node be
+either a class or a classroom, and put an edge from a class to a
+classroom if the class is assigned to that room. This is an example of a
+ <strong>bipartite graph</strong>, where the nodes can be divided into two sets <span class="math inline"><em>S</em></span> and <span class="math inline"><em>T</em></span> and all edges go from <span class="math inline"><em>S</em></span> to <span class="math inline"><em>T</em></span>.
+</dd>
+</dl>
+<h3 id="Operations_on_graphs"><span class="header-section-number">5.12.3</span> Operations on graphs</h3>
+<p>What would we like to do to graphs? Generally, we first have to build
+ a graph by starting with a set of nodes and adding in any edges we
+need, and then we want to extract information from it, such as "Is this
+graph connected?", "What is the shortest path in this graph from <span class="math inline"><em>s</em></span> to <span class="math inline"><em>t</em></span>?",
+ or "How many edges can I remove from this graph before some nodes
+become unreachable from other nodes?" There are standard algorithms for
+answering all of these questions; the information these algorithms need
+is typically (a) given a vertex <span class="math inline"><em>u</em></span>, what successors does it have; and sometimes (b) given vertices <span class="math inline"><em>u</em></span> and <span class="math inline"><em>v</em></span>, does the edge <span class="math inline">(<em>u</em>, <em>v</em>)</span> exist in the graph?</p>
+<h3 id="Representations_of_graphs"><span class="header-section-number">5.12.4</span> Representations of graphs</h3>
+<p>A good graph representation will allow us to answer one or both of
+these questions quickly. There are generally two standard
+representations of graphs that are used in graph algorithms, depending
+on which question is more important.</p>
+<p>For both representations, we simplify the representation task by insisting that vertices be labeled <span class="math inline">0, 1, 2, …, <em>n</em> − 1</span>, where <span class="math inline"><em>n</em></span>
+ is the number of vertices in the graph. If we have a graph with
+different vertex labels (say, airport codes), we can enforce an integer
+labeling by a preprocessing step where we assign integer labels, and
+then translate the integer labels back into more useful user labels
+afterwards. The preprocessing step can usually be done using a <a href="#hashTables">hash table</a> in <span class="math inline"><em>O</em>(<em>n</em>)</span>
+ time, which is likely to be smaller than the cost of whatever algorithm
+ we are running on our graph, and the savings in code complexity and
+running time from working with just integer labels will pay this cost
+back many times over.</p>
+<h4 id="Adjacency_matrices"><span class="header-section-number">5.12.4.1</span> Adjacency matrices</h4>
+<p>An <strong>adjacency matrix</strong> is just a matrix <code class="backtick">a</code> where <code class="backtick">a[i][j]</code> is <code class="backtick">1</code> if (i,j) is an edge in the graph and <code class="backtick">0</code> otherwise. It's easy to build an adjacency matrix, and adding or testing for the existence of an edges takes <span class="math inline"><em>O</em>(1)</span> time. The downsides of adjacency matrices are that finding all the outgoing edges from a vertex takes <span class="math inline"><em>O</em>(<em>n</em>)</span> time even if there aren't very many, and the <span class="math inline"><em>O</em>(<em>n</em><sup>2</sup>)</span> space cost is high for "sparse graphs," those with much fewer than <span class="math inline"><em>n</em><sup>2</sup></span> edges.</p>
+<h4 id="Adjacency_lists"><span class="header-section-number">5.12.4.2</span> Adjacency lists</h4>
+<p>An <strong>adjacency list</strong> representation of a graph creates a list of successors for each node <span class="math inline"><em>u</em></span>.
+ These lists may be represented as linked lists (the typical assumption
+in algorithms textbooks), or in languages like C may be represented by
+variable-length arrays. The cost for adding an edge is still <span class="math inline"><em>O</em>(1),</span> but testing for the existence of an edge <span class="math inline">(<em>u</em>, <em>v</em>)</span> rises to <span class="math inline"><em>O</em>(<em>d</em><sup>+</sup>(<em>u</em>))</span>, where <span class="math inline"><em>d</em><sup>+</sup>(<em>u</em>)</span> is the out-degree of <span class="math inline"><em>u</em></span> (i.e., the length of the list of <span class="math inline"><em>u</em></span>'s successors). The cost of enumerating the successors of <span class="math inline"><em>u</em></span> is also <span class="math inline"><em>O</em>(<em>d</em><sup>+</sup>(<em>u</em>))</span>, which is clearly the best possible since it takes that long just to write them all down. Finding predecessors of a node <span class="math inline"><em>u</em></span> is extremely expensive, requiring looking through every list of every node in time <span class="math inline"><em>O</em>(<em>n</em> + <em>m</em>)</span>, where <span class="math inline"><em>m</em></span>
+ is the total number of edges, although if this is something we actually
+ need to do often we can store a second copy of the graph with the edges
+ reversed.</p>
+<p>Adjacency lists are thus most useful when we mostly want to enumerate
+ outgoing edges of each node. This is common in search tasks, where we
+want to find a path from one node to another or compute the distances
+between pairs of nodes. If other operations are important, we can
+optimize them by augmenting the adjacency list representation; for
+example, using sorted arrays for the adjacency lists reduces the cost of
+ edge existence testing to <span class="math inline"><em>O</em>(log(<em>d</em><sup>+</sup>(<em>u</em>)))</span>, and adding a second copy of the graph with reversed edges lets us find all predecessors of u in <span class="math inline"><em>O</em>(<em>d</em><sup>−</sup>(<em>u</em>))</span> time, where <span class="math inline"><em>d</em><sup>−</sup>(<em>u</em>)</span> is <span class="math inline"><em>u</em></span>'s in-degree.</p>
+<p>Adjacency lists also require much less space than adjacency matrices for sparse graphs: <span class="math inline"><em>O</em>(<em>n</em> + <em>m</em>)</span> vs <span class="math inline"><em>O</em>(<em>n</em><sup>2</sup>)</span> for adjacency matrices. For this reason adjacency lists are more commonly used than adjacency matrices.</p>
+<h5 id="An_implementation"><span class="header-section-number">5.12.4.2.1</span> An implementation</h5>
+<p>Here is an implementation of a basic graph type using adjacency lists.</p>
+<div>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"><span class="co">/* basic directed graph type */</span>
+
+<span class="kw">typedef</span> <span class="kw">struct</span> graph *Graph;
+
+<span class="co">/* create a new graph with n vertices labeled 0..n-1 and no edges */</span>
+Graph graphCreate(<span class="dt">int</span> n);
+
+<span class="co">/* free all space used by graph */</span>
+<span class="dt">void</span> graphDestroy(Graph);
+
+<span class="co">/* add an edge to an existing graph */</span>
+<span class="co">/* doing this more than once may have unpredictable results */</span>
+<span class="dt">void</span> graphAddEdge(Graph, <span class="dt">int</span> source, <span class="dt">int</span> sink);
+
+<span class="co">/* return the number of vertices/edges in the graph */</span>
+<span class="dt">int</span> graphVertexCount(Graph);
+<span class="dt">int</span> graphEdgeCount(Graph);
+
+<span class="co">/* return the out-degree of a vertex */</span>
+<span class="dt">int</span> graphOutDegree(Graph, <span class="dt">int</span> source);
+
+<span class="co">/* return 1 if edge (source, sink) exists), 0 otherwise */</span>
+<span class="dt">int</span> graphHasEdge(Graph, <span class="dt">int</span> source, <span class="dt">int</span> sink);
+
+<span class="co">/* invoke f on all edges (u,v) with source u */</span>
+<span class="co">/* supplying data as final parameter to f */</span>
+<span class="co">/* no particular order is guaranteed */</span>
+<span class="dt">void</span> graphForeach(Graph g, <span class="dt">int</span> source,
+ <span class="dt">void</span> (*f)(Graph g, <span class="dt">int</span> source, <span class="dt">int</span> sink, <span class="dt">void</span> *data),
+ <span class="dt">void</span> *data);</code></pre></div>
+<a href="http://cs.yale.edu/homes/aspnes/classes/223/examples/graphs/graph.h" class="uri">examples/graphs/graph.h</a>
+</div>
+<div>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"><span class="ot">#include &lt;stdlib.h&gt;</span>
+<span class="ot">#include &lt;assert.h&gt;</span>
+
+<span class="ot">#include "graph.h"</span>
+
+<span class="co">/* basic directed graph type */</span>
+<span class="co">/* the implementation uses adjacency lists</span>
+<span class="co"> * represented as variable-length arrays */</span>
+
+<span class="co">/* these arrays may or may not be sorted: if one gets long enough</span>
+<span class="co"> * and you call graphHasEdge on its source, it will be */</span>
+
+<span class="kw">struct</span> graph {
+ <span class="dt">int</span> n; <span class="co">/* number of vertices */</span>
+ <span class="dt">int</span> m; <span class="co">/* number of edges */</span>
+ <span class="kw">struct</span> successors {
+ <span class="dt">int</span> d; <span class="co">/* number of successors */</span>
+ <span class="dt">int</span> len; <span class="co">/* number of slots in array */</span>
+ <span class="dt">int</span> isSorted; <span class="co">/* true if list is already sorted */</span>
+ <span class="dt">int</span> list[]; <span class="co">/* actual list of successors starts here */</span>
+ } *alist[];
+};
+
+<span class="co">/* create a new graph with n vertices labeled 0..n-1 and no edges */</span>
+Graph
+graphCreate(<span class="dt">int</span> n)
+{
+ Graph g;
+ <span class="dt">int</span> i;
+
+ g = malloc(<span class="kw">sizeof</span>(<span class="kw">struct</span> graph) + <span class="kw">sizeof</span>(<span class="kw">struct</span> successors *) * n);
+ assert(g);
+
+ g-&gt;n = n;
+ g-&gt;m = <span class="dv">0</span>;
+
+ <span class="kw">for</span>(i = <span class="dv">0</span>; i &lt; n; i++) {
+ g-&gt;alist[i] = malloc(<span class="kw">sizeof</span>(<span class="kw">struct</span> successors));
+ assert(g-&gt;alist[i]);
+
+ g-&gt;alist[i]-&gt;d = <span class="dv">0</span>;
+ g-&gt;alist[i]-&gt;len = <span class="dv">0</span>;
+ g-&gt;alist[i]-&gt;isSorted= <span class="dv">1</span>;
+ }
+
+ <span class="kw">return</span> g;
+}
+
+<span class="co">/* free all space used by graph */</span>
+<span class="dt">void</span>
+graphDestroy(Graph g)
+{
+ <span class="dt">int</span> i;
+
+ <span class="kw">for</span>(i = <span class="dv">0</span>; i &lt; g-&gt;n; i++) free(g-&gt;alist[i]);
+ free(g);
+}
+
+<span class="co">/* add an edge to an existing graph */</span>
+<span class="dt">void</span>
+graphAddEdge(Graph g, <span class="dt">int</span> u, <span class="dt">int</span> v)
+{
+ assert(u &gt;= <span class="dv">0</span>);
+ assert(u &lt; g-&gt;n);
+ assert(v &gt;= <span class="dv">0</span>);
+ assert(v &lt; g-&gt;n);
+
+ <span class="co">/* do we need to grow the list? */</span>
+ <span class="kw">while</span>(g-&gt;alist[u]-&gt;d &gt;= g-&gt;alist[u]-&gt;len) {
+ g-&gt;alist[u]-&gt;len = g-&gt;alist[u]-&gt;len * <span class="dv">2</span> + <span class="dv">1</span>; <span class="co">/* +1 because it might have been 0 */</span>
+ g-&gt;alist[u] =
+ realloc(g-&gt;alist[u],
+ <span class="kw">sizeof</span>(<span class="kw">struct</span> successors) + <span class="kw">sizeof</span>(<span class="dt">int</span>) * g-&gt;alist[u]-&gt;len);
+ }
+
+ <span class="co">/* now add the new sink */</span>
+ g-&gt;alist[u]-&gt;list[g-&gt;alist[u]-&gt;d++] = v;
+ g-&gt;alist[u]-&gt;isSorted = <span class="dv">0</span>;
+
+ <span class="co">/* bump edge count */</span>
+ g-&gt;m++;
+}
+
+<span class="co">/* return the number of vertices in the graph */</span>
+<span class="dt">int</span>
+graphVertexCount(Graph g)
+{
+ <span class="kw">return</span> g-&gt;n;
+}
+
+<span class="co">/* return the number of vertices in the graph */</span>
+<span class="dt">int</span>
+graphEdgeCount(Graph g)
+{
+ <span class="kw">return</span> g-&gt;m;
+}
+
+<span class="co">/* return the out-degree of a vertex */</span>
+<span class="dt">int</span>
+graphOutDegree(Graph g, <span class="dt">int</span> source)
+{
+ assert(source &gt;= <span class="dv">0</span>);
+ assert(source &lt; g-&gt;n);
+
+ <span class="kw">return</span> g-&gt;alist[source]-&gt;d;
+}
+
+<span class="co">/* when we are willing to call bsearch */</span>
+<span class="ot">#define BSEARCH_THRESHOLD (10)</span>
+
+<span class="dt">static</span> <span class="dt">int</span>
+intcmp(<span class="dt">const</span> <span class="dt">void</span> *a, <span class="dt">const</span> <span class="dt">void</span> *b)
+{
+ <span class="kw">return</span> *((<span class="dt">const</span> <span class="dt">int</span> *) a) - *((<span class="dt">const</span> <span class="dt">int</span> *) b);
+}
+
+<span class="co">/* return 1 if edge (source, sink) exists), 0 otherwise */</span>
+<span class="dt">int</span>
+graphHasEdge(Graph g, <span class="dt">int</span> source, <span class="dt">int</span> sink)
+{
+ <span class="dt">int</span> i;
+
+ assert(source &gt;= <span class="dv">0</span>);
+ assert(source &lt; g-&gt;n);
+ assert(sink &gt;= <span class="dv">0</span>);
+ assert(sink &lt; g-&gt;n);
+
+ <span class="kw">if</span>(graphOutDegree(g, source) &gt;= BSEARCH_THRESHOLD) {
+ <span class="co">/* make sure it is sorted */</span>
+ <span class="kw">if</span>(! g-&gt;alist[source]-&gt;isSorted) {
+ qsort(g-&gt;alist[source]-&gt;list,
+ g-&gt;alist[source]-&gt;d,
+ <span class="kw">sizeof</span>(<span class="dt">int</span>),
+ intcmp);
+ }
+
+ <span class="co">/* call bsearch to do binary search for us */</span>
+ <span class="kw">return</span>
+ bsearch(&amp;sink,
+ g-&gt;alist[source]-&gt;list,
+ g-&gt;alist[source]-&gt;d,
+ <span class="kw">sizeof</span>(<span class="dt">int</span>),
+ intcmp)
+ != <span class="dv">0</span>;
+ } <span class="kw">else</span> {
+ <span class="co">/* just do a simple linear search */</span>
+ <span class="co">/* we could call lfind for this, but why bother? */</span>
+ <span class="kw">for</span>(i = <span class="dv">0</span>; i &lt; g-&gt;alist[source]-&gt;d; i++) {
+ <span class="kw">if</span>(g-&gt;alist[source]-&gt;list[i] == sink) <span class="kw">return</span> <span class="dv">1</span>;
+ }
+ <span class="co">/* else */</span>
+ <span class="kw">return</span> <span class="dv">0</span>;
+ }
+}
+
+<span class="co">/* invoke f on all edges (u,v) with source u */</span>
+<span class="co">/* supplying data as final parameter to f */</span>
+<span class="dt">void</span>
+graphForeach(Graph g, <span class="dt">int</span> source,
+ <span class="dt">void</span> (*f)(Graph g, <span class="dt">int</span> source, <span class="dt">int</span> sink, <span class="dt">void</span> *data),
+ <span class="dt">void</span> *data)
+{
+ <span class="dt">int</span> i;
+
+ assert(source &gt;= <span class="dv">0</span>);
+ assert(source &lt; g-&gt;n);
+
+ <span class="kw">for</span>(i = <span class="dv">0</span>; i &lt; g-&gt;alist[source]-&gt;d; i++) {
+ f(g, source, g-&gt;alist[source]-&gt;list[i], data);
+ }
+}</code></pre></div>
+<a href="http://cs.yale.edu/homes/aspnes/classes/223/examples/graphs/graph.c" class="uri">examples/graphs/graph.c</a>
+</div>
+<p>And here is some test code: <a href="http://cs.yale.edu/homes/aspnes/classes/223/examples/graphs/graphTest.c">graphTest.c</a>.</p>
+<h4 id="Implicit_representations"><span class="header-section-number">5.12.4.3</span> Implicit representations</h4>
+<p>For some graphs, it may not make sense to represent them explicitly. An example might be the word-search graph from <a href="http://www.cs.yale.edu/homes/aspnes/pinewiki/CS223%282f%292005%282f%29Assignments%282f%29HW10.html">CS223/2005/Assignments/HW10</a>,
+ which consists of all words in a dictionary with an edge between any
+two words that differ only by one letter. In such a case, rather than
+building an explicit data structure containing all the edges, we might
+generate edges as needed when computing the neighbors of a particular
+vertex. This gives us an implicit or procedural representation of a
+graph.</p>
+<p>Implicit representations require the ability to return a vector or
+list of values from the neighborhood-computing function. There are
+various way to do this, of which the most sophisticated might be to use
+an <a href="#iterators">iterator</a>.</p>
+<h3 id="graphSearch"><span class="header-section-number">5.12.5</span> Searching for paths in a graph</h3>
+<p>A <strong>path</strong> is a sequence of vertices <span class="math inline"><em>v</em><sub>1</sub>, <em>v</em><sub>2</sub>, …<em>v</em><sub><em>k</em></sub></span> where each pair <span class="math inline">(<em>v</em><sub><em>i</em></sub>, <em>v</em><sub><em>i</em> + 1</sub>)</span> is an edge. Often we want to find a path from a source vertex <span class="math inline"><em>s</em></span> to a target vertex <span class="math inline"><em>t</em></span>, or more generally to detect which vertices are reachable from a given source vertex <span class="math inline"><em>s</em></span>.
+ We can solve these problems by using any of several standard graph
+search algorithms, of which the simplest and most commonly used are <strong>depth-first search</strong> and <strong>breadth-first search</strong>.</p>
+<p>Both of these search algorithms are a special case of a more general
+algorithm for growing a directed tree in a graph rooted at a given node <span class="math inline"><em>s</em></span>. Here we are using <em>tree</em> as a graph theorist would, to mean any set of <span class="math inline"><em>k</em></span> nodes joined by <span class="math inline"><em>k</em> − 1</span>
+ edges. This is similar to trees used in data structures except that
+there are no limits on the number of children a node can have and no
+ordering constraints within the tree.</p>
+<p>The general tree-growing algorithm might be described as follows:</p>
+<ol style="list-style-type: decimal">
+<li>Start with a tree consisting of just <span class="math inline"><em>s</em></span>.</li>
+<li>If there is at least one edge that leaves the tree (i.e. goes from a
+ node in the current tree to a node outside the current tree), pick the
+"best" such edge and add it and its sink to the tree.</li>
+<li>Repeat step 2 until no edges leave the tree.</li>
+</ol>
+<p>Practically, steps 2 and 3 are implemented by having some sort of
+data structure that acts as a bucket for unprocessed edges. When a new
+node is added to the tree, all of its outgoing edges are thrown into the
+ bucket. The "best" outgoing edge is obtained by applying some sort of
+pop, dequeue, or delete-min operation to the bucket, depending on which
+it provides; if this edge turns out to be an internal edge of the tree
+(maybe we added its sink after putting it in the bucket), we throw it
+away. Otherwise we mark the edge and its sink as belonging to the tree
+and repeat.</p>
+<p>The output of the generic tree-growing algorithm typically consists of (a) marks on all the nodes that are reachable from <span class="math inline"><em>s</em></span>, and (b) for each such node <span class="math inline"><em>v</em></span>, a parent pointer back to the source of the edge that brought <span class="math inline"><em>v</em></span>
+ into the tree. Often these two values can be combined by using a null
+parent pointer to represent the absence of a mark (this usually requires
+ making the root point to itself so that we know it's in the tree).
+Other values that may be useful are a table showing the order in which
+nodes were added to the tree.</p>
+<p>What kind of tree we get depends on what we use for the
+bucket—specifically, on what edge is returned when we ask for the "best"
+ edge. Two easy cases are:</p>
+<ol style="list-style-type: decimal">
+<li>The bucket is a stack. When we ask for an outgoing edge, we get the
+last edge inserted. This has the effect of running along as far as
+possible through the graph before backtracking, since we always keep
+going from the last node if possible. The resulting algorithm is called <strong>depth-first search</strong> and yields a <strong>depth-first search tree</strong>.
+ If we don't care about the lengths of the paths we consider,
+depth-first search is a perfectly good algorithm for testing
+connectivity. It can also be implemented without any auxiliary data
+structures as a recursive procedure, as long as we don't go so deep as
+to blow out the system stack.</li>
+<li>The bucket is a queue. Now when we ask for an outgoing edge, we get
+the first edge inserted. This favors edges that are close to the root:
+we don't start consider edges from nodes adjacent to the root until we
+have already added all the root's successors to the tree, and similarly
+we don't start considering edges at distance k until we have already
+added all the closer nodes to the tree. This gives <strong>breadth-first search</strong>, which constructs a <strong>shortest-path tree</strong> in which every path from the root to a node in the tree has the minimum length.</li>
+</ol>
+<p>Structurally, these algorithms are almost completely identical;
+indeed, if we organize the stack/queue so that it can pop from both
+ends, we can switch between depth-first search and breadth-first search
+just by choosing which end to pop from.</p>
+<p>Below, we give a [combined implementation](#combinedDFSBFS} of both
+depth-first search and breadth-first search that does precisely this,
+although this is mostly for show. Typical implementations of
+breadth-first search include a further optimization, where we test an
+edge to see if we should add it to the tree (and possibly add it) before
+ inserting into the queue. This gives the same result as the DFS-like
+implementation but only requires <span class="math inline"><em>O</em>(<em>n</em>)</span> space for the queue instead of <span class="math inline"><em>O</em>(<em>m</em>)</span>,
+ with a smaller constant as well since don't need to bother storing
+source edges in the queue. An example of this approach is given
+[below]{#graphSearchImplementation}.</p>
+<p>The running time of any of these algorithms is <em>very</em> fast: we pay <span class="math inline"><em>O</em>(1)</span> per vertex in setup costs and <span class="math inline"><em>O</em>(1)</span> per edge during the search (assuming the input is in adjacency-list form), giving a linear <span class="math inline"><em>O</em>(<em>n</em> + <em>m</em>)</span> total cost. Often it is more expensive to set up the graph in the first place than to run a search on it.</p>
+<h4 id="graphSearchImplementation"><span class="header-section-number">5.12.5.1</span> Implementation of depth-first and breadth-first search</h4>
+<p>Here is a simple implementation of depth-first search, using a
+recursive algorithm, and breadth-first search, using an iterative
+algorithm that maintains a queue of vertices. In both cases the
+algorithm is applied to a sample graph whose vertices are the integers <span class="math inline">0</span> through <span class="math inline"><em>n</em> − 1</span> for some <span class="math inline"><em>n</em></span>, and in which vertex <span class="math inline"><em>x</em></span> has edges to vertices <span class="math inline"><em>x</em>/2</span>, <span class="math inline">3 ⋅ <em>x</em></span>, and <span class="math inline"><em>x</em> + 1</span>, whenever these values are also integers in the range <span class="math inline">0</span> through <span class="math inline"><em>n</em> − 1</span>. For large graphs it may be safer to run an <a href="#combinedDFSBFS">iterative version of DFS</a> that uses an explicit stack instead of a possibly very deep recursion.</p>
+<div>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"><span class="ot">#include &lt;stdio.h&gt;</span>
+<span class="ot">#include &lt;stdlib.h&gt;</span>
+<span class="ot">#include &lt;assert.h&gt;</span>
+<span class="ot">#include &lt;stdint.h&gt;</span>
+
+<span class="kw">typedef</span> <span class="dt">int</span> Vertex;
+
+<span class="ot">#define VERTEX_NULL (-1)</span>
+
+<span class="kw">struct</span> node {
+ Vertex *neighbors; <span class="co">/* array of outgoing edges, terminated by VERTEX_NULL */</span>
+ Vertex parent; <span class="co">/* for search */</span>
+};
+
+<span class="kw">struct</span> graph {
+ size_t n; <span class="co">/* number of vertices */</span>
+ <span class="kw">struct</span> node *v; <span class="co">/* list of vertices */</span>
+};
+
+<span class="dt">void</span>
+graphDestroy(<span class="kw">struct</span> graph *g)
+{
+ Vertex v;
+
+ <span class="kw">for</span>(v = <span class="dv">0</span>; v &lt; g-&gt;n; v++) {
+ free(g-&gt;v[v].neighbors);
+ }
+
+ free(g);
+}
+
+<span class="co">/* this graph has edges from x to x+1, x to 3*x, and x to x/2 (when x is even) */</span>
+<span class="kw">struct</span> graph *
+makeSampleGraph(size_t n)
+{
+ <span class="kw">struct</span> graph *g;
+ Vertex v;
+ <span class="dt">const</span> <span class="dt">int</span> allocNeighbors = <span class="dv">4</span>;
+ <span class="dt">int</span> i;
+
+ g = malloc(<span class="kw">sizeof</span>(*g));
+ assert(g);
+
+ g-&gt;n = n;
+ g-&gt;v = malloc(<span class="kw">sizeof</span>(<span class="kw">struct</span> node) * n);
+ assert(g-&gt;v);
+
+ <span class="kw">for</span>(v = <span class="dv">0</span>; v &lt; n; v++) {
+ g-&gt;v[v].parent = VERTEX_NULL;
+
+ <span class="co">/* fill in neighbors */</span>
+ g-&gt;v[v].neighbors = malloc(<span class="kw">sizeof</span>(Vertex) * allocNeighbors);
+ i = <span class="dv">0</span>;
+ <span class="kw">if</span>(v % <span class="dv">2</span> == <span class="dv">0</span>) { g-&gt;v[v].neighbors[i++] = v/<span class="dv">2</span>; }
+ <span class="kw">if</span>(<span class="dv">3</span>*v &lt; n) { g-&gt;v[v].neighbors[i++] = <span class="dv">3</span>*v; }
+ <span class="kw">if</span>(v<span class="dv">+1</span> &lt; n) { g-&gt;v[v].neighbors[i++] = v<span class="dv">+1</span>; }
+ g-&gt;v[v].neighbors[i++] = VERTEX_NULL;
+ }
+
+ <span class="kw">return</span> g;
+}
+
+<span class="co">/* output graph in dot format */</span>
+<span class="dt">void</span>
+printGraph(<span class="dt">const</span> <span class="kw">struct</span> graph *g)
+{
+ Vertex u;
+ size_t i;
+
+ puts(<span class="st">"digraph G {"</span>);
+
+ <span class="kw">for</span>(u = <span class="dv">0</span>; u &lt; g-&gt;n; u++) {
+ <span class="kw">for</span>(i = <span class="dv">0</span>; g-&gt;v[u].neighbors[i] != VERTEX_NULL; i++) {
+ printf(<span class="st">"%d -&gt; %d;</span><span class="ch">\n</span><span class="st">"</span>, u, g-&gt;v[u].neighbors[i]);
+ }
+ }
+
+ puts(<span class="st">"}"</span>);
+}
+
+<span class="co">/* reconstruct path back to root from u */</span>
+<span class="dt">void</span>
+printPath(<span class="dt">const</span> <span class="kw">struct</span> graph *g, Vertex u)
+{
+ <span class="kw">do</span> {
+ printf(<span class="st">" %d"</span>, u);
+ u = g-&gt;v[u].parent;
+ } <span class="kw">while</span>(g-&gt;v[u].parent != u);
+}
+
+<span class="co">/* print the tree in dot format */</span>
+<span class="dt">void</span>
+printTree(<span class="dt">const</span> <span class="kw">struct</span> graph *g)
+{
+ Vertex u;
+
+ puts(<span class="st">"digraph G {"</span>);
+
+ <span class="kw">for</span>(u = <span class="dv">0</span>; u &lt; g-&gt;n; u++) {
+ <span class="kw">if</span>(g-&gt;v[u].parent != VERTEX_NULL) {
+ printf(<span class="st">"%d -&gt; %d;</span><span class="ch">\n</span><span class="st">"</span>, u, g-&gt;v[u].parent);
+ }
+ }
+
+ puts(<span class="st">"}"</span>);
+}
+
+<span class="co">/* compute DFS tree starting at root */</span>
+<span class="co">/* this uses a recursive algorithm and will not work on large graphs! */</span>
+<span class="dt">static</span> <span class="dt">void</span>
+dfsHelper(<span class="kw">struct</span> graph *g, Vertex parent, Vertex child)
+{
+ <span class="dt">int</span> i;
+ Vertex neighbor;
+
+ <span class="kw">if</span>(g-&gt;v[child].parent == VERTEX_NULL) {
+ g-&gt;v[child].parent = parent;
+ <span class="kw">for</span>(i = <span class="dv">0</span>; (neighbor = g-&gt;v[child].neighbors[i]) != VERTEX_NULL; i++) {
+ dfsHelper(g, child, neighbor);
+ }
+ }
+}
+
+<span class="dt">void</span>
+dfs(<span class="kw">struct</span> graph *g, Vertex root)
+{
+ dfsHelper(g, root, root);
+}
+
+<span class="co">/* compute BFS tree starting at root */</span>
+<span class="dt">void</span>
+bfs(<span class="kw">struct</span> graph *g, Vertex root)
+{
+ Vertex *q;
+ <span class="dt">int</span> head; <span class="co">/* deq from here */</span>
+ <span class="dt">int</span> tail; <span class="co">/* enq from here */</span>
+ Vertex current;
+ Vertex nbr;
+ <span class="dt">int</span> i;
+
+ q = malloc(<span class="kw">sizeof</span>(Vertex) * g-&gt;n);
+ assert(q);
+
+ head = tail = <span class="dv">0</span>;
+
+ <span class="co">/* push root onto q */</span>
+ g-&gt;v[root].parent = root;
+ q[tail++] = root;
+
+ <span class="kw">while</span>(head &lt; tail) {
+ current = q[head++];
+
+ <span class="kw">for</span>(i = <span class="dv">0</span>; (nbr = g-&gt;v[current].neighbors[i]) != VERTEX_NULL; i++) {
+ <span class="kw">if</span>(g-&gt;v[nbr].parent == VERTEX_NULL) {
+ <span class="co">/* haven't seen this guy */</span>
+ <span class="co">/* push it */</span>
+ g-&gt;v[nbr].parent = current;
+ q[tail++] = nbr;
+ }
+ }
+ }
+
+ free(q);
+}
+
+
+
+<span class="dt">int</span>
+main(<span class="dt">int</span> argc, <span class="dt">char</span> **argv)
+{
+ <span class="dt">int</span> n;
+ <span class="kw">struct</span> graph *g;
+
+ <span class="kw">if</span>(argc != <span class="dv">3</span>) {
+ fprintf(stderr, <span class="st">"Usage: %s action n</span><span class="ch">\n</span><span class="st">where action =</span><span class="ch">\n</span><span class="st"> g - print graph</span><span class="ch">\n</span><span class="st"> d - print dfs tree</span><span class="ch">\n</span><span class="st"> b - print bfs tree</span><span class="ch">\n</span><span class="st">"</span>, argv[<span class="dv">0</span>]);
+ <span class="kw">return</span> <span class="dv">1</span>;
+ }
+
+ n = atoi(argv[<span class="dv">2</span>]);
+
+ g = makeSampleGraph(n);
+
+ <span class="kw">switch</span>(argv[<span class="dv">1</span>][<span class="dv">0</span>]) {
+ <span class="kw">case</span> 'g':
+ printGraph(g);
+ <span class="kw">break</span>;
+ <span class="kw">case</span> 'd':
+ dfs(g, <span class="dv">0</span>);
+ printTree(g);
+ <span class="kw">break</span>;
+ <span class="kw">case</span> 'b':
+ bfs(g, <span class="dv">0</span>);
+ printTree(g);
+ <span class="kw">break</span>;
+ <span class="kw">default</span>:
+ fprintf(stderr, <span class="st">"%s: unknown action '%c'</span><span class="ch">\n</span><span class="st">"</span>, argv[<span class="dv">0</span>], argv[<span class="dv">1</span>][<span class="dv">0</span>]);
+ <span class="kw">return</span> <span class="dv">1</span>;
+ }
+
+ graphDestroy(g);
+
+ <span class="kw">return</span> <span class="dv">0</span>;
+}</code></pre></div>
+<a href="http://cs.yale.edu/homes/aspnes/classes/223/examples/graphSearch/search.c" class="uri">examples/graphSearch/search.c</a>
+</div>
+<p>The output of the program is either the graph, a DFS tree of the graph rooted at <span class="math inline">0</span>, or a BFS tree of the graph rooted at <span class="math inline">0</span>, in a format suitable for feeding to the <a href="http://graphviz.org/">GraphViz</a> program <code>dot</code>, which draws pictures of graphs.</p>
+<p>Here are the pictures for <span class="math inline"><em>n</em> = 20</span>.</p>
+<div class="figure">
+<img src="data:image/png;base64,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j4CAAHnGJyIiIiLZefUH6F7EzMwMO3fuxPXr19GrVy9MmzYN5ubmWLx4MVJTU2XxFm+luroaERERGD16NKysrLBr1y4sX74caWlp+Oyzz16pCANPdnH9/f2RmpoKb29vAKh9WK2iokLuD88RERERkWzJZGf43+7fv4+dO3di8+bNSElJgZOTE7y8vDBy5Eg4ODgoZAhESUkJzp07h0OHDiEsLAy5ubkYNGgQpk+fDk9Pz1cuwC9y9OhRzJ49G2KxGBKJBDdv3sQ777wjg/REREREpACyOSbxPFKpFBcvXkRISAgOHjyIzMxMGBgYwMXFBc7OznBycoKDgwPatWv3Vu9TUVGB5ORkJCUlIS4uDufPn8eVK1dQVVUFFxcX+Pj4YPTo0TAzM5PRJ/ufsrIy/PjjjwgPD0d0dDSnvRERERE1HPItw0+TSqW4du0aYmJicPbsWfz555/Izs4GADRv3hx2dnYwMzODhYUFLCwsoKen99x17t27B7FYDLFYjPT0dKSmpqKqqgoaGhqwt7dH37594erqin79+ilk+hsRERERNUiKK8P1ycvLQ1JSEpKTk5GSkoKsrCxkZWUhIyMDJSUlKC0tRVlZWe3rmzdvDnV1dZiYmKBt27a115fZ29ujU6dOsLe3V8qH9oiIiIhIKQlbhl/FgQMHMHbsWCh5TCIiIiJqeGRzmwQRERERUUPEMkxEREREKotlmIiIiIhUFsswEREREakslmEiIiIiUlksw0RERESksliGiYiIiEhlsQwTERERkcpiGSYiIiIilcUyTEREREQqi2WYiIiIiFQWyzARERERqSyWYSIiIiJSWSzDRERERKSyWIaJiIiISGWxDBMRERGRymIZJiIiIiKVxTJMRERERCqLZZiIiIiIVBbLMBERERGpLJZhIiIiIlJZLMNEREREpLJYhomIiIhIZbEMExEREZHKYhkmIiIiIpXFMkxEREREKotlmIiIiIhUFsswEREREakslmEiIiIiUlksw0RERESksliGiYiIiEhlsQwTERERkcrSEDrAv7m7u+Off/6p/X15eTk0NTVhZmb2zOsWLlyIuXPnKjoeERERETUiSleGs7OzkZ2dDalU+szXs7Kynvl9UVGRImMRERERUSOkdMckJk+eDHV19Re+Rk1NDR999JGCEhERERFRY6V0ZXjcuHGorq5+7vdFIhG6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R/v27REaGio6UpW4d+8enJycsH79euzatQsrVqzgjDCpLJZhIiKiV2jbti3Onz8Pd3d3DBkyBIMHD8adO3dEx3orJSUl+Prrr2FpaYnS0lIkJCTAw8NDdCwioViGiYiI/oWuri78/Pxw5swZ3L59G1ZWVpg9ezYePXokOtprkclk2LFjBywsLLB27VosXboU8fHxaN26tehoRMKxDBMREb0mBwcHJCUl4fvvv8fu3bvRokULLFy4UGnXE5eWlmLXrl2wsLDAxIkT4ezsjJSUFMycORMaGtxQiggAeAIdERHRW3j27Bk2b96MNWvWoKCgAIMHD8bEiRPRo0cPqKmJnWu6desWtm3bBn9/fxQVFcHDwwNffvklWrRoITQXkRLiccxERETvoqysDKGhodi6dSsiIyPRqFEjDBkyBMOGDUP37t2hq6tb7RnKy8tx7do1HD58GAcOHMCVK1dgZmaGTz/9FN7e3mjUqFG1ZyCqoViGiYiIqkpWVhZCQkIQHByMc+fOQUNDAx07doSdnR1sbW1hZWWFtm3bQktL663HqKioQHp6OpKTk5GUlIT4+HicO3cOjx8/homJCUaMGIERI0agc+fO3CGC6N+xDBMREVWH3NxcREdH4+zZs4iNjUVKSgpkMhk0NDTQqlUrNG/eHM2aNYOxsTEMDQ1fep+ioiJkZWUhMzMT2dnZSEtLQ3FxMQDAyMgIUqkUUqkU3bt3h7W1NQsw0ZthGSYiIlKE0tJS3LhxAzdu3EBKSgqysrKQlZWFnJwcPHr0CHK5HEVFRZXX6+joQFdXF3p6ejA1NYWRkRGMjIzQpk0bWFpawsrKCvr6+gK/IqJagWWYiIhImUgkEuzfvx/u7u6ioxCpgmBurUZEREREKotlmIiIiIhUFsswEREREakslmEiIiIiUlksw0RERESksliGiYiIiEhlsQwTERERkcpiGSYiIiIilcUyTEREREQqi2WYiIiIiFQWyzARERERqSyWYSIiIiJSWSzDRERERKSyWIaJiIiISGWxDBMRERGRymIZJiIiIiKVxTJMRERERCqLZZiIiIiIVBbLMBERERGpLJZhIiIiIlJZLMNEREREpLJYhomIiIhIZbEMExEREZHKYhkmIiIiIpXFMkxEREREKotlmIiIiIhUFsswEREREakslmEiIiIiUlksw0RERESksliGiYiIiEhlsQwTERERkcpiGSYiIiIilSWpqKioEB2CiIhIFa1fvx4rV6584bW8vDzUq1cP2trala+Zm5sjMjJS0fGIVEGwhugEREREqurJkyfIycn52+v5+fmVfy+RSFCvXj1FxiJSKVwmQUREJMiYMWMgkUheeY26ujrGjh2rmEBEKohlmIiISJAWLVrAxsYGamov/3Ysl8sxatQoBaYiUi0sw0RERAJ5enq+dHZYTU0N9vb2MDY2VnAqItXBMkxERCTQq2Z9JRIJPD09FZiGSPWwDBMREQn0wQcfwNHREerq6v/4+eHDhys4EZFqYRkmIiISzMPDA3/d6VRDQwO9e/eGgYGBoFREqoFlmIiISDA3NzdoaLy426lcLseYMWMEJSJSHSzDREREgtWtWxf9+vWDpqZm5Wva2toYOnSowFREqoFlmIiISAmMGTMGMpkMAKCpqYlBgwahTp06glMR1X4sw0REREpgwIAB0NPTAwCUlZVh9OjRghMRqQaWYSIiIiWgo6ODIUOGAADq1KmDPn36CE5EpBo0/v0SIiIiqg4FBQXIyclBXl4e5HI5TExMAAC2trY4efIkdHV1oaenB1NTUxgaGr50+zUienuSir/u5UJERERVKjU1FZcvX0ZycjJu3LiBlJQUZGVl4fnz5699D3V1dRgaGqJNmzawtLSElZUV2rVrBxsbG2hra1djeqJaLZhlmIiIqIrdu3cPYWFhOHPmDOLi4pCXlwddXV2YmZlVfpiamqJZs2YwNjaGoaHhS+9VVFSErKwsZGZmIjs7G7dv30ZqaipSUlKQn58PHR0ddO7cGd27d4erqyvs7e2hpsZVkESviWWYiIioKmRkZMDf3x+HDh3ClStX0LBhQ/To0QMODg5wcnKCpaVllZfU3NxcxMTEICYmBlFRUUhNTUXjxo0xaNAgeHh4wMHBoUrHI6qFWIaJiIjeRWRkJPz8/BAWFgYDAwO4ublh2LBhcHR0/NtBGtUtNTUVBw4cQEhICJKSkmBtbY3JkyfD09OzcqcKInoByzAREdGbksvl2Lt3L1atWoWUlBQMGzYMEyZMQM+ePZVmiUJaWhr8/f2xbds2yGQyTJo0CQsWLED9+vVFRyNSJizDREREbyIhIQFTpkzBxYsXMXToUCxatAgdOnQQHeulCgoKsHbtWmzYsAE6OjpYunQpxo0bB4lEIjoakTIIVo4fX4mIiJRcUVERpk+fji5dYMyU5wAACbpJREFUuqB+/fq4evUqQkJClLoIA0DDhg3x/fffIz09HePGjcPkyZPRvXt3JCcni45GpBRYhomIiP7FhQsX0LFjRxw4cAD79u3D8ePHYWlpKTrWG2nQoAGWLVuGpKQkaGpqwtbWFhs2bAB/QUyqjmWYiIjoFdauXQupVApra2skJyfD3d1ddKR3YmFhgdOnT2PJkiWYM2cOhg4diqKiItGxiIThmmEiIqJ/IJfLMW3aNGzbtg2+vr6YNm2a6EhV7uLFi3Bzc4O+vj6OHDkCIyMj0ZGIFI0P0BEREf1VWVkZ3N3dcfLkSezfvx/9+/cXHana5OTkwNXVFY8fP0ZUVBRatmwpOhKRIvEBOiIiov9VXl4OHx8fnDp1CpGRkbW6CAOAkZERYmNj0aRJE7i4uCA3N1d0JCKFYhkmIiL6HwsWLEBwcDAOHDgAOzs70XEUol69ejhy5Ag0NTXh6uqKkpIS0ZGIFIZlmIiI6P9ERERg9erV2Lx5M3r37i06jkIZGBjg2LFjyMzMxJw5c0THIVIYrhkmIiICUFhYCEtLS0ilUgQFBYmOI0xgYCBGjx6NsLCwWr9EhAh8gI6IiOi/Zs+ejYCAAKSlpUFfX190HKHc3d2RlJSE69evQ1NTU3QcourEB+iIiIju3r0LPz8/fPXVVypfhAFg+fLlyMjIwJYtW0RHIap2nBkmIiKVN2vWLBw8eBA3b96ElpZWtY+Xk5ODEydO4Pjx48jKykJ8fPwLny8sLMRXX32FRo0aIT8/HwUFBVixYgWMjY2rPdufpkyZgmPHjuH27dtQU+PcGdVanBkmIiLVVlpail27dmH8+PEKKcLAf7czGzp0KIKDg1FYWPjC50pKStClSxc0bdoUX3/9NTZs2ICePXvCxsYGmZmZCskHANOnT0d6ejoiIyMVNiaRCCzDRESk0qKiolBYWAhPT0+FjtugQYN/fN3X1xe3bt3C8OHDK1/z9vaGTCbD4sWLFZQOMDMzg62tLYKDgxU2JpEILMNERKTSYmJiYG5uDhMTE9FRAACxsbEA8EIeTU1N2NjYIDg4GIpc3eji4oKYmBiFjUckAsswERGptHPnzsHe3l50jEq//fbbC3/9k4GBAZ4+fYr79/9fe/cb0mS/hwH80oa10Zs0qZg5kXQ4h8MoM9ysESwiwj+oFUgLMRKCCkSKCqIIqRcVCCFUGptUsLVK6VVIf7TafLGaFo4wmbX0QHNQM5PVdOdFJ+Gc53Se53Ta/dvxvj6vb/a7Nhhc3Hz5/v4mWZbS0lKMjIwgHA5LdiaR1FiGiYhI1sbGxpCfny86xjydTgcAf5jV/bHibHZ2VrIsWq0W8Xgcb9++lexMIqmxDBMRkayFw2FkZGSIjjGvubkZqampOHr0KJ4+fYpPnz7B5XLh/v37WLRoEVatWiVZluXLlwMAJicnJTuTSGosw0REJGszMzNQKpWiY8wrKipCb28vsrOzsXXrVphMJkQiEcTjcZjNZigUCsmyqFQqAN9/I6KFimWYiIhkbdmyZX9Ybyaa2WyGx+PB58+fMTQ0hPT0dHz48AF79+6VNMePuWVeREILGcswERHJWkZGRlKPAUxNTaGlpQUmkwm7d++W9OxQKAQASTVGQvS7sQwTEZGs6fV6eL1eyc+dnp4GAMzNzf30mWg0ioaGBqSkpODGjRuS3wTn9XqhUqmQl5cn6blEUmIZJiIiWdu4cSMGBgYk3d/78OFDHDx4EMD3bRYXLlyAz+f7p2cGBwdRVlaGtLQ09PX1ISsrS7J8P7jdbhQXF89vsiBaiFLiUv77iYiIkszQ0BAMBgP6+/thNBpFx0EgEEBnZycWL16MHTt2wGAwCMkRi8Wg0WjQ2NiIU6dOCclAJAEnyzAREcneunXroNPpYLfbRUdJGnfu3EFNTQ1GR0eRk5MjOg5Rojg5JkFERLJntVrhcrkwPj4uOkrSaGtrw6ZNm1iEacHjm2EiIpK9r1+/QqfToaysDDabTXQc4bq7u1FVVQW3240NGzaIjkOUSByTICIiAgC73Y6GhgY8e/YMJSUlouMIMzMzg7Vr10Kr1eLu3bui4xAlGsswERER8H3F2bZt2xAIBPD8+XMsXbpUdCQhDhw4gJs3b+LFixfQaDSi4xAlGmeGiYiIACA1NRV2ux2RSAT79++XdNVasnA4HGhvb8fVq1dZhEk2WIaJiIj+YcWKFXA4HLh9+zZaWlpEx5HUgwcPsGfPHhw5cgTV1dWi4xBJRiE6ABERUTIpLy9HV1cXdu7cCZVKhdOnT4uOlHB9fX2oqqpCXV0dWltbRcchkhTfDBMREf2LmpoadHZ24uzZs9i3bx9isZjoSAnjdDphsViwfft2dHR0ICUlRXQkIkmxDBMREf0bVqsV9+7dg8PhgMViwcTEhOhIv1UsFsOJEyewa9cuHDp0CNevX+e1yyRLLMNEREQ/YbFY4Ha7MTk5CYPBgJ6eHtGRfotAIIDNmzejra0NNpsN586d4xthki2WYSIiov9Ap9NhYGAAdXV1qKysREVFBUZHR0XH+iVfvnzByZMnUVhYiGg0Cq/Xi/r6etGxiIRiGSYiIvoTSqUSly5dwqNHj/DmzRvo9Xo0NzcjFAqJjvaXxGIxdHR0oKCgABcvXkRrayvcbjfy8vJERyMSjmWYiIjoLyovL4fP58OZM2fQ1dWF3NxcHDt2LGnniaPRKGw2GwoKCtDU1IQtW7bA7/fj8OHDUCi4UIoIAHgDHRER0S+Ynp5Ge3s7zp8/j3A4jIqKCjQ1NcFsNiM1Vey7ppGREVy5cgXXrl1DJBJBfX09jh8/jtzcXKG5iJIQr2MmIiL6X3z79g09PT24fPkyent7kZmZicrKSlRXV8NkMkGpVCY8w9zcHF69eoXu7m64XC4MDg5Cq9WisbERVqsVmZmZCc9A9H+KZZiIiOh3CQaDuHXrFpxOJzweDxQKBYqLi1FaWor169dDr9dDp9MhLS3tl8+Ix+MYGxvDy5cv4fP54Ha74fF48PHjR2RnZ6O2tha1tbUoKSnhhgiiP8cyTERElAgTExN4/Pgxnjx5gv7+fvj9fsRiMSgUCqxZswY5OTnIysrC6tWrsXLlyp9+TiQSQTAYxLt37/D+/Xu8fv0aU1NTAAC1Wg2j0Qij0QiTyYSioiIWYKL/DsswERGRFKLRKIaHhzE8PAy/349gMIhgMIjx8XGEQiHMzs4iEonMP79kyRIolUqoVCpoNBqo1Wqo1Wrk5+ejsLAQer0e6enpAr8R0YLAMkxEREREsuXkajUiIiIiki2WYSIiIiKSLZZhIiIiIpItBQCn6BBERERERAJ4/g4V7dh7n8Y/sQAAAABJRU5ErkJggg==" alt="The full graph">
+<p class="caption">The full graph</p>
+</div>
+<div class="figure">
+<img src="data:image/png;base64,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gD59+mDjxo2YNGmS7DhmIyQkBBcvXkR6errsKKbAMieyRFFRUdi/fz9OnTqlyD07zd3Ve4p+8803GPr/2bv3sCjLxH/87wFG8IQHwF2VQVF2OPpd0NhAUQ4e8pMCQoYaaGqwVraalOYutuZlXmqZCkpX1OpHPyT2EUXDClnNABWIIA9AarACOYN4GDRKEBjm+f3RD/bjemi3ZubGZ96v6/Laa56ZfZ738Me757rnue978mTRcUyBZU4kR9999x3UajWSk5OxaNEi0XGEmzhxIgwGA7744gvRUUyFZU4kVy+99BIOHjyI6upq9OzZU3QcYb744guEhYXhxIkTCAoKEh3HVFjmRHJ15coVuLm5Yf369ViyZInoOMKMGzcOffr0QW5urugopsQNnYnkavDgwXjhhRewfv16NDc3i44jRE5ODoqKirBu3TrRUUyOd+ZEMnbjxg2MGDECq1atwooVK0THMStJkuDv748hQ4YgOztbdBxT4505kZw5OjriT3/6E9566y00NTWJjmNWH3/8MU6fPm0Rd+UAwDInkrnly5fDYDAgOTlZdBSzMRgMeP311/HUU09h1KhRouOYBcucSOb69++Pl19+Ge+88w4aGxtFxzGLffv24fz583jjjTdERzEbjpkTWYAff/wRI0eOREJCAt58803RcUxKr9fDy8sLjz/+ONLT00XHMReOmRNZgj59+uCVV17B1q1bce3aNdFxTGrPnj2ora3F6tWrRUcxK96ZE1mI27dvw83NDXFxcXj77bdFxzGJtrY2uLu7Y9KkSfjggw9ExzEn3pkTWYrevXtj5cqV2L59O7Rareg4JrFr1y5cuXIFr7/+uugoZsc7cyIL0trait/97neIjIzEtm3bRMcxqs7vFhERge3bt4uOY268MyeyJLa2tkhKSsL777+Pmpoa0XGMKi0tDTqdDklJSaKjCME7cyIL097eDg8PD0ycOBHvv/++6DhG0dzcjJEjRyI2NhabNm0SHUcE3pkTWRqlUonXX38dO3fuxMWLF0XHMYrU1FTcvn0bK1euFB1FGN6ZE1mgjo4OjBo1Co899hj+53/+R3ScX6WpqQkjRozAokWLLGbq/n3wzpzIEllbW+Ovf/0rMjIycP78edFxfpXk5GQYDAYsX75cdBSheGdOZKEMBgNGjx4Nd3d3/O///q/oOL9IY2MjRowYgcTERPz1r38VHUck3pkTWSorKyusXr0amZmZOHPmjOg4v8iWLVvQo0cPJCYmio4iHO/MiSzc448/jt/+9rf4+OOPRUf5j1y7dg0jR47EqlWr8Nprr4mOIxrvzIks3RtvvIHs7Gx8+eWXoqP8R95++2306dMHL730kugo3QLvzIkIwcHB6NmzJ44cOSI6yr9Fq9XCzc0NGzZswNKlS0XH6Q54Z05EwOrVq5Gbm4v8/HzRUf4tGzduhJOTExYtWiQ6SrfBO3MiAgCEhYWhvb0dJ06cEB3loWpqauDh4YHk5GQ8//zzouN0F5kscyICABQWFmLcuHE4evQoJk2aJDrOA/3xj3/E559/jgsXLkCpVIqO012wzInon5588kncuHEDX375JRQKheg49/jHP/4BT09PpKWlYcGCBaLjdCcscyL6p7KyMvj7+yM7OxvTp08XHecezz77LEpKSlBRUQFra2vRcboTljkR3S0qKgp1dXUoKyvrVnfn58+fx6hRo5Ceno45c+aIjtPdsMyJ6G4VFRX4/e9/j3379uGpp57qOm4wGHD9+nX85je/Men1JUnC1atX8dvf/vau47NmzcLFixfx9ddfw8qKD+L9Cz6aSER38/HxQUxMDFavXg2DwQBJknDgwAF4enpixIgR6OjoMOn1P/nkEwwZMgQzZ87EN998AwA4c+YMMjMz8de//pVF/gC8Myeie1RVVcHLywtLly5FTk4OvvnmGygUCkiShEuXLsHV1dVk137rrbeQlJQESZJgMBgwe/ZsXL9+HU1NTSguLu5WQz/dCO/MiehukiThzJkzGDhwIDZv3owLFy50HQd+KnpTqqqqgkKhQEdHByRJwv79+/H555/D1tbW5Nd+lLHMiajL4cOHMWbMGMTExODGjRtdd8edlEol/vGPf5g0w4ULF9De3t71ur29HZIkobi4GB4eHnj66adNnuFRxDInIgDA2rVrERERgfLycgC4q8Q7WVlZ4dKlSybNUV1dfd/jnaV+6NAheHt74+zZsybN8ahhmRMRAGDSpEno06fPQz/T1taGb7/91mQZ7ty5g6tXr/7s53x9fTFixAiT5XgUscyJCAAQGBiIkpISDBw4EDY2Nvf9jCRJJt1m7tKlS3jYMxnW1tb4r//6L+Tn56Nv374my/EoYpkTURdPT08UFxdj8ODBDyz0urq6+w7BGMODhliAn4Z4oqKicODAAdja2prk+o8yljkR3cXV1RUnT56ESqW6b6G3tbXhypUrJrn2P/7xD/To0eOe4wqFAs8++yw++ugjLq71ACxzIrqHi4sLioqK8Lvf/e6+hf6wO+hf435PqSgUCixZsgQ7duzgeiwPwTInovv6zW9+g1OnTuH3v//9XYVubW1tsjK/cOEC2tra7jr2+uuvY+vWrZws9DNY5kT0QAMGDEBeXh7GjRvXVeg2NjYme877X5+U2bBhA9asWWOSa8nN/X/hICL6//Xp0weffPIJpk2bhsLCQrS1td23zPV6Pa5evYq6ujo0NzejpaUFd+7c6Xrf3t4e1tbWGDRoEIYOHQoHB4d7/v/19fUAfhpa2bhxI5YvX27aLycjLHMi+ll9+vTBkSNHEB0djSNHjqC0tBTvvfceKioqUFlZiaqqKjQ0NPxHi3D17NkTKpUKnp6e8Pb2xm9+8xt0dHRAoVAgNTUVL7zwggm/kfxwoS0ieiiDwYDCwkLk5OSgoKAARUVF6OjogJOTEzw8PODh4QE3NzeoVCqoVCq4uLg88BlwSZLQ0NAAjUYDjUaDuro6XLx4ERcvXsT58+fR2toKe3t7TJo0CSEhIQgPD8fw4cPN+4UfTVzPnIjuLy8vD3v27EF2djauXbsGDw8PhIaGYsKECfDz84O7u7tRr2cwGFBUVISvv/4a+fn5yMvLg06ng6+vL6KiorBgwQKoVCqjXlNGWOZE9E+3b99Geno6UlNTUVFRAT8/P8ycORPR0dHw8PAwaxa9Xo+8vDxkZWXhwIED0Ol0iIyMxOLFixEWFmbWLI8AljkRATdv3sTGjRvx7rvvQqlUIiEhAQsWLDD63fcvZTAYcPz4cbz//vvIysqCp6cnli9fjri4OG5W8ROWOZElMxgM2LFjB5KSktDe3o4lS5Zg6dKlGDhwoOhoD3T69GmsXbsWhw4dQkBAAFJTU+Hn5yc6lmjcnILIUpWXl2P8+PF46aWXkJCQgNraWqxZs6ZbFzkA+Pn5ISsrC2fPnkXv3r3h7++PpUuX4ocffhAdTSiWOZGFkSQJycnJ8Pf3h52dHc6dO4d169ahX79+oqP9R0aNGoWjR4/iww8/xP79+zF69GiUlpaKjiUMy5zIgnz//feIiIjAihUrsH79ehw7dqzbjIv/UrNnz8a5c+fg5eWFcePGISUlRXQkIThpiMhCaDQaPPnkk2hqakJhYSHGjBkjOpLRODg44NChQ0hOTkZiYiKqq6uxZcsWi1qYi2VOZAGqqqoQGhoKJycnFBYWYsiQIaIjGZ1CocDLL7+MESNGYM6cOaivr8dHH330wHXZ5YbDLEQyp9FoMHnyZLi4uCA/P1+WRf5/RURE4OjRozhy5Aji4+MfunORnLDMiWTs9u3bmDp1Knr37o3Dhw/D3t5edCSzGDt2LPbv34+MjAysWrVKdByzYJkTydiyZctw5coV5OTk3LNKodxNnToV27Ztw4YNG/D555+LjmNynDREJFPZ2dmIjIxEZmYmZs6cKTqOMNHR0SgpKUFFRQX69+8vOo6pcAYokRy1tbXBy8sL/v7+2Lt3r+g4Qul0OqjVasTHx2Pjxo2i45gKZ4ASyVFqaiq0Wi3Wr18vOopwDg4OSEpKQkpKCurq6kTHMRnemRPJjMFgwPDhwxEdHY2tW7ea5ZparRa5ubk4cuQILl++jKKiorvelyQJO3fuxJEjR6BWq3H16lWEhYXhmWeeMUu+1tZWuLm5Yc6cOXjrrbfMck0zy4RERLLy2WefSQqFQrp48aJZr9vY2CgBkNzd3e95b82aNdKwYcOkxsbGrs8OGzZM2rp1q9nyvfHGG5KDg4N0584ds13TjPZxmIVIZjIzMxEQEAC1Wm3W6w4YMOC+x+vq6rB27VosWrSo6zMDBgxAQkIC/vKXv0Cn05kl37x586DT6VBQUGCW65kby5xIZgoKCjBlyhTRMbrs2bMHer0eEydOvOt4WFgYmpub8be//c0sOVxdXaFWq1nmRNT9Xb9+HZcuXUJAQIDoKF1OnjwJAHB2dr7reOcWcGfPnjVblsDAQBQXF5vteubEMieSkbq6OkiS1K1WQqyvrwdw7zBM57rpNTU1ZsuiVqtRW1trtuuZE8ucSEY6x5+702zPziUEFArFXcc7X7e1tZkti6OjI27cuGG265kTy5xIRpqbmwEAPXv2FJzknzo3gr5169Zdx2/evAkAZl34q1evXl1/I7lhmRPJSOfQRWdRdgdeXl4A/jnc0qnzdVBQkNmyNDY2dvtt8X4pljmRjHQWVXcaSpg5cyasrKxw/Pjxu45/8cUXUCqVZps4BPz0A7Gjo6PZrmdOLHMiGVGr1bCzs0NZWZnZr3379m0AP81A/b+cnZ3x5z//GWlpaWhqagIANDU1IS0tDatWrep6qsUcysrK4OPjY7brmZNlbMFBZCFsbW3h6+uLoqIizJ0712zX/eKLL/Dhhx8CAGpra7F582aEhYXB19cXALB27Vq4urpi8eLFcHFxwbfffovXXnsN8fHxZssoSRK+/PJLrF692mzXNCeuzUIkM6tWrcLu3btRW1trUXtg/pz8/HyEhISgvLxcjnfnXDWRSG6ee+45aLVa5OTkiI7SraSlpeHxxx+XY5ED4Jg5key4uroiKCgIKSkpoqN0G5cvX8bBgwcxf/580VFMhsMsRDJUUFCA4OBgfPLJJ5g2bZroOMLFxsaipKQElZWV6NGjh+g4psCdhojkavr06aipqUFZWRns7OxExxGmqKgIQUFBSE9PN+tjkGbGMieSq5qaGowePRrz5s1DcnKy6DhCNDU1wc/PD+7u7vj000/vWVJARvgDKJFcubq6Ii0tDdu2bUNWVpboOGZnMBiQkJCAlpYW7N69W85FDoDPmRPJWkxMDEpKShAbG4vc3FxMmDBBdCSzSUxMxOHDh3Hs2DE4OTmJjmNyvDMnkrm3334bUVFRiIiI6FpbXM4kSUJSUhK2b9+OjIwMjB07VnQks2CZE8mcQqHArl278MQTT2Dy5MmyHnJpb2/HwoULsWnTJuzatQszZswQHclsWOZEFqBHjx7Yu3cvFi9ejJiYGKxevRp6vV50LKPSarWYPHkyDh48iM8++wxxcXGiI5kVy5zIQlhZWWHTpk3YsWMHNm/ejNDQUNnsuvPxxx/D19cXt27dQnFx8T37jVoCljmRhXn22WdRVlaGlpYWeHt7Y82aNWhpaREd6xeprq5GeHg4oqKiMGvWLBQXF3dthmFpWOZEFkitVqO4uBhr167Fpk2b4OnpiV27dj0yQy9Xr17FsmXL4OPjg9raWuTn52P79u0WPTmKZU5koWxsbJCYmIjz588jODgYCQkJ8Pb2Rnp6OlpbW0XHuy+tVouVK1di5MiRyMjIwIYNG/D1119j/PjxoqMJxxmgRATgpyGLdevWISMjA/369cPChQsRHx8PNzc3obk6Ojpw/PhxvPfee8jOzoaTkxNeffVVPP/88+jVq5fQbN0Ip/MT0d2uXbuG3bt344MPPkBVVRX8/PwQHR2NyMhI+Pj4mGUmZXNzM06ePIkDBw7g0KFDuHHjBqZMmYKEhASEh4dDqVSaPMMjhmVORPfXuTNPZmYm9u/fj++++w79+/dHYGAgAgIC4OfnBx8fH7i6uv6q67S1taGyshIVFRUoLS1FUVERzpw5A71ej8DAQMTExOCpp56Cs7Ozkb6ZLLHMiejnSZKEc+fOoaCgACdOnMCpU6dQX18PALC3t4darYazszNcXFzg4uKCvn37PvA8DQ0N0Gg00Gg0qK2tRXV1NfR6PWxsbODp6YkJEyYgKCgIwcHBGDx4sDm/5qOMZU5Ev4xOp0NFRQUqKytRVVUFrVYLrVaLuro6NDc3o6WlBXfu3On6vL29PaytrTFo0CAMHToUzs7OUKlU8PT0hLe3Nzw9PWFrayvwGz3SWOZEZDr79u3DrFmzwJoxOS6BS0QkByxzIiIZYJkTEckAy5yISAZY5kREMsAyJyKSAZY5EZEMsMyJiGSAZU5EJAMscyIiGWCZExHJAMuciEgGWOZERDLAMicikgGWORGRDLDMiYhkgGVORCQDLHMiIhlgmRMRyQDLnIhIBljmREQywDInIpIBljkRkQywzImIZIBlTkQkAyxzIiIZYJkTEckAy5yISAZY5kREMsAyJyKSAZY5EZEMsMyJiGTARnQAIpKPSZMm4cKFC12vW1tboVQq4ezsfNfnVqxYgSVLlpg7nqyxzInIaOrr61FfXw9Jku46rtVq73rd1NRkzlgWgcMsRGQ08+fPh7W19UM/o1AoMHfuXDMlshwscyIymjlz5qCjo+OB71tZWeGxxx7DsGHDzJjKMrDMichoVCoVAgICYGV1/2rhXbnpsMyJyKjmzp0LhULxwPdnz55txjSWg2VOREb19NNP3/e4jY0NQkJC4OTkZOZEloFlTkRG5ejoiIkTJ97zQ6jBYEBcXJygVPLHMicio4uLi7vn8UQbGxtER0cLSiR/LHMiMroZM2ZAqVR2vVYqlZg2bRrs7e0FppI3ljkRGV3fvn0RHh7eVeh6vR6xsbGCU8kby5yITCI2Nhbt7e0AgF69emHatGmCE8kby5yITGLq1Kno3bs3ACAqKgp2dnaCE8kb12YhIqPQ6/W4evUq6urq0NzcjJaWFvj7+yMvLw8qlQq5ubmwtrbGoEGDMHToUDg4OIiOLCsK6V9/ciYieojW1laUlpaivLwcFRUVqKysRFVVFRoaGh46lf9f9ezZEyqVCp6envD29saoUaPg6+sLDw8PE6aXrUyWORE9lMFgQGFhIXJycnDixAl89dVXuHPnDpycnODh4QEPDw+4ublBpVJBpVLBxcUFffv2ve+5JElCQ0MDNBoNNBoN6urqcPHixa5/LS0tGDRoEIKCghASEoLw8HAMHz7cvF/40cQyJ6L7y8vLw549e5CdnY1r167Bw8MDoaGhCA4OxoQJEzB48GCjXs9gMKCiogL5+fnIz89HXl4edDodfH19ERUVhQULFkClUhn1mjLCMieif7p9+zbS09ORmpqKiooK+Pn5YebMmYiOjjb78Ider0deXh6ysrJw4MAB6HQ6REZGYvHixQgLCzNrlkcAy5yIgJs3b2Ljxo149913oVQqkZCQgAULFsDd3V10NAA/3bUfP34c77//PrKysuDp6Ynly5cjLi7ugSs0WhiWOZElMxgM2LFjB5KSktDe3o4lS5Zg6dKlGDhwoOhoD3T69GmsXbsWhw4dQkBAAFJTU+Hn5yc6lmiZ/E8akYUqLy/H+PHj8dJLLyEhIQG1tbVYs2ZNty5yAPDz80NWVhbOnj2L3r17w9/fH0uXLsUPP/wgOppQLHMiCyNJEpKTk+Hv7w87OzucO3cO69atQ79+/URH+4+MGjUKR48exYcffoj9+/dj9OjRKC0tFR1LGJY5kQX5/vvvERERgRUrVmD9+vU4duxYtxkX/6Vmz56Nc+fOwcvLC+PGjUNKSoroSEJwBiiRhdBoNHjyySfR1NSEwsJCjBkzRnQko3FwcMChQ4eQnJyMxMREZ2LYUwAAIABJREFUVFdXY8uWLT+7ubScsMyJLEBVVRVCQ0Ph5OSEwsJCDBkyRHQko1MoFHj55ZcxYsQIzJkzB/X19fjoo49gY2MZNcdhFiKZ02g0mDx5MlxcXJCfny/LIv+/IiIicPToURw5cgTx8fH3bJIhVyxzIhm7fft21+qFhw8ftpjNIcaOHYv9+/cjIyMDq1atEh3HLFjmRDK2bNkyXLlyBTk5ORa3SuHUqVOxbds2bNiwAZ9//rnoOCbHSUNEMpWdnY3IyEhkZmZi5syZouMIEx0djZKSElRUVKB///6i45gKZ4ASyVFbWxu8vLzg7++PvXv3io4jlE6ng1qtRnx8PDZu3Cg6jqlwBiiRHKWmpkKr1WL9+vWiowjn4OCApKQkpKSkoK6uTnQck+GdOZHMGAwGDB8+HNHR0di6dauQDDdv3sTrr78OJycn3LhxAzqdDhs3bhS2hG1rayvc3NwwZ84cvPXWW0IymBjvzInkJjc3FxqNBi+++KKQ6zc3N+Pxxx/HkCFDsHr1amzbtg1hYWEYM2YMvvvuOyGZbG1tER8fj507d6K1tVVIBlNjmRPJTGZmJgICAqBWq4Vcf/PmzaiqqrrrR9dnn30Wer0eb7zxhpBMADBv3jzodDoUFBQIy2BKLHMimSkoKMCUKVOEXf/EiRMAABcXl65jSqUSY8aMQWZmprBJPK6urlCr1SxzIur+rl+/jkuXLiEgIEBYhsbGxrv+t5OjoyN+/PFHXLlyRUQsAEBgYCCKi4uFXd+UWOZEMlJXVwdJkoSuhOjl5QUAOHbs2F3HlUolAKCjo8PsmTqp1WrU1tYKu74pscyJZESn0wGA0Nmer7zyCqysrLBy5UqcOnUK33//PQ4cOIC///3vsLa2NvpG0P8JR0dH3LhxQ9j1TYllTiQjzc3NAICePXsKy/D//t//w7Fjx+Di4oInnngC48ePR1NTEyRJQmhoqNBVDHv16tX1N5IbljmRjHRu+Xbz5k2hOUJDQ1FcXIwff/wR586dw8CBA3Ht2jXMnz9faK7GxsZuvy3eL8UyJ5KRzqLqTkMJP/zwA5YvX47x48djzpw5QrNcv34djo6OQjOYCsucSEbUajXs7OxQVlYmOgqAn2ZeLly4EAqFAhkZGbCyEls5ZWVl8PHxEZrBVFjmRDJia2sLX19fFBUViY6Cs2fPYty4cejRowcKCgrg7OwsNI8kSfjyyy8RGBgoNIepWMZ+SkQWZOLEidi9eze2bdsmZA/Mmpoa7Ny5E7a2ttixYwd+//vfmz3D/RQUFKCxsRFhYWGio5gEF9oikpmamhqMHDkS2dnZmD59uug43cYzzzyDS5cuyXXSEBfaIpIbV1dXBAUFISUlRXSUbuPy5cs4ePCg8KdpTIl35kQyVFBQgODgYHzyySeYNm2a6DjCxcbGoqSkBJWVlejRo4foOKbAnYaI5Gr69OmoqalBWVkZ7OzsRMcRpqioCEFBQUhPT8czzzwjOo6psMyJ5KqmpgajR4/GvHnzkJycLDqOEE1NTfDz84O7uzs+/fRTKBQK0ZFMhWPmRHLl6uqKtLQ0bNu2DVlZWaLjmJ3BYEBCQgJaWlqwe/duORc5AD6aSCRrMTExKCkpQWxsLHJzczFhwgTRkcwmMTERhw8fxrFjx+Dk5CQ6jsnxzpxI5t5++21ERUUhIiICJ0+eFB3H5CRJQlJSErZv346MjAyMHTtWdCSzYJkTyZxCocCuXbvwxBNPYPLkybIecmlvb8fChQuxadMm7Nq1CzNmzBAdyWxY5kQWoEePHti7dy8WL16MmJgYrF69Gnq9XnQso9JqtZg8eTIOHjyIzz77DHFxcaIjmRXLnMhCWFlZYdOmTdixYwc2b96M0NBQ2ey68/HHH8PX1xe3bt1CcXExJk6cKDqS2bHMiSzMs88+i7KyMrS0tMDb2xtr1qxBS0uL6Fi/SHV1NcLDwxEVFYVZs2ahuLgYHh4eomMJwTInskBqtRrFxcVYu3YtNm3aBE9PT+zateuRGXq5evUqli1bBh8fH9TW1iI/Px/bt2+36MlRLHMiC2VjY4PExEScP38ewcHBSEhIgLe3N9LT09Ha2io63n1ptVqsXLkSI0eOREZGBjZs2ICvv/4a48ePFx1NOM4AJSIAPw1ZrFu3DhkZGejXrx8WLlyI+Ph4uLm5Cc3V0dGB48eP47333kN2djacnJzw6quv4vnnn0evXr2EZutGOJ2fiO527do17N69Gx988AGqqqrg5+eH6OhoREZGwsfHxywzKZubm3Hy5EkcOHAAhw4dwo0bNzBlyhQkJCQgPDwcSqXS5BkeMSxzIrq/zp15MjMzsX//fnz33Xfo378/AgMDERAQAD8/P/j4+MDV1fVXXaetrQ2VlZWoqKhAaWkpioqKcObMGej1egQGBiImJgZPPfWU8J2KujmWORH9PEmScO7cORQUFODEiRM4deoU6uvrAQD29vZQq9VwdnaGi4sLXFxc0Ldv3weep6GhARqNBhqNBrW1taiuroZer4eNjQ08PT0xYcIEBAUFITg4GIMHDzbn13yUscyJ6JfR6XSoqKhAZWUlqqqqoNVqodVqUVdXh+bmZrS0tODOnTtdn7e3t4e1tTUGDRqEoUOHwtnZGSqVCp6envD29oanpydsbW0FfqNHGsuciExn3759mDVrFlgzJsclcImI5IBlTkQkAyxzIiIZYJkTEckAy5yISAZY5kREMsAyJyKSAZY5EZEMsMyJiGSAZU5EJAMscyIiGWCZExHJAMuciEgGWOZERDLAMicikgGWORGRDLDMiYhkgGVORCQDLHMiIhlgmRMRyQDLnIhIBljmREQywDInIpIBljkRkQywzImIZIBlTkQkAyxzIiIZYJkTEckAy5yISAZY5kREMsAyJyKSAZY5EZEM2IgOQETyMWnSJFy4cKHrdWtrK5RKJZydne/63IoVK7BkyRJzx5M1ljkRGU19fT3q6+shSdJdx7Va7V2vm5qazBnLInCYhYiMZv78+bC2tn7oZxQKBebOnWumRJaDZU5ERjNnzhx0dHQ88H0rKys89thjGDZsmBlTWQaWOREZjUqlQkBAAKys7l8tvCs3HZY5ERnV3LlzoVAoHvj+7NmzzZjGcrDMicionn766fset7GxQUhICJycnMycyDKwzInIqBwdHTFx4sR7fgg1GAyIi4sTlEr+WOZEZHRxcXH3PJ5oY2OD6OhoQYnkj2VOREY3Y8YMKJXKrtdKpRLTpk2Dvb29wFTyxjInIqPr27cvwsPDuwpdr9cjNjZWcCp5Y5kTkUnExsaivb0dANCrVy9MmzZNcCJ5Y5kTkUlMnToVvXv3BgBERUXBzs5OcCJ549osRGQUer0eV69eRV1dHZqbm9HS0gJ/f3/k5eVBpVIhNzcX1tbWGDRoEIYOHQoHBwfRkWVFIf3rT85ERA/R2tqK0tJSlJeXo6KiApWVlaiqqkJDQ8NDp/L/q549e0KlUsHT0xPe3t4YNWoUfH194eHhYcL0spXJMieihzIYDCgsLEROTg5OnDiBr776Cnfu3IGTkxM8PDzg4eEBNzc3qFQqqFQquLi4oG/fvvc9lyRJaGhogEajgUajQV1dHS5evNj1r6WlBYMGDUJQUBBCQkIQHh6O4cOHm/cLP5pY5kR0f3l5edizZw+ys7Nx7do1eHh4IDQ0FMHBwZgwYQIGDx5s1OsZDAZUVFQgPz8f+fn5yMvLg06ng6+vL6KiorBgwQKoVCqjXlNGWOZE9E+3b99Geno6UlNTUVFRAT8/P8ycORPR0dFmH/7Q6/XIy8tDVlYWDhw4AJ1Oh8jISCxevBhhYWFmzfIIYJkTEXDz5k1s3LgR7777LpRKJRISErBgwQK4u7uLjgbgp7v248eP4/3330dWVhY8PT2xfPlyxMXFPXCFRgvDMieyZAaDATt27EBSUhLa29uxZMkSLF26FAMHDhQd7YFOnz6NtWvX4tChQwgICEBqair8/PxExxItk/9JI7JQ5eXlGD9+PF566SUkJCSgtrYWa9as6dZFDgB+fn7IysrC2bNn0bt3b/j7+2Pp0qX44YcfREcTimVOZGEkSUJycjL8/f1hZ2eHc+fOYd26dejXr5/oaP+RUaNG4ejRo/jwww+xf/9+jB49GqWlpaJjCcMyJ7Ig33//PSIiIrBixQqsX78ex44d6zbj4r/U7Nmzce7cOXh5eWHcuHFISUkRHUkIzgAlshAajQZPPvkkmpqaUFhYiDFjxoiOZDQODg44dOgQkpOTkZiYiOrqamzZsuVnN5eWE5Y5kQWoqqpCaGgonJycUFhYiCFDhoiOZHQKhQIvv/wyRowYgTlz5qC+vh4fffQRbGwso+Y4zEIkcxqNBpMnT4aLiwvy8/NlWeT/V0REBI4ePYojR44gPj7+nk0y5IplTiRjt2/f7lq98PDhwxazOcTYsWOxf/9+ZGRkYNWqVaLjmAXLnEjGli1bhitXriAnJ8fiVimcOnUqtm3bhg0bNuDzzz8XHcfkOGmISKays7MRGRmJzMxMzJw5U3QcYaKjo1FSUoKKigr0799fdBxT4QxQIjlqa2uDl5cX/P39sXfvXtFxhNLpdFCr1YiPj8fGjRtFxzEVzgAlkqPU1FRotVqsX79edBThHBwckJSUhJSUFNTV1YmOYzIscyKZMRgM2LJlCxYtWiR0LfDS0lJMnDgRffv2xZAhQ5CQkIAbN24IybJ48WI4OjoiNTVVyPXNgWVOJDO5ubnQaDR48cUXhWU4c+YM3nzzTaxZswYFBQUIDQ3F3/72N8yfP19IHltbW8THx2Pnzp1obW0VksHUOGZOJDMLFy7EhQsXUFhYKCzD5s2b8fzzz6NXr14AgPb2djg5OaGjo0PYglg1NTUYMWIE/v73v2Py5MlCMpgQx8yJ5KagoABTpkwRmiExMbGryDvp9XrExsYKSgS4urpCrVajoKBAWAZTsox5rkQW4vr167h06RICAgJER+liMBjw17/+Fe+88w7++Mc/Cs0SGBiI4uJioRlMhWVOJCN1dXWQJKnbrIR48OBBbNmyBSdOnMCwYcMgSRIWLVoEhUIhJI9arcapU6eEXNvUWOZEMqLT6QCg28z2DAkJgbu7O44fP44VK1bghRdegFKpxHPPPSckj6Ojo7AnakyNY+ZEMtLc3AwA6Nmzp+AkPxkwYAC8vLzw0ksvIS0tDQCQnp4uLE+vXr26/kZywzInkpHOLd9u3rwpOMm9IiMjAQC9e/cWlqGxsbHbb4v3S7HMiWSks6i641BCfX09ACA8PFxYhuvXr8PR0VHY9U2JZU4kI2q1GnZ2digrKxOa45133sF///d/o6mpCQDQ0tKC5cuXY+HChVi0aJGwXGVlZfDx8RF2fVNimRPJiK2tLXx9fVFUVCQ0R2NjI1avXo2RI0di2bJlWL16NZKSkrBjxw5hT7JIkoQvv/wSgYGBQq5vapwBSiQzq1atwu7du1FbW2tRe2D+nPz8fISEhKC8vFyOd+ecAUokN8899xy0Wi1ycnJER+lW0tLS8Pjjj8uxyAFwmIVIdlxdXREUFISUlBTRUbqNy5cv4+DBg8IW+jIHDrMQyVBBQQGCg4PxySefYNq0aaLjCBcbG4uSkhJUVlaiR48eouOYAncaIpKr6dOno6amBmVlZbCzsxMdR5iioiIEBQUhPT0dzzzzjOg4psIyJ5KrmpoajB49GvPmzUNycrLoOEI0NTXBz88P7u7u+PTTT4U9SWMG/AGUSK5cXV2RlpaGbdu2ISsrS3QcszMYDEhISEBLSwt2794t5yIHwIW2iGQtJiYGJSUliI2NRW5uLiZMmCA6ktkkJibi8OHDOHbsGJycnETHMTnemRPJ3Ntvv42oqChERETg5MmTouOYnCRJSEpKwvbt25GRkYGxY8eKjmQWLHMimVMoFNi1axeeeOIJTJ48WdZDLu3t7Vi4cCE2bdqEXbt2YcaMGaIjmQ3LnMgC9OjRA3v37sXixYsRExOD1atXQ6/Xi45lVFqtFpMnT8bBgwfx2WefIS4uTnQks2KZE1kIKysrbNq0CTt27MDmzZsRGhqK2tpa0bGM4uOPP4avry9u3bqF4uJiTJw4UXQks2OZE1mYZ599FmVlZWhpaYG3tzfWrFmDlpYW0bF+kerqaoSHhyMqKgqzZs1CcXExPDw8RMcSgmVOZIHUajWKi4uxdu1abNq0CZ6enti1a9cjM/Ry9epVLFu2DD4+PqitrUV+fj62b99u0ZOjWOZEFsrGxgaJiYk4f/48goODkZCQAG9vb6Snp6O1tVV0vPvSarVYuXIlRo4ciYyMDGzYsAFff/01xo8fLzqacJwBSkQAfhqyWLduHTIyMtCvXz8sXLgQ8fHxcHNzE5qro6MDx48fx3vvvYfs7Gw4OTnh1VdfxfPPP49evXoJzdaNcDo/Ed3t2rVr2L17Nz744ANUVVXBz88P0dHRiIyMhI+Pj1lmUjY3N+PkyZM4cOAADh06hBs3bmDKlClISEhAeHg4lEqlyTM8YljmRHR/nTvzZGZmYv/+/fjuu+/Qv39/BAYGIiAgAH5+fvDx8YGrq+uvuk5bWxsqKytRUVGB0tJSFBUV4cyZM9Dr9QgMDERMTAyeeuopODs7G+mbyRLLnIh+niRJOHfuHAoKCnDixAmcOnWqa4Nme3t7qNVqODs7w8XFBS4uLujbt+8Dz9PQ0ACNRgONRoPa2lpUV1dDr9fDxsYGnp6emDBhAoKCghAcHIzBgweb82s+yljmRPTL6HQ6VFRUoLKyElVVVdBqtdBqtairq0NzczNaWlpw586drs/b29vD2toagwYNwtChQ+Hs7AyVSgVPT094e3vD09MTtra2Ar/RI41lTkSms2/fPsyaNQusGZPjErhERHLAMicikgGWORGRDLDMiYhkgGVORCQDLHMiIhlgmRMRyQDLnIhIBljmREQywDInIpIBljkRkQywzImIZIBlTkQkAyxzIiIZYJkTEckAy5yISAZY5kREMsAyJyKSAZY5EZEMsMyJiGSAZU5EJAMscyIiGWCZExHJAMuciEgGWOZERDLAMicikgGWORGRDLDMiYhkgGVORCQDLHMiIhlgmRMRyQDLnIhIBmxEByAi+Zg0aRIuXLjQ9bq1tRVKpRLOzs53fW7FihVYsmSJuePJGsuciIymvr4e9fX1kCTpruNarfau101NTeaMZRE4zEJERjN//nxYW1s/9DMKhQJz5841UyLLwTInIqOZM2cOOjo6Hvi+lZUVHnvsMQwbNsyMqSwDy5yIjEalUiEgIABWVvevFt6Vmw7LnIiMau7cuVAoFA98f/bs2WZMYzlY5kRkVE8//fR9j9vY2CAkJAROTk5mTmQZWOZEZFSOjo6YOHHiPT+EGgwGxMXFCUolfyxzIjK6uLi4ex5PtLGxQXR0tKBE8scyJyKjmzFjBpRKZddrpVKJadOmwd7eXmAqeWOZE5HR9e3bF+Hh4V2FrtfrERsbKziVvLHMicgkYmNj0d7eDgDo1asXpk2bJjiRvLHMicgkpk6dit69ewMAoqKiYGdnJziRvHFtFiIyCr1ej6tXr6Kurg7Nzc1oaWmBv78/8vLyoFKpkJubC2trawwaNAhDhw6Fg4OD6MiyopD+9SdnIqKHaG1tRWlpKcrLy1FRUYHKykpUVVWhoaHhoVP5/1XPnj2hUqng6ekJb29vjBo1Cr6+vvDw8DBhetnKZJkT0UMZDAYUFhYiJycHJ06cwFdffYU7d+7AyckJHh4e8PDwgJubG1QqFVQqFVxcXNC3b9/7nkuSJDQ0NECj0UCj0aCurg4XL17s+tfS0oJBgwYhKCgIISEhCA8Px/Dhw837hR9NLHMiur+8vDzs2bMH2dnZuHbtGjw8PBAaGorg4GBMmDABgwcPNur1DAYDKioqkJ+fj/z8fOTl5UGn08HX1xdRUVFYsGABVCqVUa8pIyxzIvqn27dvIz09HampqaioqICfnx9mzpyJ6Ohosw9/6PV65OXlISsrCwcOHIBOp0NkZCQWL16MsLAws2Z5BLDMiQi4efMmNm7ciHfffRdKpRIJCQlYsGAB3N3dRUcD8NNd+/Hjx/H+++8jKysLnp6eWL58OeLi4h64QqOFYZkTWTKDwYAdO3YgKSkJ7e3tWLJkCZYuXYqBAweKjvZAp0+fxtq1a3Ho0CEEBAQgNTUVfn5+omOJlsn/pBFZqPLycowfPx4vvfQSEhISUFtbizVr1nTrIgcAPz8/ZGVl4ezZs+jduzf8/f2xdOlS/PDDD6KjCcUyJ7IwkiQhOTkZ/v7+sLOzw7lz57Bu3Tr069dPdLT/yKhRo3D06FF8+OGH2L9/P0aPHo3S0lLRsYRhmRNZkO+//x4RERFYsWIF1q9fj2PHjnWbcfFfavbs2Th37hy8vLwwbtw4pKSkiI4kBGeAElkIjUaDJ598Ek1NTSgsLMSYMWNERzIaBwcHHDp0CMnJyUhMTER1dTW2bNnys5tLywnLnMgCVFVVITQ0FE5OTigsLMSQIUNERzI6hUKBl19+GSNGjMCcOXNQX1+Pjz76CDY2llFzHGYhkjmNRoPJkyfDxcUF+fn5sizy/ysiIgJHjx7FkSNHEB8ff88mGXLFMieSsdu3b3etXnj48GGL2Rxi7Nix2L9/PzIyMrBq1SrRccyCZU4kY8uWLcOVK1eQk5NjcasUTp06Fdu2bcOGDRvw+eefi45jcpw0RCRT2dnZiIyMRGZmJmbOnCk6jjDR0dEoKSlBRUUF+vfvLzqOqXAGKJEctbW1wcvLC/7+/ti7d6/oOELpdDqo1WrEx8dj48aNouOYCmeAEslRamoqtFot1q9fLzqKcA4ODkhKSkJKSgrq6upExzEZljmRzBgMBmzZsgWLFi0Suha4VqvFzp07ERMTg8DAQGE5AGDx4sVwdHREamqq0BymxDInkpnc3FxoNBq8+OKLQnMMHToUUVFRyMzMxM2bN4VmsbW1RXx8PHbu3InW1lahWUyFZU4kM5mZmQgICIBarRYdBQMGDBAdocu8efOg0+lQUFAgOopJsMyJZKagoABTpkwRHaPbcXV1hVqtZpkTUfd3/fp1XLp0CQEBAaKjdEuBgYEoLi4WHcMkWOZEMlJXVwdJkh75lRBNRa1Wo7a2VnQMk2CZE8mITqcDAIub7fnvcnR0xI0bN0THMAmWOZGMNDc3AwB69uwpOEn31KtXr66/kdywzIlkpHPLN9GPAnZXjY2N3X5bvF+KZU4kI51FJdehhF/r+vXrcHR0FB3DJFjmRDKiVqthZ2eHsrIy0VEA/LQEL/DTrNTuoKysDD4+PqJjmATLnEhGbG1t4evri6KiItFR8MUXX2DJkiUAgNraWmzevBlnzpwRlkeSJHz55ZfClxYwFa6aSCQzq1atwu7du1FbW2tRe2D+nPz8fISEhKC8vFyOd+dcNZFIbp577jlotVrk5OSIjtKtpKWl4fHHH5djkQPgMAuR7Li6uiIoKAgpKSmio3Qbly9fxsGDBzF//nzRUUyGwyxEMlRQUIDg4GB88sknmDZtmug4wsXGxqKkpASVlZXo0aOH6DimwJ2GiORq+vTpqKmpQVlZGezs7ETHEaaoqAhBQUFIT0/HM888IzqOqbDMieSqpqYGo0ePxrx585CcnCw6jhBNTU3w8/ODu7s7Pv30UygUCtGRTIU/gBLJlaurK9LS0rBt2zZkZWWJjmN2BoMBCQkJaGlpwe7du+Vc5AAAG9EBiMh0YmJiUFJSgtjYWOTm5mLChAmiI5lNYmIiDh8+jGPHjsHJyUl0HJPjnTmRzL399tuIiopCREQETp48KTqOyUmShKSkJGzfvh0ZGRkYO3as6EhmwTInkjmFQoFdu3bhiSeewOTJk2U95NLe3o6FCxdi06ZN2LVrF2bMmCE6ktmwzIksQI8ePbB3714sXrwYMTExWL16NfR6vehYRqXVajF58mQcPHgQn332GeLi4kRHMiuWOZGFsLKywqZNm7Bjxw5s3rwZoaGhstl15+OPP4avry9u3bqF4uJiTJw4UXQks2OZE1mYZ599FmVlZWhpaYG3tzfWrFmDlpYW0bF+kerqaoSHhyMqKgqzZs1CcXExPDw8RMcSgmVOZIHUajWKi4uxdu1abNq0CZ6enti1a9cjM/Ry9epVLFu2DD4+PqitrUV+fj62b99u0ZOjWOZEFsrGxgaJiYk4f/48goODkZCQAG9vb6Snp6O1tVV0vPvSarVYuXIlRo4ciYyMDGzYsAFff/01xo8fLzqacJwBSkQAfhqyWLduHTIyMtCvXz8sXLgQ8fHxcHNzE5qro6MDx48fx3vvvYfs7Gw4OTnh1VdfxfPPP49evXoJzdaNcDo/Ed3t2rVr2L17Nz744ANUVVXBz88P0dHRiIyMhI+Pj1lmUjY3N+PkyZM4cOAADh06hBs3bmDKlClISEhAeHg4lEqlyTM8YljmRHR/nTvzZGZmYv/+/fjuu+/Qv39/BAYGIiAgAH5+fvDx8YGrq+uvuk5bWxsqKytRUVGB0tJSFBUV4cyZM9Dr9QgMDERMTAyeeuopODs7G+mbyRLLnIh+niRJOHfuHAoKCnDixAmcOnUK9fX1AAB7e3uo1Wo4OzvDxcUFLi4u6Nu37wPP09DQAI1GA41Gg9raWlRXV0Ov18PGxgaenp6YMGECgoKCEBwcjMGDB5vzaz7KWOZE9MvodDpUVFSgsrISVVVV0Gq10Gq1qKurQ3NzM1paWnDnzp2uz9vb28Pa2hqDBg3C0KFD4ezsDJVKBU9PT3h7e8PT0xO2trYCv9EjjWVORKazb98+zJo1C6wZk+MSuEREcsAyJyKSAZY5EZEMsMyJiGSAZU5EJAMscyIiGWCZExHJAMuciEgGWOZERDLAMicikgGWORGRDLDMiYhkgGVORCQDLHMiIhlgmRMRyQDLnIhIBljmREQywDJgx4VvAAAQFUlEQVQnIpIBljkRkQywzImIZIBlTkQkAyxzIiIZYJkTEckAy5yISAZY5kREMsAyJyKSAZY5EZEMsMyJiGSAZU5EJAMscyIiGWCZExHJAMuciEgGbEQHICL5mDRpEi5cuND1urW1FUqlEs7Oznd9bsWKFViyZIm548kay5yIjKa+vh719fWQJOmu41qt9q7XTU1N5oxlETjMQkRGM3/+fFhbWz/0MwqFAnPnzjVTIsvBMicio5kzZw46Ojoe+L6VlRUee+wxDBs2zIypLAPLnIiMRqVSISAgAFZW968W3pWbDsuciIxq7ty5UCgUD3x/9uzZZkxjOVjmRGRUTz/99H2P29jYICQkBE5OTmZOZBlY5kRkVI6Ojpg4ceI9P4QaDAbExcUJSiV/LHMiMrq4uLh7Hk+0sbFBdHS0oETyxzInIqObMWMGlEpl12ulUolp06bB3t5eYCp5Y5kTkdH17dsX4eHhXYWu1+sRGxsrOJW8scyJyCRiY2PR3t4OAOjVqxemTZsmOJG8scyJyCSmTp2K3r17AwCioqJgZ2cnOJG8cW0WIjIKvV6Pq1evoq6uDs3NzWhpaYG/vz/y8vKgUqmQm5sLa2trDBo0CEOHDoWDg4PoyLKikP71J2cioodobW1FaWkpysvLUVFRgcrKSlRVVaGhoeGhU/n/Vc+ePaFSqeDp6Qlvb2+MGjUKvr6+8PDwMGF62cpkmRPRQxkMBhQWFiInJwcnTpzAV199hTt37sDJyQkeHh7w8PCAm5sbVCoVVCoVXFxc0Ldv3/ueS5IkNDQ0QKPRQKPRoK6uDhcvXuz619LSgkGDBiEoKAghISEIDw/H8OHDzfuFH00scyK6v7y8POzZswfZ2dm4du0aPDw8EBoaiuDgYEyYMAGDBw826vUMBgMqKiqQn5+P/Px85OXlQafTwdfXF1FRUViwYAFUKpVRrykjLHMi+qfbt28jPT0dqampqKiogJ+fH2bOnIno6GizD3/o9Xrk5eUhKysLBw4cgE6nQ2RkJBYvXoywsDCzZnkEsMyJCLh58yY2btyId999F0qlEgkJCViwYAHc3d1FRwPw01378ePH8f777yMrKwuenp5Yvnw54uLiHrhCo4VhmRNZMoPBgB07diApKQnt7e1YsmQJli5dioEDB4qO9kCnT5/G2rVrcejQIQQEBCA1NRV+fn4P/HxbWxvq6+tx69Yt3Lx5E7du3YJerwcA9OnTBwMGDMCAAQPw29/+Fv369TPX1zA2ljmRpSovL8fzzz+P0tJSvPrqq1ixYsUjVWbl5eVITEzEF198gcWLF+PNN99ES0sLioqKUFhYiHPnzqGqqgq1tbX/9lM2Q4cOhZeXF/7whz9gypQpCAwMvGtZgm6MZU5kaSRJQkpKCl577TWMGzcO7777brcZTvklPvroI7zyyiuwtrbG5cuXAQBqtRpjxoyBu7s73N3d4erqiv79+3fdhXcW9A8//IDGxkY0Njbi8uXLqKysRHl5OU6ePInLly/D3t4e0dHRmD9/PiZMmPDQddoFy4RERBbj1q1b0vTp06UePXpImzdvlgwGg+hIRnHjxg0pPDxcsrGxkd58802jnPPbb7+VUlJSpD/84Q8SAMnb21vKysrqrn+zfSxzIgtx+fJladSoUdKwYcOk0tJS0XGMzmAwSFu2bJGsra2lP/3pT5Jerzfaub/55hspNjZWsrKykgICAqTKykqjndtI9vFnYCILUFVVhYCAAFhbW6OwsBBjxowRHcnoFAoFXn75ZWRlZWHHjh2YNWtW1w+dv5anpyc+/PBDnDlzBgAwZswYvPPOO0Y5t7GwzIlkTqPRYPLkyXBxcUF+fj6GDBkiOpJJRURE4OjRozhy5Aji4+Pv2STj1xg1ahROnDiBpKQkvPbaa1i2bJlRz/9rcKEtIhm7fft21+qFhw8ftpjNIcaOHYv9+/cjIiICQ4cOxbp164x2bhsbG6xatQoeHh6Ii4uDXq/Htm3bjHb+X5xLdAAiMp1ly5bhypUrOH36tMWtUjh16lRs27YNL774IsLCwjBx4kSjnn/mzJno2bMnIiIi8Lvf/Q5Lliwx6vn/U3w0kUimsrOzERkZiczMTMycOVN0HGGio6NRUlKCiooK9O/f3+jnX7duHVavXo3i4mI89thjRj//v4nPmRPJUVtbG7y8vODv74+9e/eKjiOUTqeDWq1GfHw8Nm7caPTzS5LUNbmooKBA1LPomfwBlEiGUlNTodVqsX79etFRhHNwcEBSUhJSUlJQV1dn9PMrFAps3boVp06dwieffGL08//bOXhnTiQvBoMBw4cPR3R0NLZu3SokgyRJ2LlzJ44cOQK1Wo2rV68iLCwMzzzzjJA8ra2tcHNzw5w5c/DWW2+Z5BpPPPEEbGxs8Omnn5rk/D+DM0CJ5Oazzz6TFAqFdPHiRWEZ1qxZIw0bNkxqbGyUJEmSGhsbpWHDhklbt24VlumNN96QHBwcpDt37pjk/Pv27ZOsra0ljUZjkvP/3OU5zEIkM5mZmQgICIBarRZy/bq6OqxduxaLFi3CgAEDAAADBgxAQkIC/vKXv0Cn0wnJNW/ePOh0OhQUFJjk/BEREVAqlTh27JhJzv9zWOZEMlNQUIApU6YIu/6ePXug1+vveRQwLCwMzc3N+Nvf/iYkl6urK9RqtcnK3NbWFv7+/igsLDTJ+X8Oy5xIRq5fv45Lly4hICBAWIaTJ08CAJydne863rnl29mzZ82eqVNgYCCKi4tNdv4xY8Z0Tfk3N5Y5kYzU1dVBkiShS9rW19cDQNcQS6fODS9qamrMnqmTWq1GbW2tyc4/ZMgQXLt2zWTnfxiWOZGMdI5Hi5zt2blkwL8+b935uq2tzeyZOjk6OuLGjRsmO/+AAQPQ2NhosvM/DMucSEaam5sBAD179hSWoXPj51u3bt11/ObNmwAgdKGvXr16df2NHsXzPwzLnEhGOocyOotTBC8vLwD/HG7p1Pk6KCjI7Jk6NTY2mnR/0x9//BF9+vQx2fkfhmVOJCOdRWXKoYSfM3PmTFhZWeH48eN3Hf/iiy+gVCqFTRwCfvqB2NHR0WTn1+l09/xWYC4scyIZUavVsLOzQ1lZmbAMzs7O+POf/4y0tDQ0NTUBAJqampCWloZVq1Z1PdUiQllZGXx8fEx2/m+//VbY8/1cApdIRmxtbeHr64uioiLMnTtXWI61a9fC1dUVixcvhouLC7799lu89tpriI+PF5ZJkiR8+eWXWL16tcmucfr0aYSFhZns/A/DtVmIZGbVqlXYvXs3amtrYW1tLTpOt5Gfn4+QkBCUl5eb5O68oaEBQ4YMQXZ2NqZPn2708/8MrppIJDfPPfcctFotcnJyREfpVtLS0vD444+bbJhl79696N27N0JCQkxy/p/DMieSGVdXVwQFBSElJUV0lG7j8uXLOHjwIObPn2+S83d0dCAtLQ2zZs3i0yxEZDxvvvkmjh49Kmo51m5n5cqVcHZ2xsKFC01y/l27dqG6uhqvvPKKSc7/7+CYOZFMTZ8+HTU1NSgrK4OdnZ3oOMIUFRUhKCgI6enpJnks8tq1a/Dx8UFUVBTS0tKMfv5/E7eNI5KrmpoajB49GvPmzUNycrLoOEI0NTXBz88P7u7u+PTTT42+pVtHRwciIiLwzTff4OzZs11LGQjAH0CJ5MrV1RVpaWnYtm0bsrKyRMcxO4PBgISEBLS0tGD37t1GL3JJkrBkyRLk5+cjMzNTZJED4HPmRLIWExODkpISxMbGIjc3FxMmTBAdyWwSExNx+PBhHDt2DE5OTg/8XEtLy3+8lk1bWxteeOEFZGRk4ODBg3jsscd+bdxfjXfmRDL3/7V3dyFNt2Ecx79zc0lDKQMpnS+rNEYdVAcxZeZBQkIvEAt7IaqDoogOel1BUBEFRQdRSB2F6KIoMyiKoJ01IoMOxDmUOVbLGQVGZ8vN/3Y9Jw9CT0WSbuvR6wM7GPv/712/k2v8793c99WrV9myZQubN2+e2Gt8JhMRzpw5Q1tbG3fv3qWhoeG7z4eGhrh9+zZ79uzBbrdjs9no6+ub9PjhcBi32013dzdPnz6lpaVluiP8mXwcVqeUyq1kMimtra1SVFQk3d3d+S4na1KplOzdu1esVqv4fD7JZDISDAalra1Ntm7dKqWlpQKIyWSSgoICAQSQUCj027FHR0fF6/WK1WoVl8sl0Wg0B4km7YE2c6VmiXQ6LcePHxez2Sxnz56V8fHxfJc0reLxuDQ2NorNZpPt27eLy+WSoqIiAcRsNn/XvP/7+vr16y/HHRwclBMnTkhxcbHMnz9frl+/LoZh5DDZpDzQ1SxKzTIdHR0cPnyYlStX4vP5qKmpyXdJU/b48WN27NhBMpkkk8lMbGOQTqd/e6/VaiWZTE68TyQSBAIB/H4/fr+fYDBIdXU1hw4d4uDBgxQXF2ctxxTo0kSlZqNwOMzOnTsZGBjA6/Xi9XrzeqDFn4pEIhw9epRnz56xbt06ent7GR0dpaCggEwmM6kxSktL2bZtG9FolGg0SiwWI5VKsWzZMtavX8+GDRtobm6moOCv/otRm7lSs5VhGNy4cYNz586xYMECzp8/z65du7BY/v5Fbp8/f+by5cvcunWL2tpabt68SWNjI+Pj49y7d49Lly4RDocn1dTLy8tZvHgxDocDh8PBkiVLaGpqorq6OkdppkWXzpkrNcsNDw/L7t27xWKxSF1dnXR2dsrY2Fi+y/qpeDwup06dEpvNJmVlZXLt2jVJpVI/XJfJZOTJkyeyZs0aAcRisfx0rtxkMonH48lDkmn34K9+blBKZZ/dbqejo4OBgQEaGhrYt28flZWVnD59mkgkku/ySKfT+P1+PB4PNTU1dHZ2cuHCBd69e8eRI0coLCz84R6TycSmTZt48+YNgUCA5uZmTCbTD08dhYWFVFRU5CpKVmkzV0oBsHTpUtrb2xkeHubkyZM8evSI2tpaVq9ezcWLFwkGg0iOZmUTiQQvXrzgwIEDlJeX09LSQiKR4P79+8RiMY4dO8bcuXMnNZbb7eb58+f09PSwceNGTCbTdz8ACxcuzFaMnNI5c6XUT8m/J/N0dXXx8OFDPnz4wLx586ivr8flcrFq1SpWrFiBw+GY0vekUilCoRD9/f28ffuW169f09vbi2EY1NfX09raisfjwW63T0uuwcFBrly5wp07dzAMg/b29qxtjZtD+geoUur3RIS+vj5evnxJIBDg1atXfPz4EYCSkhLq6uqw2+1UVVVRVVX1y+V7IsKnT5+Ix+PE43Hev39PJBLBMAwsFgtOp5O1a9fidrtpampi0aJFWcsUj8fx+Xzs378/q4c854g2c6XUn/ny5Qv9/f2EQiGGhoYYGRlhZGSEWCxGIpHg27dvjI2NTVxfUlKC2WymrKyMiooK7HY7lZWVOJ1Oli9fjtPpZM6cOXlM9L+mzVwppWYA3QJXKaVmAm3mSik1A2gzV0qpGcACdOW7CKWUUlPS8w8+9Nm6K3H1lwAAAABJRU5ErkJggg==" alt="DFS tree">
+<p class="caption">DFS tree</p>
+</div>
+<div class="figure">
+<img src="data:image/png;base64,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" alt="BFS tree">
+<p class="caption">BFS tree</p>
+</div>
+<h4 id="combinedDFSBFS"><span class="header-section-number">5.12.5.2</span> Combined implementation of depth-first and breadth-first search</h4>
+<p>These are some older implementations of BFS and DFS that demonstrate
+how both can be written using the same code just by changing the
+behavior of the core data structure. This also demonstrates how to
+construct DFS iteratively; for BFS, the <a href="#graphSearchImplementation">preceding implementation</a> is better in every respect.</p>
+<div>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"><span class="co">/* Typical usage:</span>
+<span class="co"> *</span>
+<span class="co"> * struct searchInfo *s;</span>
+<span class="co"> * int n;</span>
+<span class="co"> *</span>
+<span class="co"> * s = searchInfoCreate(g);</span>
+<span class="co"> *</span>
+<span class="co"> * n = graph_vertices(g);</span>
+<span class="co"> * for(i = 0; i &lt; n; i++) {</span>
+<span class="co"> * dfs(s, i);</span>
+<span class="co"> * }</span>
+<span class="co"> *</span>
+<span class="co"> * ... use results in s ...</span>
+<span class="co"> *</span>
+<span class="co"> * searchInfoDestroy(s);</span>
+<span class="co"> *</span>
+<span class="co"> */</span>
+
+<span class="co">/* summary information per node for dfs and bfs */</span>
+<span class="co">/* this is not intended to be opaque---user can read it */</span>
+<span class="co">/* (but should not write it!) */</span>
+
+<span class="ot">#define SEARCH_INFO_NULL (-1) </span><span class="co">/* for empty slots */</span>
+
+<span class="kw">struct</span> searchInfo {
+ Graph graph;
+ <span class="dt">int</span> reached; <span class="co">/* count of reached nodes */</span>
+ <span class="dt">int</span> *preorder; <span class="co">/* list of nodes in order first reached */</span>
+ <span class="dt">int</span> *time; <span class="co">/* time[i] == position of node i in preorder list */</span>
+ <span class="dt">int</span> *parent; <span class="co">/* parent in DFS or BFS forest */</span>
+ <span class="dt">int</span> *depth; <span class="co">/* distance from root */</span>
+};
+
+<span class="co">/* allocate and initialize search results structure */</span>
+<span class="co">/* you need to do this before passing it to dfs or bfs */</span>
+<span class="kw">struct</span> searchInfo *searchInfoCreate(Graph g);
+
+<span class="co">/* free searchInfo data---does NOT free graph pointer */</span>
+<span class="dt">void</span> searchInfoDestroy(<span class="kw">struct</span> searchInfo *);
+
+<span class="co">/* perform depth-first search starting at root, updating results */</span>
+<span class="dt">void</span> dfs(<span class="kw">struct</span> searchInfo *results, <span class="dt">int</span> root);
+
+<span class="co">/* perform breadth-first search starting at root, updating results */</span>
+<span class="dt">void</span> bfs(<span class="kw">struct</span> searchInfo *results, <span class="dt">int</span> root);</code></pre></div>
+<a href="http://cs.yale.edu/homes/aspnes/classes/223/examples/graphs/genericSearch.h" class="uri">examples/graphs/genericSearch.h</a>
+</div>
+<div>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"><span class="ot">#include &lt;stdlib.h&gt;</span>
+<span class="ot">#include &lt;assert.h&gt;</span>
+
+<span class="ot">#include "graph.h"</span>
+<span class="ot">#include "genericSearch.h"</span>
+
+<span class="co">/* create an array of n ints initialized to SEARCH_INFO_NULL */</span>
+<span class="dt">static</span> <span class="dt">int</span> *
+createEmptyArray(<span class="dt">int</span> n)
+{
+ <span class="dt">int</span> *a;
+ <span class="dt">int</span> i;
+
+ a = malloc(<span class="kw">sizeof</span>(*a) * n);
+ assert(a);
+
+ <span class="kw">for</span>(i = <span class="dv">0</span>; i &lt; n; i++) {
+ a[i] = SEARCH_INFO_NULL;
+ }
+
+ <span class="kw">return</span> a;
+}
+
+<span class="co">/* allocate and initialize search results structure */</span>
+<span class="co">/* you need to do this before passing it to dfs or bfs */</span>
+<span class="kw">struct</span> searchInfo *
+searchInfoCreate(Graph g)
+{
+ <span class="kw">struct</span> searchInfo *s;
+ <span class="dt">int</span> n;
+
+ s = malloc(<span class="kw">sizeof</span>(*s));
+ assert(s);
+
+ s-&gt;graph = g;
+ s-&gt;reached = <span class="dv">0</span>;
+
+ n = graphVertexCount(g);
+
+ s-&gt;preorder = createEmptyArray(n);
+ s-&gt;time = createEmptyArray(n);
+ s-&gt;parent = createEmptyArray(n);
+ s-&gt;depth = createEmptyArray(n);
+
+ <span class="kw">return</span> s;
+}
+
+<span class="co">/* free searchInfo data---does NOT free graph pointer */</span>
+<span class="dt">void</span>
+searchInfoDestroy(<span class="kw">struct</span> searchInfo *s)
+{
+ free(s-&gt;depth);
+ free(s-&gt;parent);
+ free(s-&gt;time);
+ free(s-&gt;preorder);
+ free(s);
+}
+
+<span class="co">/* used inside search routines */</span>
+<span class="kw">struct</span> edge {
+ <span class="dt">int</span> u; <span class="co">/* source */</span>
+ <span class="dt">int</span> v; <span class="co">/* sink */</span>
+};
+
+<span class="co">/* stack/queue */</span>
+<span class="kw">struct</span> queue {
+ <span class="kw">struct</span> edge *e;
+ <span class="dt">int</span> bottom;
+ <span class="dt">int</span> top;
+};
+
+<span class="dt">static</span> <span class="dt">void</span>
+pushEdge(Graph g, <span class="dt">int</span> u, <span class="dt">int</span> v, <span class="dt">void</span> *data)
+{
+ <span class="kw">struct</span> queue *q;
+
+ q = data;
+
+ assert(q-&gt;top &lt; graphEdgeCount(g) + <span class="dv">1</span>);
+
+ q-&gt;e[q-&gt;top].u = u;
+ q-&gt;e[q-&gt;top].v = v;
+ q-&gt;top++;
+}
+
+<span class="co">/* this rather horrible function implements dfs if useQueue == 0 */</span>
+<span class="co">/* and bfs if useQueue == 1 */</span>
+<span class="dt">static</span> <span class="dt">void</span>
+genericSearch(<span class="kw">struct</span> searchInfo *r, <span class="dt">int</span> root, <span class="dt">int</span> useQueue)
+{
+ <span class="co">/* queue/stack */</span>
+ <span class="kw">struct</span> queue q;
+
+ <span class="co">/* edge we are working on */</span>
+ <span class="kw">struct</span> edge cur;
+
+ <span class="co">/* start with empty q */</span>
+ <span class="co">/* we need one space per edge */</span>
+ <span class="co">/* plus one for the fake (root, root) edge */</span>
+ q.e = malloc(<span class="kw">sizeof</span>(*q.e) * (graphEdgeCount(r-&gt;graph) + <span class="dv">1</span>));
+ assert(q.e);
+
+ q.bottom = q.top = <span class="dv">0</span>;
+
+ <span class="co">/* push the root */</span>
+ pushEdge(r-&gt;graph, root, root, &amp;q);
+
+ <span class="co">/* while q.e not empty */</span>
+ <span class="kw">while</span>(q.bottom &lt; q.top) {
+ <span class="kw">if</span>(useQueue) {
+ cur = q.e[q.bottom++];
+ } <span class="kw">else</span> {
+ cur = q.e[--q.top];
+ }
+
+ <span class="co">/* did we visit sink already? */</span>
+ <span class="kw">if</span>(r-&gt;parent[cur.v] != SEARCH_INFO_NULL) <span class="kw">continue</span>;
+
+ <span class="co">/* no */</span>
+ assert(r-&gt;reached &lt; graphVertexCount(r-&gt;graph));
+ r-&gt;parent[cur.v] = cur.u;
+ r-&gt;time[cur.v] = r-&gt;reached;
+ r-&gt;preorder[r-&gt;reached++] = cur.v;
+ <span class="kw">if</span>(cur.u == cur.v) {
+ <span class="co">/* we could avoid this if we were certain SEARCH_INFO_NULL */</span>
+ <span class="co">/* would never be anything but -1 */</span>
+ r-&gt;depth[cur.v] = <span class="dv">0</span>;
+ } <span class="kw">else</span> {
+ r-&gt;depth[cur.v] = r-&gt;depth[cur.u] + <span class="dv">1</span>;
+ }
+
+ <span class="co">/* push all outgoing edges */</span>
+ graphForeach(r-&gt;graph, cur.v, pushEdge, &amp;q);
+ }
+
+ free(q.e);
+}
+
+<span class="dt">void</span>
+dfs(<span class="kw">struct</span> searchInfo *results, <span class="dt">int</span> root)
+{
+ genericSearch(results, root, <span class="dv">0</span>);
+}
+
+<span class="dt">void</span>
+bfs(<span class="kw">struct</span> searchInfo *results, <span class="dt">int</span> root)
+{
+ genericSearch(results, root, <span class="dv">1</span>);
+}</code></pre></div>
+<a href="http://cs.yale.edu/homes/aspnes/classes/223/examples/graphs/genericSearch.c" class="uri">examples/graphs/genericSearch.c</a>
+</div>
+<p>And here is some test code: <a href="http://cs.yale.edu/homes/aspnes/classes/223/examples/graphs/genericSearchTest.c">genericSearchTest.c</a>. You will need to compile <code class="backtick">genericSearchTest.c</code> together with both <code class="backtick">genericSearch.c</code> and <code class="backtick">graph.c</code> to get it to work. This <a href="http://cs.yale.edu/homes/aspnes/classes/223/examples/graphs/Makefile">Makefile</a> will do this for you.</p>
+<h4 id="Other_variations_on_the_basic_algorithm"><span class="header-section-number">5.12.5.3</span> Other variations on the basic algorithm</h4>
+<p>Stacks and queues are not the only options for the bucket in the generic search algorithm. Some other choices are:</p>
+<ul>
+<li>A <a href="#priorityQueues">priority queue</a> keyed by edge weights. If the edges have <strong>weights</strong>, the generic tree-builder can be used to find a tree containing <span class="math inline"><em>s</em></span> with minimum total edge weight.<a href="#fn22" class="footnoteRef" id="fnref22"><sup>22</sup></a> The basic idea is to always pull out the lightest edge. The resulting algorithm runs in <span class="math inline"><em>O</em>(<em>n</em> + <em>m</em>log<em>m</em>)</span> time (since each heap operation takes <span class="math inline"><em>O</em>(log<em>m</em>)</span> time), and is known as <strong>Prim's algorithm</strong>. See <a href="http://en.wikipedia.org/wiki/Prim%27s_algorithm" title="WikiPedia">Prim's algorithm</a> for more details.</li>
+<li>A priority queue keyed by path lengths. Here we assume that edges have <strong>lengths</strong>,
+ and we want to build a shortest-path tree where the length of the path
+is no longer just the number of edges it contains but the sum of their
+weights. The basic idea is to keep track of the distance from the root
+to each node in the tree, and assign each edge a key equal to the sum of
+ the distance to its source and its length. The resulting search
+algorithm, known as <strong>Dijkstra's algorithm</strong>, will give a shortest-path tree if all the edge weights are non-negative. See <a href="http://en.wikipedia.org/wiki/Dijkstra%27s_algorithm" title="WikiPedia">Dijkstra's algorithm</a>.</li>
+</ul>
+<h2 id="dynamicProgramming"><span class="header-section-number">5.13</span> Dynamic programming</h2>
+<p><strong>Dynamic programming</strong> is a general-purpose <a href="#algorithmDesignTechniques">algorithm design technique</a> that is most often used to solve <strong>combinatorial optimization</strong> problems, where we are looking for the best possible input to some function chosen from an exponentially large search space.</p>
+<p>There are two parts to dynamic programming. The first part is a programming technique: dynamic programming is essentially <a href="#algorithmDesignTechniquesClassification">divide and conquer</a>
+ run in reverse: we solve a big instance of a problem by breaking it up
+recursively into smaller instances; but instead of carrying out the
+computation recursively from the top down, we start from the bottom with
+ the smallest instances of the problem, solving each increasingly large
+instance in turn and storing the result in a table. The second part is a
+ design principle: in building up our table, we are careful always to
+preserve alternative solutions we may need later, by delaying commitment
+ to particular choices to the extent that we can.</p>
+<p>The bottom-up aspect of dynamic programming is most useful when a
+straightforward recursion would produce many duplicate subproblems. It
+is most efficient when we can enumerate a class of subproblems that
+doesn't include too many extraneous cases that we don't need for our
+original problem.</p>
+<p>To take a simple example, suppose that we want to compute the <span class="math inline"><em>n</em></span>-th Fibonacci number using the defining recurrence</p>
+<ul>
+<li><span class="math inline"><em>F</em>(<em>n</em>)=<em>F</em>(<em>n</em> − 1)+<em>F</em>(<em>n</em> − 2)</span></li>
+<li><span class="math inline"><em>F</em>(1)=<em>F</em>(0)=1</span>.</li>
+</ul>
+<p>A naive approach would simply code the recurrence up directly:</p>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"><span class="dt">int</span>
+fib(<span class="dt">int</span> n)
+{
+ <span class="kw">if</span>(n &lt; <span class="dv">2</span>) {
+ <span class="kw">return</span> <span class="dv">1</span>
+ } <span class="kw">else</span> {
+ <span class="kw">return</span> fib(n<span class="dv">-1</span>) + fib(n<span class="dv">-2</span>);
+ }
+}</code></pre></div>
+<p>The running time of this procedure is easy to compute. The recurrence is</p>
+<ul>
+<li><span class="math inline"><em>T</em>(<em>n</em>)=<em>T</em>(<em>n</em> − 1)+<em>T</em>(<em>n</em> − 2)+<em>Θ</em>(1)</span>,</li>
+</ul>
+<p>whose solution is <span class="math inline"><em>Θ</em>(<em>a</em><sup><em>n</em></sup>)</span> where <span class="math inline"><em>a</em></span> is the golden ratio <span class="math inline">1.6180339887498948482…</span>. This is badly exponential.<a href="#fn23" class="footnoteRef" id="fnref23"><sup>23</sup></a></p>
+<h3 id="Memoization"><span class="header-section-number">5.13.1</span> Memoization</h3>
+<p>The problem is that we keep recomputing values of <code class="backtick">fib</code> that we've already computed. We can avoid this by <strong>memoization</strong>, where we wrap our recursive solution in a <strong>memoizer</strong> that stores previously-computed solutions in a <a href="#hashTables">hash table</a>.
+ Sensible programming languages will let you write a memoizer once and
+apply it to arbitrary recursive functions. In less sensible programming
+languages it is usually easier just to embed the memoization in the
+function definition itself, like this:</p>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"><span class="dt">int</span>
+memoFib(<span class="dt">int</span> n)
+{
+ <span class="dt">int</span> ret;
+
+ <span class="kw">if</span>(hashContains(FibHash, n)) {
+ <span class="kw">return</span> hashGet(FibHash, n);
+ } <span class="kw">else</span> {
+ ret = memoFib(n<span class="dv">-1</span>) + memoFib(n<span class="dv">-2</span>);
+ hashPut(FibHash, n, ret);
+ <span class="kw">return</span> ret;
+ }
+}</code></pre></div>
+<p>The assumption here is that <code class="backtick">FibHash</code> is a global hash table that we have initialized to map <code class="backtick">0</code> and <code class="backtick">1</code> to <code class="backtick">1</code>. The total cost of running this procedure is <span class="math inline"><em>O</em>(<em>n</em>)</span>, because <code class="backtick">fib</code> is called at most twice for each value <span class="math inline"><em>k</em></span> in <span class="math inline">0…<em>n</em></span>.</p>
+<p>Memoization is a very useful technique in practice, but it is not
+popular with algorithm designers because computing the running time of a
+ complex memoized procedure is often much more difficult than computing
+the time to fill a nice clean table. The use of a hash table instead of
+an array may also add overhead (and code complexity) that comes out in
+the constant factors. But it is always the case that a memoized
+recursive procedure considers no more subproblems than a table-based
+solution, and it may consider many fewer if we are sloppy about what we
+put in our table (perhaps because we can't easily predict what
+subproblems will be useful).</p>
+<h3 id="Dynamic_programming"><span class="header-section-number">5.13.2</span> Dynamic programming</h3>
+<p>Dynamic programming comes to the rescue. Because we know what smaller
+ cases we have to reduce F(n) to, instead of computing F(n) top-down, we
+ compute it bottom-up, hitting all possible smaller cases and storing
+the results in an array:</p>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"><span class="dt">int</span>
+fib2(<span class="dt">int</span> n)
+{
+ <span class="dt">int</span> *a;
+ <span class="dt">int</span> i;
+ <span class="dt">int</span> ret;
+
+ <span class="kw">if</span>(n &lt; <span class="dv">2</span>) {
+ <span class="kw">return</span> <span class="dv">1</span>;
+ } <span class="kw">else</span> {
+ a = malloc(<span class="kw">sizeof</span>(*a) * (n<span class="dv">+1</span>));
+ assert(a);
+
+ a[<span class="dv">1</span>] = a[<span class="dv">2</span>] = <span class="dv">1</span>;
+
+ <span class="kw">for</span>(i = <span class="dv">3</span>; i &lt;= n; i++) {
+ a[i] = a[i<span class="dv">-1</span>] + a[i<span class="dv">-2</span>];
+ }
+ }
+
+ ret = a[n];
+ free(a);
+ <span class="kw">return</span> ret;
+}</code></pre></div>
+<p>Notice the recurrence is exactly the same in this version as in our
+original recursive version, except that instead of computing F(n-1) and
+F(n-2) recursively, we just pull them out of the array. This is typical
+of dynamic-programming solutions: often the most tedious editing step in
+ converting a recursive algorithm to dynamic programming is changing
+parentheses to square brackets. As with memoization, the effect of this
+conversion is dramatic; what used to be an exponential-time algorithm is
+ now linear-time.</p>
+<h4 id="More_examples"><span class="header-section-number">5.13.2.1</span> More examples</h4>
+<h5 id="Longest_increasing_subsequence"><span class="header-section-number">5.13.2.1.1</span> Longest increasing subsequence</h5>
+<p>Suppose that we want to compute the <strong>longest increasing subsequence</strong>
+ of an array. This is a sequence, not necessarily contiguous, of
+elements from the array such that each is strictly larger than the one
+before it. Since there are <span class="math inline">2<sup><em>n</em></sup></span> different subsequences of an <span class="math inline"><em>n</em></span>-element array, the brute-force approach of trying all of them might take a while.</p>
+<p>What makes this problem suitable for dynamic programming is that any
+prefix of a longest increasing subsequence is a longest increasing
+subsequence of the part of the array that ends where the prefix ends; if
+ it weren't, we could make the big sequence longer by choosing a longer
+prefix. So to find the longest increasing subsequence of the whole
+array, we build up a table of longest increasing subsequences for each
+initial prefix of the array. At each step, when finding the longest
+increasing subsequence of elements <span class="math inline">0…<em>i</em></span>,
+ we can just scan through all the possible values for the second-to-last
+ element and read the length of the best possible subsequence ending
+there out of the table. When the table is complete, we can scan for the
+best last element and then work backwards to reconstruct the actual
+subsequence.</p>
+<p>This last step requires some explanation. We don't really want to store in <code class="backtick">table[i]</code> the full longest increasing subsequence ending at position <code class="backtick">i</code>,
+ because it may be very big. Instead, we store the index of the
+second-to-last element of this sequence. Since that second-to-last
+element also has a table entry that stores the index of its predecessor,
+ by following the indices we can generate a subsequence of length <span class="math inline"><em>O</em>(<em>n</em>)</span>, even though we only stored <span class="math inline"><em>O</em>(1)</span> pieces of information in each table entry. This is similar to the parent pointer technique used in <a href="#graphSearch">graph search algorithms</a>.</p>
+<p>Here's what the code looks like:</p>
+<div>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"><span class="co">/* compute a longest strictly increasing subsequence of an array of ints */</span>
+<span class="co">/* input is array a with given length n */</span>
+<span class="co">/* returns length of LIS */</span>
+<span class="co">/* If the output pointer is non-null, writes LIS to output pointer. */</span>
+<span class="co">/* Caller should provide at least sizeof(int)*n space for output */</span>
+<span class="co">/* If there are multiple LIS's, which one is returned is arbitrary. */</span>
+<span class="dt">unsigned</span> <span class="dt">long</span>
+longest_increasing_subsequence(<span class="dt">const</span> <span class="dt">int</span> a[], <span class="dt">unsigned</span> <span class="dt">long</span> n, <span class="dt">int</span> *output);</code></pre></div>
+<a href="http://cs.yale.edu/homes/aspnes/classes/223/examples/dynamicProgramming/lis/lis.h" class="uri">examples/dynamicProgramming/lis/lis.h</a>
+</div>
+<div>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"><span class="ot">#include &lt;stdlib.h&gt;</span>
+<span class="ot">#include &lt;assert.h&gt;</span>
+
+<span class="ot">#include "lis.h"</span>
+
+<span class="dt">unsigned</span> <span class="dt">long</span>
+longest_increasing_subsequence(<span class="dt">const</span> <span class="dt">int</span> a[], <span class="dt">unsigned</span> <span class="dt">long</span> n, <span class="dt">int</span> *output)
+{
+ <span class="kw">struct</span> lis_data {
+ <span class="dt">unsigned</span> <span class="dt">long</span> length; <span class="co">/* length of LIS ending at this point */</span>
+ <span class="dt">unsigned</span> <span class="dt">long</span> prev; <span class="co">/* previous entry in the LIS ending at this point */</span>
+ } *table;
+
+ <span class="dt">unsigned</span> <span class="dt">long</span> best; <span class="co">/* best entry in table */</span>
+ <span class="dt">unsigned</span> <span class="dt">long</span> scan; <span class="co">/* used to generate output */</span>
+
+ <span class="dt">unsigned</span> <span class="dt">long</span> i;
+ <span class="dt">unsigned</span> <span class="dt">long</span> j;
+ <span class="dt">unsigned</span> <span class="dt">long</span> best_length;
+
+ <span class="co">/* special case for empty table */</span>
+ <span class="kw">if</span>(n == <span class="dv">0</span>) <span class="kw">return</span> <span class="dv">0</span>;
+
+ table = malloc(<span class="kw">sizeof</span>(*table) * n);
+
+ <span class="kw">for</span>(i = <span class="dv">0</span>; i &lt; n; i++) {
+ <span class="co">/* default best is just this element by itself */</span>
+ table[i].length = <span class="dv">1</span>;
+ table[i].prev = n; <span class="co">/* default end-of-list value */</span>
+
+ <span class="co">/* but try all other possibilities */</span>
+ <span class="kw">for</span>(j = <span class="dv">0</span>; j &lt; i; j++) {
+ <span class="kw">if</span>(a[j] &lt; a[i] &amp;&amp; table[j].length + <span class="dv">1</span> &gt; table[i].length) {
+ <span class="co">/* we have a winner */</span>
+ table[i].length = table[j].length + <span class="dv">1</span>;
+ table[i].prev = j;
+ }
+ }
+ }
+
+ <span class="co">/* now find the best of the lot */</span>
+ best = <span class="dv">0</span>;
+
+ <span class="kw">for</span>(i = <span class="dv">1</span>; i &lt; n; i++) {
+ <span class="kw">if</span>(table[i].length &gt; table[best].length) {
+ best = i;
+ }
+ }
+
+ <span class="co">/* table[best].length is now our return value */</span>
+ <span class="co">/* save it so that we don't lose it when we free table */</span>
+ best_length = table[best].length;
+
+ <span class="co">/* do we really have to compute the output? */</span>
+ <span class="kw">if</span>(output) {
+ <span class="co">/* yes :-( */</span>
+ scan = best;
+ <span class="kw">for</span>(i = <span class="dv">0</span>; i &lt; best_length; i++) {
+ assert(scan &gt;= <span class="dv">0</span>);
+ assert(scan &lt; n);
+
+ output[best_length - i - <span class="dv">1</span>] = a[scan];
+
+ scan = table[scan].prev;
+ }
+ }
+
+ free(table);
+
+ <span class="kw">return</span> best_length;
+}</code></pre></div>
+<a href="http://cs.yale.edu/homes/aspnes/classes/223/examples/dynamicProgramming/lis/lis.c" class="uri">examples/dynamicProgramming/lis/lis.c</a>
+</div>
+<p>A sample program that runs <code class="backtick">longest_increasing_subsequence</code> on a list of numbers passed in by <code class="backtick">stdin</code> is given in <a href="http://cs.yale.edu/homes/aspnes/classes/223/examples/dynamicProgramming/lis/test_lis.c">test_lis.c</a>. Here is a <a href="http://cs.yale.edu/homes/aspnes/classes/223/examples/dynamicProgramming/lis/Makefile">Makefile</a>.</p>
+<p>Implemented like this, the cost of finding an LIS is <span class="math inline"><em>O</em>(<em>n</em><sup>2</sup>)</span>,
+ because to compute each entry in the array, we have to search through
+all the previous entries to find the longest path that ends at a value
+less than the current one. This can be improved by using a more clever
+data structure. If we use a binary search tree that stores path keyed by
+ the last value, and augment each node with a field that represents the
+maximum length of any path in the subtree under that node, then we can
+find the longest feasible path that we can append the current node to in
+ <span class="math inline"><em>O</em>(log<em>n</em>)</span> time instead of <span class="math inline"><em>O</em>(<em>n</em>)</span> time. This brings the total cost down to only <span class="math inline"><em>O</em>(<em>n</em>log<em>n</em>)</span>.</p>
+<h5 id="All-pairs_shortest_paths"><span class="header-section-number">5.13.2.1.2</span> All-pairs shortest paths</h5>
+<p>Suppose we want to compute the distance between any two points in a graph, where each edge <span class="math inline"><em>u</em><em>v</em></span> has a length <span class="math inline">ℓ<sub><em>u</em></sub><em>v</em></span> (<span class="math inline">+∞</span> for edges not in the graph) and the distance between two vertices <span class="math inline"><em>s</em></span> and t$ is the minimum over all <span class="math inline"><em>s</em></span>–<span class="math inline"><em>t</em></span> paths of the total length of the edges. There are various algorithms for doing this for a particular <span class="math inline"><em>s</em></span> and <span class="math inline"><em>t</em></span>, but there is also a very simple dynamic programming algorithm known as <strong>Floyd-Warshall</strong> that computes the distance between all <span class="math inline"><em>n</em><sup>2</sup></span> pairs of vertices in <span class="math inline"><em>Θ</em>(<em>n</em><sup>3</sup>)</span> time.</p>
+<p>The assumption is that the graph does not contain a <strong>negative cycle</strong>
+ (a cycle with total edge weight less than zero), so that for two
+connected nodes there is always a shortest path that uses each
+intermediate vertex at most once. If a graph does contain a negative
+cycle, the algorithm will detect it by reporting the distance from <span class="math inline"><em>i</em></span> to <span class="math inline"><em>i</em></span> less than zero for some <span class="math inline"><em>i</em></span>.</p>
+<p>Negative cycles don't generally exist in distance graphs (unless you
+have the ability to move faster than the speed of light), but they can
+come up in other contexts. One example would be in currency arbitrage,
+where each node is some currency, the weight of an edge <span class="math inline"><em>u</em><em>v</em></span> is the logarithm of the exchange rate from <span class="math inline"><em>u</em></span> to <span class="math inline"><em>v</em></span>, and the total weight of a path from <span class="math inline"><em>s</em></span> to <span class="math inline"><em>t</em></span> gives the logarithm of the number of units of <span class="math inline"><em>t</em></span> you can get for one unit of <span class="math inline"><em>s</em></span>,
+ since adding the logs along the path corresponds to multiplying all the
+ exchange rates. In this context a negative cycle gives you a way to
+turn a dollar into less than a dollar by running it through various
+other currencies, which is not useful, but a <em>positive cycle</em>
+lets you pay for the supercomputer you bought to find it before anybody
+else did. If we negate all the edge weights, we turn a positive cycle
+into a negative cycle, making a fast algorithm for finding this negative
+ cycle potentially valuable.</p>
+<p>However, if we don't have any negative cycles, the idea is that we
+can create restricted instances of the shortest-path problem by limiting
+ the maximum index of any node used on the path. Let <span class="math inline"><em>L</em>(<em>i</em>, <em>j</em>, <em>k</em>)</span> be the length of a shortest path from <span class="math inline"><em>i</em></span> to <span class="math inline"><em>j</em></span> that uses only the vertices <span class="math inline">0, …, <em>k</em> − 1</span> along the path (not counting the endpoints <span class="math inline"><em>i</em></span> and <span class="math inline"><em>j</em></span>, which can be anything). When <span class="math inline"><em>k</em> = 0</span>, this is just the length of the <span class="math inline"><em>i</em></span>–<span class="math inline"><em>j</em></span> edge, or <span class="math inline">+∞</span> if there is no such edge. So we can start by computing <span class="math inline"><em>L</em>(<em>i</em>, <em>j</em>, 0)</span> for all <span class="math inline"><em>i</em></span>. Now given <span class="math inline"><em>L</em>(<em>i</em>, <em>j</em>, <em>k</em>)</span> for all <span class="math inline"><em>i</em></span> and some <span class="math inline"><em>k</em></span>, we can compute <span class="math inline"><em>L</em>(<em>i</em>, <em>j</em>, <em>k</em> + 1)</span> by observing that any shortest <span class="math inline"><em>i</em></span>–<span class="math inline"><em>j</em></span> path that has intermediate vertices in <span class="math inline">0…<em>k</em></span> either consists of a path with intermediate vertices in <span class="math inline">0…<em>k</em> − 1</span>, or consists of a path from <span class="math inline"><em>i</em></span> to <span class="math inline"><em>k</em></span> followed by a path from <span class="math inline"><em>k</em></span> to <span class="math inline"><em>j</em></span>, where both of these paths have intermediate vertices in <span class="math inline">0…<em>k</em> − 1</span>. So we get</p>
+<ul>
+<li><span class="math inline"><em>L</em>(<em>i</em>, <em>j</em>, <em>k</em> + 1)=min(<em>L</em>(<em>i</em>, <em>j</em>, <em>k</em>),<em>L</em>(<em>i</em>, <em>k</em>, <em>k</em>)+<em>L</em>(<em>k</em>, <em>j</em>, <em>k</em>)</span>.</li>
+</ul>
+<p>Since this takes <span class="math inline"><em>O</em>(1)</span> time to compute if we have previously computed <span class="math inline"><em>L</em>(<em>i</em>, <em>j</em>, <em>k</em>)</span> for all <span class="math inline"><em>i</em></span> and <span class="math inline"><em>j</em></span>, we can fill in the entire table in <span class="math inline"><em>O</em>(<em>n</em><sup>3</sup>)</span> time.</p>
+<p>Implementation details:</p>
+<ul>
+<li>If we want to reconstruct the shortest path in addition to computing its length, we can store the first vertex for each <span class="math inline"><em>i</em></span>–<span class="math inline"><em>j</em></span> path. This will either be (a) the first vertex in the <span class="math inline"><em>i</em></span>–<span class="math inline"><em>j</em></span> path for the previous <span class="math inline"><em>k</em></span>, or (b) the first vertex in the <span class="math inline"><em>i</em></span>–<span class="math inline"><em>k</em></span> path.</li>
+<li>We don't actually need to use a full three-dimensional array. It's enough to store one value for each pair <span class="math inline"><em>i</em>, <em>j</em></span> and let <span class="math inline"><em>k</em></span> be implicit. At each step we let <span class="math inline"><em>L</em>[<em>i</em>][<em>j</em>]</span> be <span class="math inline">min(<em>L</em>[<em>i</em>][<em>j</em>],<em>L</em>[<em>i</em>][<em>k</em>]+<em>L</em>[<em>k</em>][<em>j</em>])</span>. The trick is that we don't care if <span class="math inline"><em>L</em>[<em>i</em>][<em>k</em>]</span> or <span class="math inline"><em>L</em>[<em>k</em>][<em>j</em>]</span> has already been updated, because that will only give us paths with a few extra <span class="math inline"><em>k</em></span> vertices, which won't be the shortest paths anyway assuming no negative cycles.</li>
+</ul>
+<h5 id="longestCommonSubsequence"><span class="header-section-number">5.13.2.1.3</span> Longest common subsequence</h5>
+<p>Given sequences of characters <span class="math inline"><em>v</em></span> and <span class="math inline"><em>w</em></span>, <span class="math inline"><em>v</em></span> is a <em>subsequence</em> of <span class="math inline"><em>w</em></span> if every character in <span class="math inline"><em>v</em></span> appears in <span class="math inline"><em>w</em></span> in the same order. For example, <code class="backtick">aaaaa</code>, <code class="backtick">brac</code>, and <code class="backtick">badar</code> are all subsequences of <code class="backtick">abracadabra</code>, but <code class="backtick">badcar</code> is not. A longest common subsequence (LCS for short) of two sequences <span class="math inline"><em>x</em></span> and <span class="math inline"><em>y</em></span> is the longest sequence that is a subsequence of both: two longest common subsequences of <code class="backtick">abracadabra</code> and <code class="backtick">badcar</code> are <code class="backtick">badar</code> and <code class="backtick">bacar</code>.</p>
+<p>As with longest increasing subsequence, one can find the LCS of two
+sequence by brute force, but it will take even longer. Not only are
+there are <span class="math inline">2<sup><em>n</em></sup></span> subsequences of a sequence of length <span class="math inline"><em>n</em></span>,
+ but checking each subsequence of the first to see if it is also a
+subsequence of the second may take some time. It is better to solve the
+problem using dynamic programming. Having sequences gives an obvious
+linear structure to exploit: the basic strategy will be to compute LCSs
+for increasingly long prefixes of the inputs. But with two sequences we
+will have to consider prefixes of both, which will give us a
+two-dimensional table where rows correspond to prefixes of sequence <span class="math inline"><em>x</em></span> and columns correspond to prefixes of sequence <span class="math inline"><em>y</em></span>.</p>
+<p>The recursive decomposition that makes this technique work looks like this. Let <span class="math inline"><em>L</em>(<em>x</em>, <em>y</em>)</span> be the length of the longest common subsequence of <span class="math inline"><em>x</em></span> and <span class="math inline"><em>y</em></span>, where <span class="math inline"><em>x</em></span> and <span class="math inline"><em>y</em></span> are strings. Let <span class="math inline"><em>a</em></span> and <span class="math inline"><em>b</em></span> be single characters. Then <span class="math inline"><em>L</em>(<em>x</em><em>a</em>, <em>y</em><em>b</em>)</span> is the maximum of:</p>
+<ul>
+<li><span class="math inline"><em>L</em>(<em>x</em>, <em>y</em>)+1</span>, if <span class="math inline"><em>a</em> = <em>b</em></span>,</li>
+<li><span class="math inline"><em>L</em>(<em>x</em><em>a</em>, <em>y</em>)</span>, or</li>
+<li><span class="math inline"><em>L</em>(<em>x</em>, <em>y</em><em>b</em>)</span>.</li>
+</ul>
+<p>The idea is that we either have a new matching character we couldn't
+use before (the first case), or we have an LCS that doesn't use one of <span class="math inline"><em>a</em></span> or <span class="math inline"><em>b</em></span> (the remaining cases). In each case the recursive call to LCS involves a shorter prefix of <span class="math inline"><em>x</em><em>a</em></span> or <span class="math inline"><em>y</em><em>b</em></span>, with an ultimate base case <span class="math inline"><em>L</em>(<em>x</em>, <em>y</em>)=0</span> if at least one of <span class="math inline"><em>x</em></span> or <span class="math inline"><em>y</em></span>
+ is the empty string. So we can fill in these values in a table, as long
+ as we are careful to make sure that the shorter prefixes are always
+filled first. If we are smart about remembering which case applies at
+each step, we can even go back and extract an actual LCS, by stitching
+together to places where <span class="math inline"><em>a</em> = <em>b</em></span>. Here's a short C program that does this:</p>
+<div>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"><span class="ot">#include &lt;stdio.h&gt;</span>
+<span class="ot">#include &lt;stdlib.h&gt;</span>
+<span class="ot">#include &lt;assert.h&gt;</span>
+<span class="ot">#include &lt;string.h&gt;</span>
+<span class="ot">#include &lt;limits.h&gt;</span>
+
+<span class="co">/* compute longest common subsequence of argv[1] and argv[2] */</span>
+
+<span class="co">/* computes longest common subsequence of x and y, writes result to lcs */</span>
+<span class="co">/* lcs should be pre-allocated by caller to 1 + minimum length of x or y */</span>
+<span class="dt">void</span>
+longestCommonSubsequence(<span class="dt">const</span> <span class="dt">char</span> *x, <span class="dt">const</span> <span class="dt">char</span> *y, <span class="dt">char</span> *lcs)
+{
+ <span class="dt">int</span> xLen;
+ <span class="dt">int</span> yLen;
+ <span class="dt">int</span> i; <span class="co">/* position in x */</span>
+ <span class="dt">int</span> j; <span class="co">/* position in y */</span>
+
+ xLen = strlen(x);
+ yLen = strlen(y);
+
+ <span class="co">/* best choice at each position */</span>
+ <span class="co">/* length gives length of LCS for these prefixes */</span>
+ <span class="co">/* prev points to previous substring */</span>
+ <span class="co">/* newChar if non-null is new character */</span>
+ <span class="kw">struct</span> choice {
+ <span class="dt">int</span> length;
+ <span class="kw">struct</span> choice *prev;
+ <span class="dt">char</span> newChar;
+ } best[xLen][yLen];
+
+ <span class="kw">for</span>(i = <span class="dv">0</span>; i &lt; xLen; i++) {
+ <span class="kw">for</span>(j = <span class="dv">0</span>; j &lt; yLen; j++) {
+ <span class="co">/* we can always do no common substring */</span>
+ best[i][j].length = <span class="dv">0</span>;
+ best[i][j].prev = <span class="dv">0</span>;
+ best[i][j].newChar = <span class="dv">0</span>;
+
+ <span class="co">/* if we have a match, try adding new character */</span>
+ <span class="co">/* this is always better than the nothing we started with */</span>
+ <span class="kw">if</span>(x[i] == y[j]) {
+ best[i][j].newChar = x[i];
+ <span class="kw">if</span>(i &gt; <span class="dv">0</span> &amp;&amp; j &gt; <span class="dv">0</span>) {
+ best[i][j].length = best[i<span class="dv">-1</span>][j<span class="dv">-1</span>].length + <span class="dv">1</span>;
+ best[i][j].prev = &amp;best[i<span class="dv">-1</span>][j<span class="dv">-1</span>];
+ } <span class="kw">else</span> {
+ best[i][j].length = <span class="dv">1</span>;
+ }
+ }
+
+ <span class="co">/* maybe we can do even better by ignoring a new character */</span>
+ <span class="kw">if</span>(i &gt; <span class="dv">0</span> &amp;&amp; best[i<span class="dv">-1</span>][j].length &gt; best[i][j].length) {
+ <span class="co">/* throw away a character from x */</span>
+ best[i][j].length = best[i<span class="dv">-1</span>][j].length;
+ best[i][j].prev = &amp;best[i<span class="dv">-1</span>][j];
+ best[i][j].newChar = <span class="dv">0</span>;
+ }
+
+ <span class="kw">if</span>(j &gt; <span class="dv">0</span> &amp;&amp; best[i][j<span class="dv">-1</span>].length &gt; best[i][j].length) {
+ <span class="co">/* throw away a character from x */</span>
+ best[i][j].length = best[i][j<span class="dv">-1</span>].length;
+ best[i][j].prev = &amp;best[i][j<span class="dv">-1</span>];
+ best[i][j].newChar = <span class="dv">0</span>;
+ }
+
+ }
+ }
+
+ <span class="co">/* reconstruct string working backwards from best[xLen-1][yLen-1] */</span>
+ <span class="dt">int</span> outPos; <span class="co">/* position in output string */</span>
+ <span class="kw">struct</span> choice *p; <span class="co">/* for chasing linked list */</span>
+
+ outPos = best[xLen<span class="dv">-1</span>][yLen<span class="dv">-1</span>].length;
+ lcs[outPos--] = '\<span class="dv">0</span>';
+
+ <span class="kw">for</span>(p = &amp;best[xLen<span class="dv">-1</span>][yLen<span class="dv">-1</span>]; p; p = p-&gt;prev) {
+ <span class="kw">if</span>(p-&gt;newChar) {
+ assert(outPos &gt;= <span class="dv">0</span>);
+ lcs[outPos--] = p-&gt;newChar;
+ }
+ }
+}
+
+<span class="dt">int</span>
+main(<span class="dt">int</span> argc, <span class="dt">char</span> **argv)
+{
+ <span class="kw">if</span>(argc != <span class="dv">3</span>) {
+ fprintf(stderr, <span class="st">"Usage: %s string1 string2</span><span class="ch">\n</span><span class="st">"</span>, argv[<span class="dv">0</span>]);
+ <span class="kw">return</span> <span class="dv">1</span>;
+ }
+
+ <span class="dt">char</span> output[strlen(argv[<span class="dv">1</span>]) + <span class="dv">1</span>];
+
+ longestCommonSubsequence(argv[<span class="dv">1</span>], argv[<span class="dv">2</span>], output);
+
+ puts(output);
+
+ <span class="kw">return</span> <span class="dv">0</span>;
+}</code></pre></div>
+<a href="http://cs.yale.edu/homes/aspnes/classes/223/examples/dynamicProgramming/lcs/lcs.c" class="uri">examples/dynamicProgramming/lcs/lcs.c</a>
+</div>
+<p>The whole thing takes <span class="math inline"><em>O</em>(<em>n</em><em>m</em>)</span> time where <span class="math inline"><em>n</em></span> and <span class="math inline"><em>m</em></span> are the lengths of <span class="math inline"><em>A</em></span> and <span class="math inline"><em>B</em></span>.</p>
+<h2 id="randomization"><span class="header-section-number">5.14</span> Randomization</h2>
+<p>Randomization is a fundamental technique in algorithm design, that
+allows programs to run quickly when the average-case behavior of an
+algorithm is better than the worst-case behavior. It is also heavily
+used in games, both in entertainment and gambling. The latter
+application gives the only example I know of a <a href="http://www.zdnet.com/article/comdex-99-the-mysterious-death-of-larry-volk/">programmer killed for writing bad code</a>, which shows how serious good random-number generation is.</p>
+<h3 id="Generating_random_values_in_C"><span class="header-section-number">5.14.1</span> Generating random values in C</h3>
+<p>If you want random values in a C program, there are three typical
+ways of getting them, depending on how good (i.e. uniform, uncorrelated,
+ and unpredictable) you want them to be.</p>
+<h4 id="The_rand_function_from_the_standard_library"><span class="header-section-number">5.14.1.1</span> The <code>rand</code> function from the standard library</h4>
+<p>E.g.</p>
+<div>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"><span class="ot">#include &lt;stdio.h&gt;</span>
+<span class="ot">#include &lt;stdlib.h&gt;</span>
+
+<span class="dt">int</span>
+main(<span class="dt">int</span> argc, <span class="dt">char</span> **argv)
+{
+ printf(<span class="st">"%d</span><span class="ch">\n</span><span class="st">"</span>, rand());
+ <span class="kw">return</span> <span class="dv">0</span>;
+}</code></pre></div>
+<a href="http://cs.yale.edu/homes/aspnes/classes/223/examples/randomization/randOnce.c" class="uri">examples/randomization/randOnce.c</a>
+</div>
+<p>The <code class="backtick">rand</code> function, declared in <code class="backtick">stdlib.h</code>, returns a random-looking integer in the range 0 to <code class="backtick">RAND_MAX</code> (inclusive) every time you call it. On machines using the GNU C library <code class="backtick">RAND_MAX</code> is equal to <code class="backtick">INT_MAX</code> which is typically <span class="math inline">2<sup>31</sup> − 1</span>, but <code>RAND_MAX</code> may be as small as 32767. There are no particularly strong guarantees about the quality of random numbers that <code class="backtick">rand</code>
+ returns, but it should be good enough for casual use, and it has the
+advantage that as part of the C standard you can assume it is present
+almost everywhere.</p>
+<p>Note that <code class="backtick">rand</code> is a <strong>pseudorandom number generator</strong>:
+ the sequence of values it returns is predictable if you know its
+starting state (and is still predictable from past values in the
+sequence even if you don't know the starting state, if you are clever
+enough). It is also the case that the initial seed is fixed, so that the
+ program above will print the same value every time you run it.</p>
+<p>This is a feature: it permits debugging randomized programs. As John
+von Neumann, who proposed pseudorandom number generators in his 1946
+talk "Various Techniques Used in Connection With Random Digits,"
+explained:</p>
+<blockquote>
+<p>We see then that we could build a physical instrument to feed random
+digits directly into a high-speed computing machine and could have the
+control call for these numbers as needed. The real objection to this
+procedure is the practical need for checking computations. If we suspect
+ that a calculation is wrong, almost any reasonable check involves
+repeating something done before. At that point the introduction of new
+random numbers would be intolerable.</p>
+</blockquote>
+<h5 id="supplying-a-seed-with-srand"><span class="header-section-number">5.14.1.1.1</span> Supplying a seed with <code>srand</code></h5>
+<p>If you want to get different sequences, you need to <strong>seed</strong> the random number generator using <code class="backtick">srand</code>. A typical use might be:</p>
+<div>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"><span class="ot">#include &lt;stdio.h&gt;</span>
+<span class="ot">#include &lt;stdlib.h&gt;</span>
+<span class="ot">#include &lt;time.h&gt;</span>
+
+<span class="dt">int</span>
+main(<span class="dt">int</span> argc, <span class="dt">char</span> **argv)
+{
+ srand(time(<span class="dv">0</span>));
+ printf(<span class="st">"%d</span><span class="ch">\n</span><span class="st">"</span>, rand());
+ <span class="kw">return</span> <span class="dv">0</span>;
+}</code></pre></div>
+<a href="http://cs.yale.edu/homes/aspnes/classes/223/examples/randomization/srandFromTime.c" class="uri">examples/randomization/srandFromTime.c</a>
+</div>
+<p>Here <code class="backtick">time(0)</code> returns the number of
+seconds since the epoch (00:00:00 UTC, January 1, 1970, for POSIX
+systems, not counting leap seconds). Note that this still might give
+repeated values if you run it twice in the same second, and it's
+extremely dangerous if you expect to distribute your code to a lot of
+people who want different results, since two of your users <em>are</em> likely to run it twice in the same second. See the discussion of <code class="backtick">/dev/urandom</code> below for a better method.</p>
+<h4 id="Better_pseudorandom_number_generators"><span class="header-section-number">5.14.1.2</span> Better pseudorandom number generators</h4>
+<p>There has been quite a bit of research on pseudorandom number
+generators over the years, and much better pseudorandom number
+generators than <code class="backtick">rand</code> are available. The current champion for simulation work is <strong>Mersenne Twister</strong>, which runs about 4 times faster than <code class="backtick">rand</code> in its standard C implementation and passes a much wider battery of statistical tests. Its English-language home page is at <a href="http://www.math.sci.hiroshima-u.ac.jp/%7Em-mat/MT/emt.html" class="uri">http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/emt.html</a>. As with <code class="backtick">rand</code>, you still need to provide an initial seed value.</p>
+<p>There are also <strong>cryptographically secure pseudorandom number generators</strong>, of which the most famous is <a href="http://en.wikipedia.org/wiki/Blum_Blum_Shub" title="WikiPedia">Blum Blum Shub</a>.
+ These cannot be predicted based on their output if seeded with a true
+random value (under certain cryptographic assumptions: hardness of
+factoring for Blum Blum Shub). Unfortunately, cryptographic PRNGs are
+usually too slow for day-to-day use.</p>
+<h4 id="Random_numbers_without_the_pseudo"><span class="header-section-number">5.14.1.3</span> Random numbers without the pseudo</h4>
+<p>If you really need actual random numbers and are on a Linux or BSD-like operating system, you can use the special device files <code class="backtick">/dev/random</code> and <code class="backtick">/dev/urandom</code>.
+ These can be opened for reading like ordinary files, but the values
+read from them are a random sequence of bytes (including null
+characters). A typical use might be:</p>
+<div>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"><span class="ot">#include &lt;stdio.h&gt;</span>
+
+<span class="dt">int</span>
+main(<span class="dt">int</span> argc, <span class="dt">char</span> **argv)
+{
+ <span class="dt">unsigned</span> <span class="dt">int</span> randval;
+ FILE *f;
+
+ f = fopen(<span class="st">"/dev/random"</span>, <span class="st">"r"</span>);
+ fread(&amp;randval, <span class="kw">sizeof</span>(randval), <span class="dv">1</span>, f);
+ fclose(f);
+
+ printf(<span class="st">"%u</span><span class="ch">\n</span><span class="st">"</span>, randval);
+
+ <span class="kw">return</span> <span class="dv">0</span>;
+}</code></pre></div>
+<a href="http://cs.yale.edu/homes/aspnes/classes/223/examples/randomization/devRandom.c" class="uri">examples/randomization/devRandom.c</a>
+</div>
+<p>(A similar construction can also be used to obtain a better initial seed for <code class="backtick">srand</code> than <code class="backtick">time(0)</code>.)</p>
+<p>Both <code class="backtick">/dev/random</code> and <code class="backtick">/dev/urandom</code>
+ derive their random bits from physically random properties of the
+computer, like time between keystrokes or small variations in hard disk
+rotation speeds. The difference between the two is that <code class="backtick">/dev/urandom</code>
+ will always give you some random-looking bits, even if it has to
+generate extra ones using a cryptographic pseudo-random number
+generator, while <code class="backtick">/dev/random</code> will only
+give you bits that it is confident are in fact random. Since your
+computer only generates a small number of genuinely random bits per
+second, this may mean that <code class="backtick">/dev/random</code> will exhaust its pool if read too often. In this case, a read on <code class="backtick">/dev/random</code> will block (just like reading a terminal with no input on it) until the pool has filled up again.</p>
+<p>Neither <code class="backtick">/dev/random</code> nor <code class="backtick">/dev/urandom</code>
+ is known to be secure against a determined attacker, but they are about
+ the best you can do without resorting to specialized hardware.</p>
+<h4 id="RANDMAX"><span class="header-section-number">5.14.1.4</span> Range issues</h4>
+<p>The problem with <code class="backtick">rand</code> is that getting a uniform value between 0 and 2<sup>31</sup>-1 may not be what you want. It could be that <code class="backtick">RAND_MAX</code> is be too small; in this case, you may have to call <code class="backtick">rand</code> more than once and paste together the results. But there can be problems with <code class="backtick">RAND_MAX</code> even if it is bigger than the values you want.</p>
+<p>For example, suppose you want to simulate a die roll for your video
+craps machine, but you don't want to get whacked by Johnny "The
+Debugger" when the Nevada State Gaming Commission notices that 6-6 is
+coming up slightly less often than it's supposed to. A natural thing to
+try would be to take the output of <code class="backtick">rand</code> mod 6:</p>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"><span class="dt">int</span> d6(<span class="dt">void</span>) {
+ <span class="kw">return</span> rand() % <span class="dv">6</span> + <span class="dv">1</span>;
+}</code></pre></div>
+<p>The problem here is that there are <span class="math inline">2<sup>31</sup></span> outputs from rand, and 6 doesn't divide <span class="math inline">2<sup>31</sup></span>.
+ So 1 and 2 are slightly more likely to come up than 3, 4, 5, or 6. This
+ can be particularly noticeable if we want a uniform variable from a
+larger range, e.g. <span class="math inline">[0…⌊(2/3)⋅2<sup>31</sup>⌋]</span>.</p>
+<p>We can avoid this with a technique called <strong>rejection sampling</strong>, where we reject excess parts of the output range of <code class="backtick">rand</code>.
+ For rolling a die, the trick is to reject anything in the last extra
+bit of the range that is left over after the largest multiple of the die
+ size. Here's a routine that does this, returning a uniform value in the
+ range 0 to n-1 for any positive n, together with a program that
+demonstrates its use for rolling dice:</p>
+<div>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"><span class="ot">#include &lt;stdio.h&gt;</span>
+<span class="ot">#include &lt;stdlib.h&gt;</span>
+<span class="ot">#include &lt;assert.h&gt;</span>
+<span class="ot">#include &lt;time.h&gt;</span>
+
+<span class="co">/* return a uniform random value in the range 0..n-1 inclusive */</span>
+<span class="dt">int</span>
+randRange(<span class="dt">int</span> n)
+{
+ <span class="dt">int</span> limit;
+ <span class="dt">int</span> r;
+
+ limit = RAND_MAX - (RAND_MAX % n);
+
+ <span class="kw">while</span>((r = rand()) &gt;= limit);
+
+ <span class="kw">return</span> r % n;
+}
+
+<span class="dt">int</span>
+main(<span class="dt">int</span> argc, <span class="dt">char</span> **argv)
+{
+ <span class="dt">int</span> i;
+
+ srand(time(<span class="dv">0</span>));
+
+ <span class="kw">for</span>(i = <span class="dv">0</span>; i &lt; <span class="dv">40</span>; i++) {
+ printf(<span class="st">"%d "</span>, randRange(<span class="dv">6</span>)+<span class="dv">1</span>);
+ }
+
+ putchar(<span class="ch">'\n'</span>);
+
+ <span class="kw">return</span> <span class="dv">0</span>;
+}</code></pre></div>
+<a href="http://cs.yale.edu/homes/aspnes/classes/223/examples/randomization/randRange.c" class="uri">examples/randomization/randRange.c</a>
+</div>
+<p>More generally, rejection sampling can be used to get random values
+with particular properties, where it's hard to generate a value with
+that property directly. Here's a program that generates random primes:</p>
+<div>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"><span class="ot">#include &lt;stdio.h&gt;</span>
+<span class="ot">#include &lt;stdlib.h&gt;</span>
+<span class="ot">#include &lt;assert.h&gt;</span>
+<span class="ot">#include &lt;time.h&gt;</span>
+
+<span class="co">/* return 1 if n is prime */</span>
+<span class="dt">int</span>
+isprime(<span class="dt">int</span> n)
+{
+ <span class="dt">int</span> i;
+
+ <span class="kw">if</span>(n % <span class="dv">2</span> == <span class="dv">0</span> || n == <span class="dv">1</span>) { <span class="kw">return</span> <span class="dv">0</span>; }
+
+ <span class="kw">for</span>(i = <span class="dv">3</span>; i*i &lt;= n; i += <span class="dv">2</span>) {
+ <span class="kw">if</span>(n % i == <span class="dv">0</span>) { <span class="kw">return</span> <span class="dv">0</span>; }
+ }
+
+ <span class="kw">return</span> <span class="dv">1</span>;
+}
+
+<span class="co">/* return a uniform random value in the range 0..n-1 inclusive */</span>
+<span class="dt">int</span>
+randPrime(<span class="dt">void</span>)
+{
+ <span class="dt">int</span> r;
+
+ <span class="co">/* extra parens avoid warnings */</span>
+ <span class="kw">while</span>(!isprime((r = rand())));
+
+ <span class="kw">return</span> r;
+}
+
+<span class="dt">int</span>
+main(<span class="dt">int</span> argc, <span class="dt">char</span> **argv)
+{
+ <span class="dt">int</span> i;
+
+ srand(time(<span class="dv">0</span>));
+
+ <span class="kw">for</span>(i = <span class="dv">0</span>; i &lt; <span class="dv">10</span>; i++) {
+ printf(<span class="st">"%d</span><span class="ch">\n</span><span class="st">"</span>, randPrime());
+ }
+
+ <span class="kw">return</span> <span class="dv">0</span>;
+}</code></pre></div>
+<a href="http://cs.yale.edu/homes/aspnes/classes/223/examples/randomization/randPrime.c" class="uri">examples/randomization/randPrime.c</a>
+</div>
+<p>One temptation to avoid is to re-use your random values. If, for
+example, you try to find a random prime by picking a random x and trying
+ x, x+1, x+2, etc., until you hit a prime, some primes are more likely
+to come up than others.</p>
+<h3 id="Randomized_algorithms"><span class="header-section-number">5.14.2</span> Randomized algorithms</h3>
+<p>Randomized algorithms typically make random choices to get good
+average worst-case performance in situations where a similar
+deterministic algorithm would fail badly for some inputs but perform
+well on most inputs. The idea is that the randomization scrambles the
+input space so that the adversary can't predict which possible input
+values will be bad for us. This still allows him to make trouble if he
+gets lucky, but most of the time our algorithm should run quickly.</p>
+<h4 id="Randomized_search"><span class="header-section-number">5.14.2.1</span> Randomized search</h4>
+<p>This is essentially rejection sampling in disguise. Suppose that you
+want to find one of many needles in a large haystack. One approach is to
+ methodically go through the straws/needles one at a time until you find
+ a needle. But you may find that your good friend the adversary has put
+all the needles at the end of your list. Picking candidate at random is
+likely to hit a needle faster if there are many of them.</p>
+<p>Here is a (silly) routine that quickly finds a number whose high-order bits match a particular pattern:</p>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"><span class="dt">int</span>
+matchBits(<span class="dt">int</span> pattern)
+{
+ <span class="dt">int</span> r;
+
+ <span class="kw">while</span>(((r = rand()) &amp; <span class="bn">0x70000000</span>) != (pattern &amp; <span class="bn">0x70000000</span>));
+
+ <span class="kw">return</span> r;
+}</code></pre></div>
+<p>This will find a winning value in 8 tries on average. In contrast,
+this deterministic version will take a lot longer for nonzero patterns:</p>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"><span class="dt">int</span>
+matchBitsDeterministic(<span class="dt">int</span> pattern)
+{
+ <span class="dt">int</span> i;
+
+ <span class="kw">for</span>(i = <span class="dv">0</span>; (i &amp; <span class="bn">0x70000000</span>) != (pattern &amp; <span class="bn">0x70000000</span>); i++);
+
+ <span class="kw">return</span> i;
+}</code></pre></div>
+<p>The downside of the randomized approach is that it's hard to tell
+when to quit if there are no matches; if we stop after some fixed number
+ of trials, we get a <a href="http://en.wikipedia.org/wiki/Monte_Carlo_algorithm" title="WikiPedia">Monte Carlo algorithm</a>
+ that may give the wrong answer with small probability. The usual
+solution is to either accept a small probability of failure, or
+interleave a deterministic backup algorithm that always works. The
+latter approach gives a <a href="http://en.wikipedia.org/wiki/Las_Vegas_algorithm" title="WikiPedia">Las Vegas algorithm</a> whose running time is variable but whose correctness is not.</p>
+<h4 id="quicksort"><span class="header-section-number">5.14.2.2</span> Quickselect and quicksort</h4>
+<p><strong>Quickselect</strong>, or <strong>Hoare's FIND</strong> (Hoare, C. A. R. Algorithm 65: FIND, CACM 4(7):321–322, July 1961), is an algorithm for quickly finding the <span class="math inline"><em>k</em></span>-th largest element in an unsorted array of <span class="math inline"><em>n</em></span> elements. It runs in <span class="math inline"><em>O</em>(<em>n</em>)</span>
+ time on average, which is the best one can hope for (we have to look at
+ every element of the array to be sure we didn't miss a small one that
+changes our answer) and better than the <span class="math inline"><em>O</em>(<em>n</em>log<em>n</em>)</span> time we get if we sort the array first using a comparison-based sorting algorithm.</p>
+<p>The idea is to pick a random pivot and divide the input into two
+piles, each of which is likely to be roughly a constant fraction of the
+size of the original input.<a href="#fn24" class="footnoteRef" id="fnref24"><sup>24</sup></a>
+ It takes O(n) time to split the input up (we have to compare each
+element to the pivot once), and in the recursive calls this gives a
+geometric series. We can even do the splitting up in place if we are
+willing to reorder the elements of our original array.</p>
+<p>If we recurse into both piles instead of just one, we get <strong>quicksort</strong>
+ (Hoare, C. A. R. Algorithm 64: Quicksort. CACM 4(7):321, July 1961), a
+very fast and simple comparison-based sorting algorithm. Here is an
+implementation of both algorithms:</p>
+<div>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"><span class="ot">#include &lt;stdio.h&gt;</span>
+<span class="ot">#include &lt;stdlib.h&gt;</span>
+<span class="ot">#include &lt;assert.h&gt;</span>
+
+<span class="co">/* reorder an array to put elements &lt;= pivot</span>
+<span class="co"> * before elements &gt; pivot.</span>
+<span class="co"> * Returns number of elements &lt;= pivot */</span>
+<span class="dt">static</span> <span class="dt">int</span>
+splitByPivot(<span class="dt">int</span> n, <span class="dt">int</span> *a, <span class="dt">int</span> pivot)
+{
+ <span class="dt">int</span> lo;
+ <span class="dt">int</span> hi;
+ <span class="dt">int</span> temp; <span class="co">/* for swapping */</span>
+
+ assert(n &gt;= <span class="dv">0</span>);
+
+ <span class="co">/* Dutch Flag algorithm */</span>
+ <span class="co">/* swap everything &lt;= pivot to bottom of array */</span>
+ <span class="co">/* invariant is i &lt; lo implies a[i] &lt;= pivot */</span>
+ <span class="co">/* and i &gt; hi implies a[i] &gt; pivot */</span>
+ lo = <span class="dv">0</span>;
+ hi = n<span class="dv">-1</span>;
+
+ <span class="kw">while</span>(lo &lt;= hi) {
+ <span class="kw">if</span>(a[lo] &lt;= pivot) {
+ lo++;
+ } <span class="kw">else</span> {
+ temp = a[hi];
+ a[hi--] = a[lo];
+ a[lo] = temp;
+ }
+ }
+
+ <span class="kw">return</span> lo;
+}
+
+<span class="co">/* find the k-th smallest element of an n-element array */</span>
+<span class="co">/* may reorder elements of the original array */</span>
+<span class="dt">int</span>
+quickselectDestructive(<span class="dt">int</span> k, <span class="dt">int</span> n, <span class="dt">int</span> *a)
+{
+ <span class="dt">int</span> pivot;
+ <span class="dt">int</span> lo;
+
+ assert(<span class="dv">0</span> &lt;= k);
+ assert(k &lt; n);
+
+ <span class="kw">if</span>(n == <span class="dv">1</span>) {
+ <span class="kw">return</span> a[<span class="dv">0</span>];
+ }
+
+ <span class="co">/* else */</span>
+ pivot = a[rand() % n]; <span class="co">/* we will tolerate non-uniformity */</span>
+
+ lo = splitByPivot(n, a, pivot);
+
+ <span class="co">/* lo is now number of values &lt;= pivot */</span>
+ <span class="kw">if</span>(k &lt; lo) {
+ <span class="kw">return</span> quickselectDestructive(k, lo, a);
+ } <span class="kw">else</span> {
+ <span class="kw">return</span> quickselectDestructive(k - lo, n - lo, a + lo);
+ }
+}
+
+<span class="co">/* sort an array in place */</span>
+<span class="dt">void</span>
+quickSort(<span class="dt">int</span> n, <span class="dt">int</span> *a)
+{
+ <span class="dt">int</span> pivot;
+ <span class="dt">int</span> lo;
+
+ <span class="kw">if</span>(n &lt;= <span class="dv">1</span>) {
+ <span class="kw">return</span>;
+ }
+
+ <span class="co">/* else */</span>
+ pivot = a[rand() % n]; <span class="co">/* we will tolerate non-uniformity */</span>
+
+ lo = splitByPivot(n, a, pivot);
+
+ quickSort(lo, a);
+ quickSort(n - lo, a + lo);
+}
+
+
+<span class="co">/* shuffle an array */</span>
+<span class="dt">void</span>
+shuffle(<span class="dt">int</span> n, <span class="dt">int</span> *a)
+{
+ <span class="dt">int</span> i;
+ <span class="dt">int</span> r;
+ <span class="dt">int</span> temp;
+
+ <span class="kw">for</span>(i = n - <span class="dv">1</span>; i &gt; <span class="dv">0</span>; i--) {
+ r = rand() % i;
+ temp = a[r];
+ a[r] = a[i];
+ a[i] = temp;
+ }
+}
+
+<span class="ot">#define N (1024)</span>
+
+<span class="dt">int</span>
+main(<span class="dt">int</span> argc, <span class="dt">char</span> **argv)
+{
+ <span class="dt">int</span> a[N];
+ <span class="dt">int</span> i;
+
+ srand(<span class="dv">0</span>); <span class="co">/* use fixed value for debugging */</span>
+
+ <span class="kw">for</span>(i = <span class="dv">0</span>; i &lt; N; i++) {
+ a[i] = i;
+ }
+
+ shuffle(N, a);
+
+ <span class="kw">for</span>(i = <span class="dv">0</span>; i &lt; N; i++) {
+ assert(quickselectDestructive(i, N, a) == i);
+ }
+
+ shuffle(N, a);
+
+ quickSort(N, a);
+
+ <span class="kw">for</span>(i = <span class="dv">0</span>; i &lt; N; i++) {
+ assert(a[i] == i);
+ }
+
+ <span class="kw">return</span> <span class="dv">0</span>;
+}</code></pre></div>
+<a href="http://cs.yale.edu/homes/aspnes/classes/223/examples/randomization/quick.c" class="uri">examples/randomization/quick.c</a>
+</div>
+<h3 id="randomizedDataStructures"><span class="header-section-number">5.14.3</span> Randomized data structures</h3>
+<p>Suppose we insert <span class="math inline"><em>n</em></span>
+elements into an initially-empty binary search tree in random order with
+ no rebalancing. Then each element is equally likely to be the root, and
+ all the elements less than the root end up in the left subtree, while
+all the elements greater than the root end up in the right subtree,
+where they are further partitioned recursively. This is exactly what
+happens in quicksort, so the structure of the tree will exactly mirror
+the structure of an execution of quicksort. In particular, the average
+depth of a node will be <span class="math inline"><em>O</em>(log<em>n</em>)</span>, giving us the same expected search cost as in a balanced binary tree.</p>
+<p>The problem with this approach is that we don't have any guarantees
+that the input will be supplied in random order, and in the worst case
+we end up with a linked list. The solution is to put the randomization
+into the algorithm itself, making the structure of the tree depend on
+random choices made by the program itself.</p>
+<h4 id="skipLists"><span class="header-section-number">5.14.3.1</span> Skip lists</h4>
+<p>A <strong>skip list</strong> (<a href="ftp://ftp.cs.umd.edu/pub/skipLists/skiplists.pdf">Pugh, 1990</a>)
+ is a randomized tree-like data structure based on linked lists. It
+consists of a level 0 list that is an ordinary sorted linked list,
+together with higher-level lists that contain a random sampling of the
+elements at lower levels. When inserted into the level i list, an
+element flips a coin that tells it with probability p to insert itself
+in the level i+1 list as well.</p>
+<p>Searches in a skip list are done by starting in the highest-level
+list and searching forward for the last element whose key is smaller
+than the target; the search then continues in the same way on the next
+level down. The idea is that the higher-level lists act as express lanes
+ to get us to our target value faster. To bound the expected running
+time of a search, it helps to look at this process backwards; the
+reversed search path starts at level 0 and continues going backwards
+until it reaches the first element that is also in a higher level; it
+then jumps to the next level up and repeats the process. On average, we
+hit <span class="math inline">1 + 1/<em>p</em></span> nodes at each level before jumping back up; for constant <span class="math inline"><em>p</em></span> (e.g. <span class="math inline">1/2</span>), this gives us <span class="math inline"><em>O</em>(log<em>n</em>)</span> steps for the search.</p>
+<p>The space per element of a skip list also depends on <span class="math inline"><em>p</em></span>. Every element has at least one outgoing pointer (on level 0), and on average has exactly <span class="math inline">1/(1 − <em>p</em>)</span> expected pointers. So the space cost can also be adjusted by adjusting <span class="math inline"><em>p</em></span>. For example, if space is at a premium, setting <span class="math inline"><em>p</em> = 1/10</span> produces <span class="math inline">10/9</span> pointers per node on average—not much more than in a linked list—but still gives <span class="math inline"><em>O</em>(log<em>n</em>)</span> search time.</p>
+<p>Below is an implementation of a skip list. To avoid having to
+allocate a separate array of pointers for each element, we put a
+length-1 array at the end of <code class="backtick">struct&nbsp;skiplist</code>
+ and rely on C's lack of bounds checking to make the array longer if
+necessary. A dummy head element stores pointers to all the initial
+elements in each level of the skip list; it is given the dummy key <code class="backtick">INT_MIN</code>
+ so that searches for values less than any in the list will report this
+value. Aside from these nasty tricks, the code for search and insertion
+is pretty straightforward. Code for deletion is a little more involved,
+because we have to make sure that we delete the leftmost copy of a key
+if there are duplicates (an alternative would be to modify <code class="backtick">skiplistInsert</code> to ignore duplicates).</p>
+<div>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"><span class="ot">#include &lt;stdlib.h&gt;</span>
+<span class="ot">#include &lt;assert.h&gt;</span>
+<span class="ot">#include &lt;limits.h&gt;</span>
+
+<span class="ot">#include "skiplist.h"</span>
+
+<span class="ot">#define MAX_HEIGHT (32)</span>
+
+<span class="kw">struct</span> skiplist {
+ <span class="dt">int</span> key;
+ <span class="dt">int</span> height; <span class="co">/* number of next pointers */</span>
+ <span class="kw">struct</span> skiplist *next[<span class="dv">1</span>]; <span class="co">/* first of many */</span>
+};
+
+<span class="co">/* choose a height according to a geometric distribution */</span>
+<span class="dt">static</span> <span class="dt">int</span>
+chooseHeight(<span class="dt">void</span>)
+{
+ <span class="dt">int</span> i;
+
+ <span class="kw">for</span>(i = <span class="dv">1</span>; i &lt; MAX_HEIGHT &amp;&amp; rand() % <span class="dv">2</span> == <span class="dv">0</span>; i++);
+
+ <span class="kw">return</span> i;
+}
+
+<span class="co">/* create a skiplist node with the given key and height */</span>
+<span class="co">/* does not fill in next pointers */</span>
+<span class="dt">static</span> Skiplist
+skiplistCreateNode(<span class="dt">int</span> key, <span class="dt">int</span> height)
+{
+ Skiplist s;
+
+ assert(height &gt; <span class="dv">0</span>);
+ assert(height &lt;= MAX_HEIGHT);
+
+ s = malloc(<span class="kw">sizeof</span>(<span class="kw">struct</span> skiplist) + <span class="kw">sizeof</span>(<span class="kw">struct</span> skiplist *) * (height - <span class="dv">1</span>));
+
+ assert(s);
+
+ s-&gt;key = key;
+ s-&gt;height = height;
+
+ <span class="kw">return</span> s;
+}
+
+<span class="co">/* create an empty skiplist */</span>
+Skiplist
+skiplistCreate(<span class="dt">void</span>)
+{
+ Skiplist s;
+ <span class="dt">int</span> i;
+
+ <span class="co">/* s is a dummy head element */</span>
+ s = skiplistCreateNode(INT_MIN, MAX_HEIGHT);
+
+ <span class="co">/* this tracks the maximum height of any node */</span>
+ s-&gt;height = <span class="dv">1</span>;
+
+ <span class="kw">for</span>(i = <span class="dv">0</span>; i &lt; MAX_HEIGHT; i++) {
+ s-&gt;next[i] = <span class="dv">0</span>;
+ }
+
+ <span class="kw">return</span> s;
+}
+
+<span class="co">/* free a skiplist */</span>
+<span class="dt">void</span>
+skiplistDestroy(Skiplist s)
+{
+ Skiplist next;
+
+ <span class="kw">while</span>(s) {
+ next = s-&gt;next[<span class="dv">0</span>];
+ free(s);
+ s = next;
+ }
+}
+
+<span class="co">/* return maximum key less than or equal to key */</span>
+<span class="co">/* or INT_MIN if there is none */</span>
+<span class="dt">int</span>
+skiplistSearch(Skiplist s, <span class="dt">int</span> key)
+{
+ <span class="dt">int</span> level;
+
+ <span class="kw">for</span>(level = s-&gt;height - <span class="dv">1</span>; level &gt;= <span class="dv">0</span>; level--) {
+ <span class="kw">while</span>(s-&gt;next[level] &amp;&amp; s-&gt;next[level]-&gt;key &lt;= key) {
+ s = s-&gt;next[level];
+ }
+ }
+
+ <span class="kw">return</span> s-&gt;key;
+}
+
+<span class="co">/* insert a new key into s */</span>
+<span class="dt">void</span>
+skiplistInsert(Skiplist s, <span class="dt">int</span> key)
+{
+ <span class="dt">int</span> level;
+ Skiplist elt;
+
+ elt = skiplistCreateNode(key, chooseHeight());
+
+ assert(elt);
+
+ <span class="kw">if</span>(elt-&gt;height &gt; s-&gt;height) {
+ s-&gt;height = elt-&gt;height;
+ }
+
+ <span class="co">/* search through levels taller than elt */</span>
+ <span class="kw">for</span>(level = s-&gt;height - <span class="dv">1</span>; level &gt;= elt-&gt;height; level--) {
+ <span class="kw">while</span>(s-&gt;next[level] &amp;&amp; s-&gt;next[level]-&gt;key &lt; key) {
+ s = s-&gt;next[level];
+ }
+ }
+
+ <span class="co">/* now level is elt-&gt;height - 1, we can start inserting */</span>
+ <span class="kw">for</span>(; level &gt;= <span class="dv">0</span>; level--) {
+ <span class="kw">while</span>(s-&gt;next[level] &amp;&amp; s-&gt;next[level]-&gt;key &lt; key) {
+ s = s-&gt;next[level];
+ }
+
+ <span class="co">/* s is last entry on this level &lt; new element */</span>
+ <span class="co">/* do list insert */</span>
+ elt-&gt;next[level] = s-&gt;next[level];
+ s-&gt;next[level] = elt;
+ }
+}
+
+<span class="co">/* delete a key from s */</span>
+<span class="dt">void</span>
+skiplistDelete(Skiplist s, <span class="dt">int</span> key)
+{
+ <span class="dt">int</span> level;
+ Skiplist target;
+
+ <span class="co">/* first we have to find leftmost instance of key */</span>
+ target = s;
+
+ <span class="kw">for</span>(level = s-&gt;height - <span class="dv">1</span>; level &gt;= <span class="dv">0</span>; level--) {
+ <span class="kw">while</span>(target-&gt;next[level] &amp;&amp; target-&gt;next[level]-&gt;key &lt; key) {
+ target = target-&gt;next[level];
+ }
+ }
+
+ <span class="co">/* take one extra step at bottom */</span>
+ target = target-&gt;next[<span class="dv">0</span>];
+
+ <span class="kw">if</span>(target == <span class="dv">0</span> || target-&gt;key != key) {
+ <span class="kw">return</span>;
+ }
+
+ <span class="co">/* now we found target, splice it out */</span>
+ <span class="kw">for</span>(level = s-&gt;height - <span class="dv">1</span>; level &gt;= <span class="dv">0</span>; level--) {
+ <span class="kw">while</span>(s-&gt;next[level] &amp;&amp; s-&gt;next[level]-&gt;key &lt; key) {
+ s = s-&gt;next[level];
+ }
+
+ <span class="kw">if</span>(s-&gt;next[level] == target) {
+ s-&gt;next[level] = target-&gt;next[level];
+ }
+ }
+
+ free(target);
+}</code></pre></div>
+<a href="http://cs.yale.edu/homes/aspnes/classes/223/examples/trees/skiplist/skiplist.c" class="uri">examples/trees/skiplist/skiplist.c</a>
+</div>
+<p>Here is the header file, Makefile, and test code: <a href="http://cs.yale.edu/homes/aspnes/classes/223/examples/trees/skiplist/skiplist.h">skiplist.h</a>, <a href="http://cs.yale.edu/homes/aspnes/classes/223/examples/trees/skiplist/Makefile">Makefile</a>, <a href="http://cs.yale.edu/homes/aspnes/classes/223/examples/trees/skiplist/test_skiplist.c">test_skiplist.c</a>.</p>
+<h4 id="Universal_hash_families"><span class="header-section-number">5.14.3.2</span> Universal hash families</h4>
+<p>Randomization can also be useful in hash tables. Recall that in
+building a hash table, we are relying on the hash function to spread out
+ bad input distributions over the indices of our array. But for any
+fixed hash function, in the worst case we may get inputs where every key
+ hashes to the same location. <strong>Universal hashing</strong> (<a href="http://dx.doi.org/10.1016%2F0022-0000%2879%2990044-8">Carter and Wegman, 1979</a>)
+ solves this problem by choosing a hash function at random. We may still
+ get unlucky and have the hash function hash all our values to the same
+location, but now we are relying on the random number generator to be
+nice to us instead of the adversary. We can also rehash with a new
+random hash function if we find out that the one we are using is bad.</p>
+<p>The problem here is that we can't just choose a function uniformly at
+ random out of the set of all possible hash functions, because there are
+ too many of them, meaning that we would spend more space representing
+our hash function than we would on the table. The solution is to observe
+ that we don't need our hash function h to be truly random; it's enough
+if the probability of collision Pr[h(x) = h(y)] for any fixed keys <span class="math inline"><em>x</em> ≠ <em>y</em></span> is <span class="math inline">1/<em>m</em></span>, where <span class="math inline"><em>m</em></span>
+ is the size of the hash table. The reason is that the cost of searching
+ for x (with chaining) is linear in the number of keys already in the
+table that collide with it. The expected number of such collisions is
+the sum of Pr[h(x) = h(y)] over all keys y in the table, or n/m if we
+have n keys. So this pairwise collision probability bound is enough to
+get the desired n/m behavior out of our table. A family of hash function
+ with this property is called <strong>universal</strong>.</p>
+<p>How do we get a universal hash family? For strings, we can use a
+table of random values, one for each position and possible character in
+the string. The hash of a string is then the exclusive or of the random
+values <code class="backtick">hashArray[i][s[i]]</code> corresponding to
+ the actual characters in the string. If our table has size a power of
+two, this has the universal property, because if two strings x and y
+differ in some position i, then there is only one possible value of <code class="backtick">hashArray[i][y[i]]</code> (mod m) that will make the hash functions equal.</p>
+<p>Typically to avoid having to build an arbitrarily huge table of
+random values, we only has an initial prefix of the string. Here is a
+hash function based on this idea, which assumes that the <code class="backtick">d</code> data structure includes a <code class="backtick">hashArray</code> field that contains the random values for this particular hash table:</p>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"><span class="dt">static</span> <span class="dt">unsigned</span> <span class="dt">long</span>
+hash_function(Dict d, <span class="dt">const</span> <span class="dt">char</span> *s)
+{
+ <span class="dt">unsigned</span> <span class="dt">const</span> <span class="dt">char</span> *us;
+ <span class="dt">unsigned</span> <span class="dt">long</span> h;
+ <span class="dt">int</span> i;
+
+ h = <span class="dv">0</span>;
+
+ us = (<span class="dt">unsigned</span> <span class="dt">const</span> <span class="dt">char</span> *) s;
+
+ <span class="kw">for</span>(i = <span class="dv">0</span>; i &lt; HASH_PREFIX_LENGTH &amp;&amp; us[i] != '\<span class="dv">0</span>'; i++) {
+ h ^= d-&gt;hashArray[i][us[i]];
+ }
+
+ <span class="kw">return</span> h;
+}</code></pre></div>
+<p>A modified version of the <code class="backtick">Dict</code> hash table from the <a href="#hashTables">chapter on hash tables</a> that uses this hash function is given here: <a href="http://cs.yale.edu/homes/aspnes/classes/223/examples/hashTables/universal/dict.c">dict.c</a>, <a href="http://cs.yale.edu/homes/aspnes/classes/223/examples/hashTables/universal/dict.h">dict.h</a>, <a href="http://cs.yale.edu/homes/aspnes/classes/223/examples/hashTables/universal/test_dict.c">test_dict.c</a>, <a href="http://cs.yale.edu/homes/aspnes/classes/223/examples/hashTables/universal/Makefile">Makefile</a>.</p>
+<h2 id="stringProcessing"><span class="header-section-number">5.15</span> String processing</h2>
+<p>Most of the time, when we've talked about the asymptotic performance
+of data structures, we have implicitly assumed that the keys we are
+looking up are of constant size. This means that computing a hash
+function or comparing two keys (as in a binary search tree) takes <span class="math inline"><em>O</em>(1)</span> time. What if this is not the case?</p>
+<p>If we consider an <span class="math inline"><em>m</em></span>-character string, any reasonable hash function is going to take <span class="math inline"><em>O</em>(<em>m</em>)</span> time since it has to look at all of the characters. Similarly, comparing two <span class="math inline"><em>m</em></span>-character strings may also take <span class="math inline"><em>O</em>(<em>m</em>)</span> time. If we charge for this (as we should!) then the cost of hash table operations goes from <span class="math inline"><em>O</em>(1)</span> to <span class="math inline"><em>O</em>(<em>m</em>)</span> and the cost of binary search tree operations, even in a balanced tree, goes from <span class="math inline"><em>O</em>(log<em>n</em>)</span> to <span class="math inline"><em>O</em>(<em>m</em>log<em>n</em>)</span>. Even sorting becomes more expensive: a sorting algorithm that does <span class="math inline"><em>O</em>(<em>n</em>log<em>n</em>)</span> comparisons may now take <span class="math inline"><em>O</em>(<em>m</em><em>n</em>log<em>n</em>)</span> time. But maybe we can exploit the structure of strings to get better performance.</p>
+<h3 id="radixSearch"><span class="header-section-number">5.15.1</span> Radix search</h3>
+<p><strong>Radix search</strong> refers to a variety of data structures
+that support searching for strings considered as sequences of digits in
+some large base (or <strong>radix</strong>). These are generally faster than simple <a href="#binarySearchTrees">binary search trees</a>
+ because they usually only require examining one byte or less of the
+target string at each level of the tree, as compared to every byte in
+the target in a full string comparison. In many cases, the best radix
+search trees are even faster than <a href="#hashTables">hash tables</a>, because they only need to look at a small part of the target string to identify it.</p>
+<p>We'll describe several radix search trees, starting with the simplest and working up.</p>
+<h4 id="Tries"><span class="header-section-number">5.15.1.1</span> Tries</h4>
+<p>A <strong>trie</strong> is a binary tree (or more generally, a <em>k</em>-ary tree where <em>k</em> is the radix) where the root represents the empty bit sequence and the two children of a node representing sequence <span class="math inline"><em>x</em></span> represent the extended sequences <span class="math inline"><em>x</em>0</span> and <span class="math inline"><em>x</em>1</span> (or generally <span class="math inline"><em>x</em>0, <em>x</em>1, …, <em>x</em>(<em>k</em> − 1)</span>).
+ So a key is not stored at a particular node but is instead represented
+bit-by-bit (or digit-by-digit) along some path. Typically a trie assumes
+ that the set of keys is prefix-free, i.e. that no key is a prefix of
+another; in this case there is a one-to-one correspondence between keys
+and leaves of the trie. If this is not the case, we can mark internal
+nodes that also correspond to the ends of keys, getting a slightly
+different data structure known as a <strong>digital search tree</strong>. For null-terminated strings as in C, the null terminator ensures that any set of strings is prefix-free.</p>
+<p>Given this simple description, a trie storing a single long key would
+ have a very large number of nodes. A standard optimization is to chop
+off any path with no branches in it, so that each leaf corresponds to
+the shortest unique prefix of a key. This requires storing the key in
+the leaf so that we can distinguish different keys with the same prefix.</p>
+<p>The name <em>trie</em> comes from the phrase "information re<em>trie</em>val." Despite the etymology, <em>trie</em> is now almost always pronounced like <em>try</em> instead of <em>tree</em> to avoid confusion with other tree data structures.</p>
+<h5 id="Searching_a_trie"><span class="header-section-number">5.15.1.1.1</span> Searching a trie</h5>
+<p>Searching a trie is similar to searching a binary search tree, except
+ that instead of doing a comparison at each step we just look at the
+next bit in the target. The time to perform a search is proportional to
+the number of bits in the longest path in the tree matching a prefix of
+the target. This can be very fast for search misses if the target is
+wildly different from all the keys in the tree.</p>
+<h5 id="Inserting_a_new_element_into_a_trie"><span class="header-section-number">5.15.1.1.2</span> Inserting a new element into a trie</h5>
+<p>Insertion is more complicated for tries than for binary search trees.
+ The reason is that a new element may add more than one new node. There
+are essentially two cases:</p>
+<ol style="list-style-type: decimal">
+<li>(The simple case.) In searching for the new key, we reach a null
+pointer leaving a non-leaf node. In this case we can simply add a new
+leaf. The cost of this case is essentially the same as for search plus <span class="math inline"><em>O</em>(1)</span> for building the new leaf.</li>
+<li>(The other case.) In searching for the new key, we reach a leaf, but
+ the key stored there isn't the same as the new key. Now we have to
+generate a new path for as long as the old key and the new key have the
+same bits, branching out to two different leaves at the end. The cost of
+ this operation is within a constant factor of the cost for searching
+for the new leaf <em>after</em> it is inserted, since that's how long the newly-built search path will be.</li>
+</ol>
+<p>In either case, the cost is bounded by the length of the new key,
+which is about the best we can hope for in the worst case for any data
+structure.</p>
+<h5 id="trieImplementation"><span class="header-section-number">5.15.1.1.3</span> Implementation</h5>
+<p>A typical trie implementation in C might look like this. It uses a <code class="backtick">GET_BIT</code> macro similar to the one from the <a href="#bitManipulation">chapter on bit manipulation</a>, except that we reverse the bits within each byte to get the right sorting order for keys.</p>
+<div>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"><span class="kw">typedef</span> <span class="kw">struct</span> trie_node *Trie;
+
+<span class="ot">#define EMPTY_TRIE (0)</span>
+
+<span class="co">/* returns 1 if trie contains target */</span>
+<span class="dt">int</span> trie_contains(Trie trie, <span class="dt">const</span> <span class="dt">char</span> *target);
+
+<span class="co">/* add a new key to a trie */</span>
+<span class="co">/* and return the new trie */</span>
+Trie trie_insert(Trie trie, <span class="dt">const</span> <span class="dt">char</span> *key);
+
+<span class="co">/* free a trie */</span>
+<span class="dt">void</span> trie_destroy(Trie);
+
+<span class="co">/* debugging utility: print all keys in trie */</span>
+<span class="dt">void</span> trie_print(Trie);</code></pre></div>
+<a href="http://cs.yale.edu/homes/aspnes/classes/223/examples/trees/trie/trie.h" class="uri">examples/trees/trie/trie.h</a>
+</div>
+<div>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"><span class="ot">#include &lt;stdio.h&gt;</span>
+<span class="ot">#include &lt;stdlib.h&gt;</span>
+<span class="ot">#include &lt;string.h&gt;</span>
+<span class="ot">#include &lt;assert.h&gt;</span>
+
+<span class="ot">#include "trie.h"</span>
+
+<span class="ot">#define BITS_PER_BYTE (8)</span>
+
+<span class="co">/* extract the n-th bit of x */</span>
+<span class="co">/* here we process bits within bytes in MSB-first order */</span>
+<span class="co">/* this sorts like strcmp */</span>
+<span class="ot">#define GET_BIT(x, n) ((((x)[(n) / BITS_PER_BYTE]) &amp; (0x1 &lt;&lt; (BITS_PER_BYTE - 1 - (n) % BITS_PER_BYTE))) != 0)</span>
+
+<span class="ot">#define TRIE_BASE (2)</span>
+
+<span class="kw">struct</span> trie_node {
+ <span class="dt">char</span> *key;
+ <span class="kw">struct</span> trie_node *kids[TRIE_BASE];
+};
+
+<span class="ot">#define IsLeaf(t) ((t)-&gt;kids[0] == 0 &amp;&amp; (t)-&gt;kids[1] == 0)</span>
+
+<span class="co">/* returns 1 if trie contains target */</span>
+<span class="dt">int</span>
+trie_contains(Trie trie, <span class="dt">const</span> <span class="dt">char</span> *target)
+{
+ <span class="dt">int</span> bit;
+
+ <span class="kw">for</span>(bit = <span class="dv">0</span>; trie &amp;&amp; !IsLeaf(trie); bit++) {
+ <span class="co">/* keep going */</span>
+ trie = trie-&gt;kids[GET_BIT(target, bit)];
+ }
+
+ <span class="kw">if</span>(trie == <span class="dv">0</span>) {
+ <span class="co">/* we lost */</span>
+ <span class="kw">return</span> <span class="dv">0</span>;
+ } <span class="kw">else</span> {
+ <span class="co">/* check that leaf really contains the target */</span>
+ <span class="kw">return</span> !strcmp(trie-&gt;key, target);
+ }
+}
+
+<span class="co">/* gcc -pedantic kills strdup! */</span>
+<span class="dt">static</span> <span class="dt">char</span> *
+my_strdup(<span class="dt">const</span> <span class="dt">char</span> *s)
+{
+ <span class="dt">char</span> *s2;
+
+ s2 = malloc(strlen(s) + <span class="dv">1</span>);
+ assert(s2);
+
+ strcpy(s2, s);
+ <span class="kw">return</span> s2;
+}
+
+
+<span class="co">/* helper functions for insert */</span>
+<span class="dt">static</span> Trie
+make_trie_node(<span class="dt">const</span> <span class="dt">char</span> *key)
+{
+ Trie t;
+ <span class="dt">int</span> i;
+
+ t = malloc(<span class="kw">sizeof</span>(*t));
+ assert(t);
+
+ <span class="kw">if</span>(key) {
+ t-&gt;key = my_strdup(key);
+ assert(t-&gt;key);
+ } <span class="kw">else</span> {
+ t-&gt;key = <span class="dv">0</span>;
+ }
+
+ <span class="kw">for</span>(i = <span class="dv">0</span>; i &lt; TRIE_BASE; i++) t-&gt;kids[i] = <span class="dv">0</span>;
+
+ <span class="kw">return</span> t;
+}
+
+<span class="co">/* add a new key to a trie */</span>
+<span class="co">/* and return the new trie */</span>
+Trie
+trie_insert(Trie trie, <span class="dt">const</span> <span class="dt">char</span> *key)
+{
+ <span class="dt">int</span> bit;
+ <span class="dt">int</span> bitvalue;
+ Trie t;
+ Trie kid;
+ <span class="dt">const</span> <span class="dt">char</span> *oldkey;
+
+ <span class="kw">if</span>(trie == <span class="dv">0</span>) {
+ <span class="kw">return</span> make_trie_node(key);
+ }
+ <span class="co">/* else */</span>
+ <span class="co">/* first we'll search for key */</span>
+ <span class="kw">for</span>(t = trie, bit = <span class="dv">0</span>; !IsLeaf(t); bit++, t = kid) {
+ kid = t-&gt;kids[bitvalue = GET_BIT(key, bit)];
+ <span class="kw">if</span>(kid == <span class="dv">0</span>) {
+ <span class="co">/* woohoo! easy case */</span>
+ t-&gt;kids[bitvalue] = make_trie_node(key);
+ <span class="kw">return</span> trie;
+ }
+ }
+
+ <span class="co">/* did we get lucky? */</span>
+ <span class="kw">if</span>(!strcmp(t-&gt;key, key)) {
+ <span class="co">/* nothing to do */</span>
+ <span class="kw">return</span> trie;
+ }
+
+ <span class="co">/* else */</span>
+ <span class="co">/* hard case---have to extend the trie */</span>
+ oldkey = t-&gt;key;
+<span class="ot">#ifdef EXCESSIVE_TIDINESS</span>
+ t-&gt;key = <span class="dv">0</span>; <span class="co">/* not required but makes data structure look tidier */</span>
+<span class="ot">#endif</span>
+
+ <span class="co">/* walk the common prefix */</span>
+ <span class="kw">while</span>(GET_BIT(oldkey, bit) == (bitvalue = GET_BIT(key, bit))) {
+ kid = make_trie_node(<span class="dv">0</span>);
+ t-&gt;kids[bitvalue] = kid;
+ bit++;
+ t = kid;
+ }
+
+ <span class="co">/* then split */</span>
+ t-&gt;kids[bitvalue] = make_trie_node(key);
+ t-&gt;kids[!bitvalue] = make_trie_node(oldkey);
+
+ <span class="kw">return</span> trie;
+}
+
+<span class="co">/* kill it */</span>
+<span class="dt">void</span>
+trie_destroy(Trie trie)
+{
+ <span class="dt">int</span> i;
+
+ <span class="kw">if</span>(trie) {
+ <span class="kw">for</span>(i = <span class="dv">0</span>; i &lt; TRIE_BASE; i++) {
+ trie_destroy(trie-&gt;kids[i]);
+ }
+
+ <span class="kw">if</span>(IsLeaf(trie)) {
+ free(trie-&gt;key);
+ }
+
+ free(trie);
+ }
+}
+
+<span class="dt">static</span> <span class="dt">void</span>
+trie_print_internal(Trie t, <span class="dt">int</span> bit)
+{
+ <span class="dt">int</span> i;
+ <span class="dt">int</span> kid;
+
+ <span class="kw">if</span>(t != <span class="dv">0</span>) {
+ <span class="kw">if</span>(IsLeaf(t)) {
+ <span class="kw">for</span>(i = <span class="dv">0</span>; i &lt; bit; i++) putchar(' ');
+ puts(t-&gt;key);
+ } <span class="kw">else</span> {
+ <span class="kw">for</span>(kid = <span class="dv">0</span>; kid &lt; TRIE_BASE; kid++) {
+ trie_print_internal(t-&gt;kids[kid], bit<span class="dv">+1</span>);
+ }
+ }
+ }
+}
+
+<span class="dt">void</span>
+trie_print(Trie t)
+{
+ trie_print_internal(t, <span class="dv">0</span>);
+}</code></pre></div>
+<a href="http://cs.yale.edu/homes/aspnes/classes/223/examples/trees/trie/trie.c" class="uri">examples/trees/trie/trie.c</a>
+</div>
+<p>Here is a short test program that demonstrates how to use it:</p>
+<div>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"><span class="ot">#include &lt;stdio.h&gt;</span>
+<span class="ot">#include &lt;stdlib.h&gt;</span>
+
+<span class="ot">#include "trie.h"</span>
+
+<span class="co">/* test for trie.c */</span>
+<span class="co">/* reads lines from stdin and echoes lines that haven't appeared before */</span>
+
+<span class="co">/* read a line of text from stdin</span>
+<span class="co"> * and return it (without terminating newline) as a freshly-malloc'd block.</span>
+<span class="co"> * Caller is responsible for freeing this block.</span>
+<span class="co"> * Returns 0 on error or EOF.</span>
+<span class="co"> */</span>
+<span class="dt">char</span> *
+getline(<span class="dt">void</span>)
+{
+ <span class="dt">char</span> *line; <span class="co">/* line buffer */</span>
+ <span class="dt">int</span> n; <span class="co">/* characters read */</span>
+ <span class="dt">int</span> size; <span class="co">/* size of line buffer */</span>
+ <span class="dt">int</span> c;
+
+ size = <span class="dv">1</span>;
+ line = malloc(size);
+ <span class="kw">if</span>(line == <span class="dv">0</span>) <span class="kw">return</span> <span class="dv">0</span>;
+
+ n = <span class="dv">0</span>;
+
+ <span class="kw">while</span>((c = getchar()) != <span class="ch">'\n'</span> &amp;&amp; c != EOF) {
+ <span class="kw">while</span>(n &gt;= size - <span class="dv">1</span>) {
+ size *= <span class="dv">2</span>;
+ line = realloc(line, size);
+ <span class="kw">if</span>(line == <span class="dv">0</span>) <span class="kw">return</span> <span class="dv">0</span>;
+ }
+ line[n++] = c;
+ }
+
+ <span class="kw">if</span>(c == EOF &amp;&amp; n == <span class="dv">0</span>) {
+ <span class="co">/* got nothing */</span>
+ free(line);
+ <span class="kw">return</span> <span class="dv">0</span>;
+ } <span class="kw">else</span> {
+ line[n++] = '\<span class="dv">0</span>';
+ <span class="kw">return</span> line;
+ }
+}
+
+<span class="dt">int</span>
+main(<span class="dt">int</span> argc, <span class="dt">char</span> **argv)
+{
+ Trie t;
+ <span class="dt">char</span> *line;
+
+ t = EMPTY_TRIE;
+
+ <span class="kw">while</span>((line = getline()) != <span class="dv">0</span>) {
+ <span class="kw">if</span>(!trie_contains(t, line)) {
+ puts(line);
+ }
+
+ <span class="co">/* try to insert it either way */</span>
+ <span class="co">/* this tests that insert doesn't blow up on duplicates */</span>
+ t = trie_insert(t, line);
+
+ free(line);
+ }
+
+ puts(<span class="st">"==="</span>);
+
+ trie_print(t);
+
+ trie_destroy(t);
+
+ <span class="kw">return</span> <span class="dv">0</span>;
+}</code></pre></div>
+<a href="http://cs.yale.edu/homes/aspnes/classes/223/examples/trees/trie/test_trie.c" class="uri">examples/trees/trie/test_trie.c</a>
+</div>
+<h4 id="Patricia_trees"><span class="header-section-number">5.15.1.2</span> Patricia trees</h4>
+<p>Tries perform well when all keys are short (or are distinguished by
+short prefixes), but can grow very large if one inserts two keys that
+have a long common prefix. The reason is that a trie has to store an
+internal node for every bit of the common prefix until the two keys
+become distinguishable, leading to long chains of internal nodes each of
+ which has only one child. An optimization (described in <a href="http://dl.acm.org/citation.cfm?id=321481">this paper</a>) known as a <strong>Patricia tree</strong> eliminates these long chains by having each node store the number of the bit to branch on, like this:</p>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"><span class="kw">struct</span> patricia_node {
+ <span class="dt">char</span> *key;
+ <span class="dt">int</span> bit;
+ <span class="kw">struct</span> patricia_node *kids[<span class="dv">2</span>];
+};
+
+<span class="kw">typedef</span> <span class="kw">struct</span> patricia_node *Patricia;</code></pre></div>
+<p>Now when searching for a key, instead of using the number of nodes
+visited so far to figure out which bit to look at, we just read the bit
+out of the table. This means in particular that we can skip over any
+bits that we don't actually branch on. We do however have to be more
+careful to make sure we don't run off the end of our target key, since
+it is possible that when skipping over intermediate bits we might skip
+over some that distinguish our target from all keys in the table,
+including longer keys. For example, a Patricia tree storing the strings <code class="backtick">abc</code> and <code class="backtick">abd</code> will first test bit position 22, since that's where <code class="backtick">abc</code> and <code class="backtick">abd</code> differ. This can be trouble if we are looking for <code class="backtick">x</code>.</p>
+<p>Here's the search code:</p>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"><span class="dt">int</span>
+patricia_contains(Patricia t, <span class="dt">const</span> <span class="dt">char</span> *key)
+{
+ <span class="dt">int</span> key_bits;
+
+ key_bits = BITS_PER_BYTE * (strlen(key)+<span class="dv">1</span>); <span class="co">/* +1 for the NUL */</span>
+
+ <span class="kw">while</span>(t &amp;&amp; !IsLeaf(t)) {
+ <span class="kw">if</span>(t-&gt;bit &gt;= key_bits) {
+ <span class="co">/* can't be there */</span>
+ <span class="kw">return</span> <span class="dv">0</span>;
+ } <span class="kw">else</span> {
+ t = t-&gt;kids[GET_BIT(key, t-&gt;bit)];
+ }
+ }
+
+ <span class="kw">return</span> t &amp;&amp; !strcmp(t-&gt;key, key);
+}</code></pre></div>
+<p>The insertion code is similar in many respects to the insertion code
+for a trie. The differences are that we never construct a long chain of
+internal nodes when splitting a leaf (although we do have to scan
+through both the old and new keys to find the first bit position where
+they differ), but we may sometimes have to add a new internal node
+between two previously existing nodes if a new key branches off at a bit
+ position that was previously skipped over.</p>
+<p>In the worst case Patricia trees are much more efficient than tries,
+in both space (linear in the number of keys instead of linear in the
+total size of the keys) and time complexity, often needing to examine
+only a very small number of bits for misses (hits still require a full
+scan in <code class="backtick">strcmp</code> to verify the correct key).
+ The only downside of Patricia trees is that since they work on bits,
+they are not quite perfectly tuned to the byte or word-oriented
+structure of modern CPUs.</p>
+<h4 id="Ternary_search_trees"><span class="header-section-number">5.15.1.3</span> Ternary search trees</h4>
+<p><strong>Ternary search trees</strong> were described by Jon Bentley and Bob Sedgewick in an article in the April 1988 issue of <em>Dr. Dobb's Journal</em>, available <a href="http://www.drdobbs.com/database/ternary-search-trees/184410528">here</a>.</p>
+<p>The basic idea is that each node in the tree stores one character from the key and three child pointers <code class="backtick">lt</code>, <code class="backtick">eq</code>, and <code class="backtick">gt</code>. If the corresponding character in the target is equal to the character in the node, we move to the <em>next</em> character in the target and follow the <code class="backtick">eq</code> pointer out of the node. If the target is less, follow the <code class="backtick">lt</code> pointer but stay at the <em>same</em> character. If the target is greater, follow the <code class="backtick">gt</code>
+ pointer and again stay at the same character. When searching for a
+string, we walk down the tree until we either reach a node that matches
+the terminating NUL (a hit), or follow a null pointer (a miss).</p>
+<p>A TST acts a bit like a 256-way trie, except that instead of storing
+an array of 256 outgoing pointers, we build something similar to a small
+ binary search tree for the next character. Note that no explicit
+balancing is done within these binary search trees. From a theoretical
+perspective, the worst case is that we get a 256-node deep linked-list
+equivalent at each step, multiplying our search time by <span class="math inline">256 = <em>O</em>(1)</span>. In practice, only those characters that actual appear in some key at this stage will show up, so the <span class="math inline"><em>O</em>(1)</span> is likely to be a small <span class="math inline"><em>O</em>(1)</span>, especially if keys are presented in random order.</p>
+<p>TSTs are one of the fastest known data structures for implementing
+dictionaries using strings as keys, beating both hash tables and tries
+in most cases. They can be slower than Patricia trees if the keys have
+many keys with long matching prefixes; however, a Patricia-like
+optimization can be applied to give a <strong>compressed ternary search tree</strong> that works well even in this case. In practice, regular TSTs are usually good enough.</p>
+<p>Here is a simple implementation of an insert-only TST. The C code
+includes two versions of the insert helper routine; the first is the
+original recursive version and the second is an iterative version
+generated by eliminating the tail recursion from the first.</p>
+<div>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"><span class="kw">typedef</span> <span class="kw">struct</span> tst_node *TST;
+
+<span class="ot">#define EMPTY_TST (0)</span>
+
+<span class="co">/* returns 1 if t contains target */</span>
+<span class="dt">int</span> tst_contains(TST t, <span class="dt">const</span> <span class="dt">char</span> *target);
+
+<span class="co">/* add a new key to a TST */</span>
+<span class="co">/* and return the new TST */</span>
+TST tst_insert(TST t, <span class="dt">const</span> <span class="dt">char</span> *key);
+
+<span class="co">/* free a TST */</span>
+<span class="dt">void</span> tst_destroy(TST);</code></pre></div>
+<a href="http://cs.yale.edu/homes/aspnes/classes/223/examples/trees/tst/tst.h" class="uri">examples/trees/tst/tst.h</a>
+</div>
+<div>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"><span class="ot">#include &lt;stdio.h&gt;</span>
+<span class="ot">#include &lt;stdlib.h&gt;</span>
+<span class="ot">#include &lt;assert.h&gt;</span>
+
+<span class="ot">#include "tst.h"</span>
+
+<span class="kw">struct</span> tst_node {
+ <span class="dt">char</span> key; <span class="co">/* value to split on */</span>
+ <span class="kw">struct</span> tst_node *lt; <span class="co">/* go here if target[index] &lt; value */</span>
+ <span class="kw">struct</span> tst_node *eq; <span class="co">/* go here if target[index] == value */</span>
+ <span class="kw">struct</span> tst_node *gt; <span class="co">/* go here if target[index] &gt; value */</span>
+};
+
+<span class="co">/* returns 1 if t contains key */</span>
+<span class="dt">int</span>
+tst_contains(TST t, <span class="dt">const</span> <span class="dt">char</span> *key)
+{
+ assert(key);
+
+ <span class="kw">while</span>(t) {
+ <span class="kw">if</span>(*key &lt; t-&gt;key) {
+ t = t-&gt;lt;
+ } <span class="kw">else</span> <span class="kw">if</span>(*key &gt; t-&gt;key) {
+ t = t-&gt;gt;
+ } <span class="kw">else</span> <span class="kw">if</span>(*key == '\<span class="dv">0</span>') {
+ <span class="kw">return</span> <span class="dv">1</span>;
+ } <span class="kw">else</span> {
+ t = t-&gt;eq;
+ key++;
+ }
+ }
+
+ <span class="kw">return</span> <span class="dv">0</span>;
+}
+
+<span class="co">/* original recursive insert */</span>
+<span class="dt">static</span> <span class="dt">void</span>
+tst_insert_recursive(TST *t, <span class="dt">const</span> <span class="dt">char</span> *key)
+{
+ <span class="kw">if</span>(*t == <span class="dv">0</span>) {
+ *t = malloc(<span class="kw">sizeof</span>(**t));
+ assert(*t);
+ (*t)-&gt;key = *key;
+ (*t)-&gt;lt = (*t)-&gt;eq = (*t)-&gt;gt = <span class="dv">0</span>;
+ }
+
+ <span class="co">/* now follow search */</span>
+ <span class="kw">if</span>(*key &lt; (*t)-&gt;key) {
+ tst_insert_recursive(&amp;(*t)-&gt;lt, key);
+ } <span class="kw">else</span> <span class="kw">if</span>(*key &gt; (*t)-&gt;key) {
+ tst_insert_recursive(&amp;(*t)-&gt;gt, key);
+ } <span class="kw">else</span> <span class="kw">if</span>(*key == '\<span class="dv">0</span>') {
+ <span class="co">/* do nothing, we are done */</span>
+ ;
+ } <span class="kw">else</span> {
+ tst_insert_recursive(&amp;(*t)-&gt;eq, key<span class="dv">+1</span>);
+ }
+}
+
+<span class="co">/* iterative version of above, since somebody asked */</span>
+<span class="co">/* This is pretty much standard tail-recursion elimination: */</span>
+<span class="co">/* The whole function gets wrapped in a loop, and recursive</span>
+<span class="co"> * calls get replaced by assignment */</span>
+<span class="dt">static</span> <span class="dt">void</span>
+tst_insert_iterative(TST *t, <span class="dt">const</span> <span class="dt">char</span> *key)
+{
+ <span class="kw">for</span>(;;) {
+ <span class="kw">if</span>(*t == <span class="dv">0</span>) {
+ *t = malloc(<span class="kw">sizeof</span>(**t));
+ assert(*t);
+ (*t)-&gt;key = *key;
+ (*t)-&gt;lt = (*t)-&gt;eq = (*t)-&gt;gt = <span class="dv">0</span>;
+ }
+
+ <span class="co">/* now follow search */</span>
+ <span class="kw">if</span>(*key &lt; (*t)-&gt;key) {
+ t = &amp;(*t)-&gt;lt;
+ } <span class="kw">else</span> <span class="kw">if</span>(*key &gt; (*t)-&gt;key) {
+ t = &amp;(*t)-&gt;gt;
+ } <span class="kw">else</span> <span class="kw">if</span>(*key == '\<span class="dv">0</span>') {
+ <span class="co">/* do nothing, we are done */</span>
+ <span class="kw">return</span>;
+ } <span class="kw">else</span> {
+ t = &amp;(*t)-&gt;eq;
+ key++;
+ }
+ }
+}
+
+
+<span class="co">/* add a new key to a TST */</span>
+<span class="co">/* and return the new TST */</span>
+TST
+tst_insert(TST t, <span class="dt">const</span> <span class="dt">char</span> *key)
+{
+ assert(key);
+
+<span class="ot">#ifdef USE_RECURSIVE_INSERT</span>
+ tst_insert_recursive(&amp;t, key);
+<span class="ot">#else</span>
+ tst_insert_iterative(&amp;t, key);
+<span class="ot">#endif</span>
+ <span class="kw">return</span> t;
+}
+
+<span class="co">/* free a TST */</span>
+<span class="dt">void</span>
+tst_destroy(TST t)
+{
+ <span class="kw">if</span>(t) {
+ tst_destroy(t-&gt;lt);
+ tst_destroy(t-&gt;eq);
+ tst_destroy(t-&gt;gt);
+ free(t);
+ }
+}</code></pre></div>
+<a href="http://cs.yale.edu/homes/aspnes/classes/223/examples/trees/tst/tst.c" class="uri">examples/trees/tst/tst.c</a>
+</div>
+<p>And here is some test code, almost identical to the test code for tries: <a href="http://cs.yale.edu/homes/aspnes/classes/223/examples/trees/tst/test_tst.c">test_tst.c</a>.</p>
+<p>The <em>Dr. Dobb's</em> article contains additional code for doing deletions and partial matches, plus some optimizations for inserts.</p>
+<h4 id="treesMoreInformation"><span class="header-section-number">5.15.1.4</span> More information</h4>
+<ul>
+<li><a href="http://imej.wfu.edu/articles/2002/2/02/index.asp" class="uri">http://imej.wfu.edu/articles/2002/2/02/index.asp</a> has some good Java-based animations of radix tries, Patricia tries, and other tree-like data structures.</li>
+</ul>
+<h3 id="radixSort"><span class="header-section-number">5.15.2</span> Radix sort</h3>
+<p>The standard <code class="backtick">quicksort</code> routine is an example of a <strong>comparison-based sorting algorithm</strong>. This means that the only information the algorithm uses about the items it is sorting is the return value of the <code class="backtick">compare</code>
+ routine. This has a rather nice advantage of making the algorithm very
+general, but has the disadvantage that the algorithm can extract only
+one bit of information from every call to <code class="backtick">compare</code>. Since there are <span class="math inline"><em>n</em>!</span> possible ways to reorder the input sequence, this means we need at least <span class="math inline">log(<em>n</em>!) = <em>O</em>(<em>n</em>log<em>n</em>)</span> calls to <code class="backtick">compare</code> to finish the sort. If we are sorting something like strings, this can get particularly expensive, because calls to <code class="backtick">strcmp</code> may take time linear in the length of the strings being compared. In the worst case, sorting <span class="math inline"><em>n</em></span> strings of length <span class="math inline"><em>m</em></span> each could take <span class="math inline"><em>O</em>(<em>n</em><em>m</em>log<em>n</em>)</span> time.</p>
+<h4 id="Bucket_sort"><span class="header-section-number">5.15.2.1</span> Bucket sort</h4>
+<p>The core idea of radix sort is that if we want to sort values from a
+small range, we can do it by making one bucket for each possible value
+and throw any object with that value into the corresponding bucket. In
+the old days, when <a href="http://en.wikipedia.org/wiki/Solitaire_%28Windows%29" title="WikiPedia">Solitaire</a>
+ was a game played with physical pieces of cardboard, a player who
+suspected that that one of these "cards" had fallen under the couch
+might sort the deck by dividing it up into Spades, Hearts, Diamonds, and
+ Club piles and then sorting each pile recursively. The same trick works
+ in a computer, but there the buckets are typically implemented as an
+array of some convenient data structure.</p>
+<p>If the number of possible values is too big, we may still be able to
+use bucket sort digit-by-digit. The resulting algorithms are known
+generally as <strong>radix sort</strong>. These are a class of
+algorithms designed for sorting strings in lexicographic order—the order
+ used by dictionaries where one string is greater than another if the
+first character on which they differ is greater. One particular variant,
+ <strong>most-significant-byte radix sort</strong> or MSB radix sort,
+has the beautiful property that its running time is not only linear in
+the size of the input in bytes, but is also linear in the smallest
+number of characters in the input that need to be examined to determine
+the correct order. This algorithm is so fast that it takes not much more
+ time to sort data than it does to read the data from memory and write
+it back. But it's a little trickier to explain that the original <strong>least-significant-byte radix sort</strong> or LSB radix sort.</p>
+<h4 id="Classic_LSB_radix_sort"><span class="header-section-number">5.15.2.2</span> Classic LSB radix sort</h4>
+<p>This is the variant used for punch cards, and works well for
+fixed-length strings. The idea is to sort on the least significant
+position first, then work backwards to the most significant position.
+This works as long as each sort is <em>stable</em>, meaning that it doesn't reorder values with equal keys. For example, suppose we are sorting the strings:</p>
+<pre><code>sat
+bat
+bad</code></pre>
+<p>The first pass sorts on the third column, giving:</p>
+<pre><code>bad
+sat
+bat</code></pre>
+<p>The second pass sorts on the second column, producing no change in
+the order (all the characters are the same). The last pass sorts on the
+first column. This moves the <code class="backtick">s</code> after the two <code class="backtick">b</code>s, but preserves the order of the two words starting with <code class="backtick">b</code>. The result is:</p>
+<pre><code>bad
+bat
+sat</code></pre>
+<p>There are three downsides to LSB radix sort:</p>
+<ol style="list-style-type: decimal">
+<li>All the strings have to be the same length (this is not necessarily a problem if they are really fixed-width data types like <code class="backtick">int</code>s).</li>
+<li>The algorithm used to sort each position must be stable, which may require more effort than most programmers would like to take.</li>
+<li>It may be that the late positions in the strings don't affect the order, but we have to sort on them anyway. If we are sorting <code class="backtick">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa</code> and <code class="backtick">baaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa</code>, we spend a lot of time matching up <code class="backtick">a</code>s against each other.</li>
+</ol>
+<h4 id="MSB_radix_sort"><span class="header-section-number">5.15.2.3</span> MSB radix sort</h4>
+<p>For these reasons, MSB radix sort is used more often. This is basically the radix sort version of <a href="#quicksort">quicksort</a>,
+ where instead of partitioning our input data into two piles based on
+whether each element is less than or greater than a random pivot, we
+partition the input into 256 piles, one for each initial byte. We can
+then sort each pile recursively using the same algorithm, taking
+advantage of the fact that we know that the first byte (or later, the
+first k bytes) are equal and so we only need to look at the next one.
+The recursion stops when we get down to 1 value, or in practice where we
+ get down to a small enough number of values that the cost of doing a
+different sorting algorithm becomes lower than the cost of creating and
+tearing down the data structures for managing the piles.</p>
+<h5 id="Issues_with_recursion_depth"><span class="header-section-number">5.15.2.3.1</span> Issues with recursion depth</h5>
+<p>The depth of recursion for MSB radix sort is equal to the length of
+the second-longest string in the worst case. Since strings can be pretty
+ long, this creates a danger of blowing out the stack. The solution (as
+in <a href="#quicksort">quicksort</a>) is to use tail recursion for the
+largest pile. Now any pile we recurse into with an actual procedure call
+ is at most half the size of the original pile, so we get stack depth at
+ most <span class="math inline"><em>O</em>(log<em>n</em>)</span>.</p>
+<h5 id="Implementing_the_buckets"><span class="header-section-number">5.15.2.3.2</span> Implementing the buckets</h5>
+<p>There is a trick we can do analagous to the Dutch flag algorithm
+where we sort the array in place. The idea is that we first count the
+number of elements that land in each bucket and assign a block of the
+array for each bucket, keeping track in each block of an initial prefix
+of values that belong in the bucket with the rest not yet processed. We
+then walk through the buckets swapping out any elements at the top of
+the good prefix to the bucket they are supposed to be in. This procedure
+ puts at least one element in the right bucket for each swap, so we
+reorder everything correctly in at most <span class="math inline"><em>n</em></span> swaps and <span class="math inline"><em>O</em>(<em>n</em>)</span> additional work.</p>
+<p>To keep track of each bucket, we use two pointers <code class="backtick">bucket[i]</code> for the first element of the bucket and <code class="backtick">top[i]</code>
+ for the first unused element. We could make these be integer array
+indices, but this slows the code down by about 10%. This seems to be a
+situation where our use of pointers is complicated enough that the
+compiler can't optimize out the array lookups.</p>
+<h5 id="Further_optimization"><span class="header-section-number">5.15.2.3.3</span> Further optimization</h5>
+<p>Since we are detecting the heaviest bucket anyway, there is a
+straightforward optimization that speeds the sort up noticeably on
+inputs with a lot of duplicates: if everything would land in the same
+bucket, we can skip the bucket-sort and just go directly to the next
+character.</p>
+<h5 id="radixSortImplementation"><span class="header-section-number">5.15.2.3.4</span> Sample implementation</h5>
+<p>Here is an implementation of MSB radix sort using the ideas above:</p>
+<div>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"><span class="ot">#include &lt;assert.h&gt;</span>
+<span class="ot">#include &lt;limits.h&gt;</span>
+<span class="ot">#include &lt;string.h&gt;</span>
+
+<span class="ot">#include "radixSort.h"</span>
+
+<span class="co">/* in-place MSB radix sort for null-terminated strings */</span>
+
+<span class="co">/* helper routine for swapping */</span>
+<span class="dt">static</span> <span class="dt">void</span>
+swapStrings(<span class="dt">const</span> <span class="dt">char</span> **a, <span class="dt">const</span> <span class="dt">char</span> **b)
+{
+ <span class="dt">const</span> <span class="dt">char</span> *temp;
+
+ temp = *a;
+ *a = *b;
+ *b = temp;
+}
+
+<span class="co">/* this is the internal routine that assumes all strings are equal for the</span>
+<span class="co"> * first k characters */</span>
+<span class="dt">static</span> <span class="dt">void</span>
+radixSortInternal(<span class="dt">int</span> n, <span class="dt">const</span> <span class="dt">char</span> **a, <span class="dt">int</span> k)
+{
+ <span class="dt">int</span> i;
+ <span class="dt">int</span> count[UCHAR_MAX<span class="dv">+1</span>]; <span class="co">/* number of strings with given character in position k */</span>
+ <span class="dt">int</span> mode; <span class="co">/* most common position-k character */</span>
+ <span class="dt">const</span> <span class="dt">char</span> **bucket[UCHAR_MAX<span class="dv">+1</span>]; <span class="co">/* position of character block in output */</span>
+ <span class="dt">const</span> <span class="dt">char</span> **top[UCHAR_MAX<span class="dv">+1</span>]; <span class="co">/* first unused index in this character block */</span>
+
+ <span class="co">/* loop implements tail recursion on most common character */</span>
+ <span class="kw">while</span>(n &gt; <span class="dv">1</span>) {
+
+ <span class="co">/* count occurrences of each character */</span>
+ memset(count, <span class="dv">0</span>, <span class="kw">sizeof</span>(<span class="dt">int</span>)*(UCHAR_MAX<span class="dv">+1</span>));
+
+ <span class="kw">for</span>(i = <span class="dv">0</span>; i &lt; n; i++) {
+ count[(<span class="dt">unsigned</span> <span class="dt">char</span>) a[i][k]]++;
+ }
+
+ <span class="co">/* find the most common nonzero character */</span>
+ <span class="co">/* we will handle this specially */</span>
+ mode = <span class="dv">1</span>;
+ <span class="kw">for</span>(i = <span class="dv">2</span>; i &lt; UCHAR_MAX<span class="dv">+1</span>; i++) {
+ <span class="kw">if</span>(count[i] &gt; count[mode]) {
+ mode = i;
+ }
+ }
+
+ <span class="kw">if</span>(count[mode] &lt; n) {
+
+ <span class="co">/* generate bucket and top fields */</span>
+ bucket[<span class="dv">0</span>] = top[<span class="dv">0</span>] = a;
+ <span class="kw">for</span>(i = <span class="dv">1</span>; i &lt; UCHAR_MAX<span class="dv">+1</span>; i++) {
+ top[i] = bucket[i] = bucket[i<span class="dv">-1</span>] + count[i<span class="dv">-1</span>];
+ }
+
+ <span class="co">/* reorder elements by k-th character */</span>
+ <span class="co">/* this is similar to dutch flag algorithm */</span>
+ <span class="co">/* we start at bottom character and swap values out until everything is in place */</span>
+ <span class="co">/* invariant is that for all i, bucket[i] &lt;= j &lt; top[i] implies a[j][k] == i */</span>
+ <span class="kw">for</span>(i = <span class="dv">0</span>; i &lt; UCHAR_MAX<span class="dv">+1</span>; i++) {
+ <span class="kw">while</span>(top[i] &lt; bucket[i] + count[i]) {
+ <span class="kw">if</span>((<span class="dt">unsigned</span> <span class="dt">char</span>) top[i][<span class="dv">0</span>][k] == i) {
+ <span class="co">/* leave it in place, advance bucket */</span>
+ top[i]++;
+ } <span class="kw">else</span> {
+ <span class="co">/* swap with top of appropriate block */</span>
+ swapStrings(top[i], top[(<span class="dt">unsigned</span> <span class="dt">char</span>) top[i][<span class="dv">0</span>][k]]++);
+ }
+ }
+ }
+
+ <span class="co">/* we have now reordered everything */</span>
+ <span class="co">/* recurse on all but 0 and mode */</span>
+ <span class="kw">for</span>(i = <span class="dv">1</span>; i &lt; UCHAR_MAX<span class="dv">+1</span>; i++) {
+ <span class="kw">if</span>(i != mode) {
+ radixSortInternal(count[i], bucket[i], k<span class="dv">+1</span>);
+ }
+ }
+
+ <span class="co">/* tail recurse on mode */</span>
+ n = count[mode];
+ a = bucket[mode];
+ k = k<span class="dv">+1</span>;
+
+ } <span class="kw">else</span> {
+
+ <span class="co">/* tail recurse on whole pile */</span>
+ k = k<span class="dv">+1</span>;
+ }
+ }
+}
+
+<span class="dt">void</span>
+radixSort(<span class="dt">int</span> n, <span class="dt">const</span> <span class="dt">char</span> **a)
+{
+ radixSortInternal(n, a, <span class="dv">0</span>);
+}</code></pre></div>
+<a href="http://cs.yale.edu/homes/aspnes/classes/223/examples/sorting/radixSort/radixSort.c" class="uri">examples/sorting/radixSort/radixSort.c</a>
+</div>
+<p>Some additional files: <a href="http://cs.yale.edu/homes/aspnes/classes/223/examples/sorting/radixSort/radixSort.h">radixSort.h</a>, <a href="http://cs.yale.edu/homes/aspnes/classes/223/examples/sorting/radixSort/test_radixSort.c">test_radixSort.c</a>, <a href="http://cs.yale.edu/homes/aspnes/classes/223/examples/sorting/radixSort/Makefile">Makefile</a>, <a href="http://cs.yale.edu/homes/aspnes/classes/223/examples/sorting/radixSort/sortInput.c">sortInput.c</a>. The last is a program that sorts lines on <code class="backtick">stdin</code> and writes the result to <code class="backtick">stdout</code>, similar to the GNU <code class="backtick">sort</code> utility. When compiled with <code class="backtick">-O3</code> and run on my machine, this runs in about the same time as the standard <code class="backtick">sort</code> program when run on a 4.7 million line input file consisting of a random shuffle of 20 copies of <code class="backtick">/usr/share/dict/words</code>, provided <code class="backtick">sort</code> is run with <code class="backtick">LANG=C&nbsp;sort&nbsp;&lt;&nbsp;/usr/share/dict/words</code> to keep it from having to deal with locale-specific collating issues. On other inputs, <code class="backtick">sort</code> is faster. This is not bad given how thoroughly <code class="backtick">sort</code> has been optimized, but is a sign that further optimization is possible.</p>
+<h1 id="other-topics-not-covered-in-detail-in-2015"><span class="header-section-number">6</span> Other topics not covered in detail in 2015</h1>
+<p>These are mostly leftovers from previous versions of the class where different topics were emphasized.</p>
+<h2 id="more-applications-of-function-pointers"><span class="header-section-number">6.1</span> More applications of function pointers</h2>
+<p>Here we show how to implement various mechanisms often found in more
+sophisticated programming languages in C using function pointers.</p>
+<h3 id="iterators"><span class="header-section-number">6.1.1</span> Iterators</h3>
+<p>Suppose we have an abstract data type that represents some sort of
+container, such as a list or dictionary. We'd like to be able to do
+something to every element of the container; say, count them up. How can
+ we write operations on the abstract data type to allow this, without
+exposing the implementation?</p>
+<p>To make the problem more concrete, let's suppose we have an abstract
+data type that represents the set of all non-negative numbers less than
+some fixed bound. The core of its interface might look like this:</p>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"><span class="co">/*</span>
+<span class="co"> * Abstract data type representing the set of numbers from 0 to</span>
+<span class="co"> * bound-1 inclusive, where bound is passed in as an argument at creation.</span>
+<span class="co"> */</span>
+<span class="kw">typedef</span> <span class="kw">struct</span> nums *Nums;
+
+<span class="co">/* Create a Nums object with given bound. */</span>
+Nums nums_create(<span class="dt">int</span> bound);
+
+<span class="co">/* Destructor */</span>
+<span class="dt">void</span> nums_destroy(Nums);
+
+<span class="co">/* Returns 1 if nums contains element, 0 otherwise */</span>
+<span class="dt">int</span> nums_contains(Nums nums, <span class="dt">int</span> element);</code></pre></div>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"><span class="ot">#include &lt;stdlib.h&gt;</span>
+<span class="ot">#include "nums.h"</span>
+
+<span class="kw">struct</span> nums {
+ <span class="dt">int</span> bound;
+};
+
+Nums nums_create(<span class="dt">int</span> bound)
+{
+ <span class="kw">struct</span> nums *n;
+ n = malloc(<span class="kw">sizeof</span>(*n));
+ n-&gt;bound = bound;
+ <span class="kw">return</span> n;
+}
+
+<span class="dt">void</span> nums_destroy(Nums n) { free(n); }
+
+<span class="dt">int</span> nums_contains(Nums n, <span class="dt">int</span> element)
+{
+ <span class="kw">return</span> element &gt;= <span class="dv">0</span> &amp;&amp; element &lt; n-&gt;bound;
+}</code></pre></div>
+<p>From the outside, a <code>Nums</code> acts like the set of numbers from <code>0</code> to <code>bound&nbsp;-&nbsp;1</code>; <code>nums_contains</code> will insist that it contains any <code>int</code> that is in this set and contains no <code>int</code> that is not in this set.</p>
+<p>Let's suppose now that we want to loop over all elements of some <code>Nums</code>, say to add them together. In particular, we'd like to implement the following pseudocode, where <code>nums</code> is some <code>Nums</code> instance:</p>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c">sum = <span class="dv">0</span>;
+<span class="kw">for</span>(each i in nums) {
+ sum += i;
+}</code></pre></div>
+<p>One way to do this would be to build the loop into some operation in <code>nums.c</code>, including its body. But we'd like to be able to substitute any body for the <code>sum&nbsp;+=&nbsp;i</code> line. Since we can't see the inside of a <code>Nums</code>, we need to have some additional operation or operations on a <code>Nums</code> that lets us write the loop. How can we do this?</p>
+<h4 id="Option_1:_Function_that_returns_a_sequence"><span class="header-section-number">6.1.1.1</span> Option 1: Function that returns a sequence</h4>
+<p>A data-driven approach might be to add a <code>nums_contents</code>
+function that returns a sequence of all elements of some instance,
+perhaps in the form of an array or linked list. The advantage of this
+approach is that once you have the sequence, you don't need to worry
+about changes to (or destruction of) the original object. The
+disadvantage is that you have to deal with storage management issues,
+and have to pay the costs in time and space of allocating and filling in
+ the sequence. This can be particularly onerous for a "virtual"
+container like <code>Nums</code>, since we could conceivably have a <code>Nums</code> instance with billions of elements.</p>
+<p>Bearing these facts in mind, let's see what this approach might look like. We'll define a new function <code>nums_contents</code> that returns an array of <code>int</code>s, terminated by a <code>-1</code> sentinel:</p>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"><span class="dt">int</span> *
+nums_contents(Nums n)
+{
+ <span class="dt">int</span> *a;
+ <span class="dt">int</span> i;
+ a = malloc(<span class="kw">sizeof</span>(*a) * (n-&gt;bound + <span class="dv">1</span>));
+ <span class="kw">for</span>(i = <span class="dv">0</span>; i &lt; n-&gt;bound; i++) a[i] = i;
+ a[n-&gt;bound] = -<span class="dv">1</span>;
+ <span class="kw">return</span> a;
+}</code></pre></div>
+<p>We might use it like this:</p>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"> sum = <span class="dv">0</span>;
+ contents = nums_contents(nums);
+ <span class="kw">for</span>(p = contents; *p != -<span class="dv">1</span>; p++) {
+ sum += *p;
+ }
+ free(contents);</code></pre></div>
+<p>Despite the naturalness of the approach, returning a sequence in this case leads to the <em>most</em> code complexity of the options we will examine.</p>
+<h4 id="Option_2:_Iterator_with_first.2Fdone.2Fnext_operations"><span class="header-section-number">6.1.1.2</span> Option 2: Iterator with first/done/next operations</h4>
+<p>If we don't want to look at all the elements at once, but just want to process them one at a time, we can build an <em>iterator</em>.
+ An iterator is an object that allows you to step through the contents
+of another object, by providing convenient operations for getting the
+first element, testing when you are done, and getting the next element
+if you are not. In C, we try to design iterators to have operations that
+ fit well in the top of a <code>for</code> loop.</p>
+<p>For the <code>Nums</code> type, we'll make each <code>Nums</code> its own iterator. The new operations are given here:</p>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"><span class="dt">int</span> nums_first(Nums n) { <span class="kw">return</span> <span class="dv">0</span>; }
+<span class="dt">int</span> nums_done(Nums n, <span class="dt">int</span> val) { <span class="kw">return</span> val &gt;= n-&gt;bound; }
+<span class="dt">int</span> nums_next(Nums n, <span class="dt">int</span> val) { <span class="kw">return</span> val<span class="dv">+1</span>; }</code></pre></div>
+<p>And we use them like this:</p>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"> sum = <span class="dv">0</span>;
+ <span class="kw">for</span>(i = nums_first(nums); !nums_done(nums, i); i = nums_next(nums, i)) {
+ sum += i;
+ }</code></pre></div>
+<p>Not only do we completely avoid the overhead of building a sequence,
+we also get much cleaner code. It helps in this case that all we need to
+ find the next value is the previous one; for a more complicated problem
+ we might have to create and destroy a separate iterator object that
+holds the state of the loop. But for many tasks in C, the
+first/done/next idiom is a pretty good one.</p>
+<h4 id="Option_3:_Iterator_with_function_argument"><span class="header-section-number">6.1.1.3</span> Option 3: Iterator with function argument</h4>
+<p>Suppose we have a very complicated iteration, say one that might
+require several nested loops or even a recursion to span all the
+elements. In this case it might be very difficult to provide
+first/done/next operations, because it would be hard to encode the state
+ of the iteration so that we could easily pick up in the next operation
+where we previously left off. What we'd really like to do is to be able
+to plug arbitrary code into the innermost loop of our horrible iteration
+ procedure, and do it in a way that is reasonably typesafe and doesn't
+violate our abstraction barrier. This is a job for function pointers,
+and an example of the <em>functional programming style</em> in action.</p>
+<p>We'll define a <code>nums_foreach</code> function that takes a function as an argument:</p>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"><span class="dt">void</span> nums_foreach(Nums n, <span class="dt">void</span> (*f)(<span class="dt">int</span>, <span class="dt">void</span> *), <span class="dt">void</span> *f_data)
+{
+ <span class="dt">int</span> i;
+ <span class="kw">for</span>(i = <span class="dv">0</span>; i &lt; n-&gt;bound; i++) f(i, f_data);
+}</code></pre></div>
+<p>The <code>f_data</code> argument is used to pass extra state into the passed-in function <code>f</code>; it's a <code>void&nbsp;*</code> because we want to let <code>f</code> work on any sort of extra state it likes.</p>
+<p>Now to do our summation, we first define an extra function <code>sum_helper</code>, which adds each element to an accumulator pointed to by <code>f_data</code>:</p>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"><span class="dt">static</span> <span class="dt">void</span> sum_helper(<span class="dt">int</span> i, <span class="dt">void</span> *f_data)
+{
+ *((<span class="dt">int</span> *) f_data) += i;
+}</code></pre></div>
+<p>We then feed <code>sum_helper</code> to the <code>nums_foreach</code> function:</p>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"> sum = <span class="dv">0</span>;
+ nums_foreach(nums, sum_helper, (<span class="dt">void</span> *) &amp;sum);</code></pre></div>
+<p>There is a bit of a nuisance in having to define the auxiliary <code>sum_helper</code> function and in all the casts to and from <code>void</code>,
+ but on the whole the complexity of this solution is not substantially
+greater than the first/done/next approach. Which you should do depends
+on whether it's harder to encapsulate the state of the iterator (in
+which case the functional approach is preferable) or of the loop body
+(in which case the first/done/next approach is preferable), and whether
+you need to bail out of the loop early (which would require special
+support from the <code>foreach</code> procedure, perhaps checking a
+return value from the function). However, it's almost always
+straightforward to encapsulate the state of a loop body; just build a <code>struct</code> containing all the variables that it uses, and pass a pointer to this struct as <code>f_data</code>.</p>
+<h3 id="closures"><span class="header-section-number">6.1.2</span> Closures</h3>
+<p>A <strong>closure</strong> is a function plus some associated state. A simple way to implement closures in C is to use a <code class="backtick">static</code>
+ local variable, but then you only get one. Better is to allocate the
+state somewhere and pass it around with the function. For example,
+here's a simple functional implementation of infinite sequences:</p>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"><span class="co">/* a sequence is an object that returns a new value each time it is called */</span>
+<span class="kw">struct</span> sequence {
+ <span class="dt">int</span> (*next)(<span class="dt">void</span> *data);
+ <span class="dt">void</span> *data;
+};
+
+<span class="kw">typedef</span> <span class="kw">struct</span> sequence *Sequence;
+
+Sequence
+create_sequence(<span class="dt">int</span> (*next)(<span class="dt">void</span> *data), <span class="dt">void</span> *data)
+{
+ Sequence s;
+
+ s = malloc(<span class="kw">sizeof</span>(*s));
+ assert(s);
+
+ s-&gt;next = next;
+ s-&gt;data = data;
+
+ <span class="kw">return</span> s;
+}
+
+<span class="dt">int</span>
+sequence_next(Sequence s)
+{
+ <span class="kw">return</span> s-&gt;next(s-&gt;data);
+}</code></pre></div>
+<p>And here are some examples of sequences:</p>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"><span class="co">/* make a constant sequence that always returns x */</span>
+<span class="dt">static</span> <span class="dt">int</span>
+constant_sequence_next(<span class="dt">void</span> *data)
+{
+ <span class="kw">return</span> *((<span class="dt">int</span> *) data);
+}
+
+Sequence
+constant_sequence(<span class="dt">int</span> x)
+{
+ <span class="dt">int</span> *data;
+
+ data = malloc(<span class="kw">sizeof</span>(*data));
+ <span class="kw">if</span>(data == <span class="dv">0</span>) <span class="kw">return</span> <span class="dv">0</span>;
+
+ *data = x;
+
+ <span class="kw">return</span> create_sequence(constant_sequence_next, data);
+}
+
+<span class="co">/* make a sequence x, x+a, x+2*a, x+3*a, ... */</span>
+<span class="kw">struct</span> arithmetic_sequence_data {
+ <span class="dt">int</span> cur;
+ <span class="dt">int</span> step;
+};
+
+<span class="dt">static</span> <span class="dt">int</span>
+arithmetic_sequence_next(<span class="dt">void</span> *data)
+{
+ <span class="kw">struct</span> arithmetic_sequence_data *d;
+
+ d = data;
+ d-&gt;cur += d-&gt;step;
+
+ <span class="kw">return</span> d-&gt;cur;
+}
+
+Sequence
+arithmetic_sequence(<span class="dt">int</span> x, <span class="dt">int</span> a)
+{
+ <span class="kw">struct</span> arithmetic_sequence_data *d;
+
+ d = malloc(<span class="kw">sizeof</span>(*d));
+ <span class="kw">if</span>(d == <span class="dv">0</span>) <span class="kw">return</span> <span class="dv">0</span>;
+
+ d-&gt;cur = x - a; <span class="co">/* back up so first value returned is x */</span>
+ d-&gt;step = a;
+
+ <span class="kw">return</span> create_sequence(arithmetic_sequence_next, d);
+}
+
+<span class="co">/* Return the sum of two sequences */</span>
+<span class="dt">static</span> <span class="dt">int</span>
+add_sequences_next(<span class="dt">void</span> *data)
+{
+ Sequence *s;
+
+ s = data;
+ <span class="kw">return</span> sequence_next(s[<span class="dv">0</span>]) + sequence_next(s[<span class="dv">1</span>]);
+}
+
+Sequence
+add_sequences(Sequence s0, Sequence s1)
+{
+ Sequence *s;
+
+ s = malloc(<span class="dv">2</span>*<span class="kw">sizeof</span>(*s));
+ <span class="kw">if</span>(s == <span class="dv">0</span>) <span class="kw">return</span> <span class="dv">0</span>;
+
+ s[<span class="dv">0</span>] = s0;
+ s[<span class="dv">1</span>] = s1;
+
+ <span class="kw">return</span> create_sequence(add_sequences_next, s);
+}
+
+<span class="co">/* Return the sequence x, f(x), f(f(x)), ... */</span>
+<span class="kw">struct</span> iterated_function_sequence_data {
+ <span class="dt">int</span> x;
+ <span class="dt">int</span> (*f)(<span class="dt">int</span>);
+}
+
+<span class="dt">static</span> <span class="dt">int</span>
+iterated_function_sequence_next(<span class="dt">void</span> *data)
+{
+ <span class="kw">struct</span> iterated_function_sequence_data *d;
+ <span class="dt">int</span> retval;
+
+ d = data;
+
+ retval = d-&gt;x;
+ d-&gt;x = d-&gt;f(d-&gt;x);
+
+ <span class="kw">return</span> retval;
+}
+
+Sequence
+iterated_function_sequence(<span class="dt">int</span> (*f)(<span class="dt">int</span>), <span class="dt">int</span> x0)
+{
+ <span class="kw">struct</span> iterated_function_sequence_data *d;
+
+ d = malloc(<span class="kw">sizeof</span>(*d));
+ <span class="kw">if</span>(d == <span class="dv">0</span>) <span class="kw">return</span> <span class="dv">0</span>;
+
+ d-&gt;x = x0;
+ d-&gt;f = f;
+
+ <span class="kw">return</span> create_sequence(iterated_function_sequence_next, d);
+}</code></pre></div>
+<p>Note that we haven't worried about how to free the <code class="backtick">data</code> field inside a <code class="backtick">Sequence</code>,
+ and indeed it's not obvious that we can write a generic data-freeing
+routine since we don't know what structure it has. The solution is to
+add more function pointers to a <code class="backtick">Sequence</code>,
+so that we can get the next value, get the sequence to destroy itself,
+etc. When we do so, we have gone beyond building a closure to building
+an <strong>object</strong>.</p>
+<h3 id="Objects"><span class="header-section-number">6.1.3</span> Objects</h3>
+<p>Here's an example of a hierarchy of counter objects. Each counter object has (at least) three operations: <code class="backtick">reset</code>, <code class="backtick">next</code>, and <code class="backtick">destroy</code>. To call the <code class="backtick">next</code> operation on counter <code class="backtick">c</code> we include <code class="backtick">c</code> and the first argument, e.g. <code class="backtick">c-&gt;next(c)</code> (one could write a wrapper to enforce this).</p>
+<p>The main trick is that we define a basic counter structure and then
+extend it to include additional data, using lots of pointer conversions
+to make everything work.</p>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"><span class="co">/* use preprocessor to avoid rewriting these */</span>
+<span class="ot">#define COUNTER_FIELDS \</span>
+<span class="ot"> void (*reset)(struct counter *); \</span>
+<span class="ot"> int (*next)(struct counter *); \</span>
+<span class="ot"> void (*destroy)(struct counter *);</span>
+
+<span class="kw">struct</span> counter {
+ COUNTER_FIELDS
+};
+
+<span class="kw">typedef</span> <span class="kw">struct</span> counter *Counter;
+
+<span class="co">/* minimal counter--always returns zero */</span>
+<span class="co">/* we don't even allocate this, just have one global one */</span>
+<span class="dt">static</span> <span class="dt">void</span> noop(Counter c) { ; }
+<span class="dt">static</span> <span class="dt">int</span> return_zero(Counter c) { <span class="kw">return</span> <span class="dv">0</span>; }
+<span class="dt">static</span> <span class="kw">struct</span> counter Zero_counter = { noop, return_zero, noop };
+
+Counter
+make_zero_counter(<span class="dt">void</span>)
+{
+ <span class="kw">return</span> &amp;Zero_counter;
+}
+
+<span class="co">/* a fancier counter that iterates a function sequence */</span>
+<span class="co">/* this struct is not exported anywhere */</span>
+<span class="kw">struct</span> ifs_counter {
+
+ <span class="co">/* copied from struct counter declaration */</span>
+ COUNTER_FIELDS
+
+ <span class="co">/* new fields */</span>
+ <span class="dt">int</span> init;
+ <span class="dt">int</span> cur;
+ <span class="dt">int</span> (*f)(<span class="dt">int</span>); <span class="co">/* update rule */</span>
+};
+
+<span class="dt">static</span> <span class="dt">void</span>
+ifs_reset(Counter c)
+{
+ <span class="kw">struct</span> ifs_counter *ic;
+
+ ic = (<span class="kw">struct</span> ifs_counter *) c;
+
+ ic-&gt;cur = ic-&gt;init;
+}
+
+<span class="dt">static</span> <span class="dt">void</span>
+ifs_next(Counter c)
+{
+ <span class="kw">struct</span> ifs_counter *ic;
+ <span class="dt">int</span> ret;
+
+ ic = (<span class="kw">struct</span> ifs_counter *) c;
+
+ ret = ic-&gt;cur;
+ ic-&gt;cur = ic-&gt;f(ic-&gt;cur);
+
+ <span class="kw">return</span> ret;
+}
+
+Counter
+make_ifs_counter(<span class="dt">int</span> init, <span class="dt">int</span> (*f)(<span class="dt">int</span>))
+{
+ <span class="kw">struct</span> ifs_counter *ic;
+
+ ic = malloc(<span class="kw">sizeof</span>(*ic));
+
+ ic-&gt;reset = ifs_reset;
+ ic-&gt;next = ifs_next;
+ ic-&gt;destroy = (<span class="dt">void</span> (*)(<span class="kw">struct</span> counter *)) free;
+
+ ic-&gt;init = init;
+ ic-&gt;cur = init;
+ ic-&gt;f = f;
+
+ <span class="co">/* it's always a Counter on the outside */</span>
+ <span class="kw">return</span> (Counter) ic;
+}</code></pre></div>
+<p>A typical use might be</p>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"><span class="dt">static</span> <span class="dt">int</span>
+times2(<span class="dt">int</span> x)
+{
+ <span class="kw">return</span> x*<span class="dv">2</span>;
+}
+
+<span class="dt">void</span>
+print_powers_of_2(<span class="dt">void</span>)
+{
+ <span class="dt">int</span> i;
+ Counter c;
+
+ c = make_ifs_counter(<span class="dv">1</span>, times2);
+
+ <span class="kw">for</span>(i = <span class="dv">0</span>; i &lt; <span class="dv">10</span>; i++) {
+ printf(<span class="st">"%d</span><span class="ch">\n</span><span class="st">"</span>, c-&gt;next(c));
+ }
+
+ c-&gt;reset(c);
+
+ <span class="kw">for</span>(i = <span class="dv">0</span>; i &lt; <span class="dv">20</span>; i++) {
+ printf(<span class="st">"%d</span><span class="ch">\n</span><span class="st">"</span>, c-&gt;next(c));
+ }
+
+ c-&gt;destroy(c);
+}</code></pre></div>
+<h2 id="suffixArrays"><span class="header-section-number">6.2</span> Suffix arrays</h2>
+<p>These are notes on practical implementations of suffix arrays, which
+are a data structure for searching quickly for substrings of a given
+large string.</p>
+<h3 id="Why_do_we_want_to_do_this.3F"><span class="header-section-number">6.2.1</span> Why do we want to do this?</h3>
+<ul>
+<li>Answer from the old days: Fast string searching is the key to
+dealing with mountains of information. Why, a modern (c. 1960)
+electronic computer can search the equivalent of hundreds of pages of
+text in just a few hours...</li>
+<li>More recent answer:
+<ul>
+<li>We still need to search enormous corpuses of text (see <a href="http://www.google.com/" class="uri">http://www.google.com</a>).</li>
+<li>Algorithms for finding long repeated substrings or patterns can be useful for <a href="http://en.wikipedia.org/wiki/Data_compression" title="WikiPedia">data compression</a>) or detecting plagiarism.</li>
+<li>Finding all occurrence of a particular substring in some huge corpus is the basis of <a href="http://en.wikipedia.org/wiki/Statistical_machine_translation" title="WikiPedia">statistical machine translation</a>.</li>
+<li>We are made out of strings over a particular finite alphabet GATC. String search is a central tool in computational biology.</li>
+</ul></li>
+</ul>
+<h3 id="String_search_algorithms"><span class="header-section-number">6.2.2</span> String search algorithms</h3>
+<p>Without preprocessing, searching an <span class="math inline"><em>n</em></span>-character string for an <span class="math inline"><em>m</em></span>-character substring can be done using algorithms of varying degrees of sophistication, the worst of which run in time <span class="math inline"><em>O</em>(<em>n</em><em>m</em>)</span> (run <code class="backtick">strncmp</code> on each position in the big string), and best of which run in time <span class="math inline"><em>O</em>(<em>n</em> + <em>m</em>)</span> (run the <a href="http://en.wikipedia.org/wiki/Boyer-Moore_string_search_algorithm" title="WikiPedia">Boyer-Moore string search algorithm</a>).
+ But we are interested in the case where we can preprocess our big
+string into a data structure that will let us do lots of searches for
+cheap.</p>
+<h3 id="Suffix_trees_and_suffix_arrays"><span class="header-section-number">6.2.3</span> Suffix trees and suffix arrays</h3>
+<p><strong>Suffix trees</strong> and <strong>suffix arrays</strong> are
+data structures for representing texts that allow substring queries like
+ "where does this pattern appear in the text" or "how many times does
+this pattern occur in the text" to be answered quickly. Both work by
+storing all suffixes of a text, where a <em>suffix</em> is a substring that runs to the end of the text. Of course, storing actual copies of all suffixes of an <span class="math inline"><em>n</em></span>-character text would take <span class="math inline"><em>O</em>(<em>n</em><sup>2</sup>)</span> space, so instead each suffix is represented by a pointer to its first character.</p>
+<p>A suffix array stores all the suffixes sorted in dictionary order. For example, the suffix array of the string <code class="backtick">abracadabra</code>
+ is shown below. The actual contents of the array are the indices in the
+ left-hand column; the right-hand shows the corresponding suffixes.</p>
+<pre><code>11 \0
+10 a\0
+ 7 abra\0
+ 0 abracadabra\0
+ 3 acadabra\0
+ 5 adabra\0
+ 8 bra\0
+ 1 bracadabra\0
+ 4 cadabra\0
+ 6 dabra\0
+ 9 ra\0
+ 2 racadabra\0</code></pre>
+<p>A suffix tree is similar, but instead using an array, we use some
+sort of tree data structure to hold the sorted list. A common choice
+given an alphabet of some fixed size <span class="math inline"><em>k</em></span> is a <a href="#radixSearch">trie</a>, in which each node at depth <span class="math inline"><em>d</em></span> represents a string of length <span class="math inline"><em>d</em></span>, and its up to <span class="math inline"><em>k</em></span> children represent all <span class="math inline">(<em>d</em> + 1)</span>-character extensions of the string. The advantage of using a suffix trie is that searching for a string of length <span class="math inline"><em>m</em></span> takes <span class="math inline"><em>O</em>(<em>m</em>)</span> time, since we can just walk down the trie at the rate of one node per character in <span class="math inline"><em>m</em></span>. A further optimization is to replace any long chain of single-child nodes with a <em>compressed</em>
+ edge labeled with the concatenation all the characters in the chain.
+Such compressed suffix tries can not only be searched in linear time but
+ can also be constructed in linear time with a sufficiently clever
+algorithm (we won't actually do this here). Of course, we could also use
+ a simple balanced binary tree, which might be preferable if the
+alphabet is large.</p>
+<p>The disadvantage of suffix trees over suffix arrays is that they
+generally require more space to store all the internal pointers in the
+tree. If we are indexing a huge text (or collection of texts), this
+extra space may be too expensive.</p>
+<h4 id="Building_a_suffix_array"><span class="header-section-number">6.2.3.1</span> Building a suffix array</h4>
+<p>A straightforward approach to building a suffix array is to run any
+decent comparison-based sorting algorithm on the set of suffixes
+(represented by pointers into the text). This will take <span class="math inline"><em>O</em>(<em>n</em>log<em>n</em>)</span> comparisons, but in the worst case each comparison will take <span class="math inline"><em>O</em>(<em>n</em>)</span> time, for a total of <span class="math inline"><em>O</em>(<em>n</em><sup>2</sup>log<em>n</em>)</span> time. This is the approach used in the sample code below.</p>
+<p>The original suffix array paper by Manber and Myers ("Suffix arrays: a
+ new method for on-line string searches," SIAM Journal on Computing
+22(5):935-948, 1993) gives an <span class="math inline"><em>O</em>(<em>n</em>log<em>n</em>)</span>
+ algorithm, somewhat resembling radix sort, for building suffix arrays
+in place with only a small amount of additional space. They also note
+that for random text, simple radix sorting works well, since most
+suffixes become distinguishable after about <span class="math inline">log<sub><em>k</em></sub><em>n</em></span> characters (where <span class="math inline"><em>k</em></span> is the size of the alphabet); this gives a cost of <span class="math inline"><em>O</em>(<em>n</em>log<em>n</em>)</span>
+ to do the sort, since radix sort only looks at the bytes it needs to
+once. For a comparison-based sort, the same assumption gives an <span class="math inline"><em>O</em>(<em>n</em>log<sup>2</sup><em>n</em>)</span> running time; this is a factor of <span class="math inline">log<em>n</em></span> slower, but this may be acceptable if programmer time is more important.</p>
+<p>The fastest approach is to build a suffix tree in <span class="math inline"><em>O</em>(<em>n</em>)</span>
+ time and extract the suffix array by traversing the tree. The only
+complication is that we need the extra space to build the tree, although
+ we get it back when we throw the tree away.</p>
+<h4 id="Searching_a_suffix_array"><span class="header-section-number">6.2.3.2</span> Searching a suffix array</h4>
+<p>Suppose we have a suffix array corresponding to an <span class="math inline"><em>n</em></span>-character text and we want to find all occurrences in the text of an <span class="math inline"><em>m</em></span>-character
+ pattern. Since the suffixes are ordered, the easiest solution is to do
+binary search for the first and last occurrences of the pattern (if any)
+ using <span class="math inline"><em>O</em>(log<em>n</em>)</span>
+comparisons. (The code below does something even lazier than this,
+searching for some match and then scanning linearly for the first and
+last matches.) Unfortunately, each comparison may take as much as <span class="math inline"><em>O</em>(<em>m</em>)</span> time, since we may have to check all <span class="math inline"><em>m</em></span> characters of the pattern. So the total cost will be <span class="math inline"><em>O</em>(<em>m</em>log<em>n</em>)</span> in the worst case.</p>
+<p>By storing additional information about the longest common prefix of
+consecutive suffixes, it is possible to avoid having to re-examine every
+ character in the pattern for every comparison, reducing the search cost
+ to <span class="math inline"><em>O</em>(<em>m</em> + log<em>n</em>)</span>.
+ With a sufficiently clever algorithm, this information can be computed
+in linear time, and can also be used to solve quickly such problems as
+finding the longest duplicate substrings, or most frequently occurring
+strings. For more details, see (Gusfield, Dan. <em>Algorithms on Strings, Trees, and Sequences: Computer Science and Computational Biology</em>. Cambridge University Press, 1997, §7.14.4]).</p>
+<p>Using binary search on the suffix array, most searching tasks are now easy:</p>
+<ul>
+<li>Finding if a substring appears in the array uses binary search directly.</li>
+<li>Finding all occurrences requires two binary searches, one for the
+first occurrence and one for the last. If we only want to count the
+occurrences and not return their positions, this takes <span class="math inline"><em>O</em>(<em>m</em> + log<em>n</em>)</span> time. If we want to return their positions, it takes <span class="math inline"><em>O</em>(<em>m</em> + log<em>n</em> + <em>k</em>)</span> time, where <span class="math inline"><em>k</em></span> is the number of times the pattern occurs.</li>
+<li>Finding duplicate substrings of length <span class="math inline"><em>m</em></span> or more can be done by looking for adjacent entries in the array with long common prefixes, which takes <span class="math inline"><em>O</em>(<em>m</em><em>n</em>)</span> time in the worst case if done naively (and <span class="math inline"><em>O</em>(<em>n</em>)</span> time if we have already computed longest common prefix information.</li>
+</ul>
+<h2 id="Burrows-Wheeler_transform"><span class="header-section-number">6.3</span> Burrows-Wheeler transform</h2>
+<p>Closely related to suffix arrays is the <strong>Burrows-Wheeler transform</strong> (Burrows and Wheeler, <em>A Block-Sorting Lossless Data Compression Algorithm</em>,
+ DEC Systems Research Center Technical Report number 124, 1994), which
+is the basis for some of the best currently known algorithms for text
+compression (it's the technique that is used, for example, in <a href="http://www.bzip.org/">bzip2</a>).</p>
+<p>The idea of the Burrows-Wheeler Transform is to construct an array
+whose rows are all cyclic shifts of the input string in dictionary
+order, and return the last column of the array. The last column will
+tend to have long runs of identical characters, since whenever some
+substring (like <code class="backtick">the</code> appears repeatedly in the input, shifts that put the first character <code class="backtick">t</code> in the last column will put the rest of the substring <code class="backtick">he</code>
+ in the first columns, and the resulting rows will tend to be sorted
+together. The relative regularity of the last column means that it will
+compress well with even very simple compression algorithms like
+run-length encoding.</p>
+<p>Below is an example of the Burrows-Wheeler transform in action, with <code class="backtick">$</code> marking end-of-text. The transformed value of <code class="backtick">abracadabra$</code> is <code class="backtick">$drcraaaabba</code>, the last column of the sorted array; note the long run of a's (and the shorter run of b's).</p>
+<pre><code>abracadabra$ abracadabra$
+bracadabra$a abra$abracad
+racadabra$ab acadabra$abr
+acadabra$abr adabra$abrac
+cadabra$abra a$abracadabr
+adabra$abrac bracadabra$a
+dabra$abraca --&gt; bra$abracada
+abra$abracad cadabra$abra
+bra$abracada dabra$abraca
+ra$abracadab racadabra$ab
+a$abracadabr ra$abracadab
+$abracadabra $abracadabra</code></pre>
+<p>The most useful property of the Burrows-Wheeler transform is that it
+can be inverted; this distinguishes it from other transforms that
+produce long runs like simply sorting the characters. We'll describe two
+ ways to do this; the first is less efficient, but more easily grasped,
+and involves rebuilding the array one column at a time, starting at the
+left. Observe that the leftmost column is just all the characters in the
+ string in sorted order; we can recover it by sorting the rightmost
+column, which we have to start off with. If we paste the rightmost and
+leftmost columns together, we have the list of all 2-character
+substrings of the original text; sorting this list gives the first <em>two</em>
+ columns of the array. (Remember that each copy of the string wraps
+around from the right to the left.) We can then paste the rightmost
+column at the beginning of these two columns, sort the result, and get
+the first three columns. Repeating this process eventually reconstructs
+the entire array, from which we can read off the original string from
+any row. The initial stages of this process for <code class="backtick">abracadabra$</code> are shown below:</p>
+<pre><code>$ a $a ab $ab abr
+d a da ab dab abr
+r a ra ac rac aca
+c a ca ad cad ada
+r a ra a$ ra$ a$a
+a b ab br abr bra
+a -&gt; b ab -&gt; br abr -&gt; bra
+a c ac ca aca cad
+a d ad da ada dab
+b r br ra bra rac
+b r br ra bra ra$
+a $ a$ $a a$a $ab</code></pre>
+<p>Rebuilding the entire array in this fashion takes <span class="math inline"><em>O</em>(<em>n</em><sup>2</sup>)</span> time and <span class="math inline"><em>O</em>(<em>n</em><sup>2</sup>)</span>
+ space. In their paper, Burrows and Wheeler showed that one can in fact
+reconstruct the original string from just the first and last columns in
+the array in <span class="math inline"><em>O</em>(<em>n</em>)</span> time.</p>
+<p>Here's the idea: Suppose that all the characters were distinct. Then
+after reconstructing the first column we would know all pairs of
+adjacent characters. So we could just start with the last character <code class="backtick">$</code>
+ and regenerate the string by appending at each step the unique
+successor to the last character so far. If all characters were distinct,
+ we would never get confused about which character comes next.</p>
+<p>The problem is what to do with pairs with duplicate first characters, like <code class="backtick">ab</code> and <code class="backtick">ac</code> in the example above. We can imagine that each <code class="backtick">a</code> in the last column is labeled in some unique way, so that we can talk about the first <code class="backtick">a</code> or the third <code class="backtick">a</code>, but how do we know which <code class="backtick">a</code> is the one that comes before <code class="backtick">b</code> or <code class="backtick">d</code>?</p>
+<p>The trick is to look closely at how the original sort works. Look at
+the rows in the original transformation. If we look at all rows that
+start with <code class="backtick">a</code>, the order they are sorted in is determined by the suffix after <code class="backtick">a</code>. These suffixes also appear as the prefixes of the rows that <em>end</em> with <code class="backtick">a</code>, since the rows that end with <code class="backtick">a</code> are just the rows that start with <code class="backtick">a</code> rotated one position. It follows that <em>all instances of the same letter occur in the same order in the first and last columns</em>. So if we use a stable sort to construct the first column, we will correctly match up instances of letters.</p>
+<p>This method is shown in action below. Each letter is annotated
+uniquely with a count of how many identical letters equal or precede it.
+ Sorting recovers the first column, and combining the last and first
+columns gives a list of unique pairs of adjacent annotated characters.
+Now start with <code class="backtick">$1</code> and construct the full sequence <code class="backtick">$1&nbsp;a1&nbsp;b1&nbsp;r1&nbsp;a3&nbsp;c1&nbsp;a4&nbsp;d1&nbsp;a2&nbsp;b2&nbsp;r2&nbsp;a5&nbsp;$1</code>. The original string is obtained by removing the end-of-string markers and annotations: <code class="backtick">abracadabra</code>.</p>
+<pre><code>$1 a1
+d1 a2
+r1 a3
+c1 a4
+r2 a5
+a1 b1
+a2 --&gt; b2
+a3 c1
+a4 d1
+b1 r1
+b2 r2
+a5 $1</code></pre>
+<p>Because we are only sorting single characters, we can perform the
+sort in linear time using counting sort. Extracting the original string
+also takes linear time if implemented reasonably.</p>
+<h3 id="Suffix_arrays_and_the_Burrows-Wheeler_transform"><span class="header-section-number">6.3.1</span> Suffix arrays and the Burrows-Wheeler transform</h3>
+<p>A useful property of the Burrows-Wheeler transform is that each row
+of the sorted array is essentially the same as the corresponding row in
+the suffix array, except for the rotated string prefix after the <code class="backtick">$</code>
+ marker. This means, among other things, that we can compute the
+Burrows-Wheeler transform in linear time using suffix trees. Ferragina
+and Manzini (<a href="http://people.unipmn.it/%7Emanzini/papers/focs00draft.pdf" class="uri">http://people.unipmn.it/~manzini/papers/focs00draft.pdf</a>)
+ have further exploited this correspondence (and some very clever
+additional ideas) to design compressed suffix arrays that compress and
+index a text at the same time, so that pattern searches can be done
+directly on the compressed text in time close to that needed for suffix
+array searches.</p>
+<h3 id="sample-implementation"><span class="header-section-number">6.3.2</span> Sample implementation</h3>
+<p>As mentioned above, this is a pretty lazy implementation of suffix
+arrays, that doesn't include many of the optimizations that would be
+necessary to deal with huge source texts.</p>
+<div>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"><span class="co">/* we expose this so user can iterate through it */</span>
+
+<span class="kw">struct</span> suffixArray {
+ size_t n; <span class="co">/* length of string INCLUDING final null */</span>
+ <span class="dt">const</span> <span class="dt">char</span> *string; <span class="co">/* original string */</span>
+ <span class="dt">const</span> <span class="dt">char</span> **suffix; <span class="co">/* suffix array of length n */</span>
+};
+
+<span class="kw">typedef</span> <span class="kw">struct</span> suffixArray *SuffixArray;
+
+<span class="co">/* construct a suffix array */</span>
+<span class="co">/* it is a bad idea to modify string before destroying this */</span>
+SuffixArray suffixArrayCreate(<span class="dt">const</span> <span class="dt">char</span> *string);
+
+<span class="co">/* destructor */</span>
+<span class="dt">void</span> suffixArrayDestroy(SuffixArray);
+
+<span class="co">/* return number of occurrences of substring */</span>
+<span class="co">/* if non-null, index of first occurrence is place in first */</span>
+size_t
+suffixArraySearch(SuffixArray, <span class="dt">const</span> <span class="dt">char</span> *substring, size_t *first);
+
+<span class="co">/* return the Burrows-Wheeler transform of the underlying string </span>
+<span class="co"> * as malloc'd data of length sa-&gt;n */</span>
+<span class="co">/* note that this may have a null in the middle somewhere */</span>
+<span class="dt">char</span> *suffixArrayBWT(SuffixArray sa);
+
+<span class="co">/* invert BWT of null-terminated string, returning a malloc'd copy of original */</span>
+<span class="dt">char</span> *inverseBWT(size_t len, <span class="dt">const</span> <span class="dt">char</span> *s);</code></pre></div>
+<a href="http://cs.yale.edu/homes/aspnes/classes/223/examples/suffixArray/suffixArray.h" class="uri">examples/suffixArray/suffixArray.h</a>
+</div>
+<div>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"><span class="ot">#include &lt;stdlib.h&gt;</span>
+<span class="ot">#include &lt;assert.h&gt;</span>
+<span class="ot">#include &lt;string.h&gt;</span>
+<span class="ot">#include &lt;limits.h&gt;</span>
+
+<span class="ot">#include "suffixArray.h"</span>
+
+<span class="dt">static</span> <span class="dt">int</span>
+saCompare(<span class="dt">const</span> <span class="dt">void</span> *s1, <span class="dt">const</span> <span class="dt">void</span> *s2)
+{
+ <span class="kw">return</span> strcmp(*((<span class="dt">const</span> <span class="dt">char</span> **) s1), *((<span class="dt">const</span> <span class="dt">char</span> **) s2));
+}
+
+SuffixArray
+suffixArrayCreate(<span class="dt">const</span> <span class="dt">char</span> *s)
+{
+ size_t i;
+ SuffixArray sa;
+
+ sa = malloc(<span class="kw">sizeof</span>(*sa));
+ assert(sa);
+
+ sa-&gt;n = strlen(s) + <span class="dv">1</span>;
+ sa-&gt;string = s;
+
+ sa-&gt;suffix = malloc(<span class="kw">sizeof</span>(*sa-&gt;suffix) * sa-&gt;n);
+ assert(sa-&gt;suffix);
+
+ <span class="co">/* construct array of pointers to suffixes */</span>
+ <span class="kw">for</span>(i = <span class="dv">0</span>; i &lt; sa-&gt;n; i++) {
+ sa-&gt;suffix[i] = s+i;
+ }
+
+ <span class="co">/* this could be a lot more efficient */</span>
+ qsort(sa-&gt;suffix, sa-&gt;n, <span class="kw">sizeof</span>(*sa-&gt;suffix), saCompare);
+
+ <span class="kw">return</span> sa;
+}
+
+<span class="dt">void</span>
+suffixArrayDestroy(SuffixArray sa)
+{
+ free(sa-&gt;suffix);
+ free(sa);
+}
+
+size_t
+suffixArraySearch(SuffixArray sa, <span class="dt">const</span> <span class="dt">char</span> *substring, size_t *first)
+{
+ size_t lo;
+ size_t hi;
+ size_t mid;
+ size_t len;
+ <span class="dt">int</span> cmp;
+
+ len = strlen(substring);
+
+ <span class="co">/* invariant: suffix[lo] &lt;= substring &lt; suffix[hi] */</span>
+ lo = <span class="dv">0</span>;
+ hi = sa-&gt;n;
+
+ <span class="kw">while</span>(lo + <span class="dv">1</span> &lt; hi) {
+ mid = (lo+hi)/<span class="dv">2</span>;
+ cmp = strncmp(sa-&gt;suffix[mid], substring, len);
+
+ <span class="kw">if</span>(cmp == <span class="dv">0</span>) {
+ <span class="co">/* we have a winner */</span>
+ <span class="co">/* search backwards and forwards for first and last */</span>
+ <span class="kw">for</span>(lo = mid; lo &gt; <span class="dv">0</span> &amp;&amp; strncmp(sa-&gt;suffix[lo<span class="dv">-1</span>], substring, len) == <span class="dv">0</span>; lo--);
+ <span class="kw">for</span>(hi = mid; hi &lt; sa-&gt;n &amp;&amp; strncmp(sa-&gt;suffix[hi<span class="dv">+1</span>], substring, len) == <span class="dv">0</span>; hi++);
+
+ <span class="kw">if</span>(first) {
+ *first = lo;
+ }
+
+ <span class="kw">return</span> hi - lo + <span class="dv">1</span>;
+ } <span class="kw">else</span> <span class="kw">if</span>(cmp &lt; <span class="dv">0</span>) {
+ lo = mid;
+ } <span class="kw">else</span> {
+ hi = mid;
+ }
+ }
+
+ <span class="kw">return</span> <span class="dv">0</span>;
+}
+
+<span class="dt">char</span> *
+suffixArrayBWT(SuffixArray sa)
+{
+ <span class="dt">char</span> *bwt;
+ size_t i;
+
+ bwt = malloc(sa-&gt;n);
+ assert(bwt);
+
+ <span class="kw">for</span>(i = <span class="dv">0</span>; i &lt; sa-&gt;n; i++) {
+ <span class="kw">if</span>(sa-&gt;suffix[i] == sa-&gt;string) {
+ <span class="co">/* wraps around to nul */</span>
+ bwt[i] = '\<span class="dv">0</span>';
+ } <span class="kw">else</span> {
+ bwt[i] = sa-&gt;suffix[i][-<span class="dv">1</span>];
+ }
+ }
+
+ <span class="kw">return</span> bwt;
+}
+
+<span class="dt">char</span> *
+inverseBWT(size_t len, <span class="dt">const</span> <span class="dt">char</span> *s)
+{
+ <span class="co">/* basic trick: stable sort of s gives successor indices */</span>
+ <span class="co">/* then we just thread through starting from the nul */</span>
+
+ size_t *successor;
+ <span class="dt">int</span> c;
+ size_t count[UCHAR_MAX<span class="dv">+1</span>];
+ size_t offset[UCHAR_MAX<span class="dv">+1</span>];
+ size_t i;
+ <span class="dt">char</span> *ret;
+ size_t thread;
+
+ successor = malloc(<span class="kw">sizeof</span>(*successor) * len);
+ assert(successor);
+
+ <span class="co">/* counting sort */</span>
+ <span class="kw">for</span>(c = <span class="dv">0</span>; c &lt;= UCHAR_MAX; c++) {
+ count[c] = <span class="dv">0</span>;
+ }
+
+ <span class="kw">for</span>(i = <span class="dv">0</span>; i &lt; len; i++) {
+ count[(<span class="dt">unsigned</span> <span class="dt">char</span>) s[i]]++;
+ }
+
+ offset[<span class="dv">0</span>] = <span class="dv">0</span>;
+
+ <span class="kw">for</span>(c = <span class="dv">1</span>; c &lt;= UCHAR_MAX; c++) {
+ offset[c] = offset[c<span class="dv">-1</span>] + count[c<span class="dv">-1</span>];
+ }
+
+ <span class="kw">for</span>(i = <span class="dv">0</span>; i &lt; len; i++) {
+ successor[offset[(<span class="dt">unsigned</span> <span class="dt">char</span>) s[i]]++] = i;
+ }
+
+ <span class="co">/* find the nul */</span>
+ <span class="kw">for</span>(thread = <span class="dv">0</span>; s[thread]; thread++);
+
+ <span class="co">/* thread the result */</span>
+ ret = malloc(len);
+ assert(ret);
+
+ <span class="kw">for</span>(i = <span class="dv">0</span>, thread = successor[thread]; i &lt; len; i++, thread = successor[thread]) {
+ ret[i] = s[thread];
+ }
+
+ <span class="kw">return</span> ret;
+}</code></pre></div>
+<a href="http://cs.yale.edu/homes/aspnes/classes/223/examples/suffixArray/suffixArray.c" class="uri">examples/suffixArray/suffixArray.c</a>
+</div>
+<p>Here is a Makefile and test code: <a href="http://cs.yale.edu/homes/aspnes/classes/223/examples/suffixArray/Makefile">Makefile</a>, <a href="http://cs.yale.edu/homes/aspnes/classes/223/examples/suffixArray/testSuffixArray.c">testSuffixArray.c</a>.</p>
+<p>The output of <code class="backtick">make&nbsp;test</code> shows all
+occurrences of a target string, the Burrows-Wheeler transform of the
+source string (second-to-last line), and its inversion (last line, which
+ is just the original string):</p>
+<pre><code>$ make test
+/bin/echo -n abracadabra-abracadabra-shmabracadabra | ./testSuffixArray abra
+Count: 6
+abra
+abra-abr
+abra-shm
+abracada
+abracada
+abracada
+aaarrrdddm\x00-rrrcccaaaaaaaaaaaashbbbbbb-
+abracadabra-abracadabra-shmabracadabra</code></pre>
+<h2 id="cplusplus"><span class="header-section-number">6.4</span> C++</h2>
+<p>Here we will describe some basic features of C++ that are useful for
+implementing abstract data types. Like all programming languages, C++
+comes with an ideology, which in this case emphasizes object-oriented
+features like inheritance. We will be ignoring this ideology and
+treating C++ as an improved version of C.</p>
+<p>The goal here is not to teach you all of C++, which would take a
+while, but instead to give you some hints for why you might want to
+learn C++ on your own. If you decide to learn C++ for real, Bjarne
+Stroustrup's <em>The C++ Programming Language</em> is the definitive source. A classic tutorial <a href="http://www.4p8.com/eric.brasseur/cppcen.html">here</a> aimed at C programmers introduces C++ features one at a time (some of these features have since migrated into C). The web site <a href="http://www.cplusplus.com/" class="uri">http://www.cplusplus.com</a> has extensive tutorials and documentation.</p>
+<h3 id="Hello_world"><span class="header-section-number">6.4.1</span> Hello world</h3>
+<p>The C++ version of "hello world" looks like this:</p>
+<div>
+<div class="sourceCode"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span class="ot">#include &lt;iostream&gt;</span>
+
+<span class="dt">int</span>
+main(<span class="dt">int</span> argc, <span class="dt">const</span> <span class="dt">char</span> **argv)
+{
+ std::cout &lt;&lt; <span class="st">"hi</span><span class="ch">\n</span><span class="st">"</span>;
+
+ <span class="kw">return</span> <span class="dv">0</span>;
+}</code></pre></div>
+<a href="http://cs.yale.edu/homes/aspnes/classes/223/examples/c++/helloworld.cpp" class="uri">examples/c++/helloworld.cpp</a>
+</div>
+<p>Compile this using <code class="backtick">g++</code> instead of <code class="backtick">gcc</code>. Make shows how it is done:</p>
+<pre><code>$ make helloworld
+g++ helloworld.cpp -o helloworld</code></pre>
+<p>Or we could use an explicit <code class="backtick">Makefile</code>:</p>
+<pre><code>CPP=g++
+CPPFLAGS=-g3 -Wall
+
+helloworld: helloworld.o
+ $(CPP) $(CPPFLAGS) -o $@ $^</code></pre>
+<p>Now the compilation looks like this:</p>
+<pre><code>$ make helloworld
+g++ -g3 -Wall -c -o helloworld.o helloworld.cpp
+g++ -g3 -Wall -o helloworld helloworld.o</code></pre>
+<p>The main difference from the C version:</p>
+<ol style="list-style-type: decimal">
+<li><code class="backtick">#include&nbsp;&lt;stdio.h&gt;</code> is replaced by <code class="backtick">#include&nbsp;&lt;iostream&gt;</code>, which gets the C++ version of the <code class="backtick">stdio</code> library.</li>
+<li><code class="backtick">printf("hi\n")</code> is replaced by <code class="backtick">std::cout&nbsp;&lt;&lt;&nbsp;"hi\n"</code>. The stream <code class="backtick">std::cout</code> is the C++ wrapper for <code class="backtick">stdout</code>; you should read this variable name as <code class="backtick">cout</code> in the <code class="backtick">std</code> namespace. The <code class="backtick">&lt;&lt;</code>
+ operator is overloaded for streams so that it sends its right argument
+out on its left argument (see the discussion of operator overloading
+below). You can also do things like <code class="backtick">std::cout&nbsp;&lt;&lt;&nbsp;37</code>, <code class="backtick">std::cout&nbsp;&lt;&lt;&nbsp;'q'</code>, <code class="backtick">std::cout&nbsp;&lt;&lt;&nbsp;4.7</code>, etc. These all do pretty much what you expect.</li>
+</ol>
+<p>If you don't like typing <code class="backtick">std::</code> before all the built-in functions and variables, you can put <code class="backtick">using&nbsp;namespace&nbsp;std</code> somewhere early in your program, like this:</p>
+<div>
+<div class="sourceCode"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span class="ot">#include &lt;iostream&gt;</span>
+
+<span class="kw">using</span> <span class="kw">namespace</span> std;
+
+<span class="dt">int</span>
+main(<span class="dt">int</span> argc, <span class="dt">const</span> <span class="dt">char</span> **argv)
+{
+ cout &lt;&lt; <span class="st">"hi</span><span class="ch">\n</span><span class="st">"</span>;
+
+ <span class="kw">return</span> <span class="dv">0</span>;
+}</code></pre></div>
+<a href="http://cs.yale.edu/homes/aspnes/classes/223/examples/c++/helloworld_using.cpp" class="uri">examples/c++/helloworld_using.cpp</a>
+</div>
+<h3 id="References"><span class="header-section-number">6.4.2</span> References</h3>
+<p>Recall that in C we sometime pass objects into function by reference instead of by value, by using a pointer:</p>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"><span class="dt">void</span> increment(<span class="dt">int</span> *x)
+{
+ (*x)++;
+}</code></pre></div>
+<p>This becomes even more useful in C++, since many of the objects we
+are dealing with are quite large, and can defend themselves against
+dangerous modifications by restricting access to their components. So
+C++ provides a special syntax allowing function parameters to be
+declared as call-by-reference rather than call-by-value. The function
+above could be rewritten in C++ as</p>
+<div class="sourceCode"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span class="dt">void</span> increment(<span class="dt">int</span> &amp;x)
+{
+ x++;
+}</code></pre></div>
+<p>The <code class="backtick">int&nbsp;&amp;x</code> declaration says that <code class="backtick">x</code> is a <strong>reference</strong> to whatever variable is passed as the argument to <code class="backtick">increment</code>. A reference acts exactly like a pointer that has already had <code class="backtick">*</code> applied to it. You can even write <code class="backtick">&amp;x</code> to get a pointer to the original variable if you want to for some reason.</p>
+<p>As with pointers, it's polite to mark a reference with <code class="backtick">const</code> if you don't intend to modify the original object:</p>
+<div class="sourceCode"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span class="dt">void</span> reportWeight(<span class="dt">const</span> SumoWrestler &amp;huge)
+{
+ cout &lt;&lt; huge.getWeight();
+}</code></pre></div>
+<p>References are also used as a return type to chain operators together; in the expression</p>
+<div class="sourceCode"><pre class="sourceCode cpp"><code class="sourceCode cpp"> cout &lt;&lt; <span class="st">"hi"</span> &lt;&lt; <span class="st">'</span><span class="ch">\n</span><span class="st">'</span>;</code></pre></div>
+<p>the return type of the first <code class="backtick">&lt;&lt;</code> operator is an <code class="backtick">ostream&nbsp;&amp;</code> reference (as is <code class="backtick">cout</code>); this means that the <code class="backtick">'\n'</code> gets sent to the same object. We could make the return value be just an <code class="backtick">ostream</code>, but then <code class="backtick">cout</code>
+ would be copied, which could be expensive and would mean that the copy
+was no longer working on the same internal state as the original. This
+same trick is used when overloading the assignment operator.</p>
+<h3 id="Function_overloading"><span class="header-section-number">6.4.3</span> Function overloading</h3>
+<p>C++ lets you define multiple functions with the same name, where the
+choice of which function to call depends on the type of its arguments.
+Here is a program that demonstrates this feature:</p>
+<div>
+<div class="sourceCode"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span class="ot">#include &lt;iostream&gt;</span>
+
+<span class="kw">using</span> <span class="kw">namespace</span> std;
+
+<span class="dt">const</span> <span class="dt">char</span> *
+typeName(<span class="dt">int</span> x)
+{
+ <span class="kw">return</span> <span class="st">"int"</span>;
+}
+
+<span class="dt">const</span> <span class="dt">char</span> *
+typeName(<span class="dt">double</span> x)
+{
+ <span class="kw">return</span> <span class="st">"double"</span>;
+}
+
+<span class="dt">const</span> <span class="dt">char</span> *
+typeName(<span class="dt">char</span> x)
+{
+ <span class="kw">return</span> <span class="st">"char"</span>;
+}
+
+<span class="dt">int</span>
+main(<span class="dt">int</span> argc, <span class="dt">const</span> <span class="dt">char</span> **argv)
+{
+ cout &lt;&lt; <span class="st">"The type of "</span> &lt;&lt; <span class="dv">3</span> &lt;&lt; <span class="st">" is "</span> &lt;&lt; typeName(<span class="dv">3</span>) &lt;&lt; <span class="st">".</span><span class="ch">\n</span><span class="st">"</span>;
+ cout &lt;&lt; <span class="st">"The type of "</span> &lt;&lt; <span class="fl">3.1</span> &lt;&lt; <span class="st">" is "</span> &lt;&lt; typeName(<span class="fl">3.1</span>) &lt;&lt; <span class="st">".</span><span class="ch">\n</span><span class="st">"</span>;
+ cout &lt;&lt; <span class="st">"The type of "</span> &lt;&lt; <span class="st">'c'</span> &lt;&lt; <span class="st">" is "</span> &lt;&lt; typeName(<span class="st">'c'</span>) &lt;&lt; <span class="st">".</span><span class="ch">\n</span><span class="st">"</span>;
+
+ <span class="kw">return</span> <span class="dv">0</span>;
+}</code></pre></div>
+<a href="http://cs.yale.edu/homes/aspnes/classes/223/examples/c++/functionOverloading.cpp" class="uri">examples/c++/functionOverloading.cpp</a>
+</div>
+<p>And here is what it looks like when we compile and run it:</p>
+<pre><code>$ make functionOverloading
+g++ functionOverloading.cpp -o functionOverloading
+$ ./functionOverloading
+The type of 3 is int.
+The type of 3.1 is double.
+The type of c is char.</code></pre>
+<p>Internally, <code class="backtick">g++</code> compiles three separate functions with different (and ugly) names, and when you use <code class="backtick">typeName</code> on an object of a particular type, <code class="backtick">g++</code> picks the one whose type matches. This is similar to what happens with built-in operators in straight C, where <code class="backtick">+</code> means different things depending on whether you apply it to a pair of <code class="backtick">int</code>s, a pair of <code class="backtick">double</code>s, or a pointer and an <code class="backtick">int</code>, but C++ lets you do it with your own functions.</p>
+<h3 id="Classes"><span class="header-section-number">6.4.4</span> Classes</h3>
+<p>C++ allows you to declare <strong>classes</strong> that look suspiciously like structs. The main differences between a class and a C-style struct are that (a) classes provide <strong>member functions</strong> or <strong>methods</strong>
+ that operate on instances of the class and that are called using a
+struct-like syntax; and (b) classes can distinguish between private
+members (only accessible to methods of the class) and public members
+(accessible to everybody).</p>
+<p>In C, we organize abstract data types by putting the representation
+in a struct and putting the operations on the data type in functions
+that work on this struct, often giving the functions a prefix that hints
+ at the type of its target (mostly to avoid namespace collisions).
+Classes in C++ make this connection between a data structure and the
+operations on it much more explicit.</p>
+<p>Here is a simple example of a C++ class in action:</p>
+<div>
+<div class="sourceCode"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span class="ot">#include &lt;iostream&gt;</span>
+
+<span class="kw">using</span> <span class="kw">namespace</span> std;
+
+<span class="co">/* counters can be incremented or read */</span>
+<span class="kw">class</span> Counter {
+ <span class="dt">int</span> value; <span class="co">/* private value */</span>
+<span class="kw">public</span>:
+ Counter(); <span class="co">/* constructor with default value */</span>
+ Counter(<span class="dt">int</span>); <span class="co">/* constructor with specified value */</span>
+ ~Counter(); <span class="co">/* useless destructor */</span>
+ <span class="dt">int</span> read(); <span class="co">/* get the value of the counter */</span>
+ <span class="dt">void</span> increment(); <span class="co">/* add one to the counter */</span>
+};
+
+Counter::Counter() { value = <span class="dv">0</span>; }
+Counter::Counter(<span class="dt">int</span> initialValue) { value = initialValue; }
+Counter::~Counter() { cerr &lt;&lt; <span class="st">"counter de-allocated with value "</span> &lt;&lt; value &lt;&lt; <span class="st">'</span><span class="ch">\n</span><span class="st">'</span>; }
+<span class="dt">int</span> Counter::read() { <span class="kw">return</span> value; }
+<span class="dt">void</span> Counter::increment() { value++; }
+
+<span class="dt">int</span>
+main(<span class="dt">int</span> argc, <span class="dt">const</span> <span class="dt">char</span> **argv)
+{
+ Counter c;
+ Counter c10(<span class="dv">10</span>);
+
+ cout &lt;&lt; <span class="st">"c starts at "</span> &lt;&lt; c.read() &lt;&lt; <span class="st">'</span><span class="ch">\n</span><span class="st">'</span>;
+ c.increment();
+ cout &lt;&lt; <span class="st">"c after one increment is "</span> &lt;&lt; c.read() &lt;&lt; <span class="st">'</span><span class="ch">\n</span><span class="st">'</span>;
+
+ cout &lt;&lt; <span class="st">"c10 starts at "</span> &lt;&lt; c10.read() &lt;&lt; <span class="st">'</span><span class="ch">\n</span><span class="st">'</span>;
+ c.increment();
+ c.increment();
+ cout &lt;&lt;<span class="st">"c10 after two increments is "</span> &lt;&lt; c10.read() &lt;&lt; <span class="st">'</span><span class="ch">\n</span><span class="st">'</span>;
+
+ <span class="kw">return</span> <span class="dv">0</span>;
+}</code></pre></div>
+<a href="http://cs.yale.edu/homes/aspnes/classes/223/examples/c++/counter.cpp" class="uri">examples/c++/counter.cpp</a>
+</div>
+<p>Things to notice:</p>
+<ol style="list-style-type: decimal">
+<li>In the <code class="backtick">class&nbsp;Counter</code> declaration, the <code class="backtick">public:</code> label introduces the public members of the class. The member <code class="backtick">value</code> is only accessible to member functions of <code class="backtick">Counter</code>. This enforces much stronger information hiding than the default in C, although one can still use <code class="backtick">void&nbsp;*</code> trickery to hunt down and extract supposedly private data in C++ objects.</li>
+<li>In addition to the member function declarations in the class
+declaration, we also need to provide definitions. These look like
+ordinary function definitions, except that the class name is prepended
+using <code class="backtick">::</code> as in <code class="backtick">Counter::read</code>.</li>
+<li>Member functions are called using <code class="backtick">struct</code> access syntax, as in <code class="backtick">c.read()</code>. Conceptually, each instance of a class has its own member functions, so that <code class="backtick">c.read</code> is the function for reading <code class="backtick">c</code> while <code class="backtick">c10.read</code> is the function for reading <code class="backtick">c10</code>. Inside a member function, names of class members refer to members of the current instance; <code class="backtick">value</code> inside <code class="backtick">c.read</code> is <code class="backtick">c.value</code> (which otherwise is not accessible, since <code class="backtick">c.value</code> is not public).</li>
+<li>Two special member functions are <code class="backtick">Counter::Counter()</code> and <code class="backtick">Counter::Counter(int)</code>. These are <strong>constructors</strong>,
+ and are identifiable as such because they are named after the class. A
+constructor is called whenever a new instance of the class is created.
+If you create an instance with no arguments (as in the declaration <code class="backtick">Counter&nbsp;c;</code>), you get the constructor with no arguments. If you create an instance with arguments (as in the declaration <code class="backtick">Counter&nbsp;c10(10);</code>),
+ you get the version with the appropriate arguments. This is just
+another example of function overloading. If you don't define any
+constructors, C++ supplies a default constructor that takes no arguments
+ and does nothing. Note that constructors don't have a return type (you
+don't need to preface them with void).</li>
+<li>The special member function <code class="backtick">Counter::~Counter()</code> is a <strong>destructor</strong>; it is called when an object of type <code class="backtick">Counter</code>
+ is de-allocated (say, when returning from a function with a local
+variable of this type). This particular destructor is not very useful.
+Destructors are mostly important for objects that allocate their own
+storage that needs to be de-allocated when the object is; see the
+section on storage allocation below.</li>
+</ol>
+<p>Compiling and running this program gives the following output. Note that the last two lines are produced by the destructor.</p>
+<pre><code>c starts at 0
+c after one increment is 1
+c10 starts at 10
+c10 after two increments is 10
+counter de-allocated with value 10
+counter de-allocated with value 3</code></pre>
+<p>One subtle difference between C and C++ is that C++ uses empty parentheses <code class="backtick">()</code> for functions with no arguments, where C would use <code class="backtick">(void)</code>. This is a bit of a historical artifact, having to do with C allowing <code class="backtick">()</code> for functions whose arguments are not specified in the declaration (which was standard practice before ANSI C).</p>
+<p>Curiously, C++ also allows you to declare <code class="backtick">struct</code>s, with the interpretation that a <code class="backtick">struct</code> is exactly like a <code class="backtick">class</code> except that all members are public by default. So if you change <code class="backtick">class</code> to <code class="backtick">struct</code>
+ in the program above, it will do exactly the same thing. In practice,
+nobody who codes in C++ does this; the feature is mostly useful to allow
+ C code with <code class="backtick">struct</code>s to mix with C++ code.</p>
+<h3 id="Operator_overloading"><span class="header-section-number">6.4.5</span> Operator overloading</h3>
+<p>Sometimes when you define a new class, you also want to define new
+interpretations of operators on that class. Here is an example of a
+class that defines elements of the <strong>max-plus algebra</strong> over <code class="backtick">int</code>s. This gives us objects that act like <code class="backtick">int</code>s, except that the <code class="backtick">+</code> operator now returns the larger of its arguments and the <code class="backtick">*</code> operator now returns the sum.<a href="#fn25" class="footnoteRef" id="fnref25"><sup>25</sup></a></p>
+<p>The mechanism in C++ for doing this is to define member functions with names <code class="backtick">operator</code><em>something</em> where <em>something</em>
+ is the name of the operator we want to define. These member functions
+take one less argument that the operator they define; in effect, <code class="backtick">x&nbsp;+&nbsp;y</code> becomes syntactic sugar for <code class="backtick">x.operator+(y)</code>
+ (which, amazingly, is actually legal C++). Because these are member
+functions, they are allowed to access members of other instances of the
+same class that would normally be hidden.</p>
+<p>This same mechanism is also used to define automatic type conversions out of a type: the <code class="backtick">MaxPlus::operator&nbsp;int()</code> function allows C++ to convert a <code class="backtick">MaxPlus</code> object to an <code class="backtick">int</code> whenever it needs to (for example, to feed it to <code class="backtick">cout</code>). (Automatic type conversions <em>into</em> a type happen if you provide an appropriate constructor.)</p>
+<div>
+<div class="sourceCode"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span class="ot">#include &lt;iostream&gt;</span>
+<span class="ot">#include &lt;algorithm&gt; </span><span class="co">// for max</span>
+
+<span class="kw">using</span> <span class="kw">namespace</span> std;
+
+<span class="co">/* act like ints, except + does max and * does addition */</span>
+<span class="kw">class</span> MaxPlus {
+ <span class="dt">int</span> value;
+<span class="kw">public</span>:
+ MaxPlus(<span class="dt">int</span>);
+ MaxPlus <span class="kw">operator</span>+(<span class="dt">const</span> MaxPlus &amp;);
+ MaxPlus <span class="kw">operator</span>*(<span class="dt">const</span> MaxPlus &amp;);
+ <span class="kw">operator</span> <span class="dt">int</span>();
+};
+
+MaxPlus::MaxPlus(<span class="dt">int</span> x) { value = x; }
+
+MaxPlus
+MaxPlus::<span class="kw">operator</span>*(<span class="dt">const</span> MaxPlus &amp;other)
+{
+ <span class="kw">return</span> MaxPlus(value + other.value);
+}
+
+MaxPlus
+MaxPlus::<span class="kw">operator</span>+(<span class="dt">const</span> MaxPlus &amp;other)
+{
+ <span class="co">/* std::max does what you expect */</span>
+ <span class="kw">return</span> MaxPlus(max(value, other.value));
+}
+
+MaxPlus::<span class="kw">operator</span> <span class="dt">int</span>() { <span class="kw">return</span> value; }
+
+<span class="dt">int</span>
+main(<span class="dt">int</span> argc, <span class="dt">const</span> <span class="dt">char</span> **argv)
+{
+ cout &lt;&lt; <span class="st">"2+3 == "</span> &lt;&lt; (MaxPlus(<span class="dv">2</span>) + MaxPlus(<span class="dv">3</span>)) &lt;&lt; <span class="st">'</span><span class="ch">\n</span><span class="st">'</span>;
+ cout &lt;&lt; <span class="st">"2*3 == "</span> &lt;&lt; (MaxPlus(<span class="dv">2</span>) * MaxPlus(<span class="dv">3</span>)) &lt;&lt; <span class="st">'</span><span class="ch">\n</span><span class="st">'</span>;
+
+ <span class="kw">return</span> <span class="dv">0</span>;
+}</code></pre></div>
+<a href="http://cs.yale.edu/homes/aspnes/classes/223/examples/c++/maxPlus.cpp" class="uri">examples/c++/maxPlus.cpp</a>
+</div>
+<p>Avoid the temptation to overuse operator overloading, as it can be
+dangerous if used to obfuscate what an operator normally does:</p>
+<div class="sourceCode"><pre class="sourceCode cpp"><code class="sourceCode cpp">MaxPlus::<span class="kw">operator</span>--() { godzilla.eat(tokyo); }</code></pre></div>
+<p>The general rule of thumb is that you should probably only do
+operator overloading if you really are making things that act like
+numbers (yes, <code class="backtick">cout&nbsp;&lt;&lt;</code> violates this).</p>
+<p>Automatic type conversions can be particularly dangerous. The line</p>
+<div class="sourceCode"><pre class="sourceCode cpp"><code class="sourceCode cpp"> cout &lt;&lt; (MaxPlus(<span class="dv">2</span>) + <span class="dv">3</span>) &lt;&lt; <span class="st">'</span><span class="ch">\n</span><span class="st">'</span>;</code></pre></div>
+<p>is ambiguous: should the compiler convert <code class="backtick">MaxPlus(2)</code> to an <code class="backtick">int</code> using the <code class="backtick">MaxPlus(int)</code> constructor and use ordinary integer addition or convert <code class="backtick">3</code> to a <code class="backtick">MaxPlus</code> using <code class="backtick">MaxPlus::operator&nbsp;int()</code> and use funky <code class="backtick">MaxPlus</code> addition? Fortunately most C++ compilers will complain about the ambiguity and fail rather than guessing wrong.</p>
+<h3 id="Templates"><span class="header-section-number">6.4.6</span> Templates</h3>
+<p>One of the things we kept running into in this class was that if we
+defined a container type like a hash table, binary search tree, or
+priority queue, we had to either bake in the type of the data it held or
+ do horrible tricks with <code class="backtick">void&nbsp;*</code> pointers to work around the C type system. C++ includes a semi-principled work-around for this problem known as <strong>templates</strong>.
+ These are essentially macros that take a type name as an argument, that
+ are expanded as needed to produce functions or classes with specific
+types (see <a href="#macros">Macros</a> for an example of how to do this if you only have C).</p>
+<p>Typical use is to prefix a definition with <code class="backtick">template&nbsp;&lt;class&nbsp;T&gt;</code> and then use <code class="backtick">T</code> as a type name throughout:</p>
+<div class="sourceCode"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span class="kw">template</span> &lt;<span class="kw">class</span> T&gt;
+T add1(T x)
+{
+ <span class="kw">return</span> x + ((T) <span class="dv">1</span>);
+}</code></pre></div>
+<p>Note the explicit cast to <code class="backtick">T</code> of <code class="backtick">1</code>; this avoids ambiguities that might arise with automatic type conversions.</p>
+<p>If you put this definition in a program, you can then apply <code class="backtick">add1</code> to any type that has a <code class="backtick">+</code> operator and that you can convert <code class="backtick">1</code> to. For example, the output of this code fragment:</p>
+<div class="sourceCode"><pre class="sourceCode cpp"><code class="sourceCode cpp"> cout &lt;&lt; <span class="st">"add1(3) == "</span> &lt;&lt; add1(<span class="dv">3</span>) &lt;&lt; <span class="st">'</span><span class="ch">\n</span><span class="st">'</span>;
+ cout &lt;&lt; <span class="st">"add1(3.1) == "</span> &lt;&lt; add1(<span class="fl">3.1</span>) &lt;&lt; <span class="st">'</span><span class="ch">\n</span><span class="st">'</span>;
+ cout &lt;&lt; <span class="st">"add1('c') == "</span> &lt;&lt; add1(<span class="st">'c'</span>) &lt;&lt; <span class="st">'</span><span class="ch">\n</span><span class="st">'</span>;
+ cout &lt;&lt; <span class="st">"add1(MaxPlus(0)) == "</span> &lt;&lt; add1(MaxPlus(<span class="dv">0</span>)) &lt;&lt; <span class="st">'</span><span class="ch">\n</span><span class="st">'</span>;
+ cout &lt;&lt; <span class="st">"add1(MaxPlus(2)) == "</span> &lt;&lt; add1(MaxPlus(<span class="dv">2</span>)) &lt;&lt; <span class="st">'</span><span class="ch">\n</span><span class="st">'</span>;</code></pre></div>
+<p>is</p>
+<pre><code>add1(3) == 4
+add1(3.1) == 4.1
+add1('c') == d
+add1(MaxPlus(0)) == 1
+add1(MaxPlus(2)) == 2</code></pre>
+<p>By default, C++ will instantiate a template to whatever type fits in
+its argument. If you want to force a particular version, you can put the
+ type in angle brackets after the name of whatever you defined. For
+example,</p>
+<div class="sourceCode"><pre class="sourceCode cpp"><code class="sourceCode cpp"> cout &lt;&lt; <span class="st">"add1&lt;int&gt;(3.1) == "</span> &lt;&lt; add1&lt;<span class="dt">int</span>&gt;(<span class="fl">3.1</span>) &lt;&lt; <span class="st">'</span><span class="ch">\n</span><span class="st">'</span>;</code></pre></div>
+<p>produces</p>
+<pre><code>add1&lt;int&gt;(3.1) == 4</code></pre>
+<p>because <code class="backtick">add1&lt;int&gt;</code> forces its argument to be converted to an <code class="backtick">int</code> (truncating to <code class="backtick">3</code>) before adding one to it.</p>
+<p>Because templates are really macros that get expanded as needed, it is common to put templates in header (<code class="backtick">.h</code>) files rather than in <code class="backtick">.cpp</code> files. See the stack implementation below for an example of this.</p>
+<h3 id="Exceptions"><span class="header-section-number">6.4.7</span> Exceptions</h3>
+<p>C provides no built-in mechanism for signaling that something bad
+happened. So C programmers are left to come up with ad-hoc mechanisms
+like:</p>
+<ol style="list-style-type: decimal">
+<li>Calling <code class="backtick">abort</code> to kill the program, either directly or via <code class="backtick">assert</code>.</li>
+<li>Calling <code class="backtick">exit</code> with a nonzero exit code.</li>
+<li>Returning a special error value from a function. This is often done
+in library routines, because it's rude for a library routine not to give
+ the caller a chance to figure out how to deal with the error. But it
+means coming up with some special error value that won't be returned
+normally, and these can vary widely from one routine to another (null
+pointers, <code class="backtick">-1</code>, etc.)</li>
+</ol>
+<p>C++ provides a standard mechanism for signaling unusual events known as <strong>exceptions</strong>. The actual mechanism is similar to <code class="backtick">return</code>: the <code class="backtick">throw</code> statement throws an exception that may be caught by a <code class="backtick">try..catch</code> statement anywhere above it on the execution stack (not necessarily in the same function). Example:</p>
+<div>
+<div class="sourceCode"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span class="ot">#include &lt;iostream&gt;</span>
+
+<span class="kw">using</span> <span class="kw">namespace</span> std;
+
+<span class="dt">int</span> fail()
+{
+ <span class="kw">throw</span> <span class="st">"you lose"</span>;
+
+ <span class="kw">return</span> <span class="dv">5</span>;
+}
+
+<span class="dt">int</span>
+main(<span class="dt">int</span> argc, <span class="dt">const</span> <span class="dt">char</span> **argv)
+{
+ <span class="kw">try</span> {
+ cout &lt;&lt; fail() &lt;&lt; <span class="st">'</span><span class="ch">\n</span><span class="st">'</span>;
+ }
+ <span class="kw">catch</span>(<span class="dt">const</span> <span class="dt">char</span> *s) {
+ cerr &lt;&lt; <span class="st">"Caught error: "</span> &lt;&lt; s &lt;&lt; <span class="st">'</span><span class="ch">\n</span><span class="st">'</span>;
+ }
+
+ <span class="kw">return</span> <span class="dv">0</span>;
+}</code></pre></div>
+<a href="http://cs.yale.edu/homes/aspnes/classes/223/examples/c++/exception.cpp" class="uri">examples/c++/exception.cpp</a>
+</div>
+<p>In action:</p>
+<pre><code>$ make exception
+g++ -g3 -Wall exception.cpp -o exception
+$ ./exception
+Caught error: you lose</code></pre>
+<p>Note the use of <code class="backtick">cerr</code> instead of <code class="backtick">cout</code>. This sends the error message to <code class="backtick">stderr</code>.</p>
+<p>A <code class="backtick">try..catch</code> statement will catch an exception only if the type matches the type of the argument to the <code class="backtick">catch</code> part of the statement. This can be used to pick and choose which exceptions you want to catch. See <a href="http://www.cplusplus.com/doc/tutorial/exceptions/" class="uri">http://www.cplusplus.com/doc/tutorial/exceptions/</a> for some examples and descriptions of some C++ standard library exceptions.</p>
+<h3 id="Storage_allocation"><span class="header-section-number">6.4.8</span> Storage allocation</h3>
+<p>C++ programs generally don't use <code class="backtick">malloc</code> and <code class="backtick">free</code>, but instead use the built-in C++ operators <code class="backtick">new</code> and <code class="backtick">delete</code>. The advantage of <code class="backtick">new</code> and <code class="backtick">delete</code> is that they know about types: not only does this mean that you don't have to play games with <code class="backtick">sizeof</code>
+ to figure out how much space to allocate, but if you allocate a new
+object from a class with a constructor, the constructor gets called to
+initialize the object, and if you delete an object, its destructor (if
+it has one) is called.</p>
+<p>There are two versions of <code class="backtick">new</code> and <code class="backtick">delete</code>,
+ depending on whether you want to allocate just one object or an array
+of objects, plus some special syntax for passing constructor arguments:</p>
+<ul>
+<li>To allocate a single object, use <code class="backtick">new</code> <em>type</em>.</li>
+<li>To allocate an array of objects, use <code class="backtick">new</code> <em>type</em><code class="backtick">[</code><em>size</em><code class="backtick">]</code>. As with <code class="backtick">malloc</code>, both operations return a pointer to <em>type</em>.</li>
+<li>If you want to pass arguments to a constructor for <em>type</em>, use <code class="backtick">new</code> <em>type</em><code class="backtick">(</code><em>args</em><code class="backtick">)</code>. This only works with the single-object version, so you can't do <code class="backtick">new&nbsp;SomeClass[12]</code> unless <code class="backtick">SomeClass</code> has a constructor that takes no arguments.</li>
+<li>To de-allocate a single object, use <code class="backtick">delete</code> <em>pointer-to-object</em>.</li>
+<li>To de-allocate an array, use <code class="backtick">delete&nbsp;[]</code> <em>pointer-to-base-of-array</em>. Mixing <code class="backtick">new</code> with <code class="backtick">delete&nbsp;[]</code> or vice versa is an error that may or may not be detected by the compiler. Mixing either with <code class="backtick">malloc</code> or <code class="backtick">free</code> is a very bad idea.</li>
+</ul>
+<p>The program below gives examples of <code class="backtick">new</code> and <code class="backtick">delete</code> in action:</p>
+<div>
+<div class="sourceCode"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span class="ot">#include &lt;iostream&gt;</span>
+<span class="ot">#include &lt;cassert&gt;</span>
+
+<span class="kw">using</span> <span class="kw">namespace</span> std;
+
+<span class="kw">class</span> Noisy {
+ <span class="dt">int</span> id;
+<span class="kw">public</span>:
+ Noisy(<span class="dt">int</span>); <span class="co">// create a noisy object with this id</span>
+ ~Noisy();
+};
+
+Noisy::Noisy(<span class="dt">int</span> initId) {
+ id = initId;
+ cout &lt;&lt; <span class="st">"Noisy object created with id "</span> &lt;&lt; id &lt;&lt; <span class="st">'</span><span class="ch">\n</span><span class="st">'</span>;
+}
+
+Noisy::~Noisy() {
+ cout &lt;&lt; <span class="st">"Noisy object destroyed with id "</span> &lt;&lt; id &lt;&lt; <span class="st">'</span><span class="ch">\n</span><span class="st">'</span>;
+}
+
+<span class="dt">int</span>
+main(<span class="dt">int</span> argc, <span class="dt">const</span> <span class="dt">char</span> **argv)
+{
+ <span class="dt">int</span> *p;
+ <span class="dt">int</span> *a;
+ <span class="dt">const</span> <span class="dt">int</span> n = <span class="dv">100</span>;
+ Noisy n1(<span class="dv">1</span>);
+ Noisy *n2;
+
+ p = <span class="kw">new</span> <span class="dt">int</span>;
+ a = <span class="kw">new</span> <span class="dt">int</span>[n];
+ n2 = <span class="kw">new</span> Noisy(<span class="dv">2</span>);
+
+ *p = <span class="dv">5</span>;
+ assert(*p == <span class="dv">5</span>);
+
+ <span class="kw">for</span>(<span class="dt">int</span> i = <span class="dv">0</span>; i &lt; n; i++) {
+ a[i] = i;
+ }
+
+ <span class="kw">for</span>(<span class="dt">int</span> i = <span class="dv">0</span>; i &lt; n; i++) {
+ assert(a[i] == i);
+ }
+
+ <span class="kw">delete</span> [] a;
+ <span class="kw">delete</span> p;
+ <span class="kw">delete</span> n2;
+
+ <span class="kw">return</span> <span class="dv">0</span>;
+}</code></pre></div>
+<a href="http://cs.yale.edu/homes/aspnes/classes/223/examples/c++/allocation.cpp" class="uri">examples/c++/allocation.cpp</a>
+</div>
+<h4 id="Storage_allocation_inside_objects"><span class="header-section-number">6.4.8.1</span> Storage allocation inside objects</h4>
+<p>Inside objects, storage allocation gets complicated. The reason is
+that if the object is copied, either by an assignment or by being passed
+ as a call-by-value parameter, the storage pointed to by the object will
+ not be copied. This can lead to two different objects that share the
+same internal data structures, which is usually not something you want.
+Furthermore, when the object is deallocated, it's necessary to also
+deallocate any space it allocated, which can be done inside the object's
+ destructor.</p>
+<p>To avoid all these problems, any object of type <code class="backtick">T</code> that uses <code class="backtick">new</code> needs to have all of:</p>
+<ol style="list-style-type: decimal">
+<li>A <em>destructor</em> <code class="backtick">T::~T()</code>.</li>
+<li>A <em>copy constructor</em> <code class="backtick">T::T(const&nbsp;T&nbsp;&amp;)</code>, which is a constructor that takes a reference to another object of the same type as an argument and copies its contents.</li>
+<li>An <em>overloaded assignment operator</em> <code class="backtick">T::operator=(const&nbsp;T&nbsp;&amp;)</code>
+ that does the same thing, but also deallocates any internal storage of
+the current object before copying new data in place of it (or possibly
+just copies the contents of internal storage without doing any
+allocation and deallocation). The overloaded assignment operator is
+particularly tricky, because you have to make sure it doesn't destroy
+the contents of the object if somebody writes the useless
+self-assignment <code class="backtick">a&nbsp;=&nbsp;a</code>, and you also need to return a reference to <code class="backtick">*this</code> so that you can chain assignments together as in <code class="backtick">a&nbsp;=&nbsp;b&nbsp;=&nbsp;c</code>.</li>
+</ol>
+<p>Here is an example of a <code class="backtick">Stack</code> class that includes all of these members. Note that it is defined using templates so we can make a stack of any type we like.</p>
+<div>
+<div class="sourceCode"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span class="kw">template</span> &lt;<span class="kw">class</span> T&gt;
+<span class="kw">class</span> Stack {
+ <span class="dt">static</span> <span class="dt">const</span> <span class="dt">int</span> initialSize = <span class="dv">32</span>; <span class="co">/* static means this is shared across entire class */</span>
+ <span class="dt">int</span> top;
+ <span class="dt">int</span> size;
+ T* contents;
+<span class="kw">public</span>:
+ Stack(); <span class="co">/* create a new empty stack */</span>
+
+ <span class="co">/* the unholy trinity of complex C++ objects */</span>
+ ~Stack(); <span class="co">/* destructor */</span>
+ Stack(<span class="dt">const</span> Stack &amp;); <span class="co">/* copy constructor */</span>
+ Stack&amp; <span class="kw">operator</span>=(<span class="dt">const</span> Stack &amp;); <span class="co">/* overloaded assignment */</span>
+
+ <span class="dt">void</span> push(T); <span class="co">/* push an element onto the stack */</span>
+ <span class="dt">int</span> isEmpty(); <span class="co">/* return 1 if empty */</span>
+ T pop(); <span class="co">/* pop top element from stack */</span>
+};
+
+<span class="kw">template</span> &lt;<span class="kw">class</span> T&gt;
+Stack&lt;T&gt;::Stack()
+{
+ size = initialSize;
+ top = <span class="dv">0</span>;
+ contents = <span class="kw">new</span> T[size];
+}
+
+<span class="kw">template</span> &lt;<span class="kw">class</span> T&gt;
+Stack&lt;T&gt;::~Stack()
+{
+ <span class="kw">delete</span> [] contents;
+}
+
+<span class="kw">template</span> &lt;<span class="kw">class</span> T&gt;
+Stack&lt;T&gt;::Stack(<span class="dt">const</span> Stack&lt;T&gt; &amp;other)
+{
+ size = other.size;
+ top = other.top;
+ contents = <span class="kw">new</span> T[size];
+
+ <span class="kw">for</span>(<span class="dt">int</span> i = <span class="dv">0</span>; i &lt; top; i++) {
+ contents[i] = other.contents[i];
+ }
+}
+
+<span class="kw">template</span> &lt;<span class="kw">class</span> T&gt;
+Stack&lt;T&gt; &amp;
+Stack&lt;T&gt;::<span class="kw">operator</span>=(<span class="dt">const</span> Stack&lt;T&gt; &amp;other)
+{
+ <span class="kw">if</span>(&amp;other != <span class="kw">this</span>) {
+ <span class="co">/* this is a real assignment */</span>
+
+ <span class="kw">delete</span> [] contents;
+
+ size = other.size;
+ top = other.top;
+ contents = <span class="kw">new</span> T[size];
+
+ <span class="kw">for</span>(<span class="dt">int</span> i = <span class="dv">0</span>; i &lt; top; i++) {
+ contents[i] = other.contents[i];
+ }
+ }
+
+ <span class="kw">return</span> *<span class="kw">this</span>;
+}
+
+<span class="kw">template</span> &lt;<span class="kw">class</span> T&gt;
+<span class="dt">void</span>
+Stack&lt;T&gt;::push(T elt)
+{
+ <span class="kw">if</span>(top &gt;= size) {
+ <span class="dt">int</span> newSize = <span class="dv">2</span>*size;
+ T *newContents = <span class="kw">new</span> T[newSize];
+
+ <span class="kw">for</span>(<span class="dt">int</span> i = <span class="dv">0</span>; i &lt; top; i++) {
+ newContents[i] = contents[i];
+ }
+
+ <span class="kw">delete</span> [] contents;
+
+ contents = newContents;
+ size = newSize;
+ }
+
+ contents[top++] = elt;
+}
+
+<span class="kw">template</span> &lt;<span class="kw">class</span> T&gt;
+T
+Stack&lt;T&gt;::pop()
+{
+ <span class="kw">if</span>(top &gt; <span class="dv">0</span>) {
+ <span class="kw">return</span> contents[--top];
+ } <span class="kw">else</span> {
+ <span class="kw">throw</span> <span class="st">"stack empty"</span>;
+ }
+}</code></pre></div>
+<a href="http://cs.yale.edu/homes/aspnes/classes/223/examples/c++/stack/stack.h" class="uri">examples/c++/stack/stack.h</a>
+</div>
+<p>Here is some code demonstrating use of the stack:</p>
+<div>
+<div class="sourceCode"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span class="ot">#include &lt;iostream&gt;</span>
+
+<span class="ot">#include "stack.h"</span>
+
+<span class="kw">using</span> <span class="kw">namespace</span> std;
+
+<span class="dt">int</span>
+main(<span class="dt">int</span> argc, <span class="dt">const</span> <span class="dt">char</span> **argv)
+{
+ Stack&lt;<span class="dt">int</span>&gt; s;
+ Stack&lt;<span class="dt">int</span>&gt; s2;
+
+ <span class="kw">try</span> {
+ s.push(<span class="dv">1</span>);
+ s.push(<span class="dv">2</span>);
+ s.push(<span class="dv">3</span>);
+
+ s2 = s;
+
+ cout &lt;&lt; s.pop() &lt;&lt; <span class="st">'</span><span class="ch">\n</span><span class="st">'</span>;
+ cout &lt;&lt; s.pop() &lt;&lt; <span class="st">'</span><span class="ch">\n</span><span class="st">'</span>;
+ cout &lt;&lt; s.pop() &lt;&lt; <span class="st">'</span><span class="ch">\n</span><span class="st">'</span>;
+
+ cout &lt;&lt; s2.pop() &lt;&lt; <span class="st">'</span><span class="ch">\n</span><span class="st">'</span>;
+ cout &lt;&lt; s2.pop() &lt;&lt; <span class="st">'</span><span class="ch">\n</span><span class="st">'</span>;
+ cout &lt;&lt; s2.pop() &lt;&lt; <span class="st">'</span><span class="ch">\n</span><span class="st">'</span>;
+
+ <span class="kw">try</span> {
+ s2.pop();
+ } <span class="kw">catch</span>(<span class="dt">const</span> <span class="dt">char</span> *err) {
+ cout &lt;&lt; <span class="st">"Caught expected exception "</span> &lt;&lt; err &lt;&lt; <span class="st">'</span><span class="ch">\n</span><span class="st">'</span>;
+ }
+
+ <span class="kw">for</span>(<span class="dt">int</span> i = <span class="dv">0</span>; i &lt; <span class="dv">1000</span>; i++) {
+ s.push(i);
+ }
+
+ cout &lt;&lt; s.pop() &lt;&lt; <span class="st">'</span><span class="ch">\n</span><span class="st">'</span>;
+ } <span class="kw">catch</span>(<span class="dt">const</span> <span class="dt">char</span> *err) {
+ cerr &lt;&lt; <span class="st">"Caught error "</span> &lt;&lt; err &lt;&lt; <span class="st">'</span><span class="ch">\n</span><span class="st">'</span>;
+ }
+
+ <span class="kw">return</span> <span class="dv">0</span>;
+}</code></pre></div>
+<a href="http://cs.yale.edu/homes/aspnes/classes/223/examples/c++/stack/testStack.cpp" class="uri">examples/c++/stack/testStack.cpp</a>
+</div>
+<h3 id="Standard_library"><span class="header-section-number">6.4.9</span> Standard library</h3>
+<p>C++ has a large standard library that includes implementations of
+many of the data structures we've seen in this class. In most
+situations, it is easier to use the standard library implementations
+than roll your own, although you have to be careful to make sure you
+understand just what the standard library implementations do. For
+example, here is a reimplementation of the main routine from <a href="http://cs.yale.edu/homes/aspnes/classes/223/examples/c++/stack/testStack.cpp">testStack.cpp</a> using the <code class="backtick">stack</code> template from <code class="backtick">#include&nbsp;&lt;stack&gt;</code>.</p>
+<div>
+<div class="sourceCode"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span class="ot">#include &lt;iostream&gt;</span>
+<span class="ot">#include &lt;stack&gt;</span>
+
+<span class="kw">using</span> <span class="kw">namespace</span> std;
+
+<span class="dt">int</span>
+main(<span class="dt">int</span> argc, <span class="dt">const</span> <span class="dt">char</span> **argv)
+{
+ stack&lt;<span class="dt">int</span>&gt; s;
+ stack&lt;<span class="dt">int</span>&gt; s2;
+
+ s.push(<span class="dv">1</span>);
+ s.push(<span class="dv">2</span>);
+ s.push(<span class="dv">3</span>);
+
+ s2 = s;
+
+ cout &lt;&lt; s.top() &lt;&lt; <span class="st">'</span><span class="ch">\n</span><span class="st">'</span>; s.pop();
+ cout &lt;&lt; s.top() &lt;&lt; <span class="st">'</span><span class="ch">\n</span><span class="st">'</span>; s.pop();
+ cout &lt;&lt; s.top() &lt;&lt; <span class="st">'</span><span class="ch">\n</span><span class="st">'</span>; s.pop();
+
+ cout &lt;&lt; s2.top() &lt;&lt; <span class="st">'</span><span class="ch">\n</span><span class="st">'</span>; s2.pop();
+ cout &lt;&lt; s2.top() &lt;&lt; <span class="st">'</span><span class="ch">\n</span><span class="st">'</span>; s2.pop();
+ cout &lt;&lt; s2.top() &lt;&lt; <span class="st">'</span><span class="ch">\n</span><span class="st">'</span>; s2.pop();
+
+ <span class="kw">for</span>(<span class="dt">int</span> i = <span class="dv">0</span>; i &lt; <span class="dv">1000</span>; i++) {
+ s.push(i);
+ }
+
+ cout &lt;&lt; s.top() &lt;&lt; <span class="st">'</span><span class="ch">\n</span><span class="st">'</span>;
+
+ <span class="kw">return</span> <span class="dv">0</span>;
+}</code></pre></div>
+<a href="http://cs.yale.edu/homes/aspnes/classes/223/examples/c++/stack/stdStack.cpp" class="uri">examples/c++/stack/stdStack.cpp</a>
+</div>
+<p>One difference between the standard stack and our stack is that <code class="backtick">std::stack</code>'s <code class="backtick">pop</code> member function doesn't return anything. So we have to use <code class="backtick">top</code> to get the top element before popping it.</p>
+<p>There is a chart of all the standard library data structures at <a href="http://www.cplusplus.com/reference/stl/" class="uri">http://www.cplusplus.com/reference/stl/</a>.</p>
+<h3 id="Things_we_haven.27t_talked_about"><span class="header-section-number">6.4.10</span> Things we haven't talked about</h3>
+<p>The main thing we've omitted here is any discussion of
+object-oriented features of C++, particularly inheritance. These are not
+ immediately useful for the abstract-data-type style of programming
+we've used in CS223, but can be helpful for building more complicated
+systems, where we might want to have various specialized classes of
+objects that can all be approached using a common interface represented
+by a class that they inherit from. If you are interested in exploring
+these tools further, the CS department occasionally offers a class on
+object-oriented programming; Mike Fischer's lecture notes from the last
+time this course was offered can be found at <a href="http://zoo.cs.yale.edu/classes/cs427/2011a/lectures.html" class="uri">http://zoo.cs.yale.edu/classes/cs427/2011a/lectures.html</a>.</p>
+<h2 id="testingDuringDevelopment"><span class="header-section-number">6.5</span> Testing during development</h2>
+<p>It is a truth universally acknowledged that test code should be
+written early in the development process. Unfortunately, most
+programmers (including me) tend to assume that a program will work on
+the first attempt and there's not much point in testing it anyway, so
+writing and running test code often gets deferred indefinitely. The
+solution is to write the test code first, and run it directly from your <code>Makefile</code>
+ every time you save and compile your program. Not only will this
+guarantee that your program actually works when you are done (or at
+least passes the tests you thought of), it allows you to see how the
+program is improving with each positive change, and prevents you from
+accidentally making new negative changes that break things that used to
+work.</p>
+<p>Going one step further, we can often write our interface and test
+code first, build a non-working stub implementation, and then slowly
+flesh out the missing pieces until the implementation passes all the
+tests. This way there is always some obvious step to do next, and we
+don't find ourselves stuck staring at an empty file.</p>
+<h3 id="unitTests"><span class="header-section-number">6.5.1</span> Unit tests</h3>
+<p>A straightforward approach to testing is to include test code with every <strong>unit</strong>
+ in your program, where a unit is any part of the program that can be
+sensibly run by itself. Typically, this will be a single function or a
+group of functions that together implement some data structure.</p>
+<p>In C, these will often make up the contents of a single source file.
+Though this is probably not the best approach if you are building a
+production-quality testing framework, a simple way to include unit tests
+ in a program is to append to each source file a test <code>main</code> function that can be enabled by defining a macro (I like <code>TEST_MAIN</code>). You can then build this file by itself with the macro defined to get a stand-alone test program for just this code.</p>
+<h4 id="what-to-put-in-the-test-code"><span class="header-section-number">6.5.1.1</span> What to put in the test code</h4>
+<p>Ideally, you want to use enough different inputs that every line of code in your program is reached by some test, a goal called <strong>code coverage</strong>. For complex programs, this may be hard to achieve, and there are programs, such as the <code>gcov</code> program that comes with <code>gcc</code>,
+ that will analyze how much code coverage you get out of your tests. For
+ simple programs, we can just try to come up with a set of inputs that
+covers all our bases.</p>
+<p>Testing can be done as <strong>black-box testing</strong>, where the test code assumes no knowledge of the implementation, or <strong>white-box testing</strong>,
+ where the test code has direct access to the implementation and can
+observe the effects of its actions. Black-box testing is handy if your
+implementation may change, and it is generally a good idea to write
+black-box tests first. White-box testing can be useful if some states of
+ the data structure are hard to reach otherwise, or if black-box testing
+ is not very informative about why a particular operation is failing.
+The example given below uses both.</p>
+<h4 id="example"><span class="header-section-number">6.5.1.2</span> Example</h4>
+<p>Here is an example of a simple data structure with some built-in test code conditionally compiled by defining <code>TEST_MAIN</code>.
+ The data structure implements a counter with built-in overflow
+protection. The counter interface does not provide the ability to read
+the counter value; instead, the user can only tell if it is zero or not.</p>
+<p>Because the counter is implemented internally as a <code>uint64_t</code>,
+ black-box testing of what happens with too many increments would take
+centuries. So we include some white-box tests that directly access the
+counter value to set up this (arguably unnecessary) test case.</p>
+<p>The code is given below. We include both the interface file and the implementation, as well as a <code>Makefile</code> showing how to build and run the test program. The <code>Makefile</code> includes some extra arguments to <code>gcc</code> to turn on the <code>TEST_MAIN</code> macro and supply the extra information needed to run <code>gcov</code>. If you type <code>make test</code>, it will make and run <code>testCounter</code>, and then run <code>gcov</code> to verify that we did in fact hit all lines of code in the program.</p>
+<div>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"><span class="co">/*</span>
+<span class="co"> * Abstract counter type.</span>
+<span class="co"> *</span>
+<span class="co"> * You can increment it, decrement it, and test for zero.</span>
+<span class="co"> *</span>
+<span class="co"> * Increment and decrement operations return 1 if successful,</span>
+<span class="co"> * 0 if the operation would cause underflow or overflow.</span>
+<span class="co"> */</span>
+
+<span class="kw">typedef</span> <span class="kw">struct</span> counter Counter;
+
+<span class="co">/* make a new counter starting at 0 */</span>
+Counter *counterCreate(<span class="dt">void</span>);
+
+<span class="co">/* destroy a counter */</span>
+<span class="dt">void</span> counterDestroy(Counter *);
+
+<span class="co">/* return 1 if counter is 0, 0 otherwise */</span>
+<span class="dt">int</span> counterIsZero(<span class="dt">const</span> Counter *);
+
+<span class="co">/* increment a counter, returns 1 if successful, 0 if increment would cause overflow */</span>
+<span class="dt">int</span> counterIncrement(Counter *);
+
+<span class="co">/* decrement a counter, returns 1 if successful, 0 if decrement would cause underflow */</span>
+<span class="dt">int</span> counterDecrement(Counter *);</code></pre></div>
+<a href="http://cs.yale.edu/homes/aspnes/classes/223/examples/unitTest/counter.h" class="uri">examples/unitTest/counter.h</a>
+</div>
+<div>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"><span class="ot">#include &lt;stdio.h&gt;</span>
+<span class="ot">#include &lt;stdlib.h&gt;</span>
+<span class="ot">#include &lt;assert.h&gt;</span>
+<span class="ot">#include "counter.h"</span>
+
+<span class="ot">#include &lt;stdint.h&gt;</span>
+
+<span class="ot">#define COUNTER_MAX (UINT64_MAX)</span>
+
+<span class="kw">struct</span> counter {
+ <span class="dt">uint64_t</span> value;
+};
+
+<span class="co">/* make a new counter starting at 0 */</span>
+Counter *
+counterCreate(<span class="dt">void</span>)
+{
+ Counter *c;
+
+ c = malloc(<span class="kw">sizeof</span>(Counter));
+ assert(c);
+
+ c-&gt;value = <span class="dv">0</span>;
+
+ <span class="kw">return</span> c;
+}
+
+<span class="co">/* destroy a counter */</span>
+<span class="dt">void</span>
+counterDestroy(Counter *c)
+{
+ free(c);
+}
+
+<span class="co">/* return 1 if counter is 0, 0 otherwise */</span>
+<span class="dt">int</span>
+counterIsZero(<span class="dt">const</span> Counter *c)
+{
+ <span class="kw">return</span> c-&gt;value == <span class="dv">0</span>;
+}
+
+<span class="co">/* increment a counter, returns 1 if successful, 0 if increment would cause overflow */</span>
+<span class="dt">int</span>
+counterIncrement(Counter *c)
+{
+ <span class="kw">if</span>(c-&gt;value == COUNTER_MAX) {
+ <span class="kw">return</span> <span class="dv">0</span>;
+ } <span class="kw">else</span> {
+ c-&gt;value++;
+ <span class="kw">return</span> <span class="dv">1</span>;
+ }
+}
+
+<span class="co">/* decrement a counter, returns 1 if successful, 0 if decrement would cause underflow */</span>
+<span class="dt">int</span>
+counterDecrement(Counter *c)
+{
+ <span class="kw">if</span>(c-&gt;value == <span class="dv">0</span>) {
+ <span class="kw">return</span> <span class="dv">0</span>;
+ } <span class="kw">else</span> {
+ c-&gt;value--;
+ <span class="kw">return</span> <span class="dv">1</span>;
+ }
+}
+
+<span class="ot">#ifdef TEST_MAIN</span>
+<span class="dt">int</span>
+main(<span class="dt">int</span> argc, <span class="dt">char</span> **argv)
+{
+ Counter *c;
+
+ <span class="co">/* black box testing */</span>
+ c = counterCreate(); <span class="co">/* 0 */</span>
+
+ assert(counterIsZero(c));
+ assert(counterIncrement(c) == <span class="dv">1</span>); <span class="co">/* 1 */</span>
+ assert(!counterIsZero(c));
+ assert(counterIncrement(c) == <span class="dv">1</span>); <span class="co">/* 2 */</span>
+ assert(!counterIsZero(c));
+ assert(counterDecrement(c) == <span class="dv">1</span>); <span class="co">/* 1 */</span>
+ assert(!counterIsZero(c));
+ assert(counterDecrement(c) == <span class="dv">1</span>); <span class="co">/* 0 */</span>
+ assert(counterIsZero(c));
+ assert(counterDecrement(c) == <span class="dv">0</span>); <span class="co">/* 0 */</span>
+ assert(counterIsZero(c));
+ assert(counterIncrement(c) == <span class="dv">1</span>); <span class="co">/* 1 */</span>
+ assert(!counterIsZero(c));
+
+ counterDestroy(c);
+
+ <span class="co">/* white box testing */</span>
+ c = counterCreate(); <span class="co">/* 0 */</span>
+
+ assert(c-&gt;value == <span class="dv">0</span>);
+ assert(counterIncrement(c) == <span class="dv">1</span>); <span class="co">/* 1 */</span>
+ assert(c-&gt;value == <span class="dv">1</span>);
+ assert(counterIncrement(c) == <span class="dv">1</span>); <span class="co">/* 2 */</span>
+ assert(c-&gt;value == <span class="dv">2</span>);
+ assert(counterDecrement(c) == <span class="dv">1</span>); <span class="co">/* 1 */</span>
+ assert(c-&gt;value == <span class="dv">1</span>);
+ assert(counterDecrement(c) == <span class="dv">1</span>); <span class="co">/* 0 */</span>
+ assert(c-&gt;value == <span class="dv">0</span>);
+ assert(counterDecrement(c) == <span class="dv">0</span>); <span class="co">/* 0 */</span>
+ assert(c-&gt;value == <span class="dv">0</span>);
+ assert(counterIncrement(c) == <span class="dv">1</span>); <span class="co">/* 1 */</span>
+ assert(c-&gt;value == <span class="dv">1</span>);
+
+ <span class="co">/* force counter value to COUNTER_MAX to test for overflow protection */</span>
+ c-&gt;value = COUNTER_MAX; <span class="co">/* COUNTER_MAX */</span>
+ assert(counterIncrement(c) == <span class="dv">0</span>); <span class="co">/* COUNTER_MAX */</span>
+ assert(c-&gt;value == COUNTER_MAX);
+ assert(counterDecrement(c) == <span class="dv">1</span>); <span class="co">/* COUNTER_MAX-1 */</span>
+ assert(c-&gt;value == COUNTER_MAX<span class="dv">-1</span>);
+ assert(counterIncrement(c) == <span class="dv">1</span>); <span class="co">/* COUNTER_MAX */</span>
+ assert(c-&gt;value == COUNTER_MAX);
+
+ counterDestroy(c);
+
+ <span class="kw">return</span> <span class="dv">0</span>;
+}
+<span class="ot">#endif</span></code></pre></div>
+<a href="http://cs.yale.edu/homes/aspnes/classes/223/examples/unitTest/counter.c" class="uri">examples/unitTest/counter.c</a>
+</div>
+<div>
+<div class="sourceCode"><pre class="sourceCode makefile"><code class="sourceCode makefile"><span class="dt">CC</span><span class="ch">=</span><span class="st">c99</span>
+<span class="dt">CFLAGS</span><span class="ch">=</span><span class="st">-g3 -pedantic -Wall</span>
+
+<span class="dv">all:</span><span class="dt"> seqprinter</span>
+
+<span class="dv">seqprinter:</span><span class="dt"> main.o sequence.o</span>
+ <span class="ch">$(</span><span class="dt">CC</span><span class="ch">)</span> <span class="ch">$(</span><span class="dt">CFLAGS</span><span class="ch">)</span> -o <span class="ch">$@</span> <span class="ch">$^</span>
+
+<span class="dv">test:</span><span class="dt"> seqprinter</span>
+ ./seqprinter
+
+<span class="co"># these rules say to rebuild main.o and sequence.o if sequence.h changes</span>
+<span class="dv">main.o:</span><span class="dt"> main.c sequence.h</span>
+<span class="dv">sequence.o:</span><span class="dt"> sequence.c sequence.h</span>
+
+<span class="dv">clean:</span>
+ <span class="ch">$(</span><span class="dt">RM</span><span class="ch">)</span> -f seqprinter *.o</code></pre></div>
+<a href="http://cs.yale.edu/homes/aspnes/classes/223/examples/ADT/sequence/Makefile" class="uri">examples/ADT/sequence/Makefile</a>
+</div>
+<h3 id="test-harnesses"><span class="header-section-number">6.5.2</span> Test harnesses</h3>
+<p>Here are some older notes on testing using a test harness that does
+some basic tricks like catching segmentation faults so that a program
+can keep going even if one test fails.</p>
+<h4 id="Module_interface"><span class="header-section-number">6.5.2.1</span> Module interface</h4>
+<p>The module will be a stack for storing integers.</p>
+<p>Let's start with the interface, which we'll put in a file called <code>stack.h</code>:</p>
+<h5 id="stack.h"><span class="header-section-number">6.5.2.1.1</span> stack.h</h5>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"><span class="co">/*</span>
+<span class="co"> * This is an "opaque struct"; it discourages people from looking at</span>
+<span class="co"> * the inside of our structure. The actual definiton of struct stack</span>
+<span class="co"> * is contained in stack.c.</span>
+<span class="co"> */</span>
+<span class="kw">typedef</span> <span class="kw">struct</span> stack *Stack;
+
+<span class="co">/* constructor and destructor */</span>
+Stack stack_create(<span class="dt">void</span>); <span class="co">/* returns 0 on allocation error */</span>
+<span class="dt">void</span> stack_destroy(Stack);
+
+<span class="co">/* push a new element onto the stack */</span>
+<span class="dt">void</span> stack_push(Stack , <span class="dt">int</span> new_element);
+
+<span class="co">/* return 1 if the stack is empty, 0 otherwise */</span>
+<span class="dt">int</span> stack_isempty(Stack);
+
+<span class="co">/* remove and return top element of stack */</span>
+<span class="co">/* returns STACK_EMPTY if stack is empty */</span>
+<span class="ot">#define STACK_EMPTY (-1)</span>
+<span class="dt">int</span> stack_pop(Stack);</code></pre></div>
+<p>Our intent is that an <code>Stack</code> acts like a stack--- we push things onto it using <code>stack_push</code>, and then pull them off again in reverse order using <code>stack_pop</code>. Ideally, we don't ever pop the stack when it's empty (which we can detect using <code>stack_isempty</code>), but if we do, we have <code>stack_pop</code> return something well-defined.</p>
+<h4 id="Test_code"><span class="header-section-number">6.5.2.2</span> Test code</h4>
+<p>Let's write some test code to try this out. Because our initial stack
+ implementation may be exceptionally bug-ridden, we'll use a test
+harness that provides macros for detecting and intercepting segmentation
+ faults and similar disasters. The various testing wrappers are defined
+in the files <code>tester.h</code> and <code>tester.c</code>, from the <a href="#testingDuringDevelopment">chapter on testing</a>;
+ you should feel free to use it for your own purposes. I've added line
+numbers in comments to all the TEST lines so we can find them again
+later.</p>
+<h5 id="test-stack.c"><span class="header-section-number">6.5.2.2.1</span> test-stack.c</h5>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"><span class="ot">#include &lt;stdio.h&gt;</span>
+<span class="ot">#include &lt;setjmp.h&gt;</span>
+<span class="ot">#include &lt;signal.h&gt;</span>
+<span class="ot">#include &lt;unistd.h&gt;</span>
+
+<span class="ot">#include &lt;stdlib.h&gt;</span>
+
+<span class="ot">#include "stack.h"</span>
+<span class="ot">#include "tester.h"</span>
+
+<span class="ot">#define STRESS_TEST_ITERATIONS (1000000)</span>
+
+<span class="dt">int</span>
+main(<span class="dt">int</span> argc, <span class="dt">char</span> **argv)
+{
+ Stack s;
+ <span class="dt">int</span> i;
+
+ tester_init();
+
+ <span class="co">/* first we need to build one */</span>
+ TRY { s = stack_create(); } ENDTRY;
+
+ <span class="co">/* 25 */</span> TEST_ASSERT(s != <span class="dv">0</span>);
+
+ <span class="co">/* now we'll try pushing and popping a bit */</span>
+ TRY { stack_push(s, <span class="dv">1</span>); } ENDTRY;
+ TRY { stack_push(s, <span class="dv">2</span>); } ENDTRY;
+ TRY { stack_push(s, <span class="dv">3</span>); } ENDTRY;
+
+ <span class="co">/* 32 */</span> TEST(stack_isempty(s), <span class="dv">0</span>);
+ <span class="co">/* 33 */</span> TEST(stack_pop(s), <span class="dv">3</span>);
+ <span class="co">/* 34 */</span> TEST(stack_isempty(s), <span class="dv">0</span>);
+ <span class="co">/* 35 */</span> TEST(stack_pop(s), <span class="dv">2</span>);
+ <span class="co">/* 36 */</span> TEST(stack_isempty(s), <span class="dv">0</span>);
+ <span class="co">/* 37 */</span> TEST(stack_pop(s), <span class="dv">1</span>);
+ <span class="co">/* 38 */</span> TEST(stack_isempty(s), <span class="dv">1</span>);
+ <span class="co">/* 39 */</span> TEST(stack_pop(s), STACK_EMPTY);
+ <span class="co">/* 40 */</span> TEST(stack_isempty(s), <span class="dv">1</span>);
+ <span class="co">/* 41 */</span> TEST(stack_pop(s), STACK_EMPTY);
+
+ <span class="co">/* can we still push after popping too much? */</span>
+ TRY { stack_push(s, <span class="dv">4</span>); } ENDTRY;
+ <span class="co">/* 45 */</span> TEST(stack_isempty(s), <span class="dv">0</span>);
+ <span class="co">/* 46 */</span> TEST(stack_pop(s), <span class="dv">4</span>);
+ <span class="co">/* 47 */</span> TEST(stack_isempty(s), <span class="dv">1</span>);
+ <span class="co">/* 48 */</span> TEST(stack_pop(s), STACK_EMPTY);
+ <span class="co">/* 49 */</span> TEST(stack_isempty(s), <span class="dv">1</span>);
+
+ <span class="co">/* let's do some stress testing */</span>
+ <span class="co">/* we won't use TEST for this because we might get too much output */</span>
+ TRY {
+ <span class="kw">for</span>(i = <span class="dv">0</span>; i &lt; STRESS_TEST_ITERATIONS; i++) {
+ stack_push(s, i);
+ }
+ <span class="kw">for</span>(i = <span class="dv">0</span>; i &lt; STRESS_TEST_ITERATIONS; i++) {
+ stack_push(s, <span class="dv">957</span>);
+ <span class="kw">if</span>(stack_pop(s) != <span class="dv">957</span>) {
+ <span class="co">/* 60 */</span> FAIL(<span class="st">"wanted 957 but didn't get it"</span>);
+ abort();
+ }
+ }
+ <span class="kw">for</span>(i = STRESS_TEST_ITERATIONS - <span class="dv">1</span>; i &gt;= <span class="dv">0</span>; i--) {
+ <span class="kw">if</span>(stack_isempty(s)) {
+ <span class="co">/* 66 */</span> FAIL(<span class="st">"stack empty too early"</span>);
+ abort();
+ }
+ <span class="kw">if</span>(stack_pop(s) != i) {
+ <span class="co">/* 70 */</span> FAIL(<span class="st">"got wrong value!"</span>);
+ abort();
+ }
+ }
+ } ENDTRY; <span class="co">/* 74 */</span>
+
+ <span class="co">/* 76 */</span> TEST(stack_isempty(s), <span class="dv">1</span>);
+
+ TRY { stack_destroy(s); } ENDTRY;
+
+ tester_report(stdout, argv[<span class="dv">0</span>]);
+ <span class="kw">return</span> tester_result();
+}</code></pre></div>
+<p>There is a lot of test code here. In practice, we might write just a
+few tests to start off with, and, to be honest, I didn't write all of
+this at once. But you can never have too many tests--- if nothing else,
+they give an immediate sense of gratification as the number of failed
+tests drops.</p>
+<h4 id="Makefile"><span class="header-section-number">6.5.2.3</span> Makefile</h4>
+<ul>
+<li>Finally, we'll write a <code>Makefile</code>:</li>
+</ul>
+<h5 id="Makefile-1"><span class="header-section-number">6.5.2.3.1</span> Makefile</h5>
+<pre><code>CC=gcc
+CFLAGS=-g3 -Wall -ansi -pedantic
+
+all:
+
+test: test-stack
+ ./test-stack
+ @echo OK!
+
+test-stack: test-stack.o tester.o stack.o
+ $(CC) $(CFLAGS) -o $@ $^
+
+test-stack.o: stack.h tester.h
+stack.o: stack.h</code></pre>
+<p>Note that we <em>don't</em> provide a convenient shortcut for building <code>test-stack</code> without running it. That's because we want to run the test code every single time.</p>
+<h3 id="Stub_implementation"><span class="header-section-number">6.5.3</span> Stub implementation</h3>
+<p>Of course, we still can't compile anything, because we don't have any
+ implementation. Let's fix that. To make it easy to write, we will try
+to add as little as possible to what we already have in <code>stack.h</code>:</p>
+<h4 id="stack.c"><span class="header-section-number">6.5.3.1</span> stack.c</h4>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"><span class="ot">#include &lt;stdlib.h&gt; </span>
+<span class="ot">#include "stack.h"</span>
+
+<span class="kw">struct</span> stack { <span class="dt">int</span> dummy; };
+Stack stack_create(<span class="dt">void</span>) { <span class="kw">return</span> malloc(<span class="kw">sizeof</span>(<span class="kw">struct</span> stack)); }
+<span class="dt">void</span> stack_destroy(Stack s) { free(s); }
+<span class="dt">void</span> stack_push(Stack s, <span class="dt">int</span> elem) { ; }
+<span class="dt">int</span> stack_pop(Stack s) { <span class="kw">return</span> STACK_EMPTY; }
+<span class="dt">int</span> stack_isempty(Stack s) { <span class="kw">return</span> <span class="dv">1</span>; }</code></pre></div>
+<p>Will this work? Of course not. There's hardly any code! But maybe it will compile if we run <code>make&nbsp;test</code>:</p>
+<pre><code>$ make test
+gcc -g3 -Wall -ansi -pedantic -c -o test-stack.o test-stack.c
+gcc -g3 -Wall -ansi -pedantic -c -o tester.o tester.c
+gcc -g3 -Wall -ansi -pedantic -c -o stack.o stack.c
+gcc -g3 -Wall -ansi -pedantic -o test-stack test-stack.o tester.o stack.o
+./test-stack
+test-stack.c:32: TEST FAILED: stack_isempty(s) -&gt; 1 but expected 0
+test-stack.c:33: TEST FAILED: stack_pop(s) -&gt; -1 but expected 3
+test-stack.c:34: TEST FAILED: stack_isempty(s) -&gt; 1 but expected 0
+test-stack.c:35: TEST FAILED: stack_pop(s) -&gt; -1 but expected 2
+test-stack.c:36: TEST FAILED: stack_isempty(s) -&gt; 1 but expected 0
+test-stack.c:37: TEST FAILED: stack_pop(s) -&gt; -1 but expected 1
+test-stack.c:45: TEST FAILED: stack_isempty(s) -&gt; 1 but expected 0
+test-stack.c:46: TEST FAILED: stack_pop(s) -&gt; -1 but expected 4
+test-stack.c:60: wanted 957 but didn't get it
+test-stack.c:74: Aborted (signal 6)
+./test-stack: errors 8/17, signals 1, FAILs 1
+make[1]: *** [test] Error 8</code></pre>
+<p>Hooray! It compiles on the first try! (Well, not really, but let's
+pretend it did.) Unfortunately, it only passes any tests at all by pure
+dumb luck. But now we just need to get the code to pass a few more
+tests.</p>
+<h3 id="Bounded-space_implementation"><span class="header-section-number">6.5.4</span> Bounded-space implementation</h3>
+<p>Here's a first attempt at a stack that suffers from some artificial
+limits. We retain the structure of the original broken implementation,
+we just put a few more lines of code in and format it more expansively.</p>
+<h4 id="stack.c-1"><span class="header-section-number">6.5.4.1</span> stack.c</h4>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"><span class="ot">#include &lt;stdlib.h&gt; </span>
+<span class="ot">#include "stack.h"</span>
+
+<span class="ot">#define MAX_STACK_SIZE (100)</span>
+
+<span class="kw">struct</span> stack {
+ <span class="dt">int</span> top;
+ <span class="dt">int</span> data[MAX_STACK_SIZE];
+};
+
+Stack
+stack_create(<span class="dt">void</span>)
+{
+ <span class="kw">struct</span> stack *s;
+
+ s = malloc(<span class="kw">sizeof</span>(*s));
+ s-&gt;top = <span class="dv">0</span>;
+ <span class="kw">return</span> s;
+}
+
+<span class="dt">void</span>
+stack_destroy(Stack s)
+{
+ free(s);
+}
+
+<span class="dt">void</span>
+stack_push(Stack s, <span class="dt">int</span> elem)
+{
+ s-&gt;data[(s-&gt;top)++] = elem;
+}
+
+<span class="dt">int</span>
+stack_pop(Stack s)
+{
+ <span class="kw">return</span> s-&gt;data[--(s-&gt;top)];
+}
+
+<span class="dt">int</span>
+stack_isempty(Stack s)
+{
+ <span class="kw">return</span> s-&gt;top == <span class="dv">0</span>;
+}</code></pre></div>
+<p>Let's see what happens now:</p>
+<pre><code>$ make test
+gcc -g3 -Wall -ansi -pedantic -c -o test-stack.o test-stack.c
+gcc -g3 -Wall -ansi -pedantic -c -o tester.o tester.c
+gcc -g3 -Wall -ansi -pedantic -c -o stack.o stack.c
+gcc -g3 -Wall -ansi -pedantic -o test-stack test-stack.o tester.o stack.o
+./test-stack
+test-stack.c:40: TEST FAILED: stack_isempty(s) -&gt; 0 but expected 1
+test-stack.c:41: TEST FAILED: stack_pop(s) -&gt; 409 but expected -1
+test-stack.c:47: TEST FAILED: stack_isempty(s) -&gt; 0 but expected 1
+test-stack.c:48: TEST FAILED: stack_pop(s) -&gt; 0 but expected -1
+test-stack.c:49: TEST FAILED: stack_isempty(s) -&gt; 0 but expected 1
+test-stack.c:74: Segmentation fault (signal 11)
+test-stack.c:76: TEST FAILED: stack_isempty(s) -&gt; 0 but expected 1
+free(): invalid pointer 0x804b830!
+./test-stack: errors 6/17, signals 1, FAILs 0
+make[1]: *** [test] Error 6</code></pre>
+<p>There are still errors, but we get past several initial tests before things blow up. Looking back at the line numbers in <code>test-stack.c</code>, we see that the first failed test is the one that checks if the stack is empty after we pop from an empty stack. The code for <code>stack_isempty</code> looks pretty clean, so what happened? Somewhere <code>s-&gt;top</code> got set to a nonzero value, and the only place this can happen is inside <code>stack_pop</code>. Aha! There's no check in <code>stack_pop</code> for an empty stack, so it's decrementing <code>s-&gt;top</code> past 0. (Exercise: why didn't the test of <code>stack_pop</code> fail?)</p>
+<h3 id="First_fix"><span class="header-section-number">6.5.5</span> First fix</h3>
+<p>If we're lucky, fixing this problem will make the later tests happier. Let's try a new version of <code>stack_pop</code>. We'll leave everything else the same.</p>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"><span class="dt">int</span>
+stack_pop(Stack s)
+{
+ <span class="kw">if</span>(stack_isempty(s)) {
+ <span class="kw">return</span> STACK_EMPTY;
+ } <span class="kw">else</span> {
+ <span class="kw">return</span> s-&gt;data[--(s-&gt;top)];
+ }</code></pre></div>
+<p>}</p>
+<p>And now we get:</p>
+<pre><code>$ make test
+gcc -g3 -Wall -ansi -pedantic -c -o test-stack.o test-stack.c
+gcc -g3 -Wall -ansi -pedantic -c -o tester.o tester.c
+gcc -g3 -Wall -ansi -pedantic -c -o stack.o stack.c
+gcc -g3 -Wall -ansi -pedantic -o test-stack test-stack.o tester.o stack.o
+./test-stack
+test-stack.c:74: Segmentation fault (signal 11)
+test-stack.c:76: TEST FAILED: stack_isempty(s) -&gt; 0 but expected 1
+./test-stack: errors 1/17, signals 1, FAILs 0
+make[1]: *** [test] Error 1</code></pre>
+<p>Which is much nicer. We are still failing the stress test, but that's not terribly surprising.</p>
+<h3 id="Final_version"><span class="header-section-number">6.5.6</span> Final version</h3>
+<p>After some more tinkering, this is what I ended up with. This version
+ uses a malloc'd data field, and realloc's it when the stack gets too
+big.</p>
+<h4 id="stack.c-2"><span class="header-section-number">6.5.6.1</span> stack.c</h4>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"><span class="ot">#include &lt;stdlib.h&gt; </span>
+<span class="ot">#include "stack.h"</span>
+
+<span class="kw">struct</span> stack {
+ <span class="dt">int</span> top; <span class="co">/* first unused slot in data */</span>
+ <span class="dt">int</span> size; <span class="co">/* number of slots in data */</span>
+ <span class="dt">int</span> *data; <span class="co">/* stack contents */</span>
+};
+
+<span class="ot">#define INITIAL_STACK_SIZE (1)</span>
+<span class="ot">#define STACK_SIZE_MULTIPLIER (2)</span>
+
+Stack
+stack_create(<span class="dt">void</span>)
+{
+ <span class="kw">struct</span> stack *s;
+
+ s = malloc(<span class="kw">sizeof</span>(*s));
+ <span class="kw">if</span>(s == <span class="dv">0</span>) <span class="kw">return</span> <span class="dv">0</span>;
+
+ s-&gt;top = <span class="dv">0</span>;
+ s-&gt;size = INITIAL_STACK_SIZE;
+ s-&gt;data = malloc(s-&gt;size * <span class="kw">sizeof</span>(*(s-&gt;data)));
+ <span class="kw">if</span>(s-&gt;data == <span class="dv">0</span>) <span class="kw">return</span> <span class="dv">0</span>;
+
+ <span class="co">/* else everything is ok */</span>
+ <span class="kw">return</span> s;
+}
+
+<span class="dt">void</span>
+stack_destroy(Stack s)
+{
+ free(s-&gt;data);
+ free(s);
+}
+
+<span class="dt">void</span>
+stack_push(Stack s, <span class="dt">int</span> elem)
+{
+ <span class="kw">if</span>(s-&gt;top == s-&gt;size) {
+ <span class="co">/* need more space */</span>
+ s-&gt;size *= STACK_SIZE_MULTIPLIER;
+ s-&gt;data = realloc(s-&gt;data, s-&gt;size * <span class="kw">sizeof</span>(*(s-&gt;data)));
+ <span class="kw">if</span>(s-&gt;data == <span class="dv">0</span>) {
+ abort(); <span class="co">/* we have no other way to signal failure :-( */</span>
+ }
+ }
+ <span class="co">/* now there is enough room */</span>
+ s-&gt;data[s-&gt;top++] = elem;
+}
+
+<span class="dt">int</span>
+stack_pop(Stack s)
+{
+ <span class="kw">if</span>(stack_isempty(s)) {
+ <span class="kw">return</span> STACK_EMPTY;
+ } <span class="kw">else</span> {
+ <span class="kw">return</span> s-&gt;data[--(s-&gt;top)];
+ }
+}
+
+<span class="dt">int</span>
+stack_isempty(Stack s)
+{
+ <span class="kw">return</span> s-&gt;top == <span class="dv">0</span>;
+}</code></pre></div>
+<p>At last we have a version that passes all tests:</p>
+<pre><code>$ make test
+gcc -g3 -Wall -ansi -pedantic -c -o test-stack.o test-stack.c
+gcc -g3 -Wall -ansi -pedantic -c -o tester.o tester.c
+gcc -g3 -Wall -ansi -pedantic -c -o stack.o stack.c
+gcc -g3 -Wall -ansi -pedantic -o test-stack test-stack.o tester.o stack.o
+./test-stack
+OK!</code></pre>
+<h3 id="Moral"><span class="header-section-number">6.5.7</span> Moral</h3>
+<p>Writing a big program all at once is hard. If you can break the
+problem down into little problems, it becomes easier. "Test first" is a
+strategy not just for getting a well-tested program, but for giving you
+something easy to do at each step--- it's usually not too hard to write
+one more test, and it's usually not too hard to get just one test
+working. If you can keep taking those small, easy steps, eventually you
+will run out of failed tests and have a working program.</p>
+<h3 id="Appendix:_Test_macros"><span class="header-section-number">6.5.8</span> Appendix: Test macros</h3>
+<div>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"><span class="co">/*</span>
+<span class="co"> * Test macros.</span>
+<span class="co"> * </span>
+<span class="co"> * Usage:</span>
+<span class="co"> *</span>
+<span class="co"> * #include &lt;setjmp.h&gt;</span>
+<span class="co"> * #include &lt;stdio.h&gt;</span>
+<span class="co"> * #include &lt;signal.h&gt;</span>
+<span class="co"> * #include &lt;unistd.h&gt;</span>
+<span class="co"> *</span>
+<span class="co"> * testerInit(); -- Initialize internal data structures.</span>
+<span class="co"> * testerReport(FILE *, "name"); -- Print report.</span>
+<span class="co"> * testerResult(); -- Returns # of failed tests.</span>
+<span class="co"> *</span>
+<span class="co"> * TRY { code } ENDTRY;</span>
+<span class="co"> *</span>
+<span class="co"> * Wraps code to catch seg faults, illegal instructions, etc. May not be</span>
+<span class="co"> * nested.</span>
+<span class="co"> * Prints a warning if a signal is caught.</span>
+<span class="co"> * To enforce a maximum time, set alarm before entering.</span>
+<span class="co"> *</span>
+<span class="co"> * TEST(expr, expected_value);</span>
+<span class="co"> *</span>
+<span class="co"> * Evaluates expr (which should yield an integer value) inside a TRY.</span>
+<span class="co"> * Prints a warning if evaluating expr causes a fault or returns a value</span>
+<span class="co"> * not equal to expected_value.</span>
+<span class="co"> *</span>
+<span class="co"> * TEST_ASSERT(expr)</span>
+<span class="co"> *</span>
+<span class="co"> * Equivalent to TEST(!(expr), 0)</span>
+<span class="co"> *</span>
+<span class="co"> * You can also cause your own failures with FAIL:</span>
+<span class="co"> *</span>
+<span class="co"> * TRY {</span>
+<span class="co"> * x = 1;</span>
+<span class="co"> * if(x == 2) FAIL("why is x 2?");</span>
+<span class="co"> * } ENDTRY;</span>
+<span class="co"> *</span>
+<span class="co"> * To limit the time taken by a test, call tester_set_time_limit with</span>
+<span class="co"> * a new limit in seconds, e.g.</span>
+<span class="co"> *</span>
+<span class="co"> * tester_set_time_limit(1);</span>
+<span class="co"> * TRY { while(1); } ENDTRY;</span>
+<span class="co"> *</span>
+<span class="co"> * There is an initial default limit of 10 seconds.</span>
+<span class="co"> * If you don't want any limit, set the limit to 0.</span>
+<span class="co"> *</span>
+<span class="co"> */</span>
+
+<span class="co">/* global data used by macros */</span>
+<span class="co">/* nothing in here should be modified directly */</span>
+<span class="kw">extern</span> <span class="kw">struct</span> tester_global_data {
+ jmp_buf escape_hatch; <span class="co">/* jump here on surprise signals */</span>
+ <span class="dt">int</span> escape_hatch_active; <span class="co">/* true if escape hatch is usable */</span>
+ <span class="dt">int</span> tests; <span class="co">/* number of tests performed */</span>
+ <span class="dt">int</span> errors; <span class="co">/* number of tests failed */</span>
+ <span class="dt">int</span> signals; <span class="co">/* number of signals caught */</span>
+ <span class="dt">int</span> expr_value; <span class="co">/* expression value */</span>
+ <span class="dt">int</span> setjmp_return; <span class="co">/* return value from setjmp */</span>
+ <span class="dt">int</span> try_failed; <span class="co">/* true if last try failed */</span>
+ <span class="dt">int</span> user_fails; <span class="co">/* number of calls to FAIL */</span>
+ <span class="dt">int</span> time_limit; <span class="co">/* time limit for TRY */</span>
+} TesterData;
+
+<span class="co">/* set up system; call this before using macros */</span>
+<span class="dt">void</span> testerInit(<span class="dt">void</span>);
+
+<span class="co">/* prints a summary report of all errors to f, prefixed with preamble */</span>
+<span class="co">/* If there were no errors, nothing is printed */</span>
+<span class="dt">void</span> testerReport(FILE *f, <span class="dt">const</span> <span class="dt">char</span> *preamble);
+
+<span class="co">/* returns number of errors so far. */</span>
+<span class="dt">int</span> testerResult(<span class="dt">void</span>);
+
+<span class="co">/* set a time limit t for TRY, TEST, TEST_ASSERT etc. */</span>
+<span class="co">/* After t seconds, an ALARM signal will interrupt the test. */</span>
+<span class="co">/* Set t = 0 to have no time limit. */</span>
+<span class="co">/* Default time limit is 10 seconds. */</span>
+<span class="dt">void</span> tester_set_time_limit(<span class="dt">int</span> t);
+
+<span class="dt">const</span> <span class="dt">char</span> *testerStrsignal(<span class="dt">int</span>); <span class="co">/* internal hack; don't use this */</span>
+
+<span class="co">/* gruesome non-syntactic macros */</span>
+<span class="ot">#define TRY \</span>
+<span class="ot"> TesterData.try_failed = 0; \</span>
+<span class="ot"> alarm(TesterData.time_limit); \</span>
+<span class="ot"> if(((TesterData.setjmp_return = setjmp(TesterData.escape_hatch)) == 0) \</span>
+<span class="ot"> &amp;&amp; (TesterData.escape_hatch_active = 1) /* one = is correct*/)</span>
+<span class="ot">#define ENDTRY else { \</span>
+<span class="ot"> fprintf(stderr, "%s:%d: %s (signal %d)\n", \</span>
+<span class="ot"> __FILE__, __LINE__, \</span>
+<span class="ot"> testerStrsignal(TesterData.setjmp_return), \</span>
+<span class="ot"> TesterData.setjmp_return); \</span>
+<span class="ot"> TesterData.signals++; \</span>
+<span class="ot"> TesterData.try_failed = 1; \</span>
+<span class="ot"> } \</span>
+<span class="ot"> alarm(0); \</span>
+<span class="ot"> TesterData.escape_hatch_active = 0</span>
+
+<span class="co">/* another atrocity */</span>
+<span class="ot">#define TEST(expr, expected_value) \</span>
+<span class="ot"> TesterData.tests++; \</span>
+<span class="ot"> TesterData.errors++; /* guilty until proven innocent */ \</span>
+<span class="ot"> TRY { TesterData.expr_value = (expr); \</span>
+<span class="ot"> if(TesterData.expr_value != expected_value) { \</span>
+<span class="ot"> fprintf(stderr, "%s:%d: TEST FAILED: %s -&gt; %d but expected %d\n", \</span>
+<span class="ot"> __FILE__, __LINE__, __STRING(expr), \</span>
+<span class="ot"> TesterData.expr_value, expected_value); \</span>
+<span class="ot"> } else { \</span>
+<span class="ot"> TesterData.errors--; \</span>
+<span class="ot"> } \</span>
+<span class="ot"> } \</span>
+<span class="ot"> ENDTRY; \</span>
+<span class="ot"> if(TesterData.try_failed) \</span>
+<span class="ot"> fprintf(stderr, "%s:%d: TEST FAILED: %s caught signal\n", \</span>
+<span class="ot"> __FILE__, __LINE__, __STRING(expr))</span>
+
+<span class="ot">#define TEST_ASSERT(expr) TEST((expr) != 0, 1)</span>
+<span class="ot">#define FAIL(msg) \</span>
+<span class="ot"> (fprintf(stderr, "%s:%d: %s\n", __FILE__, __LINE__, (msg)), \</span>
+<span class="ot"> TesterData.user_fails++, \</span>
+<span class="ot"> TesterData.try_failed = 1)</span></code></pre></div>
+<a href="http://cs.yale.edu/homes/aspnes/classes/223/examples/testHarness/tester.h" class="uri">examples/testHarness/tester.h</a>
+</div>
+<div>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"><span class="ot">#define _GNU_SOURCE </span><span class="co">/* get strsignal def */</span>
+
+<span class="ot">#include &lt;stdio.h&gt;</span>
+<span class="ot">#include &lt;signal.h&gt;</span>
+<span class="ot">#include &lt;string.h&gt;</span>
+<span class="ot">#include &lt;setjmp.h&gt;</span>
+
+<span class="ot">#include "tester.h"</span>
+
+<span class="kw">struct</span> tester_global_data TesterData;
+
+<span class="dt">const</span> <span class="dt">char</span> *
+testerStrsignal(<span class="dt">int</span> sig)
+{
+ <span class="kw">return</span> strsignal(sig);
+}
+
+<span class="dt">static</span> <span class="dt">void</span>
+tester_sighandler(<span class="dt">int</span> signal)
+{
+ <span class="kw">if</span>(TesterData.escape_hatch_active) {
+ TesterData.escape_hatch_active = <span class="dv">0</span>;
+ longjmp(TesterData.escape_hatch, signal);
+ }
+}
+
+<span class="dt">void</span>
+testerInit(<span class="dt">void</span>)
+{
+ TesterData.escape_hatch_active = <span class="dv">0</span>;
+ TesterData.tests = <span class="dv">0</span>;
+ TesterData.errors = <span class="dv">0</span>;
+ TesterData.signals = <span class="dv">0</span>;
+ TesterData.user_fails = <span class="dv">0</span>;
+
+ signal(SIGSEGV, tester_sighandler);
+ signal(SIGILL, tester_sighandler);
+ signal(SIGFPE, tester_sighandler);
+ signal(SIGALRM, tester_sighandler);
+ signal(SIGBUS, tester_sighandler);
+ signal(SIGABRT, tester_sighandler);
+}
+
+<span class="dt">void</span>
+testerReport(FILE *f, <span class="dt">const</span> <span class="dt">char</span> *preamble)
+{
+ <span class="kw">if</span>(TesterData.errors != <span class="dv">0</span> || TesterData.signals != <span class="dv">0</span>) {
+ fprintf(f, <span class="st">"%s: errors %d/%d, signals %d, FAILs %d</span><span class="ch">\n</span><span class="st">"</span>,
+ preamble,
+ TesterData.errors,
+ TesterData.tests,
+ TesterData.signals,
+ TesterData.user_fails);
+ }
+}
+
+<span class="dt">int</span>
+testerResult(<span class="dt">void</span>)
+{
+ <span class="kw">return</span> TesterData.errors;
+}
+
+<span class="dt">void</span>
+tester_set_time_limit(<span class="dt">int</span> t)
+{
+ TesterData.time_limit = t;
+}</code></pre></div>
+<a href="http://cs.yale.edu/homes/aspnes/classes/223/examples/testHarness/tester.c" class="uri">examples/testHarness/tester.c</a>
+</div>
+<h2 id="algorithmDesignTechniques"><span class="header-section-number">6.6</span> Algorithm design techniques</h2>
+<h3 id="Basic_principles_of_algorithm_design"><span class="header-section-number">6.6.1</span> Basic principles of algorithm design</h3>
+<p>The fundamental principle of algorithm design was best expressed by the mathematician <a href="http://en.wikipedia.org/wiki/George_Polya" title="WikiPedia">George Polya</a>:
+ "If there is a problem you can't solve, then there is an easier problem
+ you can solve: find it." For computers, the situation is even better:
+if there is any technique to make a problem easier even by a tiny bit,
+then you can repeat the technique—possibly millions or even billions of
+times—until the problem becomes trivial.</p>
+<p>For example, suppose we want to find the maximum element of an array of <span class="math inline"><em>n</em></span>
+ ints, but we are as dumb as bricks, so it doesn't occur to us to
+iterate through the array keeping track of the largest value seen so
+far. We might instead be able to solve the problem by observing that the
+ maximum element is either (a) the last element, or (b) the maximum of
+the first <span class="math inline"><em>n</em> − 1</span> elements,
+depending on which is bigger. Figuring out (b) is an easier version of
+the original problem, so we are pretty much done once we've realized we
+can split the problem in this way. Here's the code:</p>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"><span class="co">/* returns maximum of the n elements in a */</span>
+<span class="dt">int</span>
+max_element(<span class="dt">int</span> a[], <span class="dt">int</span> n)
+{
+ <span class="dt">int</span> prefix_max;
+
+ assert(n &gt; <span class="dv">0</span>);
+
+ <span class="kw">if</span>(n == <span class="dv">1</span>) {
+ <span class="kw">return</span> a[<span class="dv">0</span>];
+ } <span class="kw">else</span> {
+ prefix_max = max_element(a, n<span class="dv">-1</span>);
+ <span class="kw">if</span>(prefix_max &lt; a[n<span class="dv">-1</span>]) {
+ <span class="kw">return</span> a[n<span class="dv">-1</span>];
+ } <span class="kw">else</span> {
+ <span class="kw">return</span> prefix_max;
+ }
+ }
+}</code></pre></div>
+<p>Note that we need a special case for a 1-element array, because the
+empty prefix of such an array has no maximum element. We also <code class="backtick">assert</code> that the array contains at least one element, just to avoid mischief.</p>
+<p>One problem with this algorithm (at least when coding in C) is that
+the recursion may get very deep. Fortunately, there is a straightforward
+ way to convert the recursion to a loop. The idea is that instead of
+returning a value from the recursive call, we put it in a variable that
+gets used in the next pass through the loop. The result is</p>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"><span class="co">/* returns maximum of the n elements in a */</span>
+<span class="dt">int</span>
+max_element(<span class="dt">int</span> a[], <span class="dt">int</span> n)
+{
+ <span class="dt">int</span> i; <span class="co">/* this replaces n-1 from the recursive version */</span>
+ <span class="dt">int</span> prefix_max;
+
+ assert(n &gt; <span class="dv">0</span>);
+
+ prefix_max = a[<span class="dv">0</span>]; <span class="co">/* this is the i == 0 case */</span>
+
+ <span class="kw">for</span>(i = <span class="dv">1</span>; i &lt; n; i++) {
+ <span class="kw">if</span>(prefix_max &lt; a[i]) {
+ prefix_max = a[i]; <span class="co">/* was return a[n-1] */</span>
+ }
+ <span class="co">/* else case becomes prefix_max = prefix_max, a noop */</span>
+ }
+
+ <span class="co">/* at the end we have to return a value for real */</span>
+ <span class="kw">return</span> prefix_max;
+}</code></pre></div>
+<h3 id="algorithmDesignTechniquesClassification"><span class="header-section-number">6.6.2</span> Specific techniques</h3>
+<p>Algorithm design often requires both creativity and problem-specific
+knowledge, but there are certain common techniques that appear over and
+over again. The following classification is adapted from Anany Levitin, <em>Introduction to the Design &amp; Analysis of Algorithms</em>, Addison-Wesley, 2003.</p>
+<dl>
+<dt>Brute force</dt>
+<dd>Try all possible solutions until you find the right one.
+</dd>
+<dt>Divide and conquer</dt>
+<dd>Split the problem into two or more subproblems, solve the subproblems recursively, and then combine the solutions.
+</dd>
+<dt>Decrease and conquer</dt>
+<dd>Reduce the problem to a single smaller problem, solve that problem
+recursively, and then use that solution to solve the original problem.
+</dd>
+<dt>Transform and conquer</dt>
+<dd>Either (a) transform the input to a form that makes the problem easy
+ to solve, or (b) transform the input into the input to another problem
+whose solution solves the original problem.
+</dd>
+<dt>Use space</dt>
+<dd>Solve the problem using some auxiliary data structure.
+</dd>
+<dt>Dynamic programming</dt>
+<dd>Construct a table of solutions for increasingly large subproblems,
+where each new entry in the table is computed using previous entries in
+the table.
+</dd>
+<dt>Greedy method</dt>
+<dd>Run through your problem one step at a time, keeping track of the
+single best solution at each step. Hope sincerely that this will not
+lead you to make a seemingly-good choice early with bad consequences
+later.
+</dd>
+</dl>
+<p>Some of these approaches work better than others—it is the role of
+algorithm analysis (and experiments with real computers) to figure out
+which are likely to be both correct and efficient in practice. But
+having all of them in your toolbox lets you try different possibilities
+for a given problem.</p>
+<h3 id="Example:_Finding_the_maximum"><span class="header-section-number">6.6.3</span> Example: Finding the maximum</h3>
+<p>Though this classification is not completely well-defined, and is a
+bit arbitrary for some algorithms, it does provide a useful list of
+things to try in solving a problem. Here are some examples of applying
+the different approaches to a simple problem, the problem of finding the
+ maximum of an array of integers.</p>
+<dl>
+<dt>Brute force</dt>
+<dd>For index <span class="math inline"><em>i</em></span>, test if <span class="math inline"><em>A</em>[<em>i</em>]</span> is greater than or equal to every element in the array. When you find such an <span class="math inline"><em>A</em>[<em>i</em>]</span>, return it. For this algorithm, <span class="math inline"><em>T</em>(<em>n</em>)=<em>n</em> ⋅ <em>Θ</em>(<em>n</em>)=<em>Θ</em>(<em>n</em><sup>2</sup>)</span> if implemented in the most natural way.
+</dd>
+<dt>Divide and conquer</dt>
+<dd>If <span class="math inline"><em>A</em></span> has only one element, return it. Otherwise, let <span class="math inline"><em>m</em><sub>1</sub></span> be the maximum of <span class="math inline"><em>A</em>[1]…<em>A</em>[<em>n</em>/2]</span>, and let <span class="math inline"><em>m</em><sub>2</sub></span> be the maximum of <span class="math inline"><em>A</em>[<em>n</em>/2 + 1]…<em>A</em>[<em>n</em>]</span>. Return the larger of <span class="math inline"><em>m</em><sub>1</sub></span> and <span class="math inline"><em>m</em><sub>2</sub></span>. The running time is given by $T(n) = <span class="math inline">2<em>T</em>(<em>n</em>/2)+<em>Θ</em>(1)=<em>Θ</em>(<em>n</em>)</span>.
+</dd>
+<dt>Decrease and conquer</dt>
+<dd>If <span class="math inline"><em>A</em></span> has only one element, return it. Otherwise, let <span class="math inline"><em>m</em></span>* be the maximum of <span class="math inline"><em>A</em>[2]…<em>A</em>[<em>n</em>]</span>. Return the larger of <span class="math inline"><em>A</em>[0]</span> and <span class="math inline"><em>m</em></span>. Now the running time is given by <span class="math inline">$T(n) = T(n-1) + \Theta(1) = \sum_{i=1}^{n} \Theta(1) = \Theta(n)$</span>.
+</dd>
+<dt>Transform and conquer</dt>
+<dd>Sort the array, then return <span class="math inline"><em>A</em>[<em>n</em>]</span>. Using an optimal comparison-based sort, this takes <span class="math inline"><em>Θ</em>(<em>n</em>log<em>n</em>)+<em>Θ</em>(1)=<em>Θ</em>(<em>n</em>log<em>n</em>)</span>
+ time. The advantage of this approach is that you probably don't have to
+ code up the sorting routine yourself, since most libraries include
+sorting.
+</dd>
+<dt>Use space</dt>
+<dd>Insert all elements into a balanced binary search tree, then return the rightmost element. Cost is <span class="math inline"><em>Θ</em>(<em>n</em>log<em>n</em>)</span> to do <span class="math inline"><em>n</em></span> insertions, plus <span class="math inline"><em>Θ</em>(log<em>n</em>)</span> to find the rightmost element, for a total of <span class="math inline"><em>Θ</em>(<em>n</em>log<em>n</em>)</span>. Sorting is equivalent and probably easier.
+</dd>
+<dt>Dynamic programming</dt>
+<dd>Create an auxiliary array <span class="math inline"><em>B</em></span> with indices <span class="math inline">1</span> to <span class="math inline"><em>n</em></span>. Set <span class="math inline"><em>B</em>[1]=<em>A</em>[1]</span>. As <span class="math inline"><em>i</em></span> goes from <span class="math inline">2</span> to <span class="math inline"><em>n</em></span>, set <span class="math inline"><em>B</em>[<em>i</em>]</span> to the larger of <span class="math inline"><em>B</em>[<em>i</em> − 1]</span> and <span class="math inline"><em>A</em>[<em>i</em>]</span>, so that <span class="math inline"><em>B</em>[<em>i</em>]</span> is always the maximum among <span class="math inline"><em>A</em>[1]…<em>A</em>[<em>i</em>]</span>. Return <span class="math inline"><em>B</em>[<em>n</em>]</span>. Cost: <span class="math inline"><em>Θ</em>(<em>n</em>)</span>. As is often the case, one can reduce the space to <span class="math inline"><em>O</em>(1)</span> by throwing away parts of <span class="math inline"><em>B</em></span> that we aren't going to look at again.
+</dd>
+<dt>Greedy method</dt>
+<dd>Let <span class="math inline"><em>m</em> = <em>A</em>[1]</span>. For each element <span class="math inline"><em>A</em>[<em>i</em>]</span> in <span class="math inline"><em>A</em>[2…<em>n</em>]</span>, if <span class="math inline"><em>A</em>[<em>i</em>]&gt;<em>m</em></span>, set <span class="math inline"><em>m</em></span> to <span class="math inline"><em>A</em>[<em>i</em>]</span>. Return the final value of <span class="math inline"><em>m</em></span>. Cost: <span class="math inline"><em>Θ</em>(<em>n</em>)</span>. This algorithm is pretty much identical to the previous one.
+</dd>
+</dl>
+<h3 id="algorithmDesignSorting"><span class="header-section-number">6.6.4</span> Example: Sorting</h3>
+<p>The sorting problem asks, given as input an array <span class="math inline"><em>A</em></span> of <span class="math inline"><em>n</em></span> elements in arbitrary order, to produce as output an array containing the same <span class="math inline"><em>n</em></span> elements in nondecreasing order, i.e. with <span class="math inline"><em>A</em>[<em>i</em>]≤<em>A</em>[<em>i</em> + 1]</span> for all <span class="math inline"><em>i</em></span>. We can apply each of the techniques above to this problem and get a sorting algorithm (though some are not very good).</p>
+<dl>
+<dt>Brute force</dt>
+<dd>For each of the <span class="math inline"><em>n</em>!</span> permutations of the input, test if it is sorted by checking <span class="math inline"><em>A</em>[<em>i</em>]≤<em>A</em>[<em>i</em> + 1]</span> for all <span class="math inline"><em>i</em></span>. Cost if implemented naively: <span class="math inline"><em>n</em>!⋅<em>Θ</em>(<em>n</em>)=<em>Θ</em>((<em>n</em> + 1)!)</span>. This algorithm is known as <strong>deterministic monkeysort</strong> or <strong>deterministic bogosort</strong>. It also has a randomized variant, where the careful generation of all <span class="math inline"><em>n</em>!</span>
+ permutations is replaced by shuffling. The randomized variant is easier
+ to code and runs at about the same speed as the deterministic variant,
+but does not guarantee termination if the shuffling is consistently
+unlucky.
+</dd>
+<dt>Divide and conquer</dt>
+<dd>Sort <span class="math inline"><em>A</em>[1…⌊<em>n</em>/2⌋</span> and <span class="math inline"><em>A</em>[⌊<em>n</em>/2 + 1⌋…<em>n</em>]</span> separately, then merge the results (which takes <span class="math inline"><em>Θ</em>(<em>n</em>)</span> time and <span class="math inline"><em>Θ</em>(<em>n</em>)</span> additional space if implemented in the most straightforward way). Cost: <span class="math inline"><em>T</em>(<em>n</em>)=2<em>T</em>(<em>n</em>/2)+<em>Θ</em>(<em>n</em>)=<em>Θ</em>(<em>n</em>log<em>n</em>)</span> by the Master Theorem. This method gives <a href="#mergesort">mergesort</a>,
+ one of the fastest general-purpose sorting algorithms. The merge can be
+ avoided by carefully splitting the array into elements less than and
+elements greater than some pivot, then sorting the two resulting piles;
+this gives <a href="#quicksort">quicksort</a>. The performance of <a href="#quicksort">quicksort</a> is often faster than <a href="#mergesort">mergesort</a>
+ in practice, but its worst-case performance (when the pivot is chosen
+badly) is just as bad as the result of insertion sort, which we will
+look at next.
+</dd>
+<dt>Decrease and conquer</dt>
+<dd>Remove <span class="math inline"><em>A</em>[<em>n</em>]</span>, sort the remainder, then insert <span class="math inline"><em>A</em>[<em>n</em>]</span> in the appropriate place. This algorithm is called <strong>insertion sort</strong>.
+ The final insertion step requires finding the right place (which can be
+ done fairly quickly if one is clever) but then moving up to <span class="math inline"><em>n</em> − 1</span> elements to make room for <span class="math inline"><em>A</em>[<em>n</em>]</span>. Total cost is given by <span class="math inline"><em>T</em>(<em>n</em>)=<em>T</em>(<em>n</em> − 1)+<em>Θ</em>(<em>n</em>)=<em>T</em>(<em>n</em><sup>2</sup>)</span>.
+</dd>
+<dt>Transform and conquer</dt>
+<dd>I'm not aware of any good general transform-and-conquer approach to
+sorting (there are some bad ones), but in some cases one can transform
+seemingly general sorting problem (e.g. sorting strings) into
+specialized sorting problems that permit faster solutions (e.g. sorting
+small integers).
+</dd>
+<dt>Use space</dt>
+<dd>Insert the elements into a balanced binary search tree, then read
+them out from left to right. Another version: insert them into a heap.
+Both take <span class="math inline"><em>Θ</em>(<em>n</em>log<em>n</em>)</span> time, but are more complicated to implement than <a href="#mergesort">mergesort</a> or <a href="#quicksort">quicksort</a> unless you have binary search tree or heap code lying around already.
+</dd>
+<dt>Dynamic programming</dt>
+<dd>Insertion sort may be seen as an example of this.
+</dd>
+<dt>Greedy method</dt>
+<dd>Find the smallest element, mark it as used, and output it. Repeat until no elements are left. The result is <a href="http://en.wikipedia.org/wiki/Selection_Sort">selection sort</a>), which runs in a respectable but suboptimal <span class="math inline"><em>Θ</em>(<em>n</em><sup>2</sup>)</span> time.
+</dd>
+</dl>
+<h2 id="bitManipulation"><span class="header-section-number">6.7</span> Bit manipulation</h2>
+<p>Sometimes it is convenient to consider a block of <code class="backtick">char</code>s as really being a block of bits. This requires using C's bit operators to get at individual bits.</p>
+<p>Here are some simple macros for extracting a particular bit from a <code class="backtick">char</code> array, thought of as a large vector of bits. These assume that the bytes are stored in <strong>little-endian</strong> order, which means that the least significant bytes come first (see <a href="http://en.wikipedia.org/wiki/Endianness" title="WikiPedia">Endianness</a>). This may produce odd results if you feed them a <code class="backtick">char&nbsp;*</code> that has been converted from a larger integer type.</p>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"><span class="ot">#define BITS_PER_BYTE (8)</span>
+
+<span class="co">/* extract the n-th bit of x */</span>
+<span class="ot">#define GET_BIT(x, n) ((((x)[(n) / BITS_PER_BYTE]) &amp; (0x1 &lt;&lt; ((n) % BITS_PER_BYTE))) != 0)</span>
+
+<span class="co">/* set the n-th bit of x to 1 */</span>
+<span class="ot">#define SET_BIT(x, n) ((x)[(n) / BITS_PER_BYTE]) |= (0x1 &lt;&lt; ((n) % BITS_PER_BYTE))</span>
+
+<span class="co">/* set the n-th bit of x to 0 */</span>
+<span class="ot">#define RESET_BIT(x, n) ((x)[(n) / BITS_PER_BYTE]) &amp;= ~(0x1 &lt;&lt; ((n) % BITS_PER_BYTE))</span></code></pre></div>
+<p>If you want to get multiple bits, use the right-shift operator to
+shift them over to the right end of the word and then mask with bitwise
+AND. For example:</p>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"><span class="ot">#define BITS_PER_BYTE (8)</span>
+
+<span class="co">/* this rather nasty expression constructs an all-ones byte */</span>
+<span class="ot">#define BYTE_MASK ((1 &lt;&lt; BITS_PER_BYTE) - 1)</span>
+
+<span class="co">/* extract the n-th byte from a word */</span>
+<span class="ot">#define GET_BYTE(x, n) (((x) &gt;&gt; BITS_PER_BYTE * (n)) &amp; BYTE_MASK)</span>
+
+<span class="co">/* extract n bits starting at position i from x */</span>
+<span class="ot">#define GET_BITS(x, i, j) (((x) &gt;&gt; (i)) &amp; ((1 &lt;&lt; n) - 1))</span>
+
+<span class="co">/* another definition of GET_BIT */</span>
+<span class="ot">#define GET_BIT2(x, n) GET_BITS(x, n, 1)</span></code></pre></div>
+<p>Many much more sophisticated techniques for doing bit-fiddling can be found at <a href="http://www.jjj.de/bitwizardry/bitwizardrypage.html" class="uri">http://www.jjj.de/bitwizardry/bitwizardrypage.html</a>.</p>
+<h2 id="persistence"><span class="header-section-number">6.8</span> Persistence</h2>
+<p>When a C program exits, all of its global variables, local variables,
+ and heap-allocated blocks are lost. Its memory is reclaimed by the
+operating system, erased, and handed out to other programs. So what
+happens if you want to keep data around for later?</p>
+<p>To make this problem concrete, let's suppose we want to keep track of
+ a hit counter for web pages. From time to time, the user will run the
+command <code class="backtick">count_hit&nbsp;number</code> where <code class="backtick">number</code>
+ is an integer value in the range 0 to 99, say. (A real application
+would probably be using urls, but let's keep things as simple as
+possible.) We want <code class="backtick">count_hit</code> to print the number of times the page with the given number has been hit, i.e. <code class="backtick">1</code> the first time it is called, <code class="backtick">2</code> the next time, etc. Where can we store the counts so that they will survive to the next execution of <code class="backtick">count_hit</code>?</p>
+<h3 id="A_simple_solution_using_text_files"><span class="header-section-number">6.8.1</span> A simple solution using text files</h3>
+<p>The simplest solution is probably to store the data in a text file. Here's a program that reads a file <code class="backtick">hits</code>, increments the appropriate value, and the writes out a new version. To reduce the chances that data is lost (say if <code class="backtick">count_hit</code> blows up halfway through writing the file), the new values are written to a new file <code class="backtick">hit~</code>, which is then renamed to <code class="backtick">hit</code>, taking the place of the previous version.</p>
+<div>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"><span class="ot">#include &lt;stdio.h&gt;</span>
+<span class="ot">#include &lt;stdlib.h&gt;</span>
+
+<span class="ot">#define NUM_COUNTERS (100) </span><span class="co">/* number of counters we keep track of */</span>
+<span class="ot">#define COUNTER_FILE "/tmp/hit" </span><span class="co">/* where they are stored */</span>
+<span class="ot">#define NEW_COUNTER_FILE COUNTER_FILE "~" </span><span class="co">/* note use of constant string concatenation */</span>
+
+<span class="dt">int</span>
+main(<span class="dt">int</span> argc, <span class="dt">char</span> **argv)
+{
+ <span class="dt">int</span> c;
+ <span class="dt">int</span> i;
+ <span class="dt">int</span> counts[NUM_COUNTERS];
+ FILE *f;
+
+ <span class="kw">if</span>(argc &lt; <span class="dv">2</span>) {
+ fprintf(stderr, <span class="st">"Usage: %s number</span><span class="ch">\n</span><span class="st">"</span>, argv[<span class="dv">0</span>]);
+ exit(<span class="dv">1</span>);
+ }
+ <span class="co">/* else */</span>
+
+ c = atoi(argv[<span class="dv">1</span>]);
+ <span class="kw">if</span>(c &lt; <span class="dv">0</span> || c &gt;= NUM_COUNTERS) {
+ fprintf(stderr, <span class="st">"Counter %d not in range 0..%d</span><span class="ch">\n</span><span class="st">"</span>, c, NUM_COUNTERS - <span class="dv">1</span>);
+ exit(<span class="dv">2</span>);
+ }
+
+ f = fopen(COUNTER_FILE, <span class="st">"r"</span>);
+ <span class="kw">if</span>(f == <span class="dv">0</span>) {
+ perror(COUNTER_FILE);
+ exit(<span class="dv">3</span>);
+ }
+
+ <span class="co">/* read them in */</span>
+ <span class="kw">for</span>(i = <span class="dv">0</span>; i &lt; NUM_COUNTERS; i++) {
+ fscanf(f, <span class="st">"%d"</span>, &amp;counts[i]);
+ }
+ fclose(f);
+
+ printf(<span class="st">"%d</span><span class="ch">\n</span><span class="st">"</span>, ++counts[c]);
+
+ <span class="co">/* write them back */</span>
+ f = fopen(NEW_COUNTER_FILE, <span class="st">"w"</span>);
+ <span class="kw">for</span>(i = <span class="dv">0</span>; i &lt; NUM_COUNTERS; i++) {
+ fprintf(f, <span class="st">"%d</span><span class="ch">\n</span><span class="st">"</span>, counts[i]);
+ }
+ fclose(f);
+
+ rename(NEW_COUNTER_FILE, COUNTER_FILE);
+
+ <span class="kw">return</span> <span class="dv">0</span>;
+}</code></pre></div>
+<a href="http://cs.yale.edu/homes/aspnes/classes/223/examples/persistence/textFile.c" class="uri">examples/persistence/textFile.c</a>
+</div>
+<p>If you want to use this, you will need to create an initial file <code class="backtick">/tmp/hit</code> with <code class="backtick">NUM_COUNTERS</code> zeroes in it.</p>
+<p>Using a simple text file like this is the easiest way to keep data
+around, since you can look at the file with a text editor or other tools
+ if you want to do things to it. But it means that the program has to
+parse the file every time it runs. We can speed things up a little bit
+(and simplify the code) by storing the values in binary.</p>
+<h3 id="Using_a_binary_file"><span class="header-section-number">6.8.2</span> Using a binary file</h3>
+<p>Here's a version that stores the data as a binary file of exactly <code class="backtick">sizeof(int)&nbsp;*&nbsp;NUM_COUNTERS</code> bytes. It uses the <code class="backtick">stdio</code> routines <code class="backtick">fread</code> and <code class="backtick">fwrite</code>
+ to read and write the file. These are much faster than the loops in the
+ previous program, since they can just slap the bytes directly into <code class="backtick">counts</code> without processing them at all.</p>
+<p>The program also supplies and extra flag <code class="backtick">b</code> to <code class="backtick">fopen</code>.
+ This is ignored on Unix-like machines but is needed on Windows machines
+ to tell the operating system that the file contains binary data (such
+files are stored differently from text files on Windows).</p>
+<div>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"><span class="ot">#include &lt;stdio.h&gt;</span>
+<span class="ot">#include &lt;stdlib.h&gt;</span>
+
+<span class="ot">#define NUM_COUNTERS (100) </span><span class="co">/* number of counters we keep track of */</span>
+<span class="ot">#define COUNTER_FILE "/tmp/hit" </span><span class="co">/* where they are stored */</span>
+<span class="ot">#define NEW_COUNTER_FILE COUNTER_FILE "~" </span><span class="co">/* note use of constant string concatenation */</span>
+
+<span class="dt">int</span>
+main(<span class="dt">int</span> argc, <span class="dt">char</span> **argv)
+{
+ <span class="dt">int</span> c;
+ <span class="dt">int</span> counts[NUM_COUNTERS];
+ FILE *f;
+
+ <span class="kw">if</span>(argc &lt; <span class="dv">2</span>) {
+ fprintf(stderr, <span class="st">"Usage: %s number</span><span class="ch">\n</span><span class="st">"</span>, argv[<span class="dv">0</span>]);
+ exit(<span class="dv">1</span>);
+ }
+ <span class="co">/* else */</span>
+
+ c = atoi(argv[<span class="dv">1</span>]);
+ <span class="kw">if</span>(c &lt; <span class="dv">0</span> || c &gt;= NUM_COUNTERS) {
+ fprintf(stderr, <span class="st">"Counter %d not in range 0..%d</span><span class="ch">\n</span><span class="st">"</span>, c, NUM_COUNTERS - <span class="dv">1</span>);
+ exit(<span class="dv">2</span>);
+ }
+
+ f = fopen(COUNTER_FILE, <span class="st">"rb"</span>);
+ <span class="kw">if</span>(f == <span class="dv">0</span>) {
+ perror(COUNTER_FILE);
+ exit(<span class="dv">3</span>);
+ }
+
+ <span class="co">/* read them in */</span>
+ fread(counts, <span class="kw">sizeof</span>(*counts), NUM_COUNTERS, f);
+ fclose(f);
+
+ printf(<span class="st">"%d</span><span class="ch">\n</span><span class="st">"</span>, ++counts[c]);
+
+ <span class="co">/* write them back */</span>
+ f = fopen(NEW_COUNTER_FILE, <span class="st">"wb"</span>);
+ fwrite(counts, <span class="kw">sizeof</span>(*counts), NUM_COUNTERS, f);
+ fclose(f);
+
+ rename(NEW_COUNTER_FILE, COUNTER_FILE);
+
+ <span class="kw">return</span> <span class="dv">0</span>;
+}</code></pre></div>
+<a href="http://cs.yale.edu/homes/aspnes/classes/223/examples/persistence/binaryFile.c" class="uri">examples/persistence/binaryFile.c</a>
+</div>
+<p>Again, you'll have to initialize <code class="backtick">/tmp/hit</code>
+ to use this; in this case, you want it to contain exactly 400 null
+characters. On a Linux machine you can do this with the command <code class="backtick">dd&nbsp;if=/dev/zero&nbsp;of=/tmp/hit&nbsp;bs=400&nbsp;count=1</code>.</p>
+<p>The advantage of using binary files is that reading and writing them
+is both simpler and faster. The disadvantages are (a) you can't look at
+or update the binary data with your favorite text editor any more, and
+(b) the file may no longer be portable from one machine to another, if
+the different machines have different endianness or different values of <code class="backtick">sizeof(int)</code>.
+ The second problem we can deal with by converting the data to a
+standard word size and byte order before storing it, but then we lose
+some advantages of speed.</p>
+<h3 id="A_version_that_updates_the_file_in_place"><span class="header-section-number">6.8.3</span> A version that updates the file in place</h3>
+<p>We still may run into speed problems if <code class="backtick">NUM_COUNTERS</code> is huge. The next program avoids rewriting the entire file just to update one value inside it. This program uses the <code class="backtick">fseek</code> function to position the cursor inside the file. It opens the file using the <code class="backtick">"r+b"</code> flag to <code class="backtick">fopen</code>, which means to open an existing binary file for reading and writing.</p>
+<div>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"><span class="ot">#include &lt;stdio.h&gt;</span>
+<span class="ot">#include &lt;stdlib.h&gt;</span>
+
+<span class="ot">#define NUM_COUNTERS (100) </span><span class="co">/* number of counters we keep track of */</span>
+<span class="ot">#define COUNTER_FILE "/tmp/hit" </span><span class="co">/* where they are stored */</span>
+
+<span class="dt">int</span>
+main(<span class="dt">int</span> argc, <span class="dt">char</span> **argv)
+{
+ <span class="dt">int</span> c;
+ <span class="dt">int</span> count;
+ FILE *f;
+
+ <span class="kw">if</span>(argc &lt; <span class="dv">2</span>) {
+ fprintf(stderr, <span class="st">"Usage: %s number</span><span class="ch">\n</span><span class="st">"</span>, argv[<span class="dv">0</span>]);
+ exit(<span class="dv">1</span>);
+ }
+ <span class="co">/* else */</span>
+
+ c = atoi(argv[<span class="dv">1</span>]);
+ <span class="kw">if</span>(c &lt; <span class="dv">0</span> || c &gt;= NUM_COUNTERS) {
+ fprintf(stderr, <span class="st">"Counter %d not in range 0..%d</span><span class="ch">\n</span><span class="st">"</span>, c, NUM_COUNTERS - <span class="dv">1</span>);
+ exit(<span class="dv">2</span>);
+ }
+
+ f = fopen(COUNTER_FILE, <span class="st">"r+b"</span>);
+ <span class="kw">if</span>(f == <span class="dv">0</span>) {
+ perror(COUNTER_FILE);
+ exit(<span class="dv">3</span>);
+ }
+
+ <span class="co">/* read counter */</span>
+ fseek(f, <span class="kw">sizeof</span>(<span class="dt">int</span>) * c, SEEK_SET);
+ fread(&amp;count, <span class="kw">sizeof</span>(<span class="dt">int</span>), <span class="dv">1</span>, f);
+
+ printf(<span class="st">"%d</span><span class="ch">\n</span><span class="st">"</span>, ++count);
+
+ <span class="co">/* write it back */</span>
+ fseek(f, <span class="kw">sizeof</span>(<span class="dt">int</span>) * c, SEEK_SET);
+ fwrite(&amp;count, <span class="kw">sizeof</span>(<span class="dt">int</span>), <span class="dv">1</span>, f);
+ fclose(f);
+
+ <span class="kw">return</span> <span class="dv">0</span>;
+}</code></pre></div>
+<a href="http://cs.yale.edu/homes/aspnes/classes/223/examples/persistence/binaryFileFseek.c" class="uri">examples/persistence/binaryFileFseek.c</a>
+</div>
+<p>Note that this program is not only shorter than the last one, but it also avoids allocating the <code class="backtick">counts</code>
+ array. It also is less likely to run into trouble with running out of
+space during writing. If we ignore issues of concurrency, this is the
+best we can probably do with just <code class="backtick">stdio</code>.</p>
+<h3 id="An_even_better_version_using_mmap"><span class="header-section-number">6.8.4</span> An even better version using mmap</h3>
+<p>We can do even better using the <code class="backtick">mmap</code> routine, available in all POSIX-compliant C libraries. <a href="http://en.wikipedia.org/wiki/POSIX" title="WikiPedia">POSIX</a>, which is short for <em>Portable Standard Unix</em>, is supported by essentially all Unix-like operating systems and NT-based versions of Microsoft Windows. The <code class="backtick">mmap</code>
+ routine tells the operating system to "map" a file in the filesystem to
+ a region in the process's address space. Reading bytes from this region
+ will read from the file; writing bytes to this region will write to the
+ file (although perhaps not immediately). Even better, if more than one
+process calls <code class="backtick">mmap</code> on the same file at
+once, they will share the memory region, so that updates made by one
+process will be seen immediately by the others (with some caveats having
+ to do with how concurrent access to memory actually works on real
+machines).</p>
+<p>Here is the program using <code class="backtick">mmap</code>:</p>
+<div>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"><span class="ot">#include &lt;stdio.h&gt;</span>
+<span class="ot">#include &lt;stdlib.h&gt;</span>
+<span class="ot">#include &lt;sys/types.h&gt;</span>
+<span class="ot">#include &lt;sys/stat.h&gt;</span>
+<span class="ot">#include &lt;fcntl.h&gt;</span>
+<span class="ot">#include &lt;sys/mman.h&gt; </span><span class="co">/* For mmap. I think mman is short for "memory management." */</span>
+
+<span class="ot">#define NUM_COUNTERS (100) </span><span class="co">/* number of counters we keep track of */</span>
+<span class="ot">#define COUNTER_FILE "/tmp/hit" </span><span class="co">/* where they are stored */</span>
+<span class="ot">#define NEW_COUNTER_FILE COUNTER_FILE "~" </span><span class="co">/* note use of constant string concatenation */</span>
+
+<span class="dt">int</span>
+main(<span class="dt">int</span> argc, <span class="dt">char</span> **argv)
+{
+ <span class="dt">int</span> c;
+ <span class="dt">int</span> *counts;
+ <span class="dt">int</span> fd;
+
+ <span class="kw">if</span>(argc &lt; <span class="dv">2</span>) {
+ fprintf(stderr, <span class="st">"Usage: %s number</span><span class="ch">\n</span><span class="st">"</span>, argv[<span class="dv">0</span>]);
+ exit(<span class="dv">1</span>);
+ }
+ <span class="co">/* else */</span>
+
+ c = atoi(argv[<span class="dv">1</span>]);
+ <span class="kw">if</span>(c &lt; <span class="dv">0</span> || c &gt;= NUM_COUNTERS) {
+ fprintf(stderr, <span class="st">"Counter %d not in range 0..%d</span><span class="ch">\n</span><span class="st">"</span>, c, NUM_COUNTERS - <span class="dv">1</span>);
+ exit(<span class="dv">2</span>);
+ }
+
+ <span class="co">/* open and map the file */</span>
+ fd = open(COUNTER_FILE, O_RDWR);
+ <span class="kw">if</span>(fd &lt; <span class="dv">0</span>) {
+ perror(COUNTER_FILE);
+ exit(<span class="dv">3</span>);
+ }
+ counts = mmap(<span class="dv">0</span>, <span class="kw">sizeof</span>(*counts) * NUM_COUNTERS, PROT_READ|PROT_WRITE, MAP_SHARED, fd, <span class="dv">0</span>);
+
+ <span class="kw">if</span>(counts == <span class="dv">0</span>) {
+ perror(COUNTER_FILE);
+ exit(<span class="dv">4</span>);
+ }
+
+ printf(<span class="st">"%d</span><span class="ch">\n</span><span class="st">"</span>, ++counts[c]);
+
+ <span class="co">/* unmap the region and close the file just to be safe */</span>
+ munmap(counts, <span class="kw">sizeof</span>(*counts) * NUM_COUNTERS);
+ close(fd);
+
+ <span class="kw">return</span> <span class="dv">0</span>;
+}</code></pre></div>
+<a href="http://cs.yale.edu/homes/aspnes/classes/223/examples/persistence/binaryFileMmap.c" class="uri">examples/persistence/binaryFileMmap.c</a>
+</div>
+<p>Now the code for actually incrementing <code class="backtick">counts[c]</code> and writing it to the file is trivial. Unfortunately, we have left <code class="backtick">stdio</code> behind, and have to deal with low-level POSIX calls like <code class="backtick">open</code> and <code class="backtick">close</code>
+ to get at the file. Still, this may be the most efficient version we
+can do, and becomes even better if we plan to do many updates to the
+same file, since we can just keep the file open.</p>
+<h3 id="Concurrency_and_fault-tolerance_issues:_ACIDity"><span class="header-section-number">6.8.5</span> Concurrency and fault-tolerance issues: ACIDity</h3>
+<p>All of the solutions described so far can fail if you run two copies of <code class="backtick">count_hits</code> simultaneously. The <code class="backtick">mmap</code>
+ solution is probably the least vulnerable to failures, as the worst
+that can happen is that some update is lost if the same locations is
+updated at exactly the same time. The other solutions can fail more
+spectacularly; simultaneous writes to <code class="backtick">/tmp/hit~</code>
+ in the simple text file version, for example, can produce a wide
+variety of forms of file corruption. For a simple web page hit counter,
+this may not be a problem. If you are writing a back-end for a bank, you
+ probably want something less vulnerable.</p>
+<p>Database writers aim for a property called <strong>ACIDity</strong> from the acronym <strong>ACID</strong> = <strong>Atomicity</strong>, <strong>Consistency</strong>, <strong>Isolation</strong>, and <strong>Durability</strong>. These are defined for a system in which the database is accessed via <strong>transactions</strong> consisting of one or more operations. An example of a transaction might be <code class="backtick">++counts[c]</code>, which we can think of as consisting of two operations: reading <code class="backtick">counts[c]</code>, and writing back <code class="backtick">counts[c]+1</code>.</p>
+<p><em>Atomicity</em> means that either every operation in a transaction
+ is performed or none is. In practice, this means if the transaction
+fails any partial progress must be undone.</p>
+<p><em>Consistency</em> means that at the end of a transaction the
+database is in a "consistent" state. This may just mean that no data has
+ been corrupted (e.g. in the text data file we have exactly 100 lines
+and they're all integer counts), or it may also extend to integrity
+constraints enforce by the database (e.g. in a database of airline
+flights, the fact that flight 2937 lands at HVN at 22:34 on 12/17
+implies that flight 2937 exists, has an assigned pilot, etc.).</p>
+<p><em>Isolation</em> says that two concurrent transactions can't detect
+ each other; the partial progress of one transaction is not visible to
+others until the transaction commits.</p>
+<p><em>Durability</em> means that the results of any committed
+transaction are permanent. In practice this means there is enough
+information physically written to a disk to reconstruct the transaction
+before the transaction finished.</p>
+<p>How can we enforce these requirements for our hit counter? Atomicity
+is not hard: if I stop a transaction after a read but before the write,
+no one will be the wiser (although there is a possible problem if only
+half of my write succeeds). Consistency is enforced by the <code class="backtick">fseek</code> and <code class="backtick">mmap</code>
+ solutions, since they can't change the structure of the file. Isolation
+ is not provided by any of our solutions, and would require some sort of
+ locking (e.g. using <code class="backtick">flock</code>) to make sure that only one program uses the file at a time. Durability is enforced by not having <code class="backtick">count_hits</code> return until the <code class="backtick">fclose</code> or <code class="backtick">close</code> operation has succeeded (although full durability would require running <code class="backtick">fsync</code> or <code class="backtick">msync</code> to actually guarantee data was written to disk).</p>
+<p>Though it would be possible to provide full ACIDity with enough work,
+ this is a situation where using an existing well-debugged tool beats
+writing our own. Depending on what we are allowed to do to the machine
+our program is running on, we have many options for getting much better
+handling of concurrency. Some standard tools we could use are:</p>
+<ul>
+<li><a href="http://www.gnu.org/software/gdbm/gdbm.html">gdbm</a>. This
+is a minimal hash-table-on-disk library that uses simplistic locking to
+get isolation. The advantage of this system is that it's probably
+already installed on any Linux machine. The disadvantage is that it
+doesn't provide much functionality beyond basic transactions.</li>
+<li><a href="http://www.oracle.com/technetwork/database/database-technologies/berkeleydb/downloads/index.html">Berkeley DB</a>
+ is a fancier hash-table-on-disk library that provides full ACIDity but
+not much else. There is a good chance that some version of this is also
+installed by default on any Linux or BSD machine you run into.</li>
+<li>Various toy databases like <a href="http://www.sqlite.org/">SQLite</a> or <a href="http://www.mysql.com/">MySQL</a>
+ provide tools that look very much like serious databases with easy
+installation and little overhead. These are probably the solutions most
+people choose, especially since MySQL is integrated tightly with PHP and
+ other Web-based scription languages. Such a solution also allows other
+programs to access the table without having to know a lot of details
+about how it is stored, because the <a href="http://en.wikipedia.org/wiki/SQL" title="WikiPedia">SQL</a> query language hides the underlying storage format.</li>
+<li>Production-quality databases like <a href="http://www.postgresql.org/">PostgreSQL</a>, <a href="http://www.microsoft.com/en-us/server-cloud/products/sql-server/">SQL Server</a>, or <a href="http://www.oracle.com/index.html">Oracle</a>
+ provide very high levels of robustness and concurrency at the cost of
+requiring non-trivial management and possibly large licensing fees. This
+ is what you pick if you really are running a bank.</li>
+</ul>
+<h1 id="whatNext"><span class="header-section-number">7</span> What next?</h1>
+<p>Congratulations! You now know everything there is to know about programming in C. Now what do you do?</p>
+<p>My recommendation would be the following: learn C++, since you know
+75% of it already, and you will be able to escape from some (but not
+all) of the annoying limitations of C. And learn a scripting language
+you can be comfortable with, for writing programs quickly where
+performance isn't the main requirement.</p>
+<h2 id="What.27s_wrong_with_C"><span class="header-section-number">7.1</span> What's wrong with C</h2>
+<p>In this class, we had to work around fundamental limitations in C on several occasions.</p>
+<dl>
+<dt>C doesn't have a garbage collector</dt>
+<dd>Many modern program languages will detect and free unreachable data
+for you automatically. C doesn't, so the programmer has to spend a lot
+of time worrying about when and by whom data allocated with <code class="backtick">malloc</code> will be passed to <code class="backtick">free</code>.
+ Not only does this create many possibilities for error, but it also
+means that certain kinds of data structures in which a single component
+of the data structure is pointed to by an unpredictable number of other
+components are difficult to write in C, since it's hard to tell when it
+is safe to free a component. Garbage-collected languages avoid all of
+these problems at a slight cost in performance. Though there exists a
+garbage collector for C/C++ <a href="http://www.hboehm.info/gc/" class="uri">http://www.hboehm.info/gc/</a>, it isn't 100% portable and may not work as well as a built-in collector.
+</dd>
+<dt>C doesn't support any kind of polymorphism</dt>
+<dd>Polymorphism is when a function can work on more than one data type. The closest C can do is either parameterized macros (see <a href="#macros">Macros</a>Macros.html)), heavy use of <code class="backtick">void&nbsp;*</code> and function pointers as in <code class="backtick">qsort</code>, or various nasty hacks where code is automatically generated with type names filled in from a base template (see <a href="#macros">Macros</a>Macros.html)
+ again). Most modern programming languages have some sort of support for
+ polymorphism, allowing you to write, for example, a generic sorting
+routine without resorting to <code class="backtick">void&nbsp;*</code>-like departures from the type system.
+</dd>
+<dt>C doesn't have exceptions</dt>
+<dd>Exceptions are a mechanism for doing non-standard returns from a
+function when something blows up, which get caught using an "exception
+handler" that is often separate from the code handling the normal return
+ values and which can often be used to catch exceptions from a variety
+of sources. Instead, C requires function writers to invent and document
+an ad-hoc protocol for indicating bad outcomes for every function they
+write, and requires function users to remember to test for bad return
+values. Most programmers are too lazy to do this all the time, leading
+to undetected run-time errors. Most modern programming languages fix
+this.
+</dd>
+<dt>C doesn't support object-oriented programming very well</dt>
+<dd>"Object-oriented" is a buzzword with many possible meanings (but see <a href="http://c2.com/cgi/wiki?HeInventedTheTerm" class="uri">http://c2.com/cgi/wiki?HeInventedTheTerm</a>).
+ However, at minimum it means that in addition to supporting
+polymorphism (described above), your language should support strong
+encapsulation (controlling who can get at the internal data of an
+object) and inheritance (allowing one abstract data type to be defined
+by extending another). You can fake most of these things in C if you try
+ hard enough (for example, using <a href="#functionPointers">function pointers</a>),
+ but it is always possible to muck around with internal bits of things
+just because of the unlimited control C gives you over the environment.
+This can quickly become dangerous in large software projects.
+</dd>
+<dt>C provides only limited support for avoiding namespace collisions</dt>
+<dd>In a large C program, it's impossible to guarantee that my <code class="backtick">eat_leftovers</code> function exported from <code class="backtick">leftovers.c</code> doesn't conflict with your <code class="backtick">eat_leftovers</code> function in <code class="backtick">cannibalism.c</code>. A mediocre solution is to use longer names: <code class="backtick">leftovers_eat_leftovers</code> vs <code class="backtick">cannibalism_eat_leftovers</code>, and one can also play games with function pointers and global <code class="backtick">struct</code> variables to allow something like <code class="backtick">leftovers.eat_leftovers</code> vs <code class="backtick">cannibalism.eat_leftovers</code>.
+ Most modern programming languages provide an explicit package or
+namespace mechanism to allow the programmer to control who sees what
+names where.
+</dd>
+</dl>
+<h2 id="What_C.2B-.2B-_fixes"><span class="header-section-number">7.2</span> What C++ fixes</h2>
+<p>On the above list, C++ fixes everything except the missing garbage
+collector. If you want to learn C++, you should get a copy of <em>The C++ Programming Language</em>, by Bjarne Stroustrup, which is the definitive reference manual. But you can get a taste of it from several on-line tutorials:</p>
+<ul>
+<li><a href="http://www.4p8.com/eric.brasseur/cppcen.html">C++ tutorial for C users</a>, by <a href="http://www.4p8.com/eric.brasseur/index.html">Eric Brasseur</a>. Exactly what it says. Introduces C++ features not found in C in order of increasing complexity.</li>
+<li>Some other on-line tutorials that assume little or no prior programming experience:
+<ul>
+<li><a href="http://www.cplusplus.com/doc/tutorial/" class="uri">http://www.cplusplus.com/doc/tutorial/</a></li>
+<li><a href="http://www.cprogramming.com/tutorial.html" class="uri">http://www.cprogramming.com/tutorial.html</a></li>
+</ul></li>
+</ul>
+<h2 id="other-c-like-languages"><span class="header-section-number">7.3</span> Other C-like languages</h2>
+<p>C syntax has become the default for new programming languages
+targeted at a general audience. Some noteworthy examples of C-like
+languages are <a href="http://www.oracle.com/technetwork/java/index.html">Java</a> (used in Android), <a href="https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/ProgrammingWithObjectiveC/Introduction/Introduction.html">Objective-C</a> (used in OSX and iOS), and <a href="http://www.ecma-international.org/publications/standards/Ecma-334.htm">C#</a> (used in Windows).</p>
+<p>Each of these fix some of the misfeatures of C (including the lack of
+ a garbage collector and bounds checks on arrays) while retaining much
+of the flavor of C. Which to choose probably depends on what platform
+you are interested in developing for.</p>
+<h2 id="Scripting_languages"><span class="header-section-number">7.4</span> Scripting languages</h2>
+<p>Much current programming is done in so-called <strong>scripting languages</strong> like <a href="https://www.python.org/">Python</a>, <a href="http://www.perl.org/">Perl</a>, <a href="http://php.net/">PHP</a>, <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript">JavaScript</a>, <a href="http://msdn.microsoft.com/en-us/library/2x7h1hfk.aspx">Visual Basic</a>, <a href="http://www.tcl.tk/">Tcl</a>,
+ etc. These are generally interpreted languages similar to Lisp or
+Scheme under the hood, with dynamic typing (type information is carried
+along with values, so type errors are detected only at runtime but
+polymorphism is provided automatically), garbage collectors, and support
+ for many advanced programming features like objects and anonymous
+functions. What distinguishes scripting languages from the Lisp-like
+languages is that the syntax is generally more accessible to newcomers
+and the language runtime usually comes with very large libraries
+providing built-in tools for doing practical programming tasks like
+parsing odd input formats and interfacing to databases and network
+services. The result is that common programming tasks can be implemented
+ using very few lines of code, at a cost in performance that ranges from
+ slight to horrendous depending on what you are doing.</p>
+<p>Let's look at an example in two common scripting languages, Perl and Python.</p>
+<p>Here are some solutions to an old assignment, which find all the palindromes on <code class="backtick">stdin</code> and report the first non-matching character for any non-palindrome.</p>
+<p>The original C version looks like this:</p>
+<div>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"><span class="ot">#include &lt;stdio.h&gt;</span>
+<span class="ot">#include &lt;stdlib.h&gt;</span>
+<span class="ot">#include &lt;string.h&gt;</span>
+
+<span class="co">/* Palindrome detector.</span>
+<span class="co"> *</span>
+<span class="co"> * For each line of the input, prints PALINDROME if it is a palindrome</span>
+<span class="co"> * or the index of the first non-matching character otherwise.</span>
+<span class="co"> *</span>
+<span class="co"> * Note: does not handle lines containing nulls.</span>
+<span class="co"> */</span>
+
+<span class="co">/* read a line of text from stdin</span>
+<span class="co"> * and return it (without terminating newline) as a freshly-malloc'd block.</span>
+<span class="co"> * Caller is responsible for freeing this block.</span>
+<span class="co"> * Returns 0 on error or EOF.</span>
+<span class="co"> */</span>
+<span class="dt">char</span> *
+getLine(<span class="dt">void</span>)
+{
+ <span class="dt">char</span> *line; <span class="co">/* line buffer */</span>
+ <span class="dt">int</span> n; <span class="co">/* characters read */</span>
+ <span class="dt">int</span> size; <span class="co">/* size of line buffer */</span>
+ <span class="dt">int</span> c;
+
+ size = <span class="dv">1</span>;
+ line = malloc(size);
+ <span class="kw">if</span>(line == <span class="dv">0</span>) <span class="kw">return</span> <span class="dv">0</span>;
+
+ n = <span class="dv">0</span>;
+
+ <span class="kw">while</span>((c = getchar()) != <span class="ch">'\n'</span> &amp;&amp; c != EOF) {
+ <span class="kw">while</span>(n &gt;= size - <span class="dv">1</span>) {
+ size *= <span class="dv">2</span>;
+ line = realloc(line, size);
+ <span class="kw">if</span>(line == <span class="dv">0</span>) <span class="kw">return</span> <span class="dv">0</span>;
+ }
+ line[n++] = c;
+ }
+
+ <span class="kw">if</span>(c == EOF &amp;&amp; n == <span class="dv">0</span>) {
+ <span class="co">/* got nothing */</span>
+ free(line);
+ <span class="kw">return</span> <span class="dv">0</span>;
+ } <span class="kw">else</span> {
+ line[n++] = '\<span class="dv">0</span>';
+ <span class="kw">return</span> line;
+ }
+}
+
+<span class="ot">#define IS_PALINDROME (-1)</span>
+
+<span class="co">/* returns IS_PALINDROME if s is a palindrome,</span>
+<span class="co"> * or index of first unmatched character otherwise. */</span>
+<span class="dt">int</span>
+testPalindrome(<span class="dt">const</span> <span class="dt">char</span> *s)
+{
+ <span class="dt">int</span> n; <span class="co">/* length of s */</span>
+ <span class="dt">int</span> i;
+
+ n = strlen(s);
+
+ <span class="co">/* we only have to check up to floor(n/2) */</span>
+ <span class="kw">for</span>(i = <span class="dv">0</span>; i &lt; n/<span class="dv">2</span>; i++) {
+ <span class="kw">if</span>(s[i] != s[n<span class="dv">-1</span>-i]) {
+ <span class="kw">return</span> i;
+ }
+ }
+ <span class="co">/* else */</span>
+ <span class="kw">return</span> IS_PALINDROME;
+}
+
+<span class="dt">int</span>
+main(<span class="dt">int</span> argc, <span class="dt">char</span> **argv)
+{
+ <span class="dt">char</span> *line;
+ <span class="dt">int</span> mismatch;
+
+ <span class="kw">while</span>((line = getLine()) != <span class="dv">0</span>) {
+ mismatch = testPalindrome(line);
+ <span class="kw">if</span>(mismatch == IS_PALINDROME) {
+ puts(<span class="st">"PALINDROME"</span>);
+ } <span class="kw">else</span> {
+ printf(<span class="st">"%d</span><span class="ch">\n</span><span class="st">"</span>, mismatch);
+ }
+
+ free(line);
+ }
+
+ <span class="kw">return</span> <span class="dv">0</span>;
+}
+
+ </code></pre></div>
+<a href="http://cs.yale.edu/homes/aspnes/classes/223/examples/scripting/palindrome.c" class="uri">examples/scripting/palindrome.c</a>
+</div>
+<p>This version is written in Perl (<a href="http://www.perl.org/" class="uri">http://www.perl.org</a>):</p>
+<div>
+<div class="sourceCode"><pre class="sourceCode perl"><code class="sourceCode perl"><span class="kw">#!/usr/bin/perl</span>
+
+<span class="co"># For each line in stdin, print PALINDROME if it is a palindrome, or index of</span>
+<span class="co"># the first non-matching character otherwise.</span>
+
+<span class="kw">while</span>(&lt;&gt;) {
+ <span class="fu">chomp</span>; <span class="co"># remove trailing newline</span>
+ <span class="kw">if</span>(<span class="dt">$_</span> <span class="kw">eq</span> <span class="fu">reverse</span> <span class="dt">$_</span>) {
+ <span class="fu">print</span> <span class="kw">"</span><span class="st">PALINDROME</span><span class="ch">\n</span><span class="kw">"</span>;
+ } <span class="kw">else</span> {
+ <span class="kw">for</span> <span class="dt">$i</span> (<span class="dv">0</span>..<span class="fu">length</span>(<span class="dt">$_</span>) - <span class="dv">1</span>) {
+ <span class="kw">if</span>(<span class="fu">substr</span>(<span class="dt">$_</span>, <span class="dt">$i</span>, <span class="dv">1</span>) <span class="kw">ne</span> <span class="fu">substr</span>(<span class="dt">$_</span>, <span class="fu">length</span>(<span class="dt">$_</span>) - <span class="dt">$i</span> - <span class="dv">1</span>, <span class="dv">1</span>)) {
+ <span class="fu">print</span> <span class="dt">$i</span>, <span class="kw">"</span><span class="ch">\n</span><span class="kw">"</span>;
+ <span class="kw">last</span>;
+ }
+ }
+ }
+}</code></pre></div>
+<a href="http://cs.yale.edu/homes/aspnes/classes/223/examples/scripting/palindrome.pl" class="uri">examples/scripting/palindrome.pl</a>
+</div>
+<p>The things to notice about Perl is that the syntax is deliberately
+very close to C (with some idiosyncratic extensions like putting <code class="backtick">$</code>
+ on the front of all variable names), and that common tasks like reading
+ all input lines get hidden inside default constructions like <code class="backtick">while(&lt;&gt;)</code> and the <code class="backtick">$_</code> variable that functions with no arguments like <code class="backtick">chomp</code> operate on by default. This can allow for very compact but sometimes very incomprehensible code.</p>
+<p>Here's a version in Python (<a href="https://www.python.org/" class="uri">https://www.python.org/</a>):</p>
+<div>
+<div class="sourceCode"><pre class="sourceCode python"><code class="sourceCode python"><span class="co">#!/usr/bin/python</span>
+
+<span class="co">"""For each line in stdin, print PALINDROME if it is a palindrome, or index of</span>
+<span class="co">the first non-matching character otherwise."""</span>
+
+<span class="im">import</span> sys
+
+<span class="cf">for</span> line <span class="op">in</span> sys.stdin:
+ line <span class="op">=</span> line.rstrip(<span class="st">'</span><span class="ch">\n</span><span class="st">'</span>) <span class="co"># remove trailing newline</span>
+ <span class="cf">if</span> line <span class="op">==</span> line[::<span class="op">-</span><span class="dv">1</span>]:
+ <span class="bu">print</span>(<span class="st">"PALINDROME"</span>)
+ <span class="cf">else</span>:
+ mismatches <span class="op">=</span> [ i <span class="cf">for</span> i <span class="op">in</span> <span class="bu">range</span>(<span class="bu">len</span>(line)) <span class="cf">if</span> line[i] <span class="op">!=</span> line[<span class="op">-</span>(i<span class="dv">+1</span>)] ]
+ <span class="bu">print</span>(<span class="bu">min</span>(mismatches))</code></pre></div>
+<a href="http://cs.yale.edu/homes/aspnes/classes/223/examples/scripting/palindrome.py" class="uri">examples/scripting/palindrome.py</a>
+</div>
+<p>Here the syntax is a little more alien if you are used to C: Python
+doesn't use curly braces for block structure, using indentation instead.
+ The code above uses some other odd features of the language, such as
+the ability to take "slices" of sequence variables like strings (the
+expression <code class="backtick">line[::-1]</code> means "take all elements of <code class="backtick">line</code>
+ starting from the obvious default starting point (the empty string
+before the first colon) to the obvious default ending point (the empty
+string before the second colon) stepping backwards one character at a
+time (the <code class="backtick">-1</code>)), a feature the language adopted from array-processing languages like <a href="http://www.mathworks.com/">MatLab</a>; and the ability to do <em>list comprehensions</em> (the large expression assigned to <code class="backtick">mismatches</code>), a feature that Python adopted from <a href="http://www.haskell.org/">Haskell</a> and that Haskell adopted from set theory.</p>
+<p>What these gain in short code length they lose in speed; run times on <code class="backtick">/usr/share/dict/words</code> in the Zoo are</p>
+<table style="width:33%;">
+<colgroup>
+<col width="15%">
+<col width="18%">
+</colgroup>
+<tbody>
+<tr class="odd">
+<td align="left"><p>C</p></td>
+<td align="left"><p>0.107s</p></td>
+</tr>
+<tr class="even">
+<td align="left"><p>Perl</p></td>
+<td align="left"><p>0.580s</p></td>
+</tr>
+<tr class="odd">
+<td align="left"><p>Python</p></td>
+<td align="left"><p>2.052s</p></td>
+</tr>
+</tbody>
+</table>
+<p>Note that for Perl and Python some of the cost is the time to start
+the interpreter and parse the script, but factors of 10–100 are not
+unusual slowdowns when moving from C to a scripting language. The
+selling point of these languages is that in many applications run time
+is not as critical as ease and speed of implementation.</p>
+<p>As an even shorter example, if you just want to print all the
+palindromes in a file, you can do that from the command line in one line
+ of Perl, e.g:</p>
+<pre><code>$ perl -ne 'chomp; print $_, "\n" if($_ eq reverse $_)' &lt; /usr/share/dict/words</code></pre>
+<h1 id="assignments"><span class="header-section-number">8</span> Assignments</h1>
+<h2 id="hw1"><span class="header-section-number">8.1</span> Assignment 1, due Thursday 2015-01-29, at 11:00pm</h2>
+<h3 id="bureaucratic-part"><span class="header-section-number">8.1.1</span> Bureaucratic part</h3>
+<p>Make sure that you sign up for an account on the Zoo at <a href="http://zoo.cs.yale.edu/accounts.html" class="uri">http://zoo.cs.yale.edu/accounts.html</a>.
+ If you already have an account, you still need to check the CPSC 223
+box so that you can turn in assignments. It's best to do this as soon as
+ possible.</p>
+<p>You do not need to develop your solution on the Zoo, but you will
+need to turn it in there, and it will be tested using the compiler on
+the Zoo.</p>
+<h3 id="a-rotten-cipher"><span class="header-section-number">8.1.2</span> A rotten cipher</h3>
+<p>For this assignment, you are to implement an encoder for a
+polyalphabetic substitution cipher vaguely inspired by the Enigma
+machines used by Germany during World War 2. Unlike the Enigma machine,
+this cipher doesn't provide much security, so you can probably tell your
+ non-US-national friends about it without violating US export control
+laws.<a href="#fn26" class="footnoteRef" id="fnref26"><sup>26</sup></a></p>
+<p>Each letter <code>'A'</code> through <code>'Z'</code> or <code>'a'</code> through <code>'z'</code> is encrypted by shifting it some number of positions forward in the alphabet, wrapping around at the end.</p>
+<p>The number of positions is determined by an offset that changes over
+time. The initial shift is 17 positions. After encoding an uppercase
+letter, the shift is increased by 5. After encoding a lowercase letter,
+the shift is increased by 3. To avoid overflow on long texts, it's
+probably a good idea to store the offset modulo 26.</p>
+<p>An uppercase letter is always encoded by an uppercase letter, and a
+lowercase letter is always encoded by a lowercase letter. All other
+characters are passed through intact.</p>
+<p>Below is an example of encoding a famous Napoleonic palindrome using this cipher:</p>
+<pre><code>Plaintext: A b l e w a s I e r e I s a w E l b a
+Offset: 17 22 25 2 5 8 11 14 19 22 25 2 7 10 13 16 21 24 1
+Ciphertext: R x k g b i d W x n d K z k j U g z b</code></pre>
+<h3 id="your-task"><span class="header-section-number">8.1.3</span> Your task</h3>
+<p>For this assignment, you are to write a program <code>encode.c</code> that takes a plaintext from <code>stdin</code>, encodes it using the above algorithm, and writes the result to <code>stdout</code>.</p>
+<p>For example, given the input</p>
+<pre><code>"Stop, thief!" cried Tom, arrestingly.
+
+"You'll never take me alive!" replied the criminal, funereally.</code></pre>
+<p>Your program should output</p>
+<pre><code>"Jpnr, yptsw!" woihj Ccd, uorhycucygw.
+
+"Zud'xa fztfv akxu fa znndp!" fvjiihj ctt umgnmuky, vnjdtjiwzp.</code></pre>
+<h3 id="hints"><span class="header-section-number">8.1.4</span> Hints</h3>
+<ul>
+<li>You should assume that you are using the standard Latin 26-letter alphabet.</li>
+<li>You may assume that the characters <code>'A'</code> through <code>'Z'</code> and <code>'a'</code> through <code>'z'</code> are represented using continuous ranges of integers, so that the expression <code>c - 'A'</code> gives the position of <code>c</code> in the alphabet, provided <code>c</code> is an uppercase character, and counting <code>A</code> as <span class="math inline">0</span>. This means that your program will not be portable to machines that use EBCDIC or some other exotic character representation.</li>
+<li>To test if a character is uppercase or lowercase, one option would be to put <code>#include &lt;ctype.h&gt;</code> in your program and use the <code>isupper</code> and <code>islower</code>
+ macros. Note that these may behave oddly if you have set a locale that
+uses a different alphabet. It may be safer to make your own tests.</li>
+</ul>
+<h3 id="testing-your-assignment"><span class="header-section-number">8.1.5</span> Testing your assignment</h3>
+<p>Sample inputs and outputs can be found in <code>/c/cs223/Hwk1/testFiles</code>
+ on the Zoo. Note that some of these files contain non-printing
+characters that may have odd effects if you send them to your screen.
+The safest way to test if your program produces the same output as the
+sample output is probably to use <code>cmp</code>, for example:</p>
+<pre><code>$ ./encode &lt; test.in &gt; tmp
+$ cmp tmp test.out</code></pre>
+<p>If <code>tmp</code> and <code>test.out</code> contain the same characters, <code>cmp</code> will say nothing. Otherwise it will tell you the first position where they differ.</p>
+<p>If you want to see what characters are in a binary file, trying using <code>od -t x1z</code>, as in</p>
+<pre><code>$ echo hi &gt; file
+$ cat file
+hi
+$ od -t x1z file
+0000000 68 69 0a &gt;hi.&lt;
+0000003</code></pre>
+<h3 id="submitting-your-assignment"><span class="header-section-number">8.1.6</span> Submitting your assignment</h3>
+<p>Submit your assignment using the command:</p>
+<pre><code>/c/cs223/bin/submit 1 encode.c</code></pre>
+<p>You can test that your program compiles (and passes a few basic tests) using the command:</p>
+<pre><code>/c/cs223/bin/testit 1 encode</code></pre>
+<p>This runs the test script in <code>/c/cs223/Hwk1/test.encode</code> on your submitted assignment. You can also run this script by hand to test the version of <code>encode.c</code> in your current working directory.</p>
+<p>The unsympathetic robo-grading script used to grade this assignment
+may or may not use the same tests as this command, so you should make
+sure your program works on other inputs as well. You may also want to
+look at the <a href="#programmingStyle">style grading checklist</a> to
+see that you haven't committed any gross atrocities against readability,
+ in case a human being should happen to look at your code.</p>
+<p>You can submit your assignment more than once, but any late penalties
+ will be assessed based on the last submission. For more details about
+the <code>submit</code> script and its capabilities, see <a href="#submitScript">here</a>.</p>
+<h3 id="hw1Solution"><span class="header-section-number">8.1.7</span> Sample solution</h3>
+<div>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"><span class="co">/*</span>
+<span class="co"> * Encode text on stdin by alphabet rotation with shifting offset.</span>
+<span class="co"> *</span>
+<span class="co"> * Initially, each character 'A'..'Z' or 'a'..'z' is rotated 17 positions.</span>
+<span class="co"> *</span>
+<span class="co"> * After encoding an uppercase letter, the offset is increased by 5 (mod 26).</span>
+<span class="co"> *</span>
+<span class="co"> * After encoding a lowercase letter, the offset is increased by 3 (mod 26).</span>
+<span class="co"> *</span>
+<span class="co"> * These parameters are set using the INITIAL_OFFSET, UPPERCASE_STEP, and LOWERCASE_STEP</span>
+<span class="co"> * constants defined below.</span>
+<span class="co"> *</span>
+<span class="co"> */</span>
+<span class="ot">#include &lt;stdio.h&gt;</span>
+
+<span class="ot">#define INITIAL_OFFSET (17)</span>
+
+<span class="ot">#define UPPERCASE_STEP (5)</span>
+<span class="ot">#define LOWERCASE_STEP (3)</span>
+
+<span class="ot">#define MODULUS ('z' - 'a' + 1)</span>
+
+<span class="dt">int</span>
+main(<span class="dt">int</span> argc, <span class="dt">char</span> **argv)
+{
+ <span class="dt">int</span> offset = INITIAL_OFFSET;
+ <span class="dt">int</span> c;
+
+ <span class="kw">while</span>((c = getchar()) != EOF) {
+ <span class="kw">if</span>(('a' &lt;= c) &amp;&amp; (c &lt;= 'z')) {
+ putchar(((c - 'a') + offset) % MODULUS + 'a');
+ offset = (offset + LOWERCASE_STEP) % MODULUS;
+ } <span class="kw">else</span> <span class="kw">if</span>(('A' &lt;= c) &amp;&amp; (c &lt;= 'Z')) {
+ putchar(((c - 'A') + offset) % MODULUS + 'A');
+ offset = (offset + UPPERCASE_STEP) % MODULUS;
+ } <span class="kw">else</span> {
+ putchar(c);
+ }
+ }
+
+ <span class="kw">return</span> <span class="dv">0</span>;
+}</code></pre></div>
+<a href="http://cs.yale.edu/homes/aspnes/classes/223/examples/2015/hw/1/encode.c" class="uri">examples/2015/hw/1/encode.c</a>
+</div>
+<h2 id="hw2"><span class="header-section-number">8.2</span> Assignment 2, due Wednesday 2015-02-04, at 11:00pm</h2>
+<h3 id="opening-a-safe"><span class="header-section-number">8.2.1</span> Opening a safe</h3>
+<p>The Hollywood Hackable Safe Company has announced a new line of
+electronically-controlled safes with a C API to permit maximum opening
+speed while still protecting your valuable loot. This interface is
+defined in the following file, which can also be found on the Zoo in the
+ directory <code>/c/cs223/Hwk2/sourceFiles</code>:</p>
+<div>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"><span class="co">/*</span>
+<span class="co"> * API for safes made by the </span>
+<span class="co"> * Hollywood Hackable Safe Company LLC.</span>
+<span class="co"> */</span>
+
+<span class="kw">typedef</span> <span class="kw">struct</span> safe Safe; <span class="co">/* opaque data type for a safe */</span>
+
+<span class="co">/*</span>
+<span class="co"> * Returns the number of tumblers on a safe.</span>
+<span class="co"> * If this is n, the possible tumbler indices will be 0 through n-1.</span>
+<span class="co"> * */</span>
+<span class="dt">int</span> numTumblers(Safe *s);
+
+<span class="co">/* </span>
+<span class="co"> * Returns the number of positions of each tumbler.</span>
+<span class="co"> * If this is n, the possible tumbler positions will be 0 through n-1.</span>
+<span class="co"> */</span>
+<span class="dt">int</span> numPositions(Safe *s);
+
+<span class="co">/* Return codes for tryCombination */</span>
+<span class="ot">#define SAFE_BAD_COMBINATION (-1)</span>
+<span class="ot">#define SAFE_SELF_DESTRUCTED (-2)</span>
+
+<span class="co">/*</span>
+<span class="co"> * Try a combination.</span>
+<span class="co"> *</span>
+<span class="co"> * This should be an array of numTumbler(s) ints.</span>
+<span class="co"> *</span>
+<span class="co"> * Returns contents of safe (a non-negative int) if combination is correct</span>
+<span class="co"> * and safe has not yet self-destructed.</span>
+<span class="co"> *</span>
+<span class="co"> * Returns SAFE_BAD_COMBINATION if combination is incorrect</span>
+<span class="co"> * and safe has not yet self-destructed.</span>
+<span class="co"> *</span>
+<span class="co"> * Returns SAFE_SELF_DESTRUCTED if safe has self-destructed.</span>
+<span class="co"> *</span>
+<span class="co"> * Note: may modify combination.</span>
+<span class="co"> */</span>
+<span class="dt">int</span> tryCombination(Safe *s, <span class="dt">int</span> *combination);</code></pre></div>
+<a href="http://cs.yale.edu/homes/aspnes/classes/223/examples/2015/hw/2/safe.h" class="uri">examples/2015/hw/2/safe.h</a>
+</div>
+<p>The noteworthy function in this API is <code>tryCombination</code>, which takes a pointer to a safe and an array of <code>int</code>s representing the combination, and returns either the contents of the safe (an <code>int</code>), the special code <code>SAFE_BAD_COMBINATION</code> if the combination is incorrect, or the special code <code>SAFE_SELF_DESTRUCTED</code> if the safe blew up after seeing too many bad combinations. Note that <code>tryCombination</code> does not declare its second argument to be <code>const</code>
+ and may not leave it intact. The additional functions allow you to
+obtain important information about the safe, like how many tumblers it
+has and what values these tumblers can be set to. The behavior of a safe
+ given a combination with the wrong number of values or values outside
+the permitted range is undefined.</p>
+<p>Your task is to write a function <code>openSafe</code> that will open
+ a safe, if possible, by trying all possible combinations. Note that if
+the safe self-destructs before you can try all the possibilities, this
+task may not in fact be possible. Your <code>openSafe</code> function should return <code>SAFE_SELF_DESTRUCTED</code> in this case. Your function should be defined in a file <code>openSafe.c</code> and should match the declaration in this file:</p>
+<div>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"><span class="co">/* Include safe.h before this file to get the definition of Safe. */</span>
+
+<span class="co">/*</span>
+<span class="co"> * Open a safe and return the value returned by tryCombination,</span>
+<span class="co"> * or SAFE_SELF_DESTRUCTED if the safe self-destructed.</span>
+<span class="co"> */</span>
+<span class="dt">int</span> openSafe(Safe *s);</code></pre></div>
+<a href="http://cs.yale.edu/homes/aspnes/classes/223/examples/2015/hw/2/openSafe.h" class="uri">examples/2015/hw/2/openSafe.h</a>
+</div>
+<p>It is recommended that you put the lines below in your <code>openSafe.c</code> file to ensure consistency with these declarations:</p>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"><span class="ot">#include "safe.h"</span>
+<span class="ot">#include "openSafe.h"</span></code></pre></div>
+<p>You may put additional functions in <code>openSafe.c</code> if that would be helpful. You should declare these <code>static</code> to avoid the possibility of namespace conflicts.</p>
+<p>In addition to <code>safe.h</code> and <code>openSafe.h</code>, <code>/c/cs223/Hwk2/sourceFiles</code> also contains a <a href="http://cs.yale.edu/homes/aspnes/classes/223/examples/2015/hw/2/main.c">main.c</a> file that can be compiled together with <code>openSafe.c</code>
+ to generate a program that can be called from the command line. This
+program generates a safe with a pseudorandom combination based on
+parameters specified on the command line, runs your <code>openSafe</code> routine on it, and prints the value that <code>openSafe</code> returns. You should not rely on your function being tested with this particular program.</p>
+<h3 id="submitting-your-assignment-1"><span class="header-section-number">8.2.2</span> Submitting your assignment</h3>
+<p>Submit your assignment as usual with</p>
+<pre><code>/c/cs223/bin/submit 2 openSafe.c</code></pre>
+<p>You do not need to submit any other files (and the test script will ignore them if you do).</p>
+<p>You can test that your program compiles and passes a few basic tests with the command</p>
+<pre><code>/c/cs223/bin/testit 2 openSafe</code></pre>
+<p>This runs the test script in <code>/c/cs223/Hwk2/test.openSafe</code> on your submitted assignment. You can also run this script by hand to test the version of <code>openSafe.c</code> in your current working directory.</p>
+<h3 id="hw2valgrind"><span class="header-section-number">8.2.3</span> Valgrind</h3>
+<p>You may need to allocate storage using <code>malloc</code> to complete this assignment. If you do so, you should make sure that you call <code>free</code> on any block you allocate inside your <code>openSafe</code> function before the function returns. The <code>test.openSafe</code> script attempts to detect storage leaks or other problems resulting from misuse of these routines by running your program with <a href="#valgrind">valgrind</a>. You can also use <code>valgrind</code> yourself to track down the source of errors, particularly if you remember to compile with debugging info turned on using the <code>-g3</code> option to <code>gcc</code>. The script <code>/c/cs223/bin/vg</code> gives a shortcut for running <code>valgrind</code> with some of the more useful options.</p>
+<h3 id="hw2Solution"><span class="header-section-number">8.2.4</span> Sample solution</h3>
+<div>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"><span class="ot">#include &lt;stdlib.h&gt;</span>
+<span class="ot">#include &lt;assert.h&gt;</span>
+
+<span class="ot">#include "safe.h"</span>
+<span class="ot">#include "openSafe.h"</span>
+
+<span class="co">/* set combination to all zeros */</span>
+<span class="dt">static</span> <span class="dt">void</span>
+zeroCombination(<span class="dt">int</span> n, <span class="dt">int</span> *combination)
+{
+ <span class="dt">int</span> i;
+
+ <span class="kw">for</span>(i = <span class="dv">0</span>; i &lt; n; i++) {
+ combination[i] = <span class="dv">0</span>;
+ }
+}
+
+<span class="co">/* non-destructive version of tryCombination */</span>
+<span class="dt">static</span> <span class="dt">int</span>
+nondestructiveTryCombination(Safe *s, <span class="dt">const</span> <span class="dt">int</span> *combination)
+{
+ <span class="dt">int</span> *copy; <span class="co">/* duplicate of combination */</span>
+ <span class="dt">int</span> result; <span class="co">/* result of tryCombination */</span>
+ <span class="dt">int</span> n; <span class="co">/* number of tumblers */</span>
+ <span class="dt">int</span> i;
+
+ n = numTumblers(s);
+
+ copy = (<span class="dt">int</span> *) malloc(<span class="kw">sizeof</span>(<span class="dt">int</span>) * n);
+
+ <span class="kw">for</span>(i = <span class="dv">0</span>; i &lt; n; i++) {
+ copy[i] = combination[i];
+ }
+
+ result = tryCombination(s, copy);
+
+ free(copy);
+
+ <span class="kw">return</span> result;
+}
+
+<span class="co">/* update combination to next value */</span>
+<span class="dt">static</span> <span class="dt">void</span>
+nextCombination(<span class="dt">int</span> n, <span class="dt">int</span> base, <span class="dt">int</span> *combination)
+{
+ <span class="dt">int</span> i;
+
+ <span class="co">/* we are essentially incrementing an n-digit number in given base */</span>
+ <span class="co">/* this means setting any digit that overflows to 0 and continuing */</span>
+ <span class="co">/* until we get a digit we can increment without carrying */</span>
+ <span class="kw">for</span>(i = <span class="dv">0</span>; i &lt; n &amp;&amp; ++(combination[i]) &gt;= base; i++) {
+ combination[i] = <span class="dv">0</span>;
+ }
+}
+
+
+<span class="dt">int</span>
+openSafe(Safe *s)
+{
+ <span class="dt">int</span> *combination; <span class="co">/* counter for combinations */</span>
+ <span class="dt">int</span> n; <span class="co">/* number of tumblers */</span>
+ <span class="dt">int</span> base; <span class="co">/* number of positions */</span>
+ <span class="dt">int</span> result; <span class="co">/* result of tryCombination */</span>
+
+ <span class="co">/* allocate space */</span>
+ n = numTumblers(s);
+ base = numPositions(s);
+
+ combination = malloc(<span class="kw">sizeof</span>(<span class="dt">int</span>) * n);
+ assert(combination);
+
+ <span class="kw">for</span>(zeroCombination(n, combination);
+ (result = nondestructiveTryCombination(s, combination)) == SAFE_BAD_COMBINATION;
+ nextCombination(n, base, combination));
+
+ free(combination);
+ <span class="kw">return</span> result;
+}</code></pre></div>
+<a href="http://cs.yale.edu/homes/aspnes/classes/223/examples/2015/hw/2/openSafe.c" class="uri">examples/2015/hw/2/openSafe.c</a>
+</div>
+<h2 id="hw3"><span class="header-section-number">8.3</span> Assignment 3, due Wednesday 2015-02-11, at 11:00pm</h2>
+<h3 id="quadratic-letter-sequences"><span class="header-section-number">8.3.1</span> Quadratic letter sequences</h3>
+<p>Given a string <span class="math inline"><em>s</em></span>, an <strong>quadratic letter sequence</strong> for <span class="math inline"><em>s</em></span> is defined by giving non-negative integer coefficients <span class="math inline"><em>c</em><sub>0</sub>, <em>c</em><sub>1</sub>, <em>c</em><sub>2</sub></span>, where at least one of <span class="math inline"><em>c</em><sub>1</sub></span> and <span class="math inline"><em>c</em><sub>2</sub></span> is not zero, and computing the sequence of letters <span class="math inline"><em>s</em>[<em>c</em><sub>0</sub> + <em>c</em><sub>1</sub> ⋅ <em>i</em> + <em>c</em><sub>2</sub> ⋅ <em>i</em><sup>2</sup>]</span> for <span class="math inline"><em>i</em> = 0, 1, 2, …</span>.</p>
+<p>These can be used to hide secret message inside larger texts. For
+example, the famous Napoleonic palindrome "Able was I ere I saw Elba"
+hides the word "bIb" at positions 1, 9, and 23, which are generated by <span class="math inline"><em>c</em><sub>0</sub> = 1</span>, <span class="math inline"><em>c</em><sub>1</sub> = 5</span> and <span class="math inline"><em>c</em><sub>2</sub> = 3</span>:</p>
+<table>
+<thead>
+<tr class="header">
+<th align="left"><span class="math inline"><em>i</em></span></th>
+<th align="left"><span class="math inline"><em>c</em><sub>0</sub> + <em>c</em><sub>1</sub><em>i</em> + <em>c</em><sub>2</sub><em>i</em><sup>2</sup></span></th>
+</tr>
+</thead>
+<tbody>
+<tr class="odd">
+<td align="left">0</td>
+<td align="left"><span class="math inline">1 = 1 + 5 ⋅ 0 + 3 ⋅ 0</span></td>
+</tr>
+<tr class="even">
+<td align="left">1</td>
+<td align="left"><span class="math inline">9 = 1 + 5 ⋅ 1 + 3 ⋅ 1<sup>2</sup></span></td>
+</tr>
+<tr class="odd">
+<td align="left">2</td>
+<td align="left"><span class="math inline">23 = 1 + 5 ⋅ 2 + 3 ⋅ 2<sup>2</sup></span></td>
+</tr>
+</tbody>
+</table>
+<p>Similarly, we can use quadratic letter sequences to reveal secret messages hidden in the <a href="http://cs.yale.edu/homes/aspnes/classes/223/examples/2015/hw/3/gangnam-style-excerpt.txt">lyrics of K-pop songs</a>:</p>
+<pre><code>$ ./qls hail satan &lt; gangnam-style-excerpt.txt
+470 3 5 hail
+14 10 30 satan
+14 56 7 satan</code></pre>
+<p>or even examine <a href="http://cs.yale.edu/homes/aspnes/classes/223/examples/2015/hw/3/tempest-act-one.txt">Act 1 of <em>The Tempest</em></a> to help resolve the <a href="http://en.wikipedia.org/wiki/Shakespeare_authorship_question">Shakespeare authorship question</a>:<a href="#fn27" class="footnoteRef" id="fnref27"><sup>27</sup></a></p>
+<pre><code>$ ./qls "Bacon" "de Vere" "Marlowe" "Stanley" "that Stratford dude" &lt; tempest-act-one.txt
+120 387 777 Bacon
+120 542 906 Bacon
+120 851 850 Bacon
+120 1592 726 Bacon
+120 1607 472 Bacon
+120 2461 95 Bacon
+120 2729 50 Bacon
+120 3225 215 Bacon
+120 3420 284 Bacon
+120 4223 330 Bacon
+120 4534 76 Bacon
+120 5803 29 Bacon
+143 46 161 Bacon
+143 268 727 Bacon
+143 684 1434 Bacon
+[... 280 more lines of Bacon omitted ...]
+19959 1178 87 Bacon
+5949 239 465 Marlowe</code></pre>
+<h3 id="your-task-1"><span class="header-section-number">8.3.2</span> Your task</h3>
+<p>Write a program <code>qls.c</code> that takes a text on <code>stdin</code> and searches for quadratic letter sequences that start with the strings given in <code>argv</code>. Your program should output all such quadratic letter sequences that it finds, using the format</p>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"> printf(<span class="st">"%d %d %d %s</span><span class="ch">\n</span><span class="st">"</span>, [...]);</code></pre></div>
+<p>where <code>[...]</code> should be replaced by appropriate expressions to give <span class="math inline"><em>c</em><sub>0</sub></span>, <span class="math inline"><em>c</em><sub>1</sub></span>, <span class="math inline"><em>c</em><sub>2</sub></span>, and the string found.</p>
+<p>If a string appears more than once at the start of a quadratic letter
+ sequence, your program should print all occurrences. The order your
+output lines appear in is not important, since the test script sorts
+them into a canonical order. Do whatever is convenient.</p>
+<p>Your program should be reasonably efficient, but you do not need to
+get carried away looking for a sophisticated algorithm for this problem.
+ Simply testing all plausible combinations of coefficients should be
+enough.</p>
+<p>Because neither K-pop songs nor Elizabethan plays use null
+characters, you may assume that no null characters appear in your input.</p>
+<p>You may also assume that any search strings will contain at least two characters, in order to keep the number of outputs finite.</p>
+<h3 id="submitting-your-assignment-2"><span class="header-section-number">8.3.3</span> Submitting your assignment</h3>
+<p>Submit your assignment as usual with</p>
+<pre><code>/c/cs223/bin/submit 3 qls.c</code></pre>
+<p>You can run some basic tests on your submitted solution with</p>
+<pre><code>/c/cs223/bin/testit 3 qls</code></pre>
+<p>The test program is also available as <code>/c/cs223/Hwk3/test.qls</code>. Sample inputs and outputs can be found in <code>/c/cs223/Hwk3/testFiles</code>. The title of each file contains the test strings used, separated by <code>-</code> characters. Before comparing the output of your program to the output files, you may find it helpful to run it through <code>sort</code>, e.g.</p>
+<pre><code>./qls hail satan &lt; hail-satan.in | sort &gt; test.out
+diff test.out hail-satan.out</code></pre>
+<h3 id="hw3Solution"><span class="header-section-number">8.3.4</span> Sample solution</h3>
+<div>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"><span class="co">/*</span>
+<span class="co"> * Search for quadratic letter sequences starting with words from argv on stdin.</span>
+<span class="co"> *</span>
+<span class="co"> * A quadratic letter sequence of length n in s is a sequence of characters</span>
+<span class="co"> *</span>
+<span class="co"> * s[c0 + c1*i + c2*i*i]</span>
+<span class="co"> *</span>
+<span class="co"> * where c0, c1, c2 are all &gt;= 0, at least one of c1 and c2 is &gt; 0,</span>
+<span class="co"> * and i ranges over 0, 1, 2, ..., n-1.</span>
+<span class="co"> *</span>
+<span class="co"> * For each QLS found, prints c0, c1, c2, and the target string to stdout.</span>
+<span class="co"> */</span>
+
+<span class="ot">#include &lt;stdio.h&gt;</span>
+<span class="ot">#include &lt;stdlib.h&gt;</span>
+<span class="ot">#include &lt;string.h&gt;</span>
+<span class="ot">#include &lt;assert.h&gt;</span>
+
+<span class="ot">#define NUM_COEFFICIENTS (3) </span><span class="co">/* how many coefficients to pass around */</span>
+
+<span class="co">/*</span>
+<span class="co"> * Return true iff we get a match in s for t with coefficients c</span>
+<span class="co"> *</span>
+<span class="co"> * Behavior is undefined if coefficients would send us off the end of s.</span>
+<span class="co"> */</span>
+<span class="dt">static</span> <span class="dt">int</span>
+qlsMatch(<span class="dt">const</span> <span class="dt">char</span> *s, <span class="dt">const</span> <span class="dt">char</span> *t, <span class="dt">int</span> c[NUM_COEFFICIENTS])
+{
+ <span class="dt">int</span> i;
+
+ <span class="kw">for</span>(i = <span class="dv">0</span>; t[i] != '\<span class="dv">0</span>'; i++) {
+ <span class="kw">if</span>(s[c[<span class="dv">0</span>] + c[<span class="dv">1</span>] * i + c[<span class="dv">2</span>] * i * i] != t[i]) {
+ <span class="co">/* no match */</span>
+ <span class="kw">return</span> <span class="dv">0</span>;
+ }
+ }
+
+ <span class="kw">return</span> <span class="dv">1</span>;
+}
+
+<span class="co">/* </span>
+<span class="co"> * Search for quadratic letter sequences in s starting with t</span>
+<span class="co"> * and print results to stdout.</span>
+<span class="co"> */</span>
+<span class="dt">static</span> <span class="dt">void</span>
+qlsSearch(<span class="dt">const</span> <span class="dt">char</span> *s, <span class="dt">const</span> <span class="dt">char</span> *t)
+{
+ <span class="dt">int</span> c[NUM_COEFFICIENTS]; <span class="co">/* coefficients */</span>
+ <span class="dt">int</span> lenS; <span class="co">/* length of s */</span>
+ <span class="dt">int</span> lenT; <span class="co">/* length of t */</span>
+ <span class="dt">int</span> maxI; <span class="co">/* maximum value for i (this is lenT-1) */</span>
+
+ lenS = strlen(s);
+ lenT = strlen(t);
+ maxI = lenT<span class="dv">-1</span>;
+
+ <span class="co">/* try all possible c[0] that will let us finish before lenS */</span>
+ <span class="kw">for</span>(c[<span class="dv">0</span>] = <span class="dv">0</span>; c[<span class="dv">0</span>] + maxI &lt; lenS; c[<span class="dv">0</span>]++) {
+ <span class="co">/* if s[c[0]] isn't right, c[1] and c[2] can't fix it */</span>
+ <span class="kw">if</span>(s[c[<span class="dv">0</span>]] == t[<span class="dv">0</span>]) {
+ <span class="co">/* try all feasible c[1] */</span>
+ <span class="kw">for</span>(c[<span class="dv">1</span>] = <span class="dv">0</span>; c[<span class="dv">0</span>] + c[<span class="dv">1</span>] * maxI &lt; lenS; c[<span class="dv">1</span>]++) {
+ <span class="co">/* try all feasible c[2], but start at 1 if c[1] == 0 */</span>
+ <span class="kw">for</span>(c[<span class="dv">2</span>] = (c[<span class="dv">1</span>] == <span class="dv">0</span>); c[<span class="dv">0</span>] + c[<span class="dv">1</span>] * maxI + c[<span class="dv">2</span>] * maxI * maxI &lt; lenS; c[<span class="dv">2</span>]++) {
+ <span class="co">/* now see if we get a match */</span>
+ <span class="kw">if</span>(qlsMatch(s, t, c)) {
+ printf(<span class="st">"%d %d %d %s</span><span class="ch">\n</span><span class="st">"</span>, c[<span class="dv">0</span>], c[<span class="dv">1</span>], c[<span class="dv">2</span>], t);
+ }
+ }
+ }
+ }
+ }
+}
+
+<span class="co">/* used internally by getContents; initial size of buffer */</span>
+<span class="ot">#define INITIAL_BUFFER_SIZE (16)</span>
+
+<span class="co">/* </span>
+<span class="co"> * Return a single string holding all characters from stdin.</span>
+<span class="co"> *</span>
+<span class="co"> * This is malloc'd data that the caller should eventually free.</span>
+<span class="co"> */</span>
+<span class="dt">static</span> <span class="dt">char</span> *
+getContents(<span class="dt">void</span>)
+{
+ size_t size;
+ size_t len;
+ <span class="dt">char</span> *text;
+ <span class="dt">int</span> c;
+
+ size = INITIAL_BUFFER_SIZE;
+ len = <span class="dv">0</span>;
+
+ text = malloc(size);
+ assert(text);
+
+ <span class="kw">while</span>((c = getchar()) != EOF) {
+ <span class="co">/* grow the buffer if full */</span>
+ <span class="kw">if</span>(len &gt;= size) {
+ size *= <span class="dv">2</span>;
+ text = realloc(text, size);
+ assert(text);
+ }
+
+ text[len++] = c;
+ }
+
+ <span class="co">/* cleanup */</span>
+ text = realloc(text, len<span class="dv">+1</span>);
+ assert(text);
+
+ text[len] = '\<span class="dv">0</span>';
+
+ <span class="kw">return</span> text;
+}
+
+
+<span class="dt">int</span>
+main(<span class="dt">int</span> argc, <span class="dt">char</span> **argv)
+{
+ <span class="dt">int</span> i;
+ <span class="dt">char</span> *s;
+
+ s = getContents();
+
+ <span class="kw">for</span>(i = <span class="dv">1</span>; i &lt; argc; i++) {
+ qlsSearch(s, argv[i]);
+ }
+
+ free(s);
+
+ <span class="kw">return</span> <span class="dv">0</span>;
+}</code></pre></div>
+<a href="http://cs.yale.edu/homes/aspnes/classes/223/examples/2015/hw/3/qls.c" class="uri">examples/2015/hw/3/qls.c</a>
+</div>
+<h2 id="hw4"><span class="header-section-number">8.4</span> Assignment 4, due Wednesday 2015-02-18, at 11:00pm</h2>
+<h3 id="an-ascii-art-compositor"><span class="header-section-number">8.4.1</span> An ASCII art compositor</h3>
+<p>For this assignment you are to write a program that takes from <code>stdin</code>
+ a sequence of instructions for pasting ASCII art pictures together,
+reads those pictures from files, and writes the combined picture to <code>stdout</code>.</p>
+<p>Each instruction is of the form <em>row column filename</em>, suitable for reading with <code>scanf("%d %d %s", &amp;row, &amp;col, filename);</code>, where <code>row</code> and <code>col</code> are declared as <code>int</code>s and <code>filename</code> is a suitably large buffer of <code>char</code>s. Such an instruction means to paste the contents of file <em>filename</em> into the picture with each character shifted <em>row</em> rows down and <em>column</em> columns to the right of its position in file <em>filename</em>. When pasting an image, all characters other than space (<code>' '</code>,
+ or ASCII code 32) overwrite any characters from earlier files at the
+same position. Spaces should be treated as transparent, having no effect
+ on the final image.</p>
+<p>For example, suppose that the current directory contains these files:</p>
+<div>
+<pre><code> # # #
+\==========/
+ \......../
+</code></pre>
+<a href="http://cs.yale.edu/homes/aspnes/classes/223/examples/2015/hw/4/ship" class="uri">examples/2015/hw/4/ship</a>
+</div>
+<div>
+<pre><code> /\
+ /vv\
+/vvvv\
+ ||
+</code></pre>
+<a href="http://cs.yale.edu/homes/aspnes/classes/223/examples/2015/hw/4/tree" class="uri">examples/2015/hw/4/tree</a>
+</div>
+<div>
+<pre><code> * * *
+ ____|_|_|_____
+|_____________|
+|___HAPPY_____|
+|__BIRTHDAY___|
+|_____________|
+</code></pre>
+<a href="http://cs.yale.edu/homes/aspnes/classes/223/examples/2015/hw/4/cake" class="uri">examples/2015/hw/4/cake</a>
+</div>
+<p>Then this is what we should get from executing the command:</p>
+<pre><code>$ echo "1 1 ship 3 5 ship 3 19 tree 7 2 ship 13 4 ship 4 22 tree 5 6 cake" | ./compositor</code></pre>
+<div>
+<pre><code>
+ # # #
+ \==========/
+ \......#.# # /\
+ \==========/ /vv\/\
+ \....*.*.* /vvv/vv\
+ ____|_|_|_____|/vvvv\
+ |_____________| ||
+ \===|___HAPPY_____|
+ \..|__BIRTHDAY___|
+ |_____________|
+
+
+ # # #
+ \==========/
+ \......../
+</code></pre>
+<a href="http://cs.yale.edu/homes/aspnes/classes/223/examples/2015/hw/4/example.out" class="uri">examples/2015/hw/4/example.out</a>
+</div>
+<h3 id="submitting-your-assignment-3"><span class="header-section-number">8.4.2</span> Submitting your assignment</h3>
+<p>For this assignment, you may submit whatever source files you like, along with a file <code>Makefile</code> that will generate the program <code>compositor</code> when <code>make</code> is called with no arguments (see the <a href="#make">instructions for using make</a>.)</p>
+<p>You can test your submitted assignment using the public test script with</p>
+<pre><code>/c/cs223/bin/testit 4 public</code></pre>
+<p>You may also test your unsubmitted assignment in the current working directory with</p>
+<pre><code>/c/cs223/Hwk4/test.public</code></pre>
+<p>The test script is intended mostly to guard against trivial errors in output format and is not necessarily exhaustive.</p>
+<h3 id="notes"><span class="header-section-number">8.4.3</span> Notes</h3>
+<h4 id="input"><span class="header-section-number">8.4.3.1</span> Input</h4>
+<p>For parsing the commands on <code>stdin</code>, we recommend using <code>scanf</code>. You can test for end of file by checking if <code>scanf</code> correctly parsed all three arguments, as in</p>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"> <span class="dt">int</span> row;
+ <span class="dt">int</span> col;
+ <span class="dt">char</span> filename[BUFFER_SIZE];
+
+ <span class="kw">while</span>(scanf(<span class="st">"%d %d %s"</span>, &amp;row, &amp;col, filename) == <span class="dv">3</span>) {
+ <span class="co">/* do something with this file */</span>
+ }</code></pre></div>
+<p>You may assume that <code>row</code> and <code>col</code> are always non-negative.</p>
+<p>Your program should exit with a non-zero error code if it cannot open a file for reading. Because <code>scanf</code>'s <code>%s</code>
+ conversion specifier only reads up to the next whitespace character,
+you may assume that filenames do not contain whitespace. You may also
+assume that no filename appearing in the input will require more than
+2048 bytes to store (including the terminal null character).<a href="#fn28" class="footnoteRef" id="fnref28"><sup>28</sup></a></p>
+<p>You may assume that the input contains no null characters.</p>
+<h4 id="output"><span class="header-section-number">8.4.3.2</span> Output</h4>
+<p>Your output should include newline and space characters to put the
+composited characters in the appropriate rows and columns. It should not
+ include any more of such characters than are absolutely necessary.</p>
+<p>For example, there should never be a space at the end of a line (even
+ if there is a space at the end of a line in one of the input files).
+Similarly, there should not be any blank lines at the end of your
+output. You may, however, find it necessary to add a newline to the end
+of the last line to avoid having the output end in the middle of a line.</p>
+<h4 id="general"><span class="header-section-number">8.4.3.3</span> General</h4>
+<p>You may assume that the final picture is not so big that you can't store a row or column number for one of its characters in an <code>int</code>.</p>
+<h3 id="hw4Solution"><span class="header-section-number">8.4.4</span> Sample solution</h3>
+<p>I wrote two versions of this. <a href="http://cs.yale.edu/homes/aspnes/classes/223/examples/2015/hw/4/jaggedArray">The first</a>
+ used a jagged array to represent an image, but I decided I didn't like
+it and did another version using a sorted linked list of points. This
+second version is shown below.</p>
+<div>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"><span class="co">/*</span>
+<span class="co"> * Alternate version of ASCII art thing using a queue.</span>
+<span class="co"> */</span>
+
+<span class="ot">#include &lt;stdio.h&gt;</span>
+<span class="ot">#include &lt;stdlib.h&gt;</span>
+<span class="ot">#include &lt;assert.h&gt;</span>
+
+<span class="co">/*</span>
+<span class="co"> * Idea of this data structure is that we have a sorted array</span>
+<span class="co"> * of pixels, where each pixel specifies a row, column, and character</span>
+<span class="co"> * to put in that position. The sort order is row then column.</span>
+<span class="co"> *</span>
+<span class="co"> * This is organized as a queue in the sense that we can push</span>
+<span class="co"> * new pixels on to the end of it, although as it happens we</span>
+<span class="co"> * never actually dequeue anything.</span>
+<span class="co"> */</span>
+<span class="kw">struct</span> pixel {
+ <span class="dt">int</span> row;
+ <span class="dt">int</span> col;
+ <span class="dt">char</span> value;
+};
+
+<span class="kw">struct</span> queue {
+ size_t top; <span class="co">/* number of elements */</span>
+ size_t size; <span class="co">/* number of allocated slots */</span>
+ <span class="kw">struct</span> pixel *pixels; <span class="co">/* pixel values, sorted by row then column */</span>
+};
+
+<span class="ot">#define QUEUE_INITIAL_SIZE (16)</span>
+
+<span class="co">/* create new empty queue */</span>
+<span class="kw">struct</span> queue *
+queueCreate(<span class="dt">void</span>)
+{
+ <span class="kw">struct</span> queue *q;
+
+ q = malloc(<span class="kw">sizeof</span>(<span class="kw">struct</span> queue));
+ assert(q);
+
+ q-&gt;top = <span class="dv">0</span>;
+ q-&gt;size = QUEUE_INITIAL_SIZE;
+
+ q-&gt;pixels = malloc(<span class="kw">sizeof</span>(<span class="kw">struct</span> pixel) * q-&gt;size);
+ assert(q-&gt;pixels);
+
+ <span class="kw">return</span> q;
+}
+
+<span class="co">/* clean up queue */</span>
+<span class="dt">void</span>
+queueDestroy(<span class="kw">struct</span> queue *q)
+{
+ free(q-&gt;pixels);
+ free(q);
+}
+
+<span class="co">/* add a new pixel to queue */</span>
+<span class="dt">void</span>
+queuePush(<span class="kw">struct</span> queue *q, <span class="kw">struct</span> pixel p)
+{
+ <span class="kw">while</span>(q-&gt;top &gt;= q-&gt;size) {
+ q-&gt;size *= <span class="dv">2</span>;
+ q-&gt;pixels = realloc(q-&gt;pixels, <span class="kw">sizeof</span>(<span class="kw">struct</span> pixel) * q-&gt;size);
+ assert(q-&gt;pixels);
+ }
+
+ q-&gt;pixels[q-&gt;top++] = p;
+}
+
+<span class="co">/* returns malloc'd data, free with queueDestroy */</span>
+<span class="kw">struct</span> queue *
+queueRead(<span class="dt">const</span> <span class="dt">char</span> *filename)
+{
+ FILE *f;
+ <span class="kw">struct</span> queue *q;
+ <span class="kw">struct</span> pixel p;
+ <span class="dt">int</span> c;
+
+ q = queueCreate();
+
+ f = fopen(filename, <span class="st">"r"</span>);
+ <span class="kw">if</span>(f == <span class="dv">0</span>) {
+ perror(filename);
+ exit(<span class="dv">1</span>);
+ }
+
+ p.row = p.col = <span class="dv">0</span>;
+
+ <span class="kw">while</span>((c = getc(f)) != EOF) {
+ <span class="kw">switch</span>(c) {
+ <span class="kw">case</span> <span class="ch">'\n'</span>:
+ p.row++;
+ p.col = <span class="dv">0</span>;
+ <span class="kw">break</span>;
+ <span class="kw">case</span> ' ':
+ p.col++;
+ <span class="kw">break</span>;
+ <span class="kw">default</span>:
+ p.value = c;
+ queuePush(q, p);
+ p.col++;
+ <span class="kw">break</span>;
+ }
+ }
+
+ fclose(f);
+
+ <span class="kw">return</span> q;
+}
+
+<span class="co">/* write pixels in queue to stdout */</span>
+<span class="dt">void</span>
+queueWrite(<span class="dt">const</span> <span class="kw">struct</span> queue *q)
+{
+ <span class="dt">int</span> outputRow = <span class="dv">0</span>;
+ <span class="dt">int</span> outputCol = <span class="dv">0</span>;
+ <span class="dt">int</span> i;
+
+ <span class="kw">for</span>(i = <span class="dv">0</span>; i &lt; q-&gt;top; i++) {
+ <span class="kw">while</span>(outputRow &lt; q-&gt;pixels[i].row) {
+ putchar(<span class="ch">'\n'</span>);
+ outputRow++;
+ outputCol = <span class="dv">0</span>;
+ }
+ <span class="kw">while</span>(outputCol &lt; q-&gt;pixels[i].col) {
+ putchar(' ');
+ outputCol++;
+ }
+ putchar(q-&gt;pixels[i].value);
+ outputCol++;
+ }
+
+ <span class="co">/* end last row */</span>
+ putchar(<span class="ch">'\n'</span>);
+}
+
+<span class="co">/* </span>
+<span class="co"> * Merge two queues, creating a new, freshly-allocated queue.</span>
+<span class="co"> * New queue is sorted. If there are pixels in both left </span>
+<span class="co"> * and right with the same row and column, the one from right</span>
+<span class="co"> * overwrites the one from left.</span>
+<span class="co"> */</span>
+<span class="kw">struct</span> queue *
+queueMerge(<span class="dt">const</span> <span class="kw">struct</span> queue *left, <span class="dt">const</span> <span class="kw">struct</span> queue *right)
+{
+ <span class="dt">int</span> l = <span class="dv">0</span>;
+ <span class="dt">int</span> r = <span class="dv">0</span>;
+ <span class="kw">struct</span> queue *q;
+
+ q = queueCreate();
+
+ <span class="kw">while</span>(l &lt; left-&gt;top &amp;&amp; r &lt; right-&gt;top) {
+ <span class="kw">if</span>(left-&gt;pixels[l].row &lt; right-&gt;pixels[r].row) {
+ queuePush(q, left-&gt;pixels[l++]);
+ } <span class="kw">else</span> <span class="kw">if</span>(left-&gt;pixels[l].row == right-&gt;pixels[r].row) {
+ <span class="kw">if</span>(left-&gt;pixels[l].col &lt; right-&gt;pixels[r].col) {
+ queuePush(q, left-&gt;pixels[l++]);
+ } <span class="kw">else</span> <span class="kw">if</span>(left-&gt;pixels[l].col == right-&gt;pixels[r].col) {
+ <span class="co">/* right wins but both increment */</span>
+ queuePush(q, right-&gt;pixels[r++]);
+ l++;
+ } <span class="kw">else</span> {
+ <span class="co">/* right is earlier */</span>
+ queuePush(q, right-&gt;pixels[r++]);
+ }
+ } <span class="kw">else</span> {
+ <span class="co">/* right is earlier */</span>
+ queuePush(q, right-&gt;pixels[r++]);
+ }
+ }
+
+ <span class="co">/* clean out whichever tail is still nonempty */</span>
+ <span class="kw">while</span>(l &lt; left-&gt;top) {
+ queuePush(q, left-&gt;pixels[l++]);
+ }
+
+ <span class="kw">while</span>(r &lt; right-&gt;top) {
+ queuePush(q, right-&gt;pixels[r++]);
+ }
+
+ <span class="kw">return</span> q;
+}
+
+<span class="co">/* in-place offset by r rows and c columns */</span>
+<span class="dt">void</span>
+queueOffset(<span class="kw">struct</span> queue *q, <span class="dt">int</span> r, <span class="dt">int</span> c)
+{
+ <span class="dt">int</span> i;
+
+ <span class="kw">for</span>(i = <span class="dv">0</span>; i &lt; q-&gt;top; i++) {
+ q-&gt;pixels[i].row += r;
+ q-&gt;pixels[i].col += c;
+ }
+}
+
+<span class="co">/* max filename size as promised in assignment text */</span>
+<span class="ot">#define BUFFER_SIZE (2048)</span>
+
+<span class="dt">int</span>
+main(<span class="dt">int</span> argc, <span class="dt">char</span> **argv)
+{
+ <span class="kw">struct</span> queue *merged; <span class="co">/* holding place for result of merge */</span>
+ <span class="kw">struct</span> queue *left; <span class="co">/* accumulated picture */</span>
+ <span class="kw">struct</span> queue *right; <span class="co">/* new picture */</span>
+ <span class="dt">int</span> row; <span class="co">/* row offset for new picture */</span>
+ <span class="dt">int</span> col; <span class="co">/* column offset for new picture */</span>
+ <span class="dt">char</span> filename[BUFFER_SIZE]; <span class="co">/* filename for new picture */</span>
+
+ <span class="kw">if</span>(argc != <span class="dv">1</span>) {
+ fprintf(stderr, <span class="st">"Usage: %s</span><span class="ch">\n</span><span class="st">"</span>, argv[<span class="dv">0</span>]);
+ <span class="kw">return</span> <span class="dv">1</span>;
+ }
+
+ <span class="kw">for</span>(left = queueCreate(); scanf(<span class="st">"%d %d %s"</span>, &amp;row, &amp;col, filename) == <span class="dv">3</span>; left = merged) {
+ right = queueRead(filename);
+ queueOffset(right, row, col);
+
+ merged = queueMerge(left, right);
+
+ queueDestroy(left);
+ queueDestroy(right);
+ }
+
+ queueWrite(left);
+
+ queueDestroy(left);
+
+ <span class="kw">return</span> <span class="dv">0</span>;
+}</code></pre></div>
+<a href="http://cs.yale.edu/homes/aspnes/classes/223/examples/2015/hw/4/compositor.c" class="uri">examples/2015/hw/4/compositor.c</a>
+</div>
+<p>Here is a <a href="http://cs.yale.edu/homes/aspnes/classes/223/examples/2015/hw/4/Makefile">Makefile</a>.</p>
+<h2 id="hw5"><span class="header-section-number">8.5</span> Assignment 5, due Wednesday 2015-02-25, at 11:00pm</h2>
+<h3 id="build-a-turing-machine"><span class="header-section-number">8.5.1</span> Build a Turing machine!</h3>
+<p>A <strong>Turing machine</strong> is a hypothetical computational device that consists of a little trolley, called the <strong>controller</strong>,
+ that rolls around on an infinite paper tape on which it can write
+letters. The controller itself has a small number of states that affect
+its behavior, and a program that tells it what to do when it is in a
+particular state and sees a particular letter.</p>
+<p>In C terms, we can think of a Turing machine as consisting of an infinite array of <code>char</code>s (representing the tape), an integer index into the array (representing the current position of the controller), and an <code>int</code> (representing the current state of the controller). At each step, the machine</p>
+<ol style="list-style-type: decimal">
+<li>Looks at the symbol <span class="math inline"><em>s</em></span> on the current tape cell.</li>
+<li>Looks up its state <span class="math inline"><em>q</em></span> and symbol <span class="math inline"><em>s</em></span> in the table representing its program. This table will specify an action, which consists of three parts:
+<ol style="list-style-type: lower-alpha">
+<li>A new symbol to write to the current tape cell.</li>
+<li>A direction <code>-</code> or <code>+</code> to move.</li>
+<li>A new state to switch to.</li>
+</ol></li>
+</ol>
+<p>If the new state is 0, the machine halts and takes no more steps.</p>
+<p>For this assignment, you are to write a Turing machine simulator. The program for machine will be supplied in <code>argv</code>; <code>argv[i]</code> will give the behavior of the machine when in state <code>i</code>, where the first three characters specify what to do if the machine sees an <code>'a'</code>, the second three characters specify what to do if the machine sees a <code>'b'</code>, and so on. Each of these three-letter groups will look like <em>(new-symbol,direction,new-state)</em>, where <em>new-symbol</em> is the new symbol to write (a lower-case letter), <em>direction</em> is the direction to move (<code>'+'</code>, meaning one position to the right, or <code>'-'</code>, meaning one position to the left) and <em>new-state</em>
+ is the new state to go to (a digit). Your program should run this
+program starting in state 1 on some location in the middle of a tape
+initially made up entirely of <code>'a'</code> characters, and continue
+until the program enters the special halting state 0. It should then
+print the number of steps until this occurred.</p>
+<p>You may assume that the program is <code>argv</code> is complete in
+the sense that it includes rules for any combination of state and symbol
+ you will encounter while executing it. You are not required to detect
+if this assumption is violated.</p>
+<h3 id="example-1"><span class="header-section-number">8.5.2</span> Example</h3>
+<p>The program</p>
+<pre><code>b+2a-0 a-1a-1</code></pre>
+<p>gives instructions for what to do in state 1 (<code>b+2a-0</code>) and state 2 (<code>a-1a-1</code>). In state 1, if the controller reads an <code>a</code>, the triple <code>b+2</code> means that it should write <code>b</code>, move right (<code>+</code>), and switch to state 2. If instead it reads a <code>b</code>, the triple <code>a-0</code> means that it should write <code>a</code>, move left (<code>-</code>), and halt (<code>0</code>). In state 2, the machine always writes <code>a</code>, moves left, and switches to state 1.</p>
+<p>Below is a depiction of this machine's execution. It passes through 4
+ states (including both the initial state and the final halting state)
+using a total of 3 steps. The controller and its current state is shown
+above its current position on the tape at each point in time. To avoid
+having to put in infinitely long lines, only the middle three tape cells
+ are shown.</p>
+<pre><code> 1
+aaa
+
+ 2
+aba
+
+ 1
+aba
+
+0
+aaa</code></pre>
+<h3 id="your-task-2"><span class="header-section-number">8.5.3</span> Your task</h3>
+<p>You should submit a <code>Makefile</code> and whatever source files are needed to generate a program <code>./turing</code> when <code>make</code> is called with no arguments. The <code>turing</code>
+ program should simulate a Turing machine as described above and print
+the number of steps that it takes until it halts in decimal format,
+followed by a newline. It should not produce any other output. For
+example, using the program above, your program should print 3:</p>
+<pre><code>$ ./turing b+2a-0 a-1a-1
+3</code></pre>
+<p>For more complex programs you may get different results. Here is a 3 state, 3 symbol program that runs for a bit longer:</p>
+<pre><code>$ ./turing b+2a-0c-3 b-3c+2b-2 b-1a+2c-1
+92649163</code></pre>
+<p>You may assume that tape symbols can always be represented by
+lowercase letters, that states can always be represented by single
+digits, and that <code>argv</code> is in the correct format (although it may be worth including a few sanity checks in your program just in case).</p>
+<p>Not all Turing machine programs will halt. Your program is not
+required to detect if the Turing machine it is simulating will halt
+eventually or not (although it should notice if it does halt).</p>
+<h3 id="submitting-your-assignment-4"><span class="header-section-number">8.5.4</span> Submitting your assignment</h3>
+<p>Submit all files needed to build your program as usual using <code>/c/cs223/bin/submit 5</code> <em>filename</em>.</p>
+<p>There is a public test script in <code>/c/cs223/Hwk5/test.public</code>. You can run this on your submitted files with <code>/c/cs223/bin/testit 5 public</code>.</p>
+<h3 id="hw5Solution"><span class="header-section-number">8.5.5</span> Sample solution</h3>
+<div>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"><span class="co">/*</span>
+<span class="co"> * Simple Turing machine simulator.</span>
+<span class="co"> *</span>
+<span class="co"> * Tape holds symbols 0 (default) through 2.</span>
+<span class="co"> *</span>
+<span class="co"> * Controller programming is specified in argv:</span>
+<span class="co"> *</span>
+<span class="co"> * argv[i] gives transitions for state i as six characters.</span>
+<span class="co"> *</span>
+<span class="co"> * Each triple of characters is &lt;action&gt;&lt;direction&gt;&lt;new-state&gt;</span>
+<span class="co"> *</span>
+<span class="co"> * where &lt;action&gt; is one of:</span>
+<span class="co"> *</span>
+<span class="co"> * a,b,c: write this value to tape</span>
+<span class="co"> *</span>
+<span class="co"> * &lt;direction&gt; is one of:</span>
+<span class="co"> *</span>
+<span class="co"> * -: go left</span>
+<span class="co"> * +: go right</span>
+<span class="co"> * .: stay put</span>
+<span class="co"> *</span>
+<span class="co"> * The three pairs give the transition for reading 0, 1, 2 from tape.</span>
+<span class="co"> *</span>
+<span class="co"> * State 0 is the halting state.</span>
+<span class="co"> *</span>
+<span class="co"> * On halting, prints number of transitions followed by contents</span>
+<span class="co"> * of all tape cells that have ever been visited by the </span>
+<span class="co"> * finite-state controller.</span>
+<span class="co"> */</span>
+
+<span class="ot">#include &lt;stdio.h&gt;</span>
+<span class="ot">#include &lt;stdlib.h&gt;</span>
+<span class="ot">#include &lt;string.h&gt;</span>
+<span class="ot">#include &lt;assert.h&gt;</span>
+<span class="ot">#include &lt;sys/types.h&gt;</span>
+
+<span class="kw">struct</span> configuration {
+ <span class="dt">unsigned</span> <span class="dt">int</span> state;<span class="co">/* state of head */</span>
+ size_t leftmost; <span class="co">/* leftmost cell visited */</span>
+ size_t rightmost; <span class="co">/* rightmost cell visited */</span>
+ size_t current; <span class="co">/* current cell */</span>
+ size_t tapeLength; <span class="co">/* current allocated space for tape */</span>
+ <span class="dt">char</span> *tape; <span class="co">/* contents of cells */</span>
+};
+
+<span class="co">/* increase the size of the tape and recenter contents in middle */</span>
+<span class="dt">void</span>
+configurationExpand(<span class="kw">struct</span> configuration *c)
+{
+ size_t newTapeLength;
+ <span class="dt">char</span> *oldTape;
+ <span class="dt">char</span> *newTape;
+ size_t i;
+ ssize_t offset;
+
+ newTapeLength = <span class="dv">4</span>*c-&gt;tapeLength;
+ newTape = malloc(newTapeLength);
+ assert(newTape);
+
+ <span class="kw">for</span>(i = <span class="dv">0</span>; i &lt; newTapeLength; i++) {
+ newTape[i] = <span class="dv">0</span>;
+ }
+
+ <span class="co">/* copy old tape */</span>
+ offset = newTapeLength / <span class="dv">2</span> - c-&gt;current;
+
+ <span class="kw">for</span>(i = c-&gt;leftmost; i &lt;= c-&gt;rightmost; i++) {
+ newTape[i + offset] = c-&gt;tape[i];
+ }
+
+ oldTape = c-&gt;tape;
+ c-&gt;tape = newTape;
+ c-&gt;tapeLength = newTapeLength;
+ c-&gt;current += offset;
+ c-&gt;leftmost += offset;
+ c-&gt;rightmost += offset;
+
+ free(oldTape);
+}
+
+<span class="ot">#define INITIAL_TAPE_LENGTH (16)</span>
+
+<span class="kw">struct</span> configuration *
+configurationCreate(<span class="dt">void</span>)
+{
+ <span class="kw">struct</span> configuration *c;
+ size_t i;
+
+ c = malloc(<span class="kw">sizeof</span>(<span class="kw">struct</span> configuration));
+ assert(c);
+
+ c-&gt;state = <span class="dv">1</span>;
+ c-&gt;tapeLength = INITIAL_TAPE_LENGTH;
+ c-&gt;leftmost = c-&gt;rightmost = c-&gt;current = c-&gt;tapeLength / <span class="dv">2</span>;
+ c-&gt;tape = malloc(c-&gt;tapeLength);
+ assert(c-&gt;tape);
+
+ <span class="kw">for</span>(i = <span class="dv">0</span>; i &lt; c-&gt;tapeLength; i++) {
+ c-&gt;tape[i] = <span class="dv">0</span>;
+ }
+
+ <span class="kw">return</span> c;
+}
+
+<span class="dt">void</span>
+configurationDestroy(<span class="kw">struct</span> configuration *c)
+{
+ free(c-&gt;tape);
+ free(c);
+}
+
+<span class="ot">#define SYMBOL_BASE ('a')</span>
+<span class="ot">#define STATE_BASE ('0')</span>
+
+<span class="co">/* used for debugging mostly */</span>
+<span class="dt">void</span>
+configurationPrint(<span class="dt">const</span> <span class="kw">struct</span> configuration *c)
+{
+ size_t i;
+
+ <span class="kw">for</span>(i = c-&gt;leftmost; i &lt; c-&gt;current; i++) {
+ putchar(' ');
+ }
+ putchar(STATE_BASE + c-&gt;state);
+ putchar(<span class="ch">'\n'</span>);
+
+ <span class="kw">for</span>(i = c-&gt;leftmost; i &lt;= c-&gt;rightmost; i++) {
+ putchar(SYMBOL_BASE + c-&gt;tape[i]);
+ }
+ putchar(<span class="ch">'\n'</span>);
+}
+
+<span class="dt">int</span>
+main(<span class="dt">int</span> argc, <span class="dt">char</span> **argv)
+{
+ <span class="kw">struct</span> configuration *c;
+ <span class="dt">char</span> cellValue;
+ <span class="dt">const</span> <span class="dt">char</span> *transition;
+ size_t steps;
+
+ <span class="kw">if</span>(argc == <span class="dv">1</span>) {
+ fprintf(stderr, <span class="st">"Usage: %s transitions</span><span class="ch">\n</span><span class="st">"</span>, argv[<span class="dv">0</span>]);
+ <span class="kw">return</span> <span class="dv">1</span>;
+ }
+
+ c = configurationCreate();
+ steps = <span class="dv">0</span>;
+
+ <span class="kw">while</span>(c-&gt;state != <span class="dv">0</span>) {
+ steps++;
+
+ <span class="co">/* execute the next transition */</span>
+ assert(c-&gt;state &lt; argc);
+
+ cellValue = c-&gt;tape[c-&gt;current];
+ assert(<span class="dv">0</span> &lt;= cellValue);
+ assert(<span class="dv">3</span>*(cellValue<span class="dv">+1</span>) &lt;= strlen(argv[c-&gt;state]));
+
+ transition = argv[c-&gt;state] + <span class="dv">3</span>*c-&gt;tape[c-&gt;current];
+
+ c-&gt;tape[c-&gt;current] = transition[<span class="dv">0</span>] - SYMBOL_BASE;
+
+ <span class="kw">switch</span>(transition[<span class="dv">1</span>]) {
+ <span class="kw">case</span> '-':
+ <span class="kw">if</span>(c-&gt;current == <span class="dv">0</span>) {
+ configurationExpand(c);
+ }
+ c-&gt;current--;
+ <span class="kw">if</span>(c-&gt;current &lt; c-&gt;leftmost) {
+ c-&gt;leftmost = c-&gt;current;
+ }
+ <span class="kw">break</span>;
+ <span class="kw">case</span> '+':
+ <span class="kw">if</span>(c-&gt;current == c-&gt;tapeLength - <span class="dv">1</span>) {
+ configurationExpand(c);
+ }
+ c-&gt;current++;
+ <span class="kw">if</span>(c-&gt;current &gt; c-&gt;rightmost) {
+ c-&gt;rightmost = c-&gt;current;
+ }
+ <span class="kw">break</span>;
+ <span class="kw">case</span> '.':
+ <span class="co">/* do nothing */</span>
+ <span class="kw">break</span>;
+ <span class="kw">default</span>:
+ fprintf(stderr, <span class="st">"Bad direction '%c'</span><span class="ch">\n</span><span class="st">"</span>, transition[<span class="dv">2</span>]);
+ exit(<span class="dv">2</span>);
+ <span class="kw">break</span>;
+ }
+
+ c-&gt;state = transition[<span class="dv">2</span>] - STATE_BASE;
+
+<span class="ot">#ifdef PRINT_CONFIGURATION</span>
+ configurationPrint(c);
+<span class="ot">#endif</span>
+ }
+
+ <span class="co">/* print number of steps */</span>
+ printf(<span class="st">"%zu</span><span class="ch">\n</span><span class="st">"</span>, steps);
+
+ configurationDestroy(c);
+
+ <span class="kw">return</span> <span class="dv">0</span>;
+}</code></pre></div>
+<a href="http://cs.yale.edu/homes/aspnes/classes/223/examples/2015/hw/5/turing.c" class="uri">examples/2015/hw/5/turing.c</a>
+</div>
+<div>
+<div class="sourceCode"><pre class="sourceCode makefile"><code class="sourceCode makefile"><span class="dt">CC</span><span class="ch">=</span><span class="st">gcc</span>
+<span class="dt">CFLAGS=-std</span><span class="ch">=</span><span class="st">c99 -Wall -pedantic -g3</span>
+
+<span class="dv">all:</span><span class="dt"> turing</span>
+
+<span class="dv">compositor:</span><span class="dt"> turing.o</span>
+ <span class="ch">$(</span><span class="dt">CC</span><span class="ch">)</span> <span class="ch">$(</span><span class="dt">CFLAGS</span><span class="ch">)</span> -o <span class="ch">$@</span> <span class="ch">$^</span>
+
+<span class="dv">clean:</span>
+ <span class="ch">$(</span><span class="dt">RM</span><span class="ch">)</span> turing *.o</code></pre></div>
+<a href="http://cs.yale.edu/homes/aspnes/classes/223/examples/2015/hw/5/Makefile" class="uri">examples/2015/hw/5/Makefile</a>
+</div>
+<h2 id="hw6"><span class="header-section-number">8.6</span> Assignment 6, due Wednesday 2015-03-25, at 11:00pm</h2>
+<h3 id="sinking-ships"><span class="header-section-number">8.6.1</span> Sinking ships</h3>
+<p>For this assignment, you are to implement a data structure for
+playing a game involving ships placed in a large square grid. Each ship
+occupies one more more squares in either a vertical or horizontal line,
+and has a name that consists of a single <code>char</code> other than a
+period (which will be used to report the absence of a ship). Ships have a
+ bounded maximum length; attempts to place ships longer than this length
+ have no effect.</p>
+<p>All type and constant definitions for the data type, and all function declarations, are given in the file <code>ships.h</code>, which is shown <a href="#hw6-2015-source-files">below</a>, and which you can also find in <code>/c/cs223/Hwk6/sourceFiles/ships.h</code>. The playing field is represented by a <code>struct field</code> (which you get to define). A new <code>struct field</code> is created by <code>fieldCreate</code>, and when no longer needed should be destroyed by <code>fieldDestroy</code>.</p>
+<p>These data types from <a href="http://cs.yale.edu/homes/aspnes/classes/223/examples/2015/hw/6/ships.h">ships.h</a> control ship naming and placement. Note that <code>uint32_t</code> is defined in <code>stdint.h</code> (which is also included by <code>inttypes.h</code>. You will need to include one of these files before <code>ships.h</code> to get this definition.</p>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"><span class="kw">typedef</span> <span class="dt">uint32_t</span> coord;
+
+<span class="kw">struct</span> position {
+ coord x;
+ coord y;
+};
+
+<span class="kw">struct</span> ship {
+ <span class="kw">struct</span> position topLeft; <span class="co">/* coordinates of top left corner */</span>
+ <span class="dt">int</span> direction; <span class="co">/* HORIZONTAL or VERTICAL */</span>
+ <span class="dt">unsigned</span> <span class="dt">int</span> length; <span class="co">/* length of ship */</span>
+ <span class="dt">char</span> name; <span class="co">/* name of ship */</span>
+};</code></pre></div>
+<p>Actual placement is done using the <code>fieldPlaceShip</code> function, declared as follows:</p>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"><span class="dt">void</span> fieldPlaceShip(<span class="kw">struct</span> field *f, <span class="kw">struct</span> ship s);</code></pre></div>
+<p>A ship of length <span class="math inline"><em>m</em></span> placed horizontally with its top left corner at position <span class="math inline">(<em>x</em>, <em>y</em>)</span> will occupy positions <span class="math inline">(<em>x</em>, <em>y</em>)</span> through <span class="math inline">(<em>x</em> + <em>m</em> − 1, <em>y</em>)</span>. If instead it is placed vertically, it will occupy positions <span class="math inline">(<em>x</em>, <em>y</em>)</span> through <span class="math inline">(<em>x</em>, <em>y</em> + <em>m</em> − 1)</span>. If any of these coordinates exceed the maximum coordinate <code>COORD_MAX</code> (defined in <a href="http://cs.yale.edu/homes/aspnes/classes/223/examples/2015/hw/6/ships.h"><code>ships.h</code></a>), the ship will not be placed. The ship will also not be placed if its <code>name</code> field is equal to <code>NO_SHIP_NAME</code> or if the length exceeds <code>MAX_SHIP_LENGTH</code>.</p>
+<p>If the new ship will occupy any position as a ship previously placed
+in the field, the previous ship will be removed. It is possible for many
+ ships to be removed at once in this way.</p>
+<p>The <code>fieldAttack</code> function can be used to remove a ship at
+ a particular location without placing a new ship. It returns the name
+of the removed ship, if any, or <code>NO_SHIP_NAME</code> if there is no ship at that location.</p>
+<p>Finally, the <code>fieldCountShips</code> returns the number of ships still present in the field.</p>
+<p>Your job is to write an implementation of these functions, which you should probably put in a file <code>ships.c</code>. You must also supply a <code>Makefile</code>, which, when <code>make</code> is called with no arguments, generates a test program <code>testShips</code> from your implementation and the file <a href="http://cs.yale.edu/homes/aspnes/classes/223/examples/2015/hw/6/testShips.c"><code>testShips.c</code></a> that we will provide. You should not count on precisely this version of <code>testShips.c</code> being supplied; your implementation should work with any main program that respects the interface in <code>ships.h</code>.</p>
+<h3 id="things-to-watch-out-for"><span class="header-section-number">8.6.2</span> Things to watch out for</h3>
+<p>You should write your implementation so that it will continue to work if the <code>typedef</code> for <code>coord</code>, or the definitions of the constants <code>COORD_MAX</code>, <code>NO_SHIP_NAME</code>, <code>SHIP_MAX_LENGTH</code>, <code>HORIZONTAL</code>, or <code>VERTICAL</code> change. You may, however, assume that <code>coord</code> is an unsigned integer type and the <code>COORD_MAX</code> is the largest value that can be represented by this type.</p>
+<p>If it helps in crafting your implementation, you may assume that <code>MAX_SHIP_LENGTH</code>
+ will alway be a reasonably small constant. You do not need to worry
+about implementing a data structure that will handle huge ships
+efficiently. On the other hand, <code>COORD_MAX</code> as defined in the default <code>ships.h</code> is <span class="math inline">2<sup>32</sup> − 1</span>, so you will need to be able to deal with a field with at least <span class="math inline">2<sup>64</sup></span> possible locations, a consideration you should take into account when choosing a data structure to represent a field.</p>
+<h3 id="the-testships-program"><span class="header-section-number">8.6.3</span> The <code>testShips</code> program</h3>
+<p>The supplied <code>testShips</code> program creates a field, processes commands from <code>stdin</code>, then destroys the field when it reaches <code>EOF</code> or a command that it can't parse. Each command is either of the form</p>
+<pre><code>+ x y vertical length name</code></pre>
+<p>which means to call <code>fieldPlaceShip</code> for a new ship at coordinates (<code>x</code>,<code>y</code>), with direction <code>HORIZONTAL</code> if <code>isVertical</code> is false and <code>VERTICAL</code> otherwise, and length <code>length</code> and name <code>name</code>.</p>
+<p>The command</p>
+<pre><code>- x y</code></pre>
+<p>calls <code>fieldAttack</code> on coordinates (<code>x</code>,<code>y</code>).</p>
+<p>Here is a small input file:</p>
+<pre><code>+ 0 0 0 3 a
++ 1 2 0 4 b
++ 3 0 1 3 c
+- 1 0</code></pre>
+<p>After processing the first line, the contents of the field should look like this:</p>
+<pre><code>aaa..
+.....
+.....
+.....
+.....</code></pre>
+<p>After processing the second line:</p>
+<pre><code>aaa..
+.....
+.bbbb
+.....
+.....</code></pre>
+<p>The third line places a ship vertically that intersects one of the previous ships, sinking it:</p>
+<pre><code>aaac.
+...c.
+...c.
+.....
+.....</code></pre>
+<p>Had ship <code>c</code> been shifted one position to the left, it would have sunken <code>a</code> as well.</p>
+<p>Finally, the last line drops a bomb at <span class="math inline">(1, 0)</span>, sinking <code>a</code>:</p>
+<pre><code>...c.
+...c.
+...c.
+.....
+.....</code></pre>
+<p>The input files used by <code>test.public</code> can be found in <code>/c/cs223/Hwk6/testFiles</code>. Some of these were generated randomly using the script <code>/c/cs223/Hwk6/makeRandom</code>, which you should feel free to use for your own nefarious purposes.</p>
+<p>Because the interface in <code>ships.h</code> gives no way to find
+out what ships are currently in the field, the test program will not
+actually produce pictures like the above. Instead, it prints after each
+command a line giving the name of the ship sunken by <code>fieldAttack</code> (or <code>NO_SHIP_NAME</code> if no ship is sunk or <code>fieldPlaceShip</code>
+ is called) and the number of ships left in the field following the
+attack. So the user must imagine the carnage as the 100000 ships in <code>randomSparseBig.in</code> somehow leave only 25336 survivors in <code>randomSparseBig.out</code>, demonstrating the importance of strict navigational rules in real life.</p>
+<div class="figure">
+<img src="data:image/png;base64,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" alt="Why you should respect people's space">
+<p class="caption">Why you should respect people's space</p>
+</div>
+<h3 id="submitting-your-assignment-5"><span class="header-section-number">8.6.4</span> Submitting your assignment</h3>
+<p>Submit your assignment as usual with</p>
+<pre><code>/c/cs223/bin/submit 6</code></pre>
+<p>You can run the public test script in <code>/c/cs223/Hwk6/test.public</code> on your submitted files with</p>
+<pre><code>/c/cs223/bin/testit 6 public</code></pre>
+<h3 id="hw6-2015-source-files"><span class="header-section-number">8.6.5</span> Provided source files</h3>
+<div>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"><span class="ot">#define HORIZONTAL (0) </span><span class="co">/* place ship horizontally */</span>
+<span class="ot">#define VERTICAL (1) </span><span class="co">/* place ship vertically */</span>
+
+<span class="ot">#define MAX_SHIP_LENGTH (17) </span><span class="co">/* length of longest ship (width is always 1) */</span>
+
+<span class="ot">#define NO_SHIP_NAME ('.') </span><span class="co">/* what to return when hitting no ship */</span>
+
+<span class="co">/*</span>
+<span class="co"> * Type for coordinates, and their maximum possible value.</span>
+<span class="co"> *</span>
+<span class="co"> * Include &lt;stdint.h&gt; before this header file</span>
+<span class="co"> * to get the definition of uint32_t</span>
+<span class="co"> * and its maximum value UINT32_MAX.</span>
+<span class="co"> */</span>
+<span class="kw">typedef</span> <span class="dt">uint32_t</span> coord;
+<span class="ot">#define COORD_MAX (UINT32_MAX)</span>
+
+<span class="co">/*</span>
+<span class="co"> * Non-opaque structs for passing around positions and ship placements.</span>
+<span class="co"> */</span>
+<span class="kw">struct</span> position {
+ coord x;
+ coord y;
+};
+
+<span class="kw">struct</span> ship {
+ <span class="kw">struct</span> position topLeft; <span class="co">/* coordinates of top left corner */</span>
+ <span class="dt">int</span> direction; <span class="co">/* HORIZONTAL or VERTICAL */</span>
+ <span class="dt">unsigned</span> <span class="dt">int</span> length; <span class="co">/* length of ship */</span>
+ <span class="dt">char</span> name; <span class="co">/* name of ship */</span>
+};
+
+<span class="co">/*</span>
+<span class="co"> * Create a playing field for holding ships.</span>
+<span class="co"> */</span>
+<span class="kw">struct</span> field *fieldCreate(<span class="dt">void</span>);
+
+<span class="co">/*</span>
+<span class="co"> * Free all space associated with a field.</span>
+<span class="co"> */</span>
+<span class="dt">void</span> fieldDestroy(<span class="kw">struct</span> field *);
+
+<span class="co">/*</span>
+<span class="co"> * Place a ship in a field with given placement and name.</span>
+<span class="co"> *</span>
+<span class="co"> * If placement.length is less than one or greater than MAX_SHIP_LENGTH, </span>
+<span class="co"> * or if some part of the ship would have a coordinate greater than COORD_MAX, </span>
+<span class="co"> * or if the ship's name is NO_SHIP_NAME,</span>
+<span class="co"> * the function returns without placing a ship.</span>
+<span class="co"> *</span>
+<span class="co"> * Placing a new ship that intersects any previously-placed ships</span>
+<span class="co"> * sinks the previous ships, removing them from the field.</span>
+<span class="co"> */</span>
+<span class="dt">void</span> fieldPlaceShip(<span class="kw">struct</span> field *f, <span class="kw">struct</span> ship s);
+
+<span class="co">/*</span>
+<span class="co"> * Attack!</span>
+<span class="co"> *</span>
+<span class="co"> * Drop a shell at given position.</span>
+<span class="co"> *</span>
+<span class="co"> * Returns NO_SHIP_NAME if attack misses (does not intersect any ship).</span>
+<span class="co"> *</span>
+<span class="co"> * Otherwise returns name of ship hit. </span>
+<span class="co"> *</span>
+<span class="co"> * Hitting a ship sinks it, removing it from the field.</span>
+<span class="co"> */</span>
+<span class="dt">char</span> fieldAttack(<span class="kw">struct</span> field *f, <span class="kw">struct</span> position p);
+
+<span class="co">/*</span>
+<span class="co"> * Return number of ships in the field.</span>
+<span class="co"> */</span>
+size_t fieldCountShips(<span class="dt">const</span> <span class="kw">struct</span> field *f);</code></pre></div>
+<a href="http://cs.yale.edu/homes/aspnes/classes/223/examples/2015/hw/6/ships.h" class="uri">examples/2015/hw/6/ships.h</a>
+</div>
+<div>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"><span class="ot">#include &lt;stdio.h&gt;</span>
+<span class="ot">#include &lt;stdlib.h&gt;</span>
+<span class="ot">#include &lt;assert.h&gt;</span>
+<span class="ot">#include &lt;stdint.h&gt;</span>
+<span class="ot">#include &lt;inttypes.h&gt;</span>
+
+<span class="ot">#include "ships.h"</span>
+
+<span class="ot">#define PLACE_SHIP ('+') </span><span class="co">/* command to place a new ship */</span>
+<span class="ot">#define ATTACK ('-') </span><span class="co">/* command to attack a location */</span>
+
+<span class="dt">int</span>
+main(<span class="dt">int</span> argc, <span class="dt">char</span> **argv)
+{
+ <span class="kw">struct</span> field *f; <span class="co">/* where we keep our ships */</span>
+ <span class="dt">int</span> command; <span class="co">/* command char */</span>
+ <span class="kw">struct</span> ship s; <span class="co">/* ship we are placing */</span>
+ <span class="kw">struct</span> position p; <span class="co">/* location to attack */</span>
+ <span class="dt">int</span> sank; <span class="co">/* ship we sank */</span>
+
+ <span class="kw">if</span>(argc != <span class="dv">1</span>) {
+ fprintf(stderr, <span class="st">"Usage: %s</span><span class="ch">\n</span><span class="st">"</span>, argv[<span class="dv">0</span>]);
+ <span class="kw">return</span> <span class="dv">1</span>;
+ }
+
+ f = fieldCreate();
+
+ <span class="kw">while</span>((command = getchar()) != EOF) {
+ <span class="kw">switch</span>(command) {
+ <span class="kw">case</span> PLACE_SHIP:
+ <span class="kw">if</span>(scanf(<span class="st">"%"</span> SCNu32 <span class="st">" %"</span> SCNu32 <span class="st">"%d %u %c "</span>, &amp;s.topLeft.x, &amp;s.topLeft.y, &amp;s.direction, &amp;s.length, &amp;s.name) != <span class="dv">5</span>) {
+ <span class="co">/* not enough args */</span>
+ fprintf(stderr, <span class="st">"Not enough enough args to %c</span><span class="ch">\n</span><span class="st">"</span>, PLACE_SHIP);
+ <span class="kw">return</span> <span class="dv">1</span>;
+ }
+ <span class="co">/* else */</span>
+
+ <span class="co">/* fix the direction to match actual definitions */</span>
+ s.direction = s.direction ? VERTICAL : HORIZONTAL;
+
+ fieldPlaceShip(f, s);
+ sank = NO_SHIP_NAME;
+
+ <span class="kw">break</span>;
+
+ <span class="kw">case</span> ATTACK:
+ <span class="kw">if</span>(scanf(<span class="st">"%"</span> SCNu32 <span class="st">" %"</span> SCNu32 <span class="st">" "</span>, &amp;p.x, &amp;p.y) != <span class="dv">2</span>) {
+ fprintf(stderr, <span class="st">"Not enough enough args to %c</span><span class="ch">\n</span><span class="st">"</span>, ATTACK);
+ <span class="kw">return</span> <span class="dv">1</span>;
+ }
+ <span class="co">/* else */</span>
+ sank = fieldAttack(f, p);
+
+ <span class="kw">break</span>;
+
+ <span class="kw">default</span>:
+ <span class="co">/* bad command */</span>
+ fprintf(stderr, <span class="st">"Bad command %c</span><span class="ch">\n</span><span class="st">"</span>, command);
+ <span class="kw">return</span> <span class="dv">1</span>;
+ <span class="kw">break</span>;
+ }
+
+ printf(<span class="st">"%c %zu</span><span class="ch">\n</span><span class="st">"</span>, sank, fieldCountShips(f));
+ }
+
+ fieldDestroy(f);
+
+ <span class="kw">return</span> <span class="dv">0</span>;
+}</code></pre></div>
+<a href="http://cs.yale.edu/homes/aspnes/classes/223/examples/2015/hw/6/testShips.c" class="uri">examples/2015/hw/6/testShips.c</a>
+</div>
+<h3 id="hw6Solution"><span class="header-section-number">8.6.6</span> Sample solution</h3>
+<div>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"><span class="ot">#include &lt;stdlib.h&gt;</span>
+<span class="ot">#include &lt;assert.h&gt;</span>
+<span class="ot">#include &lt;string.h&gt;</span>
+<span class="ot">#include &lt;stdint.h&gt;</span>
+
+<span class="ot">#include "ships.h"</span>
+
+<span class="co">/* basic hash table */</span>
+<span class="kw">struct</span> field {
+ size_t size; <span class="co">/* number of slots in table */</span>
+ size_t occupancy; <span class="co">/* number of elements in table */</span>
+ <span class="kw">struct</span> elt **table; <span class="co">/* hash table, malloc'd */</span>
+};
+
+<span class="kw">struct</span> elt {
+ <span class="kw">struct</span> elt *next; <span class="co">/* pointer to next element in linked list */</span>
+ <span class="kw">struct</span> ship ship; <span class="co">/* ship in this element */</span>
+};
+
+<span class="co">/* picked more or less at whim from http://planetmath.org/goodhashtableprimes */</span>
+<span class="ot">#define X_HASH_FACTOR (201326611)</span>
+<span class="ot">#define Y_HASH_FACTOR (3145739)</span>
+
+<span class="dt">static</span> size_t
+hash(<span class="kw">struct</span> position p)
+{
+ <span class="kw">return</span> X_HASH_FACTOR * p.x + Y_HASH_FACTOR * p.y;
+}
+
+<span class="ot">#define DEFAULT_INITIAL_SIZE (8)</span>
+
+<span class="co">/* like fieldCreate, but argument gives initial size */</span>
+<span class="dt">static</span> <span class="kw">struct</span> field *
+fieldCreateInternal(size_t initialSize)
+{
+ <span class="kw">struct</span> field *f;
+ size_t i;
+
+ f = malloc(<span class="kw">sizeof</span>(<span class="kw">struct</span> field));
+ assert(f);
+
+ f-&gt;size = initialSize;
+ f-&gt;occupancy = <span class="dv">0</span>;
+
+ f-&gt;table = malloc(<span class="kw">sizeof</span>(<span class="kw">struct</span> elt *) * f-&gt;size);
+
+ <span class="kw">for</span>(i = <span class="dv">0</span>; i &lt; f-&gt;size; i++) {
+ f-&gt;table[i] = <span class="dv">0</span>;
+ }
+
+ <span class="kw">return</span> f;
+}
+
+<span class="kw">struct</span> field *
+fieldCreate(<span class="dt">void</span>)
+{
+ <span class="kw">return</span> fieldCreateInternal(DEFAULT_INITIAL_SIZE);
+}
+
+<span class="co">/* destroy contents of f but don't free f itself */</span>
+<span class="dt">static</span> <span class="dt">void</span>
+fieldDestroyContents(<span class="kw">struct</span> field *f)
+{
+ size_t i;
+ <span class="kw">struct</span> elt *e;
+ <span class="kw">struct</span> elt *next;
+
+ <span class="kw">for</span>(i = <span class="dv">0</span>; i &lt; f-&gt;size; i++) {
+ <span class="kw">for</span>(e = f-&gt;table[i]; e != <span class="dv">0</span>; e = next) {
+ next = e-&gt;next;
+ free(e);
+ }
+ }
+
+ free(f-&gt;table);
+}
+
+<span class="dt">void</span>
+fieldDestroy(<span class="kw">struct</span> field *f)
+{
+ fieldDestroyContents(f);
+ free(f);
+}
+
+<span class="co">/* when to grow field */</span>
+<span class="ot">#define MAX_ALPHA (1)</span>
+
+<span class="co">/*</span>
+<span class="co"> * Helper for fieldPlaceShip.</span>
+<span class="co"> * </span>
+<span class="co"> * This skips all the sanity-checking in fieldPlaceShip,</span>
+<span class="co"> * and just performs the hash table insertion.</span>
+<span class="co"> */</span>
+<span class="dt">static</span> <span class="dt">void</span>
+fieldInsertShip(<span class="kw">struct</span> field *f, <span class="kw">struct</span> ship s)
+{
+ size_t h; <span class="co">/* hashed coordinates */</span>
+ <span class="kw">struct</span> elt *e; <span class="co">/* new element to insert */</span>
+
+ h = hash(s.topLeft) % f-&gt;size;
+
+ e = malloc(<span class="kw">sizeof</span>(<span class="kw">struct</span> elt));
+ assert(e);
+
+ e-&gt;ship = s;
+ e-&gt;next = f-&gt;table[h];
+ f-&gt;table[h] = e;
+ f-&gt;occupancy++;
+}
+
+
+<span class="dt">void</span>
+fieldPlaceShip(<span class="kw">struct</span> field *f, <span class="kw">struct</span> ship s)
+{
+ <span class="kw">struct</span> field *f2;
+ <span class="kw">struct</span> elt *e;
+ <span class="kw">struct</span> position pos;
+ size_t i;
+
+ <span class="co">/* test if we can just throw this away */</span>
+ <span class="kw">if</span>(s.name == NO_SHIP_NAME
+ || s.length == <span class="dv">0</span>
+ || s.length &gt; MAX_SHIP_LENGTH
+ || (s.direction == HORIZONTAL &amp;&amp; s.topLeft.x &gt; COORD_MAX - (s.length - <span class="dv">1</span>))
+ || (s.direction == VERTICAL &amp;&amp; s.topLeft.y &gt; COORD_MAX - (s.length - <span class="dv">1</span>))
+ )
+ {
+ <span class="kw">return</span>;
+ }
+ <span class="co">/* else */</span>
+
+ <span class="kw">if</span>(f-&gt;occupancy &gt;= f-&gt;size * MAX_ALPHA) {
+ <span class="co">/* grow the field */</span>
+ f2 = fieldCreateInternal(f-&gt;size * <span class="dv">2</span>);
+
+ <span class="co">/* copy to new field */</span>
+ <span class="kw">for</span>(i = <span class="dv">0</span>; i &lt; f-&gt;size; i++) {
+ <span class="kw">for</span>(e = f-&gt;table[i]; e != <span class="dv">0</span>; e = e-&gt;next) {
+ <span class="co">/* skip testing for occupancy or intersections */</span>
+ fieldInsertShip(f2, e-&gt;ship);
+ }
+ }
+
+ <span class="co">/* transplant new field into old field */</span>
+ fieldDestroyContents(f);
+ *f = *f2;
+
+ free(f2);
+ }
+
+ <span class="co">/* check for intersections */</span>
+ pos = s.topLeft;
+ <span class="kw">for</span>(i = <span class="dv">0</span>; i &lt; s.length; i++) {
+ <span class="kw">if</span>(s.direction == HORIZONTAL) {
+ pos.x = s.topLeft.x + i;
+ } <span class="kw">else</span> {
+ pos.y = s.topLeft.y + i;
+ }
+
+ fieldAttack(f, pos);
+ }
+
+ <span class="co">/* call helper to do the actual hash table insertion */</span>
+ fieldInsertShip(f, s);
+}
+
+<span class="co">/*</span>
+<span class="co"> * Helper for fieldAttack.</span>
+<span class="co"> *</span>
+<span class="co"> * If there is a ship with topLeft at given position, return pointer</span>
+<span class="co"> * to location in hash table that points to it (either table entry</span>
+<span class="co"> * or next component).</span>
+<span class="co"> *</span>
+<span class="co"> * If not, return null.</span>
+<span class="co"> */</span>
+<span class="dt">static</span> <span class="kw">struct</span> elt **
+fieldShipAt(<span class="kw">struct</span> field *f, <span class="kw">struct</span> position p)
+{
+ <span class="kw">struct</span> elt **prev; <span class="co">/* previous pointer */</span>
+
+ <span class="kw">for</span>(prev = &amp;f-&gt;table[hash(p) % f-&gt;size]; *prev != <span class="dv">0</span>; prev = &amp;((*prev)-&gt;next)) {
+ <span class="kw">if</span>((*prev)-&gt;ship.topLeft.x == p.x &amp;&amp; (*prev)-&gt;ship.topLeft.y == p.y) {
+ <span class="kw">return</span> prev;
+ }
+ }
+
+ <span class="co">/* didn't find anything */</span>
+ <span class="kw">return</span> <span class="dv">0</span>;
+}
+
+<span class="co">/*</span>
+<span class="co"> * Attack!</span>
+<span class="co"> *</span>
+<span class="co"> * Drop a shell at given position.</span>
+<span class="co"> *</span>
+<span class="co"> * Returns 0 if attack misses (does not intersect any ship).</span>
+<span class="co"> *</span>
+<span class="co"> * Otherwise returns name of ship hit, </span>
+<span class="co"> * which should be freed by caller when no longer needed.</span>
+<span class="co"> *</span>
+<span class="co"> * Hitting a ship sinks it, removing it from the field.</span>
+<span class="co"> */</span>
+<span class="dt">char</span>
+fieldAttack(<span class="kw">struct</span> field *f, <span class="kw">struct</span> position p)
+{
+ <span class="kw">struct</span> position p2;
+ <span class="dt">int</span> i;
+ <span class="dt">int</span> direction;
+ <span class="kw">struct</span> elt **prev;
+ <span class="kw">struct</span> elt *freeMe;
+ <span class="dt">char</span> name;
+
+ <span class="kw">for</span>(direction = <span class="dv">0</span>; direction &lt;= <span class="dv">1</span>; direction++) {
+ <span class="kw">for</span>(i = <span class="dv">0</span>; i &lt; MAX_SHIP_LENGTH &amp;&amp; i &lt;= (direction == HORIZONTAL ? p.x : p.y); i++) {
+ <span class="kw">if</span>(direction == HORIZONTAL) {
+ p2.x = p.x - i;
+ p2.y = p.y;
+ } <span class="kw">else</span> {
+ p2.x = p.x;
+ p2.y = p.y - i;
+ }
+
+ prev = fieldShipAt(f, p2);
+
+ <span class="kw">if</span>(prev) {
+ <span class="co">/* if we sink anybody, it will be this ship */</span>
+ <span class="co">/* but maybe it doesn't reach */</span>
+ <span class="co">/* or points in the wrong direction */</span>
+ <span class="kw">if</span>((*prev)-&gt;ship.length &gt; i &amp;&amp; (*prev)-&gt;ship.direction == direction) {
+ <span class="co">/* got it */</span>
+ freeMe = *prev;
+ *prev = freeMe-&gt;next;
+
+ name = freeMe-&gt;ship.name;
+ free(freeMe);
+
+ f-&gt;occupancy--;
+
+ <span class="kw">return</span> name;
+ } <span class="kw">else</span> {
+ <span class="co">/* didn't get it */</span>
+ <span class="co">/* maybe try again in other direction */</span>
+ <span class="kw">break</span>;
+ }
+ }
+ }
+ }
+
+ <span class="co">/* didn't get anything */</span>
+ <span class="kw">return</span> NO_SHIP_NAME;
+}
+
+<span class="co">/*</span>
+<span class="co"> * Return number of ships in the field.</span>
+<span class="co"> */</span>
+size_t
+fieldCountShips(<span class="dt">const</span> <span class="kw">struct</span> field *f)
+{
+ <span class="kw">return</span> f-&gt;occupancy;
+}</code></pre></div>
+<a href="http://cs.yale.edu/homes/aspnes/classes/223/examples/2015/hw/6/ships.c" class="uri">examples/2015/hw/6/ships.c</a>
+</div>
+<h2 id="hw7"><span class="header-section-number">8.7</span> Assignment 7, due Wednesday 2015-04-01, at 11:00pm</h2>
+<h3 id="solitaire-with-big-cards"><span class="header-section-number">8.7.1</span> Solitaire with big cards</h3>
+<p>For this assignment you are to implement a strategy for playing a card game involving moving cards (represented by <code>uint64_t</code>s) down through a sequence of <span class="math inline"><em>n</em></span> piles. The interface to your strategy is given in the file <a href="http://cs.yale.edu/homes/aspnes/classes/223/examples/2015/hw/7/strategy.h"><code>strategy.h</code></a>, shown below:</p>
+<div>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"><span class="co">/*</span>
+<span class="co"> * Interface for card-playing strategy.</span>
+<span class="co"> *</span>
+<span class="co"> * The deal function supplies a new card to the strategy. Each possible card will only be dealt once.</span>
+<span class="co"> *</span>
+<span class="co"> * The play function should return a card that has been dealt previously but not yet played.</span>
+<span class="co"> * If asked for a card when the hand is empty, its behavior is undefined.</span>
+<span class="co"> */</span>
+
+<span class="ot">#include &lt;stdint.h&gt;</span>
+
+<span class="kw">typedef</span> <span class="dt">uint64_t</span> Card; <span class="co">/* representation of a card */</span>
+
+<span class="co">/* opaque type for strategy data */</span>
+<span class="kw">typedef</span> <span class="kw">struct</span> strategy Strategy;
+
+<span class="co">/* set up a new strategy for numPiles many piles */</span>
+Strategy *strategyCreate(<span class="dt">int</span> numPiles);
+
+<span class="co">/* clean up all space used by a strategy */</span>
+<span class="dt">void</span> strategyDestroy(Strategy *);
+
+<span class="co">/* add a card to the current hand */</span>
+<span class="dt">void</span> strategyDeal(Strategy *, Card);
+
+<span class="co">/* play a card from pile k */</span>
+Card strategyPlay(Strategy *, <span class="dt">int</span> k);</code></pre></div>
+<a href="http://cs.yale.edu/homes/aspnes/classes/223/examples/2015/hw/7/strategy.h" class="uri">examples/2015/hw/7/strategy.h</a>
+</div>
+<p>Initially, the player has <span class="math inline"><em>n</em></span> piles, numbered <span class="math inline">1</span> through <span class="math inline"><em>n</em></span>. The <code>strategyDeal</code> function is called to indicate that a new card has been dealt to pile <span class="math inline"><em>n</em></span>. The <code>strategyPlay</code> function is called to indicate that a card should be moved from pile <code>k</code> to pile <code>k-1</code>; this function should return the card to move. Cards moved to pile <span class="math inline">0</span>
+ leave the game and are not used again. Each card is unique: once a card
+ is dealt, the same card will never be dealt again during the same play
+of the game.</p>
+<p>The choice of when to deal and when to play from pile is controlled
+by some external entity, which at some point will stop and compute the
+smallest card in each pile. The goal of the strategy is to make these
+smallest cards be as large as possible, giving priority to the
+highest-numbered piles: given two runs of the game, the better-scoring
+one is the one that has the larger smallest card in pile <span class="math inline"><em>n</em></span>, or, if both have the same smallest card in pile <span class="math inline"><em>n</em></span>, the one that has the larger smallest card in pile <span class="math inline"><em>n</em> − 1</span>, and so forth. A tie would require that both runs end with the same smallest card in every pile. An empty pile counts as <code>UINT64_MAX</code> for this purpose (although note that a strategy has no control over which piles are empty).</p>
+<p>Your job is to implement a strategy that produces the best possible result for any sequence of calls to <code>strategyDeal</code> and <code>strategyPlay</code>.
+ Your strategy implementation will most likely need to keep track of
+which cards are available in each pile, as this information is not
+provided by the caller. Your <code>strategyPlay</code> function should
+only make legal moves: that is, it should only play cards that are
+actually present in the appropriate pile. You may assume that <code>strategyPlay</code> is never called on an empty pile.</p>
+<p>Your implementation should consist of a file <code>strategy.c</code> and any supporting source and header files that you need other than <code>strategy.h</code>, which we have provided for you. You should also supply a file <code>Makefile</code> that generates a program <code>testStrategy</code> when <code>make</code> is called with no arguments, using your implementation and the <a href="http://cs.yale.edu/homes/aspnes/classes/223/examples/2015/hw/7/testStrategy.c"><code>testStrategy.c</code></a> file that you can find in <code>/c/cs223/Hwk7/sourceFiles/testStrategy.c</code>.</p>
+<h3 id="explanation-of-the-testing-program"><span class="header-section-number">8.7.2</span> Explanation of the testing program</h3>
+<p>The <code>testStrategy</code> program implements one of four rules for when you can play from each pile. The arguments to <code>testStrategy</code>
+ are a character indicating which rule to apply, the number of cards to
+deal (which can be pretty big), and the number of piles (which is much
+more limited, because <code>testStrategy.c</code> tracks the pile each card is in using a <code>char</code>
+ to save space). The actual cards dealt are generated deterministically
+and will be the same in every execution with the same arguments. The
+test files in <code>/c/cs223/Hwk7/testFiles</code> give the expected output when <code>testStrategy</code> is run with the arguments specified in the filename (after removing the <code>-</code> characters); this will always be the value, in hexadecimal, of the smallest card in each pile, starting with the top pile.</p>
+<p>For example, running the <em>harmonic</em> rule <code>h</code> with 1000 cards and 4 piles (not counting the 0 pile) gives the output</p>
+<pre><code>$ ./testStrategy h 1000 4
+5462035faf0d6fa1
+501ebb6268d39af3
+25732b5fee7c8ad7
+301e0f608d124ede</code></pre>
+<p>This output would appear in a filename <code>h-1000-4</code>, if this particular combination of parameters were one of the test cases.</p>
+<h3 id="submitting-your-assignment-6"><span class="header-section-number">8.7.3</span> Submitting your assignment</h3>
+<p>Submit your assignment as usual with <code>/c/cs223/bin/submit 7</code>. You should submit your source file(s), your <code>Makefile</code>, and any other files needed to build your program other than <code>strategy.h</code> and <code>testStrategy.c</code>, which will be supplied by the test script. You can test your submission using the public test script in <code>/c/cs223/Hwk7/test.public</code> using the command <code>/c/cs223/bin/testit 7 public</code>.</p>
+<h3 id="hw7Solution"><span class="header-section-number">8.7.4</span> Sample solution</h3>
+<p>I implemented a heap with <code>uint64_t</code> elements as a separate module (<a href="http://cs.yale.edu/homes/aspnes/classes/223/examples/2015/hw/7/heap.h">heap.h</a>, <a href="http://cs.yale.edu/homes/aspnes/classes/223/examples/2015/hw/7/heap.c">heap.c</a>) and then used in in a main module <a href="http://cs.yale.edu/homes/aspnes/classes/223/examples/2015/hw/7/strategy.c">strategy.c</a> that allocates a separate heap for each pile and manages the translation between <code>strategyDeal</code> and <code>strategyPlay</code> and the heap functions. The <a href="http://cs.yale.edu/homes/aspnes/classes/223/examples/2015/hw/7/Makefile">Makefile</a> is pretty much the usual.</p>
+<h2 id="hw8"><span class="header-section-number">8.8</span> Assignment 8, due Wednesday 2015-04-08, at 11:00pm</h2>
+<h3 id="an-ordered-set"><span class="header-section-number">8.8.1</span> An ordered set</h3>
+<p>For this assignment, you are to implement an ordered set data type
+for holding null-terminated strings. The interface to this data type is
+given in the file <a href="http://cs.yale.edu/homes/aspnes/classes/223/examples/2015/hw/8/orderedSet.h">orderedSet.h</a>, shown below.</p>
+<div>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"><span class="co">/*</span>
+<span class="co"> * Ordered set data structure.</span>
+<span class="co"> */</span>
+
+<span class="co">/* Make a new empty set */</span>
+<span class="kw">struct</span> orderedSet *orderedSetCreate(<span class="dt">void</span>);
+
+<span class="co">/* Destroy a set */</span>
+<span class="dt">void</span> orderedSetDestroy(<span class="kw">struct</span> orderedSet *);
+
+<span class="co">/* How many elements in this set? */</span>
+size_t orderedSetSize(<span class="dt">const</span> <span class="kw">struct</span> orderedSet *);
+
+<span class="co">/* Insert a new element. Has no effect if element is already present. */</span>
+<span class="dt">void</span> orderedSetInsert(<span class="kw">struct</span> orderedSet *, <span class="dt">const</span> <span class="dt">char</span> *);
+
+<span class="co">/* Delete an element. Has no effect if element is not already present. */</span>
+<span class="dt">void</span> orderedSetDelete(<span class="kw">struct</span> orderedSet *, <span class="dt">const</span> <span class="dt">char</span> *);
+
+<span class="co">/* Return a new ordered set containing all elements e</span>
+<span class="co"> * for which predicate(arg, x) != 0.</span>
+<span class="co"> * The predicate function should be applied to the elements in increasing order. */</span>
+<span class="kw">struct</span> orderedSet *orderedSetFilter(<span class="dt">const</span> <span class="kw">struct</span> orderedSet *, <span class="dt">int</span> (*predicate)(<span class="dt">void</span> *arg, <span class="dt">const</span> <span class="dt">char</span> *), <span class="dt">void</span> *arg);</code></pre></div>
+<a href="http://cs.yale.edu/homes/aspnes/classes/223/examples/2015/hw/8/orderedSet.h" class="uri">examples/2015/hw/8/orderedSet.h</a>
+</div>
+<p>In addition to the usual create and destroy functions, an ordered set
+ supports inserting and deleting elements, counting the number of
+distinct elements in the set, and filtering the set based on a predicate
+ function passed in as an argument. This filtering operation does not
+modify the input set, but instead generates a new ordered set containing
+ only those elements on which the predicate returns a nonzero value.</p>
+<p>The filtering operation is where most of the excitement happens; because the predicate function takes an argument of type <code>void *</code>
+ that is also passed to the filter function, it is possible for the
+predicate to compute an arbitrary function on the elements of the set as
+ a side-effect of processing each element to decide whether to put it in
+ the output set. This allows predicates to be abused to perform all
+sorts of computations, including printing out all elements of the set or
+ computing a hash of all the strings in the set concatenated together.
+These features are used by the test program <a href="http://cs.yale.edu/homes/aspnes/classes/223/examples/2015/hw/8">testOrderedSet.c</a>
+ that we have provided. To ensure that these traversals give consistent
+results, it is required that when your implementation of <code>orderedSetFilter</code> is executed, it calls the predicate function exactly once on each element of the set in increasing order as determined by <code>strcmp</code>.</p>
+<h3 id="the-testorderedset-wrapper"><span class="header-section-number">8.8.2</span> The <code>testOrderedSet</code> wrapper</h3>
+<p>The test program is a fairly thin wrapper over the implementation
+that allows you to call the various functions using one-line commands on
+ standard input. A command is given as the first character of the line,
+and the rest of the line contains the argument to the command if needed.
+ The <code>+</code> and <code>-</code> commands add or remove an element from the set, respectively, while the <code>p</code>, <code>s</code>, and <code>h</code> commands print the contents of the set, the size of the set, and a hash of the set (these commands ignore any argument). The <code>f</code> command removes all elements of the set that do not contain a particular substring.</p>
+<p>Here is a simple input to the program that inserts four strings, filters out the ones that don't contain <code>ee</code>, then prints various information about the results.</p>
+<pre><code>+feed
++the
++bees
++please
+fee
+s
+h
+p</code></pre>
+<p>This should produce the output</p>
+<pre><code>2
+15082778b3db8cb3
+bees
+feed</code></pre>
+<h3 id="hw8submission"><span class="header-section-number">8.8.3</span> Submitting your assignment</h3>
+<p>Submit, with the usual <code>/c/cs223/bin/submit 8 filename</code>, your <code>Makefile</code> and any supporting files needed to build the program <code>testOrderedSet</code> from <code>testOrderedSet.c</code> and <code>orderedSet.h</code> when <code>make</code> is called with no arguments. These last two files will be provided by the test script and you do not need to submit them.</p>
+<p>You can test your submission against the public test script in <code>/c/cs223/Hwk8/test.public</code> with <code>/c/cs223/bin/testit 8</code>.</p>
+<h3 id="hw8Solution"><span class="header-section-number">8.8.4</span> Sample solution</h3>
+<p>There were a lot of ways to do this. For the sample solution, I
+decided to do something unusual, and store the set as a hash table. This
+ is not ordered, but since the only operation that requires the set to
+be ordered is <code>orderedSetFilter</code>, which will take <span class="math inline"><em>Ω</em>(<em>n</em>)</span> time no matter how you implement it, the <span class="math inline"><em>O</em>(<em>n</em>log<em>n</em>)</span> cost to call <code>qsort</code> to sort the elements as needed does not add much overhead.</p>
+<div>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"><span class="ot">#include &lt;stdio.h&gt;</span>
+<span class="ot">#include &lt;stdlib.h&gt;</span>
+<span class="ot">#include &lt;assert.h&gt;</span>
+<span class="ot">#include &lt;stdint.h&gt;</span>
+<span class="ot">#include &lt;string.h&gt;</span>
+
+<span class="ot">#include "orderedSet.h"</span>
+
+<span class="co">/* We'll use a hash table with linear probing.</span>
+<span class="co"> * This is not actually ordered, but the only operations that</span>
+<span class="co"> * depend on order a linear-time anyway, so we can afford to sort as needed */</span>
+<span class="kw">struct</span> orderedSet {
+ size_t n; <span class="co">/* number of elements */</span>
+ size_t size; <span class="co">/* size of the table */</span>
+ <span class="dt">char</span> **table; <span class="co">/* hash table */</span>
+};
+
+<span class="ot">#define INITIAL_SIZE (16)</span>
+<span class="ot">#define MAX_ALPHA (0.75)</span>
+
+<span class="co">/* Make a new empty set with given size */</span>
+<span class="dt">static</span> <span class="kw">struct</span> orderedSet *
+orderedSetCreateInternal(size_t size)
+{
+ <span class="kw">struct</span> orderedSet *s;
+
+ s = malloc(<span class="kw">sizeof</span>(*s));
+ assert(s);
+
+ s-&gt;n = <span class="dv">0</span>;
+ s-&gt;size = size;
+ s-&gt;table = calloc(s-&gt;size, <span class="kw">sizeof</span>(<span class="dt">char</span> *));
+
+ <span class="kw">return</span> s;
+}
+
+<span class="kw">struct</span> orderedSet *
+orderedSetCreate(<span class="dt">void</span>)
+{
+ <span class="kw">return</span> orderedSetCreateInternal(INITIAL_SIZE);
+}
+
+<span class="co">/* Destroy a set */</span>
+<span class="dt">void</span>
+orderedSetDestroy(<span class="kw">struct</span> orderedSet *s)
+{
+ size_t i;
+
+ <span class="kw">for</span>(i = <span class="dv">0</span>; i &lt; s-&gt;size; i++) {
+ <span class="kw">if</span>(s-&gt;table[i]) {
+ free(s-&gt;table[i]);
+ }
+ }
+
+ free(s-&gt;table);
+ free(s);
+}
+
+<span class="co">/* How many elements in this set? */</span>
+size_t
+orderedSetSize(<span class="dt">const</span> <span class="kw">struct</span> orderedSet *s)
+{
+ <span class="kw">return</span> s-&gt;n;
+}
+
+<span class="dt">static</span> size_t
+hash(<span class="dt">const</span> <span class="dt">char</span> *s)
+{
+ size_t h;
+
+ <span class="co">/* usual crummy hash function */</span>
+ <span class="kw">for</span>(h = <span class="dv">0</span>; *s; h = h * <span class="dv">97</span> + *s++);
+
+ <span class="kw">return</span> h;
+}
+
+<span class="dt">static</span> <span class="dt">char</span> *
+strMalloc(<span class="dt">const</span> <span class="dt">char</span> *s)
+{
+ <span class="dt">char</span> *s2;
+
+ s2 = malloc(strlen(s)+<span class="dv">1</span>);
+ strcpy(s2, s);
+
+ <span class="kw">return</span> s2;
+}
+
+<span class="co">/* Insert and element without doing size check or malloc */</span>
+<span class="co">/* Frees element if already present */</span>
+<span class="dt">static</span> <span class="dt">void</span>
+orderedSetInsertInternal(<span class="kw">struct</span> orderedSet *s, <span class="dt">char</span> *elt)
+{
+ size_t h;
+
+ assert(elt);
+
+ <span class="co">/* skip over non-empty slots with different values */</span>
+ <span class="kw">for</span>(h = hash(elt) % s-&gt;size; s-&gt;table[h] &amp;&amp; strcmp(s-&gt;table[h], elt); h = (h<span class="dv">+1</span>) % s-&gt;size);
+
+ <span class="co">/* check if not already present */</span>
+ <span class="kw">if</span>(s-&gt;table[h] == <span class="dv">0</span>) {
+ s-&gt;table[h] = elt;
+ s-&gt;n++;
+ } <span class="kw">else</span> {
+ free(elt);
+ }
+}
+
+<span class="co">/* Insert a new element. Has no effect if element is already present. */</span>
+<span class="dt">void</span>
+orderedSetInsert(<span class="kw">struct</span> orderedSet *s, <span class="dt">const</span> <span class="dt">char</span> *elt)
+{
+ size_t h;
+ <span class="kw">struct</span> orderedSet *s2;
+
+ <span class="kw">if</span>(s-&gt;n &gt;= s-&gt;size * MAX_ALPHA) {
+ <span class="co">/* rebuild the table */</span>
+ s2 = orderedSetCreateInternal(s-&gt;size * <span class="dv">2</span>);
+
+ <span class="co">/* copy all the elements */</span>
+ <span class="kw">for</span>(h = <span class="dv">0</span>; h &lt; s-&gt;size; h++) {
+ <span class="kw">if</span>(s-&gt;table[h]) {
+ orderedSetInsertInternal(s2, s-&gt;table[h]);
+ }
+ }
+
+ <span class="co">/* free the table and then do a brain transplant */</span>
+ free(s-&gt;table);
+ *s = *s2;
+ free(s2);
+ }
+
+ orderedSetInsertInternal(s, strMalloc(elt));
+}
+
+<span class="co">/* Delete an element. Has no effect if element is not already present. */</span>
+<span class="dt">void</span>
+orderedSetDelete(<span class="kw">struct</span> orderedSet *s, <span class="dt">const</span> <span class="dt">char</span> *elt)
+{
+ size_t h;
+ <span class="dt">char</span> *later;
+
+ <span class="co">/* skip over non-empty slots with different values */</span>
+ <span class="kw">for</span>(h = hash(elt) % s-&gt;size; s-&gt;table[h] &amp;&amp; strcmp(s-&gt;table[h], elt); h = (h<span class="dv">+1</span>) % s-&gt;size);
+
+ <span class="co">/* if we reached a nonempty slot, it must be our target */</span>
+ <span class="kw">if</span>(s-&gt;table[h] != <span class="dv">0</span>) {
+ <span class="co">/* remove the initial element */</span>
+ free(s-&gt;table[h]);
+ s-&gt;table[h] = <span class="dv">0</span>;
+ s-&gt;n--;
+
+ <span class="co">/* remove and reinsert any elements up to the next hole, in case they wanted to be earlier */</span>
+ <span class="kw">for</span>(h = (h<span class="dv">+1</span>) % s-&gt;size; s-&gt;table[h] ; h = (h<span class="dv">+1</span>) % s-&gt;size) {
+ later = s-&gt;table[h];
+ s-&gt;table[h] = <span class="dv">0</span>;
+ s-&gt;n--;
+ orderedSetInsertInternal(s, later);
+ }
+ }
+}
+
+<span class="dt">static</span> <span class="dt">int</span>
+compare(<span class="dt">const</span> <span class="dt">void</span> *s1, <span class="dt">const</span> <span class="dt">void</span> *s2)
+{
+ <span class="kw">return</span> strcmp(*((<span class="dt">const</span> <span class="dt">char</span> **) s1), *((<span class="dt">const</span> <span class="dt">char</span> **) s2));
+}
+
+<span class="co">/* Return a new ordered set containing all elements e</span>
+<span class="co"> * for which predicate(arg, x) != 0.</span>
+<span class="co"> * The predicate function should be applied to the elements in increasing order. */</span>
+<span class="kw">struct</span> orderedSet *
+orderedSetFilter(<span class="dt">const</span> <span class="kw">struct</span> orderedSet *s, <span class="dt">int</span> (*predicate)(<span class="dt">void</span> *arg, <span class="dt">const</span> <span class="dt">char</span> *), <span class="dt">void</span> *arg)
+{
+ size_t h;
+ <span class="dt">const</span> <span class="dt">char</span> **a; <span class="co">/* temporary array to sort */</span>
+ size_t top; <span class="co">/* where to put things in a */</span>
+ size_t i;
+ <span class="kw">struct</span> orderedSet *s2;
+
+ a = malloc(<span class="kw">sizeof</span>(<span class="dt">const</span> <span class="dt">char</span> *) * s-&gt;size);
+ assert(a);
+
+ top = <span class="dv">0</span>;
+
+ <span class="kw">for</span>(h = <span class="dv">0</span>; h &lt; s-&gt;size; h++) {
+ <span class="kw">if</span>(s-&gt;table[h]) {
+ a[top++] = s-&gt;table[h];
+ }
+ }
+
+ qsort(a, top, <span class="kw">sizeof</span>(<span class="dt">const</span> <span class="dt">char</span> *), compare);
+
+ s2 = orderedSetCreate();
+
+ <span class="kw">for</span>(i = <span class="dv">0</span>; i &lt; top; i++) {
+ <span class="kw">if</span>(predicate(arg, a[i])) {
+ orderedSetInsert(s2, a[i]);
+ }
+ }
+
+ free(a);
+
+ <span class="kw">return</span> s2;
+}</code></pre></div>
+<a href="http://cs.yale.edu/homes/aspnes/classes/223/examples/2015/hw/8/orderedSet.c" class="uri">examples/2015/hw/8/orderedSet.c</a>
+</div>
+<p><a href="#Makefile-1">Makefile</a>{examples/2015/hw/8/Makefile}</p>
+<h2 id="hw9"><span class="header-section-number">8.9</span> Assignment 9, due Wednesday 2015-04-15, at 11:00pm</h2>
+<h3 id="finding-a-cycle-in-a-maze"><span class="header-section-number">8.9.1</span> Finding a cycle in a maze</h3>
+<p>For this problem, you are given a rectangular maze consisting of <em>wall</em> squares (represented by 0) and <em>path</em>
+ squares (represented by 1). Two path squares are considered to be
+adjacent if they are at most one square away orthogonally or diagonally;
+ in chess terms, two path squares are adjacent if a king can move from
+one to the other in one turn. The input to your program is a maze in
+which the graph consisting of all path squares is connected and contains
+ at most one cycle, where a cycle is a sequence of distinct squares <span class="math inline"><em>s</em><sub>1</sub>, <em>s</em><sub>2</sub>, …, <em>s</em><sub><em>k</em></sub></span> where each <span class="math inline"><em>s</em><sub><em>i</em></sub></span> is adjacent to <span class="math inline"><em>s</em><sub><em>i</em> + 1</sub></span> and <span class="math inline"><em>s</em><sub><em>n</em></sub></span> is adjacent to <span class="math inline"><em>s</em><sub>1</sub></span>. Your job is to write a program <code>maze</code> that finds this cycle if it exists, and marks all of its squares as <em>cycle</em> squares (represented by 2).</p>
+<p>For example, here is a picture of a 200-by-100 maze that contains a small cycle:</p>
+<div class="figure">
+<img src="data:image/png;base64,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" alt="200 by 100 maze">
+<p class="caption">200 by 100 maze</p>
+</div>
+<p>and here is the same maze with the cycle highlighted in white:</p>
+<div class="figure">
+<img src="data:image/png;base64,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" alt="200 by 100 maze, showing cycle">
+<p class="caption">200 by 100 maze, showing cycle</p>
+</div>
+<h3 id="input-and-output-format"><span class="header-section-number">8.9.2</span> Input and output format</h3>
+<p>The input to your program should be taken from <code>stdin</code>, in a restricted version of <a href="http://netpbm.sourceforge.net/doc/pgm.html">raw PGM format</a>,
+ an old image format designed to be particularly easy to parse. The
+input file header will be a line that looks like it was generated by the
+ <code>printf</code> conversion string <code>"P5 %d %d 255\n"</code>, where the first <code>int</code>
+ value is the width of the image in columns and the second is the height
+ of the image in rows; the same conversion string can be given to <code>scanf</code>
+ to parse this line. Following the newline will be a long sequence of
+bytes, each representing one pixel of the image, with each row following
+ immediately after the previous one. These bytes will be either 0 or 1
+depending on whether that position in the maze is a wall or a path.</p>
+<p>The output to your program should be in the same format, with the
+difference that now some of the bytes in the image data may be 2,
+indicating the cycle. If there is no cycle, the output should be
+identical to the input. Your program is not required to detect or
+respond in any particular way to input mazes that violate the format or
+do not contain a connected graph of path squares, although you are
+encouraged to put in reasonable error checking for your own benefit
+during testing.</p>
+<p>For example, the maze depicted above is stored in the file <a href="http://cs.yale.edu/homes/aspnes/classes/223/examples/2015/hw/9/200-100-4.in.pgm">200-100-4.in.pgm</a>; the corresponding output is stored in the file <a href="http://cs.yale.edu/homes/aspnes/classes/223/examples/2015/hw/9/200-100-4.out.pgm">200-100-4.out.pgm</a>. Other sample inputs and outputs can be found in <code>/c/cs223/Hwk9/testFiles</code>.</p>
+<p>This file format is hard to read with the naked eye, even after loading into a text editor. The script <code>/c/cs223/Hwk9/toPng</code>
+ will generate a PNG file that doubles the pixel size and rescales the
+0, 1, 2 pixel values to more reasonable values for display. This can be
+called as <code>/c/cs223/Hwk9/toPng filename.pgm</code> to produce a new file <code>filename.pgm.png</code>. This works best if <code>filename.pgm</code> is already in a directory you can write to. PNG files can be displayed using most web browsers and image manipulation tools.</p>
+<h3 id="submitting-and-testing-your-program"><span class="header-section-number">8.9.3</span> Submitting and testing your program</h3>
+<p>Submit whatever files you need to build <code>maze</code> (including a <code>Makefile</code> that generates <code>maze</code> when called with no arguments) using <code>/c/cs223/bin/submit 9</code>. You can apply the public test script in <code>/c/cs223/Hwk9/test.public</code> to your submitted files using <code>/c/cs223/bin/testit 9 public</code>.</p>
+<h3 id="hw9solution"><span class="header-section-number">8.9.4</span> Sample solution</h3>
+<p>This uses breadth-first search, which makes the search a bit simpler
+than depth-first search but requires some more effort to compute the
+cycle. The program also includes code for generating random mazes.</p>
+<div>
+<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"><span class="ot">#include &lt;stdio.h&gt;</span>
+<span class="ot">#include &lt;stdlib.h&gt;</span>
+<span class="ot">#include &lt;assert.h&gt;</span>
+<span class="ot">#include &lt;math.h&gt;</span>
+<span class="ot">#include &lt;limits.h&gt;</span>
+
+<span class="kw">struct</span> direction {
+ <span class="dt">signed</span> <span class="dt">char</span> x;
+ <span class="dt">signed</span> <span class="dt">char</span> y;
+};
+
+<span class="ot">#define DIRECTIONS (8)</span>
+
+<span class="dt">const</span> <span class="kw">struct</span> direction directions[DIRECTIONS] = {
+ { -<span class="dv">1</span>, -<span class="dv">1</span> },
+ { -<span class="dv">1</span>, <span class="dv">0</span> },
+ { -<span class="dv">1</span>, <span class="dv">1</span> },
+ { <span class="dv">0</span>, -<span class="dv">1</span> },
+ { <span class="dv">0</span>, <span class="dv">1</span> },
+ { <span class="dv">1</span>, -<span class="dv">1</span> },
+ { <span class="dv">1</span>, <span class="dv">0</span> },
+ { <span class="dv">1</span>, <span class="dv">1</span> }
+};
+
+<span class="kw">struct</span> position {
+ <span class="dt">int</span> x;
+ <span class="dt">int</span> y;
+};
+
+<span class="dt">const</span> <span class="kw">struct</span> position NO_POSITION = { -<span class="dv">1</span>, -<span class="dv">1</span> };
+
+<span class="dt">static</span> <span class="kw">inline</span> <span class="dt">int</span>
+eqPosition(<span class="kw">struct</span> position p, <span class="kw">struct</span> position q)
+{
+ <span class="kw">return</span> p.x == q.x &amp;&amp; p.y == q.y;
+}
+
+<span class="ot">#define WALL (0)</span>
+<span class="ot">#define PATH (1)</span>
+<span class="ot">#define CYCLE (2)</span>
+
+<span class="kw">struct</span> square {
+ <span class="dt">int</span> contents;
+ <span class="kw">struct</span> position parent; <span class="co">/* used by search routine */</span>
+};
+
+<span class="kw">struct</span> maze {
+ <span class="kw">struct</span> position size; <span class="co">/* rows = size.x, columns = size.y */</span>
+ <span class="kw">struct</span> square *a; <span class="co">/* packed array of squares */</span>
+};
+
+<span class="co">/* look up a position in a maze */</span>
+<span class="ot">#define Mref(m, pos) ((m)-&gt;a[(pos).y * (m)-&gt;size.x + (pos).x])</span>
+<span class="ot">#define Mget(m, pos) (assert((pos).x &gt;= 0 &amp;&amp; (pos).y &gt;= 0 &amp;&amp; (pos).x &lt; (m)-&gt;size.x &amp;&amp; (pos).y &lt; (m)-&gt;size.y), Mref((m), (pos)))</span>
+
+<span class="co">/* add direction to source to get target */</span>
+<span class="co">/* returns 1 if target is in range */</span>
+<span class="dt">int</span>
+offset(<span class="dt">const</span> <span class="kw">struct</span> maze *m, <span class="kw">struct</span> position *target, <span class="kw">struct</span> position source, <span class="kw">struct</span> direction dir)
+{
+ target-&gt;x = source.x + dir.x;
+ target-&gt;y = source.y + dir.y;
+
+ <span class="kw">return</span> target-&gt;x &gt;= <span class="dv">0</span> &amp;&amp; target-&gt;y &gt;= <span class="dv">0</span> &amp;&amp; target-&gt;x &lt; m-&gt;size.x &amp;&amp; target-&gt;y &lt; m-&gt;size.y;
+}
+
+<span class="co">/* free a maze */</span>
+<span class="dt">void</span>
+destroyMaze(<span class="kw">struct</span> maze *m)
+{
+ free(m-&gt;a);
+ free(m);
+}
+
+<span class="co">/* load a maze in restricted PGM format */</span>
+<span class="kw">struct</span> maze *
+loadMaze(FILE *f)
+{
+ <span class="kw">struct</span> maze *m;
+ <span class="kw">struct</span> position i;
+
+ m = malloc(<span class="kw">sizeof</span>(*m));
+ assert(m);
+
+ fscanf(f, <span class="st">"P5 %d %d 255</span><span class="ch">\n</span><span class="st">"</span>, &amp;m-&gt;size.x, &amp;m-&gt;size.y);
+
+ m-&gt;a = malloc(<span class="kw">sizeof</span>(<span class="kw">struct</span> square) * m-&gt;size.y * m-&gt;size.x);
+
+ <span class="kw">for</span>(i.y = <span class="dv">0</span>; i.y &lt; m-&gt;size.y; i.y++) {
+ <span class="kw">for</span>(i.x = <span class="dv">0</span>; i.x &lt; m-&gt;size.x; i.x++) {
+ Mref(m, i).contents = getchar();
+ assert(Mref(m, i).contents == <span class="dv">0</span> || Mref(m, i).contents == <span class="dv">1</span>);
+ }
+ }
+
+ <span class="kw">return</span> m;
+}
+
+<span class="dt">void</span>
+saveMaze(<span class="kw">struct</span> maze *m, FILE *f)
+{
+ <span class="kw">struct</span> position i;
+
+ fprintf(f, <span class="st">"P5 %d %d 255</span><span class="ch">\n</span><span class="st">"</span>, m-&gt;size.x, m-&gt;size.y);
+
+ <span class="kw">for</span>(i.y = <span class="dv">0</span>; i.y &lt; m-&gt;size.y; i.y++) {
+ <span class="kw">for</span>(i.x = <span class="dv">0</span>; i.x &lt; m-&gt;size.x; i.x++) {
+ putc(Mref(m, i).contents, f);
+ }
+ }
+}
+
+<span class="co">/* how many neighbors of position are PATH? */</span>
+<span class="dt">int</span>
+countNeighbors(<span class="dt">const</span> <span class="kw">struct</span> maze *m, <span class="kw">struct</span> position p)
+{
+ <span class="kw">struct</span> position q;
+ <span class="dt">int</span> i;
+ <span class="dt">int</span> count = <span class="dv">0</span>;
+
+ <span class="kw">for</span>(i = <span class="dv">0</span>; i &lt; DIRECTIONS; i++) {
+ <span class="kw">if</span>(offset(m, &amp;q, p, directions[i]) &amp;&amp; Mget(m, q).contents == PATH) {
+ count++;
+ }
+ }
+
+ <span class="kw">return</span> count;
+}
+
+<span class="kw">struct</span> position
+randomPosition(<span class="dt">const</span> <span class="kw">struct</span> maze *m)
+{
+ <span class="kw">struct</span> position r;
+
+ r.x = rand() % m-&gt;size.x;
+ r.y = rand() % m-&gt;size.y;
+
+ <span class="kw">return</span> r;
+}
+
+<span class="ot">#define PATIENCE_MULTIPLIER (4)</span>
+
+<span class="co">/* generate a random connected maze with no cycles */</span>
+<span class="kw">struct</span> maze *
+generateMaze(<span class="kw">struct</span> position size)
+{
+ <span class="kw">struct</span> maze *m;
+ <span class="kw">struct</span> position r;
+ <span class="kw">struct</span> position i;
+ size_t countdown; <span class="co">/* how long to run before we get tired of not making progress */</span>
+ size_t maxCountdown; <span class="co">/* value to reset countdown to when we make progress */</span>
+
+ m = malloc(<span class="kw">sizeof</span>(<span class="kw">struct</span> maze));
+ assert(m);
+
+ m-&gt;size = size;
+ m-&gt;a = malloc(<span class="kw">sizeof</span>(<span class="kw">struct</span> square) * m-&gt;size.x * m-&gt;size.y);
+ assert(m-&gt;a);
+
+ <span class="co">/* start with all WALL */</span>
+ <span class="kw">for</span>(i.y = <span class="dv">0</span>; i.y &lt; m-&gt;size.y; i.y++) {
+ <span class="kw">for</span>(i.x = <span class="dv">0</span>; i.x &lt; m-&gt;size.x; i.x++) {
+ Mref(m, i).contents = WALL;
+ }
+ }
+
+ <span class="co">/* place a PATH on a random square */</span>
+ r = randomPosition(m);
+ Mref(m, r).contents = PATH;
+
+ maxCountdown = PATIENCE_MULTIPLIER * size.x * size.y * log(size.x * size.y);
+
+ <span class="kw">for</span>(countdown = maxCountdown; countdown &gt; <span class="dv">0</span>; countdown--) {
+ <span class="co">/* pick a random square */</span>
+ r = randomPosition(m);
+
+ <span class="co">/* add if we have exactly one neighbor already in the maze */</span>
+ <span class="kw">if</span>(Mget(m, r).contents == WALL &amp;&amp; countNeighbors(m, r) == <span class="dv">1</span>) {
+ Mref(m, r).contents = PATH;
+
+ <span class="co">/* reset countdown */</span>
+ countdown = maxCountdown;
+ }
+ }
+
+ <span class="kw">return</span> m;
+}
+
+<span class="co">/* create a cycle by adding one extra PATH square</span>
+<span class="co"> * that connects two existing squares */</span>
+<span class="dt">void</span>
+mazeAddCycle(<span class="kw">struct</span> maze *m)
+{
+ <span class="kw">struct</span> position r;
+
+ <span class="kw">do</span> {
+ r = randomPosition(m);
+ } <span class="kw">while</span>(Mget(m, r).contents != WALL || countNeighbors(m, r) != <span class="dv">2</span>);
+
+ Mref(m, r).contents = PATH;
+}
+
+<span class="co">/* Search for a cycle of PATH nodes.</span>
+<span class="co"> * If found, mark all nodes on the cycle as CYCLE. */</span>
+<span class="dt">void</span>
+mazeSearchForCycle(<span class="kw">struct</span> maze *m)
+{
+ <span class="kw">struct</span> position root; <span class="co">/* root of tree */</span>
+ <span class="kw">struct</span> position current; <span class="co">/* what we just popped */</span>
+ <span class="kw">struct</span> position parent ; <span class="co">/* current's parent */</span>
+ <span class="kw">struct</span> position neighbor; <span class="co">/* neighbor to push */</span>
+ <span class="kw">struct</span> position ancestor; <span class="co">/* for filling in CYCLE */</span>
+ <span class="dt">int</span> i;
+ <span class="kw">struct</span> position *queue;
+ size_t head; <span class="co">/* where to dequeue */</span>
+ size_t tail; <span class="co">/* where to enqueue */</span>
+
+ <span class="co">/* this is probably more space than we need */</span>
+ queue = malloc(<span class="kw">sizeof</span>(<span class="kw">struct</span> position) * m-&gt;size.x * m-&gt;size.y);
+ assert(queue);
+
+ head = tail = <span class="dv">0</span>;
+
+ <span class="co">/* clear out bookkeeping data */</span>
+ <span class="kw">for</span>(current.y = <span class="dv">0</span>; current.y &lt; m-&gt;size.y; current.y++) {
+ <span class="kw">for</span>(current.x = <span class="dv">0</span>; current.x &lt; m-&gt;size.x; current.x++) {
+ Mref(m, current).parent = NO_POSITION;
+
+ <span class="co">/* probably not necessary but will avoid trouble</span>
+<span class="co"> * if somebody calls this twice */</span>
+ <span class="kw">if</span>(Mget(m, current).contents != WALL) {
+ Mref(m, current).contents = PATH;
+ }
+ }
+ }
+
+ <span class="co">/* find a root */</span>
+ <span class="co">/* we don't care what this is, but it can't be a WALL */</span>
+ <span class="kw">do</span> {
+ root = randomPosition(m);
+ } <span class="kw">while</span>(Mget(m, root).contents != PATH);
+
+ <span class="co">/* push root */</span>
+ Mref(m, root).parent = root;
+ queue[tail++] = root;
+
+ <span class="co">/* now perform the BFS */</span>
+ <span class="co">/* if we ever find a neighbor that is already in the tree and not our parent,</span>
+<span class="co"> * we have found our cycle */</span>
+ <span class="kw">while</span>(head &lt; tail) {
+ current = queue[head++];
+ parent = Mget(m, current).parent;
+
+ <span class="co">/* push all neighbors not already in tree */</span>
+ <span class="co">/* if one is in the tree, we win */</span>
+ <span class="kw">for</span>(i = <span class="dv">0</span>; i &lt; DIRECTIONS; i++) {
+ <span class="kw">if</span>(offset(m, &amp;neighbor, current, directions[i]) &amp;&amp; Mget(m, neighbor).contents == PATH &amp;&amp; !eqPosition(neighbor, parent)) {
+ <span class="co">/* is it already in the tree? */</span>
+ <span class="kw">if</span>(!eqPosition(Mget(m, neighbor).parent, NO_POSITION)) {
+ <span class="co">/* we win */</span>
+ <span class="co">/* cycle consists of all ancestors of neighbor and current</span>
+<span class="co"> * up to common ancestor */</span>
+ <span class="kw">for</span>(ancestor = neighbor; !eqPosition(ancestor, root); ancestor = Mget(m, ancestor).parent) {
+ Mref(m, ancestor).contents = CYCLE;
+ }
+
+ <span class="co">/* also mark root */</span>
+ Mref(m, root).contents = CYCLE;
+
+ <span class="co">/* now work up from current */</span>
+ <span class="kw">for</span>(ancestor = current; !eqPosition(ancestor, root); ancestor = Mget(m, ancestor).parent) {
+ <span class="kw">if</span>(Mget(m, ancestor).contents == PATH) {
+ <span class="co">/* add to the cycle */</span>
+ Mref(m, ancestor).contents = CYCLE;
+ } <span class="kw">else</span> {
+ <span class="co">/* this is the common ancestor, which is not root */</span>
+ <span class="co">/* mark all proper ancestors as PATH */</span>
+ <span class="kw">do</span> {
+ ancestor = Mget(m, ancestor).parent;
+ Mref(m, ancestor).contents = PATH;
+ } <span class="kw">while</span>(!eqPosition(ancestor, root));
+
+ <span class="co">/* can't just break, too many loops */</span>
+ <span class="kw">goto</span> doneWithSearch;
+ }
+ }
+ } <span class="kw">else</span> {
+ Mref(m, neighbor).parent = current;
+ queue[tail++] = neighbor;
+ }
+ }
+ }
+ }
+
+doneWithSearch:
+ free(queue);
+}
+
+<span class="dt">int</span>
+main(<span class="dt">int</span> argc, <span class="dt">char</span> **argv)
+{
+ <span class="kw">struct</span> maze *m;
+ <span class="kw">struct</span> position size = { <span class="dv">80</span>, <span class="dv">60</span> };
+ <span class="dt">int</span> seed;
+
+ <span class="kw">switch</span>(argc) {
+ <span class="kw">case</span> <span class="dv">1</span>:
+ <span class="co">/* sample solution for the assignment */</span>
+ m = loadMaze(stdin);
+ mazeSearchForCycle(m);
+ saveMaze(m, stdout);
+ destroyMaze(m);
+ <span class="kw">break</span>;
+ <span class="kw">case</span> <span class="dv">4</span>:
+ <span class="co">/* generate a new test image */</span>
+ <span class="co">/* usage is ./maze width height seed */</span>
+ <span class="co">/* if seed is negative, use absolute value and don't put in cycle */</span>
+ size.x = atoi(argv[<span class="dv">1</span>]);
+ size.y = atoi(argv[<span class="dv">2</span>]);
+ seed = atoi(argv[<span class="dv">3</span>]);
+
+ srand(seed &lt; <span class="dv">0</span> ? -seed : seed);
+ m = generateMaze(size);
+ <span class="kw">if</span>(seed &gt;= <span class="dv">0</span>) { mazeAddCycle(m); }
+ saveMaze(m, stdout);
+ destroyMaze(m);
+ <span class="kw">break</span>;
+ <span class="kw">default</span>:
+ fprintf(stderr, <span class="st">"Usage %s or %s width height seed</span><span class="ch">\n</span><span class="st">"</span>, argv[<span class="dv">0</span>], argv[<span class="dv">0</span>]);
+ <span class="kw">return</span> <span class="dv">1</span>;
+ }
+
+ <span class="kw">return</span> <span class="dv">0</span>;
+}</code></pre></div>
+<a href="http://cs.yale.edu/homes/aspnes/classes/223/examples/2015/hw/9/maze.c" class="uri">examples/2015/hw/9/maze.c</a>
+</div>
+<p>And the <a href="http://cs.yale.edu/homes/aspnes/classes/223/examples/2015/hw/9/Makefile">Makefile</a>.</p>
+<h1 id="codingHints"><span class="header-section-number">9</span> Common C coding and debugging issues</h1>
+<p>Here are some notes from a helpful Zoo denizen about debugging
+programs in 223. (Note: these have been edited slightly from the
+original.)</p>
+<pre><code>Date: Thu, 10 Feb 2005 06:02:23 -0500 (EST)
+From: James Terry &lt;james.c.terry@yale.edu&gt;
+Subject: 223 coding feedback
+
+Hi Jim,
+
+Several of your students for 223 were up late last night in the Zoo
+working on their assignments, and they seemed to be getting hung up on
+some coding issues. They were pretty frustrated with some standard
+language/debugging issues, so I helped them get the type-checker and
+Valgrind to stop yelling at them. I noticed some recurring problems and I
+thought I'd pass them on to you. They're pretty standard mistakes, and
+I've made most of them myself at some point, either in your class or in
+Stan's. It occurred to me that there might be more confused people than
+were around last night, and they'd probably appreciate it if someone told
+them about these sort of things. I'm not trying to intrude on how you
+teach the class; I just thought this feedback would be helpful and I
+wasn't sure that it would find its way to you otherwise. I'm sure you've
+already taught them several of these, and I understand that sometimes
+students just don't pay attention. Still, these seem like good points to
+hammer down:
+
+Recurring debugging/coding problems:
+
+1. If you want a debugger/Valgrind to give you line numbers, you must
+compile with debugging info turned on, i. e. using the -g[level] flag.
+2. On the Zoo, pointers and int's are 4 bytes; char's are 1. (Some
+people didn't seem to realize that a char* is 4 bytes rather than 1.)
+3. I think it would be helpful if you explained why, when using
+realloc(), it's a good idea to increase the allocated size
+multiplicatively rather than additively. Besides, everyone loves the
+"tearing down the hotel" metaphor. :)
+4. If they use call-by-reference, they had better make sure that they
+keep the same reference. So if they pass in a pointer as an argument to a
+function, they shouldn't call malloc() or realloc() on that function.
+(Mention the double pointer as another option.) Most people will make
+this mistake eventually if no one warns them about it. When I was
+learning C, I sort of viewed malloc() and realloc() as magical
+memory-increasing functions; that is to say, I didn't think very hard
+about the meaning of assigning a pointer to malloc()'s return value. I
+suspect some of your students would benefit from having the details
+spelled out. (Or spelled out again, if you've already done that.)
+5. It's possible to get through a lot (but not all) of the CS major
+without learning basic Unix shell syntax, but that's really just wasted
+time. Pipes, backgrounding, man, scp, and grep really help even at the
+intro level. I realize the purpose of the class isn't to teach Unix, but
+in past years I think there was a TA help session on these things. They
+don't need to know how to write their own Emacs modes, but the basics
+would definitely be helpful.
+6. malloc/free -- If Valgrind/gdb reports a problem inside of malloc() or
+free(), chances are that the student has *not* discovered a bug in gcc.
+(I just heard how one of Zhong's students' proved the correctness of the
+libraries for his thesis; that's pretty cool.) Explain why you can't
+malloc() twice on the same pointer. Explain how with multidimensional
+pointers, you must malloc/free each dimension separately. Drill down the
+one-to-one correspondence between malloc'ing and free'ing.
+7. Null characters: It's not obvious to newbies that some library functions
+require them, particularly null-terminated strings. Tell them that
+char*'s must be null terminated in order for &lt;string.h&gt;
+functions to work.
+8. Off-by-one errors: Tell people that when all else fails, take a hard
+look at their comparison operators; i. e. make sure that &gt; shouldn't
+really be a &gt;=.
+9. This is probably another thing for a help session or workshop, but I
+feel almost everyone could benefit from basic software engineering
+methodology. Stylistic awkwardness I noticed:
+ --Using a mess of if-then-else's instead of nested control
+structures.
+ --Using while-loops with iterators that get initialized right
+before the beginning of the loop and get incremented with each iteration,
+when they could be using for-loops.
+ --Doing the setup work for a loop right before the beginning of
+the loop and then at the end of every iteration, instead of at the
+beginning of every iteration. Conversely: doing the cleanup work at the
+beginning of every iteration and then after the loop has completed.
+10. Tell them to use assert(). (Frequently.) When you cover binary
+search, using placement of debugging statements in code in order to pin
+down an error might be an instructive example.
+11. Tell them to use either printf statements or a debugger to debug. I
+think they can figure out how to do this on their own, they just need to
+be told it's a good idea.
+
+Hopefully some of these suggestions will be helpful. I won't be offended
+if you don't pass them on to your students, and I understand if you put a
+higher teaching priority on non-coding subjects, but all the things I
+mentioned were things I wish someone had told me. I'd be happy to run a
+help session on this stuff if you and the TAs are too busy, but otherwise
+I wouldn't presume.
+
+Best,
+Jim</code></pre>
+<div class="footnotes">
+<hr>
+<ol>
+<li id="fn1"><p>I would like to thank David Galles for making this site available and Xiao Shi for pointing me to it.<a href="#fnref1">↩</a></p></li>
+<li id="fn2"><p>Note that because each row is in the same <code>malloc</code>-ed block as its adjacent rows, <code>valgrind</code> will not detect if you run off the end of a row in this implementation.<a href="#fnref2">↩</a></p></li>
+<li id="fn3"><p>The compiler is GCC version 4.8.2-19ubuntu1 running on a
+ Linux 3.13.0-44-generic kernel running inside VirtualBox on a Windows
+8.1 machine with a 3.30-Ghz AMD FX-6100 CPU, so don't be surprised if
+you get different numbers on a real machine.<a href="#fnref3">↩</a></p></li>
+<li id="fn4"><p>The pattern here is that <code class="backtick">HEAD</code> is the most recent commit, <code class="backtick">HEAD^</code> the one before it, <code class="backtick">HEAD^^</code> the one before that, and so on. This is sometimes nicer than having to pull hex gibberish out of the output of <code class="backtick">git&nbsp;log</code>.<a href="#fnref4">↩</a></p></li>
+<li id="fn5"><p>Technically I can use <code class="backtick">git&nbsp;reset</code> to get rid of the commit, but <code class="backtick">git&nbsp;reset</code> can be dangerous, since it throws away information.<a href="#fnref5">↩</a></p></li>
+<li id="fn6"><p>This convention was not always followed in the early days of computing. For example, the <a href="http://www.linfo.org/pdp-7.html">PDP-7</a>
+ on which UNIX was first developed used 18-bit words, which conveniently
+ translated into six octal digits back in the pre-hexadecimal era.<a href="#fnref6">↩</a></p></li>
+<li id="fn7"><p>Certain ancient versions of C ran on machines with a different character set encoding, like <a href="http://en.wikipedia.org/wiki/EBCDIC" title="WikiPedia">EBCDIC</a>. The C standard does not guarantee ASCII encoding.<a href="#fnref7">↩</a></p></li>
+<li id="fn8"><p>C++ programmers will prefer <code>++x</code> if they are not otherwise using the return value, because if <code>x</code> is some very complicated type with overloaded <code>++</code>, using preincrement avoids having to save a copy of the old value.<a href="#fnref8">↩</a></p></li>
+<li id="fn9"><p>Exception: Global variables and static local variables
+are guaranteed to be initialized to an all-0 pattern, which will give
+the value 0 for most types.<a href="#fnref9">↩</a></p></li>
+<li id="fn10"><p>The reason for excluding <code>char *</code> and <code>void *</code> is that these are often used to represent pointers to objects with arbitrary types.<a href="#fnref10">↩</a></p></li>
+<li id="fn11"><p>In this case you will get lucky most of the time, since
+ the odds are that malloc will give you a block that is slightly bigger
+than <code class="backtick">strlen(s)</code> anyway. But bugs that only
+manifest themselves occasionally are even worse than bugs that kill your
+ program every time, because they are much harder to track down.<a href="#fnref11">↩</a></p></li>
+<li id="fn12"><p>Some programs (e.g. <code class="backtick">/c/cs223/bin/submit</code>) will use this to change their behavior depending on what name you call them with.<a href="#fnref12">↩</a></p></li>
+<li id="fn13"><p>There are various ways to work around this. The simplest is to put a <code>union</code> inside a larger <code>struct</code> that includes an explicit type tag.<a href="#fnref13">↩</a></p></li>
+<li id="fn14"><p>Arguably, this is a bug in the design of the language: if the compiler knows that <code class="backtick">sp</code> has type <code class="backtick">struct&nbsp;string&nbsp;*</code>, there is no particular reason why it can't interpret <code class="backtick">sp.length</code> as <code class="backtick">sp-&gt;length</code>. But it doesn't do this, so you will have to remember to write <code class="backtick">sp-&gt;length</code> instead.<a href="#fnref14">↩</a></p></li>
+<li id="fn15"><p>This is also the simplest way to deal with the
+inconsistencies between different compilers in how they handle inline
+functions. For an extensive discussion of the terrifying portability
+issues that arise in pre-C99 C compilers, see <a href="http://www.greenend.org.uk/rjk/tech/inline.html" class="uri">http://www.greenend.org.uk/rjk/tech/inline.html</a>.<a href="#fnref15">↩</a></p></li>
+<li id="fn16"><p>To make the example work, we are violating our usual rule of always using braces in <code>if</code> statements.<a href="#fnref16">↩</a></p></li>
+<li id="fn17"><p>The <code>#</code> operator looks like it ought to be
+useful here, but it only works for expanding arguments to macros and not
+ for expanding macros themselves. Attempting to get around this by
+wrapping <code>MESSAGE</code> in a macro that applies the <code>#</code> operator to its first argument will end in tears if <code>MESSAGE</code> contains any special characters like commas or right parentheses. The C preprocessor has many unfortunate limitations.<a href="#fnref17">↩</a></p></li>
+<li id="fn18"><p>This is an abuse of notation, where the equals sign is
+really acting like set membership. The general rule is that an
+expression <span class="math inline"><em>O</em>(<em>f</em>(<em>n</em>)) = <em>O</em>(<em>g</em>(<em>n</em>))</span> is true if for any choice of a function in <span class="math inline"><em>O</em>(<em>f</em>(<em>n</em>))</span>, that function is in <span class="math inline"><em>O</em>(<em>g</em>(<em>n</em>))</span>. This relation is transitive and symmetric, but unlike real equality it's not symmetric.<a href="#fnref18">↩</a></p></li>
+<li id="fn19"><p>The example below uses the <code>offsetof</code> macro, defined in <code>stddef.h</code>,
+ to allocate a truncated head that doesn't include this extra space.
+This is probably more trouble than it is worth in this case, but might
+be useful if we were creating a lot of dummy heads and the contents were
+ more than 4 bytes long.<a href="#fnref19">↩</a></p></li>
+<li id="fn20"><p>A small child of my acquaintance once explained that this wouldn't work, because you would hit your head on the ceiling.<a href="#fnref20">↩</a></p></li>
+<li id="fn21"><p>A summary of the state of this problem as of 2013 can be found in <a href="http://arxiv.org/pdf/1306.0207v1.pdf" class="uri">http://arxiv.org/pdf/1306.0207v1.pdf</a>.<a href="#fnref21">↩</a></p></li>
+<li id="fn22"><p>This only works if the graph is undirected, which means that for every edge <span class="math inline"><em>u</em><em>v</em></span> there is a matching edge <span class="math inline"><em>v</em><em>u</em></span> with the same weight.<a href="#fnref22">↩</a></p></li>
+<li id="fn23"><p>But it's linear in the numerical value of the output, which means that <code>fib(n)</code> will actually terminate in a reasonable amount of time on a typical modern computer when run on any <span class="math inline"><em>n</em></span> small enough that <span class="math inline"><em>F</em>(<em>n</em>)</span> fits in 32 bits. Running it using 64-bit (or larger) integer representations will be slower.<a href="#fnref23">↩</a></p></li>
+<li id="fn24"><p>The actual analysis is pretty complicated, since we are
+ more likely to land in a bigger pile, but it's not hard to show that on
+ average even the bigger pile has no more than 3/4 of the elements.<a href="#fnref24">↩</a></p></li>
+<li id="fn25"><p>This otherwise insane-looking modification is useful for modeling scheduling problems, where <code class="backtick">a+b</code> is the time to do <code class="backtick">a</code> and <code class="backtick">b</code> in parallel, and <code class="backtick">a*b</code> is the time to do <code class="backtick">a</code> and <code class="backtick">b</code> sequentially. The reason for making the first case <code class="backtick">+</code> and the second case <code class="backtick">*</code> is because this makes the distributive law <code class="backtick">a*(b+c)&nbsp;=&nbsp;(a*b)+(a*c)</code> work. It also allows tricks like matrix multiplication using the standard definition. See <a href="http://maxplus.org/" class="uri">http://maxplus.org</a> for more than you probably want to know about this.<a href="#fnref25">↩</a></p></li>
+<li id="fn26"><p>Not intended as legal advice.<a href="#fnref26">↩</a></p></li>
+<li id="fn27"><p>Stratfordians, Oxfordians, and other conspiracy
+theorists might object that these results depend critically on the
+precise formatting of the text. We counter this objection by observing
+that we used the <a href="http://www.gutenberg.org/ebooks/2235">Project Gutenberg e-text of <em>The Tempest</em></a>,
+ which, while not necessarily the most favored by academic Shakespeare
+scholars, is the easiest version to obtain on-line. We consider it
+further evidence of Sir Francis Bacon's genius that not only was he able
+ to subtly encode his name throughout his many brilliant plays, but he
+was even able to anticipate the effects of modern spelling and
+punctuation on this encoding.<a href="#fnref27">↩</a></p></li>
+<li id="fn28"><p>Normally this is a dangerous thing to assume, but this assignment is complicated enough already.<a href="#fnref28">↩</a></p></li>
+</ol>
+</div>
+
+
+</body></html> \ No newline at end of file
diff --git a/Computer_Science/data_structures/chapter_4/a.out b/Computer_Science/data_structures/chapter_4/a.out
deleted file mode 100755
index b1815f0..0000000
--- a/Computer_Science/data_structures/chapter_4/a.out
+++ /dev/null
Binary files differ
diff --git a/Computer_Science/data_structures/chapter_4/avl_tree b/Computer_Science/data_structures/chapter_4/avl_tree
index 1d5d102..95b05bd 100755
--- a/Computer_Science/data_structures/chapter_4/avl_tree
+++ b/Computer_Science/data_structures/chapter_4/avl_tree
Binary files differ
diff --git a/Computer_Science/data_structures/chapter_4/avl_tree.c b/Computer_Science/data_structures/chapter_4/avl_tree.c
index da6ab0d..f84db7b 100644
--- a/Computer_Science/data_structures/chapter_4/avl_tree.c
+++ b/Computer_Science/data_structures/chapter_4/avl_tree.c
@@ -134,6 +134,63 @@ AvlTree insert(elem_t x, AvlTree t)
return t;
}
+AvlTree insert_nonrecursive(elem_t x, AvlTree t)
+{
+ Position tmp;
+ Position prev[100] ;
+ Position p = t;
+ int i = 0;
+ int j;
+
+ /* index 0 not used */
+ prev[i] = p;
+ while(p) {
+ if(x < p->elem) {
+ prev[++i] = p;
+ p = p->left;
+ } else if(x > p->elem) {
+ prev[++i] = p;
+ p = p->right;
+ } else
+ return t;
+ }
+
+ tmp = malloc(sizeof(struct AvlNode));
+ tmp->elem = x;
+ tmp->left = tmp->right = NULL;
+ tmp->height = 0;
+
+ if(!prev[i]) {
+ return tmp;
+ } else if(x < prev[i]->elem) {
+ prev[i]->left = tmp;
+ prev[i]->height++;
+ if(i - 1 > 0) {
+ if(prev[i - 1]->left == prev[i]
+ && prev[i]->height - height(prev[i - 1]->right) == 2)
+ prev[i - 2] = single_rotate_with_left(prev[i - 1]);
+ else if(prev[i - 1]->right == prev[i]
+ && prev[i]->height - height(prev[i - 1]->left) == 2)
+ prev[i - 2] = double_rotate_with_left(prev[i - 1]);
+ }
+ }
+ else {
+ prev[i]->right = tmp;
+ prev[i]->height++;
+ if(i - 1 > 0) {
+ if(prev[i - 1]->right == prev[i]
+ && prev[i]->height - height(prev[i - 1]->left) == 2)
+ prev[i - 2] = single_rotate_with_right(prev[i - 1]);
+ else if(prev[i - 1]->left == prev[i]
+ && prev[i]->height - height(prev[i - 1]->right) == 2) {
+ prev[i - 2] = double_rotate_with_right(prev[i - 2]);
+ }
+ }
+ }
+
+ return t;
+}
+
/* lazy delete ? */
AvlTree delete(elem_t x, AvlTree t)
{
@@ -142,18 +199,15 @@ AvlTree delete(elem_t x, AvlTree t)
void test()
{
+ int i;
AvlTree t = NULL;
- t = insert(4, t);
- t = insert(3, t);
- t = insert(2, t);
- t = insert(1, t);
- t = insert(8, t);
- t = insert(9, t);
+ for(i = 0; i < 3; i++) {
+ t = insert_nonrecursive(i + 1, t);
+ }
printf("min:%d\n", find_min(t)->elem);
printf("max:%d\n", find_max(t)->elem);
- printf("find 2:%d\n", find(2, t)->elem);
print_ascii_tree(t);
}
diff --git a/Computer_Science/data_structures/chapter_4/avl_tree.c.out b/Computer_Science/data_structures/chapter_4/avl_tree.c.out
new file mode 100755
index 0000000..005cc26
--- /dev/null
+++ b/Computer_Science/data_structures/chapter_4/avl_tree.c.out
Binary files differ
diff --git a/Computer_Science/data_structures/chapter_4/binary_search_tree.c.out b/Computer_Science/data_structures/chapter_4/binary_search_tree.c.out
new file mode 100755
index 0000000..231ea0b
--- /dev/null
+++ b/Computer_Science/data_structures/chapter_4/binary_search_tree.c.out
Binary files differ
diff --git a/Computer_Science/data_structures/chapter_4/depth_or_random_binary_search_tree.pdf b/Computer_Science/data_structures/chapter_4/depth_or_random_binary_search_tree.pdf
new file mode 100644
index 0000000..04ba606
--- /dev/null
+++ b/Computer_Science/data_structures/chapter_4/depth_or_random_binary_search_tree.pdf
Binary files differ
diff --git a/Computer_Science/data_structures/chapter_4/depth_or_random_binary_search_tree_handout.pdf b/Computer_Science/data_structures/chapter_4/depth_or_random_binary_search_tree_handout.pdf
new file mode 100644
index 0000000..e2ea753
--- /dev/null
+++ b/Computer_Science/data_structures/chapter_4/depth_or_random_binary_search_tree_handout.pdf
Binary files differ
diff --git a/Computer_Science/leetcode/15-3_sum.c b/Computer_Science/leetcode/15-3_sum.c
new file mode 100644
index 0000000..cb60873
--- /dev/null
+++ b/Computer_Science/leetcode/15-3_sum.c
@@ -0,0 +1,37 @@
+/**
+ * Return an array of arrays of size *returnSize.
+ * Note: The returned array must be malloced, assume caller calls free().
+ */
+void helper(int **result, int *nums, int start, int numsSize, int *tmp, int count, int *returnSize)
+{
+ if(start >= numsSize) return;
+ if(count < 3) {
+ tmp[count] = nums[start];
+ helper(result, nums, start + 1, numsSize, tmp, count + 1, returnSize);
+ }
+ else if(count == 3) {
+ if(tmp[0] + tmp[1] + tmp[2] == 0) {
+ *(result + *returnSize) = malloc(sizeof(int) * 3);
+ **(result + *returnSize) = tmp[0];
+ *(*(result + *returnSize) + 1) = tmp[1];
+ *(*(result + *returnSize) + 2) = tmp[2];
+ ++*returnSize;
+ }
+ helper(result, nums, start, numsSize, tmp, count - 1, returnSize);
+ helper(result, nums, start, numsSize, tmp, count - 2, returnSize);
+ }
+
+}
+
+int** threeSum(int* nums, int numsSize, int* returnSize) {
+ *returnSize = 0;
+ int **result = malloc(sizeof(int *) * 100);
+ int tmp[3];
+ int count = 0;
+
+ for(int i = 0; i < numsSize; i++) {
+ helper(result, nums, i, numsSize, tmp, 0, returnSize);
+ }
+
+ return result;
+}
diff --git a/Computer_Science/leetcode/15-3_sum.c~ b/Computer_Science/leetcode/15-3_sum.c~
new file mode 100644
index 0000000..54dbbd2
--- /dev/null
+++ b/Computer_Science/leetcode/15-3_sum.c~
@@ -0,0 +1,7 @@
+/**
+ * Return an array of arrays of size *returnSize.
+ * Note: The returned array must be malloced, assume caller calls free().
+ */
+int** threeSum(int* nums, int numsSize, int* returnSize) {
+
+}
diff --git a/Computer_Science/leetcode/17-letter_combinations_of_a_phone_number.c b/Computer_Science/leetcode/17-letter_combinations_of_a_phone_number.c
new file mode 100644
index 0000000..eeabd21
--- /dev/null
+++ b/Computer_Science/leetcode/17-letter_combinations_of_a_phone_number.c
@@ -0,0 +1,46 @@
+/**
+ * Return an array of size *returnSize.
+ * Note: The returned array must be malloced, assume caller calls free().
+ */
+void helper(char **result, char *map[10], char *digits, char *tmp, int index, int *returnSize)
+{
+ char *p = map[*digits - '0'];
+ for(; *p; ++p) {
+ tmp[index] = *p;
+ helper(result, map, digits + 1, tmp, index + 1, returnSize);
+ }
+ if(*digits == '\0') {
+ *(result + *returnSize) = malloc(sizeof(char) * index + 1);
+ for(int i = 0; i < index; i++) {
+ *(*(result + *returnSize) + i) = tmp[i];
+ }
+ *(*(result + *returnSize) + index) = '\0';
+ ++*returnSize;
+ }
+}
+char** letterCombinations(char* digits, int* returnSize) {
+ int len = strlen(digits);
+ int index = 0;
+ char tmp[len + 1];
+ char **result = malloc(sizeof(int *) * 100);
+ char *map[10] = {
+ " ", " ", "abc", "def", "ghi", "jkl", "mno", "pqrs", "tuv", "wxyz"
+ };
+
+ *returnSize = 0;
+
+ if(len < 1)
+ return result;
+
+ while(*digits) {
+ if(*digits >= '2' && *digits <= '9') {
+ helper(result, map, digits, tmp, index, returnSize);
+ } else {
+ *returnSize = 0;
+ break;
+ }
+ ++digits;
+ }
+
+ return result;
+}
diff --git a/Computer_Science/leetcode/17-letter_combinations_of_a_phone_number.c~ b/Computer_Science/leetcode/17-letter_combinations_of_a_phone_number.c~
new file mode 100644
index 0000000..d31867b
--- /dev/null
+++ b/Computer_Science/leetcode/17-letter_combinations_of_a_phone_number.c~
@@ -0,0 +1,11 @@
+/**
+ * Return an array of size *returnSize.
+ * Note: The returned array must be malloced, assume caller calls free().
+ */
+char** letterCombinations(char* digits, int* returnSize) {
+ while(*digits) {
+ if(*digits >= '2' && *digits <= '9') {
+ } else
+ return "";
+ }
+}
diff --git a/Computer_Science/leetcode/5-longest_palindromic_substring.c b/Computer_Science/leetcode/5-longest_palindromic_substring.c
new file mode 100644
index 0000000..ee65b8e
--- /dev/null
+++ b/Computer_Science/leetcode/5-longest_palindromic_substring.c
@@ -0,0 +1,34 @@
+void extend(char *s, int len, int i, int j, int *lo, int *hi)
+{
+ while(i >= 0 && i < len && s[i] == s[j]) {
+ i--;
+ j++;
+ }
+
+ if(j - i > *hi - *lo) {
+ *lo = i;
+ *hi = j;
+ }
+}
+
+char* longestPalindrome(char* s) {
+ int *lo, *hi;
+ int len = strlen(s);
+
+ lo = malloc(sizeof(int));
+ hi = malloc(sizeof(int));
+
+ *lo = *hi = 0;
+ if(len < 2)
+ return s;
+
+ for(int i = 0; i < len - 1; i++) {
+ extend(s, len, i, i, lo, hi);
+ extend(s, len, i, i + 1, lo, hi);
+ }
+
+ *(s + (*hi)) = '\0';
+ return s + *lo + 1;
+}
+
+
diff --git a/Computer_Science/leetcode/5-longest_palindromic_substring.c~ b/Computer_Science/leetcode/5-longest_palindromic_substring.c~
new file mode 100644
index 0000000..99c44fc
--- /dev/null
+++ b/Computer_Science/leetcode/5-longest_palindromic_substring.c~
@@ -0,0 +1,7 @@
+char* longestPalindrome(char* s) {
+ int *lo, *hi;
+
+ *(p + (*hi) + 1) = '0';
+ return p + *lo;
+}
+
diff --git a/Computer_Science/leetcode/60-permutation_sequence.c b/Computer_Science/leetcode/60-permutation_sequence.c
index 4eadf4c..259d00b 100644
--- a/Computer_Science/leetcode/60-permutation_sequence.c
+++ b/Computer_Science/leetcode/60-permutation_sequence.c
@@ -1,18 +1,35 @@
-char* getPermutation(int n, int k) {
- char* result = malloc(sizeof(char) * n + 1);
+int getKth(int k, int* nums, int len)
+{
+ int result = nums[k];
+
+ for(int i = k; i < len - 1; i++)
+ nums[i] = nums[i + 1];
+
+ return result;
+}
+char* getPermutation(int n, int k)
+{
+ if(n == 0) return NULL;
+
+ char* result = malloc(sizeof(char) * (n + 1));
int use;
- int used[n];
+ int nums[n];
int fac[n];
+ int len = n;
+
fac[0] = 1;
- fac[1] = 1;
- for(int i = 2; i < n; ++i) {
- fac[i] = fac[i - 1] * n;
+ for(int i = 1; i < n; ++i) {
+ nums[i - 1] = i;
+ fac[i] = fac[i - 1] * i;
}
+ nums[n - 1] = n;
for(int i = 0; i < n; ++i) {
- use = 1 + ((k - 1) / fac[n-i]);
- k -= fac[n-i];
+ /* here k = n - 1, i.e. get 2th, index = 1 */
+ use = getKth(((k - 1) / fac[n - 1 - i]), nums, len);
+ len--;
+ k -= ((k - 1) / fac[n - 1 - i]) * fac[n - 1 - i];
result[i] = use + '0';
}
diff --git a/Computer_Science/leetcode/67-add_binary.c b/Computer_Science/leetcode/67-add_binary.c
new file mode 100644
index 0000000..48e4744
--- /dev/null
+++ b/Computer_Science/leetcode/67-add_binary.c
@@ -0,0 +1,75 @@
+#define MAX(a, b) ((a) > (b) ? (a) : (b))
+char* addBinary(char* a, char* b) {
+ int lenA = strlen(a);
+ int lenB = strlen(b);
+
+ int len = MAX(lenA, lenB) + 1;
+ char* result = malloc(sizeof(char) * (len + 1));
+ result[len--] = '\0';
+ char in = '0';
+ int sum = 0;
+
+ lenA--;
+ lenB--;
+
+ if(len == 0) return "0";
+
+ while(lenA >= 0 && lenB >=0) {
+ sum = a[lenA] + b[lenB] + in - 3 * '0';
+ switch(sum) {
+ case 0:
+ in = '0';
+ result[len] = '0';
+ break;
+ case 1:
+ in = '0';
+ result[len] = '1';
+ break;
+ case 2:
+ in = '1';
+ result[len] = '0';
+ break;
+ case 3:
+ in = '1';
+ result[len] = '1';
+ break;
+ }
+ lenA--;
+ lenB--;
+ len--;
+ }
+
+ while(lenA >= 0) {
+ if(in == '0') {
+ result[len] = a[lenA];
+ } else if(a[lenA] == '1') {
+ result[len] = '0';
+ in = '1';
+ } else {
+ result[len] = '1';
+ in = '0';
+ }
+ lenA--;
+ len--;
+ }
+
+ while(lenB >= 0) {
+ if(in == '0') {
+ result[len] = b[lenB];
+ } else if(b[lenB] == '1') {
+ result[len] = '0';
+ in = '1';
+ } else {
+ result[len] = '1';
+ in = '0';
+ }
+ lenB--;
+ len--;
+ }
+
+ if(in == '0')
+ return result + 1;
+
+ *result = '1';
+ return result;
+}
diff --git a/Computer_Science/leetcode/67-add_binary.c~ b/Computer_Science/leetcode/67-add_binary.c~
new file mode 100644
index 0000000..1fdffec
--- /dev/null
+++ b/Computer_Science/leetcode/67-add_binary.c~
@@ -0,0 +1,30 @@
+#define MAX(a, b) ((a) > (b) ? (a) : (b))
+char* addBinary(char* a, char* b) {
+ char* result = malloc(sizeof(char) * (MAX(strlen(a), strlen(b)) + 2));
+ char in = '0';
+ int sum = 0;
+ while(*a && *b) {
+ sum = *a + *b + in - 3 * '0';
+ switch(sum) {
+ case 0:
+ in = '0';
+ *result = '0';
+ break;
+ case 1:
+ in = '0';
+ *result = '1';
+ break;
+ case 2:
+ in = '1';
+ *result = '0';
+ break;
+ case 3:
+ in = '1';
+ *result = '1';
+ break;
+ }
+
+ result++;
+ }
+
+}
diff --git a/Computer_Science/leetcode/73-set_matrix_zeros.c b/Computer_Science/leetcode/73-set_matrix_zeros.c
new file mode 100644
index 0000000..31d530f
--- /dev/null
+++ b/Computer_Science/leetcode/73-set_matrix_zeros.c
@@ -0,0 +1,46 @@
+void helper(int** matrix, int rowOffset, int colOffset, int rowSize, int colSize, int maxRowSize, int maxColSize)
+{
+ if(rowOffset >= maxRowSize || colOffset >= maxColSize
+ || rowOffset < 0 || colOffset < 0
+ || rowSize <= 0 || colSize <= 0)
+ return;
+ for(int i = 0; i < rowSize; i++)
+ for(int j = 0; j < colSize; j++)
+ if(matrix[rowOffset + i][colOffset + j] == 0) {
+ for(int m = 0; m < colSize; m++)
+ matrix[rowOffset + i][colOffset + m] = 0;
+ for(int m = 0; m < rowSize; m++)
+ matrix[rowOffset + m][colOffset + j] = 0;
+ //left
+ helper(matrix, rowOffset + 1, colOffset, rowSize - 1 - i, j, maxRowSize, maxColSize);
+ //right
+ helper(matrix, rowOffset + 1, colOffset + j + 1, rowSize - 1 - i, colSize - 1 - j, maxRowSize, maxColSize);
+ return;
+ }
+}
+void setZeroes(int** matrix, int matrixRowSize, int matrixColSize) {
+ helper(matrix, 0, 0, matrixRowSize, matrixColSize, matrixRowSize, matrixColSize);
+}
+
+
+//Flag version need to be improved
+
+
+void setZeroes(int** matrix, int matrixRowSize, int matrixColSize) {
+ int flag = INT_MIN;
+
+ for(int i = 0; i < matrixRowSize; i++)
+ for(int j = 0; j < matrixColSize; j++) {
+ if(matrix[i][j] == 0) {
+ for(int m = 0; m < matrixRowSize; m++)
+ matrix[m][j] = matrix[m][j] == 0 ? 0 : flag;
+ for(int m = 0; m < matrixColSize; m++)
+ matrix[i][m] = matrix[i][m] == 0 ? 0 : flag;
+ }
+ }
+
+ for(int i = 0; i < matrixRowSize; i++)
+ for(int j = 0; j < matrixColSize; j++) {
+ if(matrix[i][j] == flag) matrix[i][j] = 0;
+ }
+}
diff --git a/Computer_Science/leetcode/73-set_matrix_zeros.c~ b/Computer_Science/leetcode/73-set_matrix_zeros.c~
new file mode 100644
index 0000000..e9f222b
--- /dev/null
+++ b/Computer_Science/leetcode/73-set_matrix_zeros.c~
@@ -0,0 +1,7 @@
+void helper(int** matrix, int offset, int rowSize, int colSize)
+{
+ if(offset > rowSize || offset > colSize)
+ return;
+}
+void setZeroes(int** matrix, int matrixRowSize, int matrixColSize) {
+}
diff --git a/Computer_Science/leetcode/746-min_cost_climbing_stairs.c b/Computer_Science/leetcode/746-min_cost_climbing_stairs.c
new file mode 100644
index 0000000..74cc72b
--- /dev/null
+++ b/Computer_Science/leetcode/746-min_cost_climbing_stairs.c
@@ -0,0 +1,14 @@
+#define MIN(a, b) ((a) > (b) ? (b) : (a))
+int minCostClimbingStairs(int* cost, int costSize) {
+ int dp[costSize + 1];
+ if(costSize == 1)
+ return cost[0];
+ dp[0] = 0;
+ dp[1] = 0;
+
+ for(int i = 2; i < costSize + 1; i++) {
+ dp[i] = MIN(dp[i - 1] + cost[i - 1], dp[i - 2] + cost[i - 2]);
+ }
+
+ return dp[costSize];
+}
diff --git a/Computer_Science/leetcode/746-min_cost_climbing_stairs.c~ b/Computer_Science/leetcode/746-min_cost_climbing_stairs.c~
new file mode 100644
index 0000000..44ffb6b
--- /dev/null
+++ b/Computer_Science/leetcode/746-min_cost_climbing_stairs.c~
@@ -0,0 +1,14 @@
+#define MIN(a, b) ((a) > (b) ? (a) : (b))
+int minCostClimbingStairs(int* cost, int costSize) {
+ int dp[costSize];
+ if(costSize == 1)
+ return cost[0];
+ dp[0] = 0;
+ dp[1] = 0;
+
+ for(i = 2; i < costSize; i++) {
+ dp[i] = MIN(dp[i - 1] + cost[i - 1], dp[i - 2] + cost[i - 2]);
+ }
+
+ return dp[costSize - 1];
+}
diff --git a/Computer_Science/leetcode/75-sort_colors.c b/Computer_Science/leetcode/75-sort_colors.c
new file mode 100644
index 0000000..cc8fe51
--- /dev/null
+++ b/Computer_Science/leetcode/75-sort_colors.c
@@ -0,0 +1,41 @@
+void swap(int* a, int*b)
+{
+ int tmp;
+ tmp = *a;
+ *a = *b;
+ *b = tmp;
+}
+
+void sortColors(int* nums, int numsSize) {
+ int wIndex, bIndex;
+ wIndex = 0;
+ bIndex = numsSize - 1;
+
+ while(nums[bIndex] == 2)
+ bIndex--;
+
+ // here <= or < ?
+ for(int i = 0; i <= bIndex; i++) {
+ if(nums[i] == 0) {
+ swap(nums + i, nums + wIndex);
+ wIndex++;
+ } else if(nums[i] == 2) {
+ if(nums[bIndex] == 0) {
+ swap(nums + i, nums + bIndex);
+ swap(nums + i, nums + wIndex);
+ wIndex++;
+ bIndex--;
+ } else if(nums[bIndex] == 1) {
+ swap(nums + i, nums + bIndex);
+ bIndex--;
+ } else if(i != bIndex) {
+ swap(nums + i, nums + bIndex - 1);
+ if(nums[i] == 0) {
+ swap(nums + i, nums + wIndex);
+ wIndex++;
+ }
+ bIndex -= 2;
+ }
+ }
+ }
+}
diff --git a/Computer_Science/leetcode/75-sort_colors.c~ b/Computer_Science/leetcode/75-sort_colors.c~
new file mode 100644
index 0000000..1729e67
--- /dev/null
+++ b/Computer_Science/leetcode/75-sort_colors.c~
@@ -0,0 +1,7 @@
+void sortColors(int* nums, int numsSize) {
+ int wIndex, bIndex;
+ wIndex = 0;
+ bIndex = numsSize - 1;
+
+ for(int i = 0; i < numsSize && ; i++)
+}
diff --git a/Personal/Plan/plan.org b/Personal/Plan/plan.org
index 9ea16d9..e66f036 100644
--- a/Personal/Plan/plan.org
+++ b/Personal/Plan/plan.org
@@ -21,14 +21,57 @@ Six days a week(except Saturday, it's plan to be empty, but still study in that
* Courses
+** Database
+
+*** TODO chap1
+ SCHEDULED: <2017-12-25 一>
+*** TODO chap2
+ SCHEDULED: <2017-12-26 二>
+*** TODO chap3
+ SCHEDULED: <2017-12-27 三>
+*** TODO chap4
+ SCHEDULED: <2017-12-28 四>
+*** TODO chap5
+ SCHEDULED: <2017-12-29 五>
+*** TODO chap6
+*** TODO chap7
+ SCHEDULED: <2017-12-30 六>
+*** TODO chap8
+ SCHEDULED: <2017-12-31 日>
+*** TODO
+*** TODO
+ SCHEDULED: <2017-12-31 日
+*** TODO lab-finnal
+ SCHEDULED: <2018-01-01 一>
+
** Computer Networks
+*** TODO hm6
+ SCHEDULED: <2017-12-26 二>
+*** TODO lab1 chap1
+ SCHEDULED: <2017-12-25 一>
+*** TODO lab2 chap2
+ SCHEDULED: <2017-12-26 二>
+*** TODO lab3 chap3
+ SCHEDULED: <2017-12-27 三>
+*** TODO lab4 chap4
+ SCHEDULED: <2017-12-28 四>
+*** TODO lab5 chap5
+ SCHEDULED: <2017-12-29 五>
+*** TODO lab6 chap6
+ SCHEDULED: <2017-12-30 六>
+*** TODO lab7 chap7
+ SCHEDULED: <2017-12-31 日>
** Operating System
* Coding
** Leetcode
+*** TODO ac 8 problems a day
+ SCHEDULED: <2017-12-25 一>
+*** TODO ac 8 problemsj a day
+
* Healthy
Take 3 times exercise a week.