diff options
| author | Steve Lee <me@xiangyangli.com> | 2018-01-13 05:13:14 +0800 |
|---|---|---|
| committer | Steve Lee <me@xiangyangli.com> | 2018-01-13 05:13:14 +0800 |
| commit | a46ec300092c1ee8ccac629b7f335643f87662f5 (patch) | |
| tree | b03e20d905e6f583df626386164daf4aa5f81519 /Computer_Science/data_structures/chapter_4/Notes on Data Structures and Programming Techniques (CPSC 223, Spring 2015).html | |
| parent | 79a9c52fa923fc78074d88463449a8b7f95ca3ef (diff) | |
| download | 42-a46ec300092c1ee8ccac629b7f335643f87662f5.tar.xz 42-a46ec300092c1ee8ccac629b7f335643f87662f5.zip | |
update
Diffstat (limited to 'Computer_Science/data_structures/chapter_4/Notes on Data Structures and Programming Techniques (CPSC 223, Spring 2015).html')
| -rw-r--r-- | Computer_Science/data_structures/chapter_4/Notes on Data Structures and Programming Techniques (CPSC 223, Spring 2015).html | 20469 |
1 files changed, 20469 insertions, 0 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&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&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&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>&</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&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&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><string.h></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&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&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&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&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 <james.faulkner@yale.edu> +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 <stdio.h></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 <= <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 <stdio.h></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&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 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 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 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> <em>program</em> will show you the on-line documentation (the <em>man page</em>) for a program (e.g., try <code>man man</code> or <code>man 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 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 /some/other/dir</code>; list files in that directory instead.</li> +<li><code>ls -l</code>; long output format showing modification dates and owners.</li> +</ul> +</dd> +<dt>mkdir</dt> +<dd><code>mkdir dir</code> will create a new directory in the current directory named <code>dir</code>. +</dd> +<dt>rmdir</dt> +<dd><code>rmdir dir</code> deletes a directory. It only works on directories that contain no files. +</dd> +<dt>cd</dt> +<dd><code>cd 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 old-name 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 old-name new-name</code> makes a copy of a file. +</dd> +<dt>rm</dt> +<dd><code>rm 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 644 file</code>; owner can read or write the file, others can only read it.</li> +<li><code>chmod 600 file</code>; owner can read or write the file, others can't do anything with it.</li> +<li><code>chmod 755 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 700 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 %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 %1</code> to kill process <code class="backtick">%1</code> politely, <code class="backtick">kill -KILL %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 > 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 < 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 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 -KILL 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 -KILL 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">$ </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"><</code> symbol, like this:</p> +<pre><code>$ ./count < huge-input-file</code></pre> +<p>A '>' 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 < huge-input-file > 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 < /dev/null > /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 | more</code> or <code class="backtick">./slow-but-boring | tee 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 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 t</code> puts up the tutorial, <code>C-h b</code> lists every command available in the current mode, <code>C-h k</code> tells you what a particular sequence of keystrokes does, and <code>C-h 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 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 compile</code> is that if your program has errors in it, you can type <code>C-x `</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 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 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><< and >></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 myprog</code>, <code class="backtick">:make 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">:! echo hello world</code> or <code class="backtick">:! gdb 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><control-P> 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 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 -a</code> or <code class="backtick">ls -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 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 -g3 -o foo 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 -Wall -pedantic -o foo 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 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 -> .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 > 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"><assert.h></code>, which gives you the <code class="backtick">assert</code> macro (see Appendix B6 of K&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 <assert.h></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 <stdio.h></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><=</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 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 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 -= 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 somefunction</code> stops before executing the first line <code>somefunction</code>. - <code>break 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 somefunc</code> lists all lines of <code>somefunc</code>. - <code>list 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 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 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 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> < <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 <stdio.h></span> +<span class="ot">#include <stdlib.h></span> +<span class="ot">#include <assert.h></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 <http://gnu.org/licenses/gpl.html> +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: +<http://www.gnu.org/software/gdb/bugs/>. +Find the GDB manual and other documentation resources online at: +<http://www.gnu.org/software/gdb/documentation/>. +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 <__PRETTY_FUNCTION__.2355> "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 <__PRETTY_FUNCTION__.2355> "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 <stdio.h></span> +<span class="ot">#include <stdlib.h></span> +<span class="ot">#include <assert.h></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 < 10; i += 0) { +1: i = 0 +(gdb) n +11 i *= 37; +1: i = 0 +(gdb) n +10 for(i = 0; i < 10; i += 0) { +1: i = 0 +(gdb) n +11 i *= 37; +1: i = 0 +(gdb) n +10 for(i = 0; i < 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 <stdio.h></span> +<span class="ot">#include <stdlib.h></span> +<span class="ot">#include <assert.h></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 < <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 <stdlib.h> +3 #include <assert.h> +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 < 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 < 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 < 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 < test-input</code></pre> +<p>See <code class="backtick">valgrind --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 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 ./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 <stdio.h></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] = '\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 <stdio.h></span> +<span class="ot">#include <stdlib.h></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 <stdio.h></span> +<span class="ot">#include <stdlib.h></span> +<span class="ot">#include <assert.h></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 <stdio.h></span> +<span class="ot">#include <stdlib.h></span> +<span class="ot">#include <assert.h></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 0x419a029 is 0 bytes after a block of size 1 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 0x419a029 is 1 bytes inside a block of size 2 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, ...)</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] == %d\n", 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]->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 <stdio.h></span> +<span class="ot">#include <stdlib.h></span> +<span class="ot">#include <assert.h></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 <stdio.h></span> +<span class="ot">#include <stdlib.h></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 < <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 < 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 < 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 < 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 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 < <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 < 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 <math.h></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 < <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 < 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"><math.h></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 < <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 < 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 * factor <= 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 < <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 <= 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; }' > tiny.c +$ git add tiny.c</code></pre> +<p>The <code class="backtick">git 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 <file>..." to unstage) +# +# new file: tiny.c +#</code></pre> +<p>The <code class="backtick">git 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 <ja54@tick.zoo.cs.yale.edu> +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 <you@example.com>' + + 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 <aspnes@cs.yale.edu>" -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 commit --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 config --global 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 log</code>:</p> +<pre><code>$ git log +commit a44e1e195de4ce785cd95cae3b93c817d598a9ee +Author: James Aspnes <aspnes@cs.yale.edu> +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 <stdio.h></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 status</code>:</p> +<pre><code>$ git status +# On branch master +# Changed but not updated: +# (use "git add <file>..." to update what will be committed) +# (use "git checkout -- <file>..." 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 commit -a</code> to include these changes in my next commit. I can also do <code class="backtick">git add 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 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 <stdio.h> ++ ++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 <aspnes@cs.yale.edu> +Date: Thu Dec 29 20:34:06 2011 -0500 + + expand previous program to hello world + +commit a44e1e195de4ce785cd95cae3b93c817d598a9ee +Author: James Aspnes <aspnes@cs.yale.edu> +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 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 <file>..." to unstage) +# +# renamed: tiny.c -> hello.c +#</code></pre> +<p>These changes don't get written to the repository unless you do another <code class="backtick">git 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 => 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 add</code>:</p> +<pre><code>$ cp hello.c goodbye.c +$ git status +# On branch master +# Untracked files: +# (use "git add <file>..." 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 <file>..." to update what will be committed) +# (use "git checkout -- <file>..." 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 checkout -- 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 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 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 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 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><ENTER> 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 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 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 checkout 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&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 <stdio.h> </span><span class="co">/* This is needed to get the declarations of fprintf and printf */</span> +<span class="ot">#include <stdlib.h> </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 <= i and i < 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 < 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)] <- 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 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 char</code> or <code class="backtick">unsigned 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">/* <- 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 char</code> to guarantee a signed type that holds exactly 8 bits, or <code>uint64_t</code> instead of <code>unsigned long 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 <stdio.h></span> +<span class="ot">#include <stdlib.h></span> +<span class="ot">#include <assert.h></span> + +<span class="ot">#include <inttypes.h></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, &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 <= 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 long</code> version of 1. By default integer constants are (signed) <code class="backtick">int</code>s. For <code class="backtick">long long</code> constants, use <code class="backtick">ll</code>, e.g., the <code class="backtick">unsigned long 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 % 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 == x*(y/x) + 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">&</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 & 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&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"><<</code> and <code class="backtick">>></code> shift the bit sequence left or right: <code class="backtick">x << 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 >> 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 >> 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 << -2</code> is equivalent to <code class="backtick">x >> 2</code>.</p> +<p>Examples (<code class="backtick">unsigned char 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 << y</code></th> +<th align="left"><code>x >> 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 char 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 << y</code></th> +<th align="left"><code>x >> 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 << 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 & (1<<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 <stdio.h></span> +<span class="ot">#include <stdlib.h></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 >> <span class="dv">1</span>); + + <span class="kw">for</span>(; mask != <span class="dv">0</span>; mask >>= <span class="dv">1</span>) { + putchar((n & 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 | (1 << i)</code> or to 0 by doing <code class="backtick">x & ~(1 << 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">&&</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">&&</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> && 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">&</code> with <code class="backtick">&&</code>. The expression <code class="backtick">1 & 2</code> evaluates to 0, but <code class="backtick">1 && 2</code> evaluates to 1. The statement <code class="backtick">0 & 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 ? y : 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">&&</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"><</code> (less than), <code class="backtick">></code> (greater than), <code class="backtick"><=</code> (less than or equal to) and <code class="backtick">>=</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 >= MIN_SIZE && size <= 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 == x</code> just so that if their finger slips, they will get a syntax error on <code class="backtick">5 = 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 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 <stdio.h></span> +<span class="ot">#include <stdlib.h></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 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 sin(double)</code>, but there are usually <code class="backtick">float</code> versions as well (<code class="backtick">float 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 > y</code>, <code class="backtick">x / y</code>, <code class="backtick">x + 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 / 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"><<</code>, <code class="backtick">>></code>, <code class="backtick">&</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 < 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 f</code> to <code class="backtick">int 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 00000000 00000000000000000000000</code>. (There is also a -0 = <code class="backtick">1 00000000 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 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^ to 2^31^-1 that fit in a 32-bit </code>int<code class="backtick"> or </code>long<code class="backtick">. (A 64-bit </code>long long<code class="backtick"> does better.) So </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) == 0.3</code> in C. This can produce odd results if you try writing something like <code class="backtick">for(f = 0.0; f <= 0.3; f += 0.1)</code>: it will be hard to predict in advance whether the loop body will be executed with <code class="backtick">f = 0.3</code> or not. (Even more hilarity ensues if you write <code class="backtick">for(f = 0.0; f != 0.3; f += 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) <= fabs(EPSILON * 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 *</code>, and <code class="backtick">"%f"</code>, which reads a <code class="backtick">float</code> value into a <code class="backtick">float *</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"><math.h></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&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 <math.h></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">></code> means that <code class="backtick">2+3*4 > 5</code> gets parsed as <code class="backtick">(2+(3*4)) > 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 = y = 0</code> is interpreted as <code class="backtick">x = (y = 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 = y) = 0</code> (which would give an error because <code class="backtick">(x = 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>-></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>&</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><<</code> <code>>></code></p></td> +<td align="left"><p>shifts</p></td> +</tr> +<tr class="even"> +<td align="left"><p><code><</code> <code><=</code> <code>>=</code> <code>></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>&</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>&&</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>&=</code> <code>^=</code> <code>|=</code> <code><<=</code> <code>>>=</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 <stdio.h></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 >= <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 <stdio.h></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">= 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 <stdio.h></span> +<span class="ot">#include <ctype.h></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&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 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 += y</code> is equivalent to writing <code class="backtick">x = x + y</code>, <code class="backtick">x /= y</code> is the same as <code class="backtick">x = x / 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 = 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 = &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 > /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 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 3 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">&</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", &x)</code> will work only if <code>x</code> is a <code>float</code>, which means that <code>scanf("%lf", &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>, &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>, &n); <span class="co">/* read an int formatted in decimal */</span> + scanf(<span class="st">"%u"</span>, &n); <span class="co">/* read an unsigned int formatted in decimal */</span> + scanf(<span class="st">"%o"</span>, &n); <span class="co">/* read an unsigned int formatted in octal */</span> + scanf(<span class="st">"%x"</span>, &n); <span class="co">/* read an unsigned int formatted in hexadecimal */</span> + scanf(<span class="st">"%f"</span>, &x); <span class="co">/* read a float */</span> + scanf(<span class="st">"%lf"</span>, &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>, &total, &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 && 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>, &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 *</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 <stdio.h></span> +<span class="ot">#include <stdlib.h></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 < <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>, &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, "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, "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 <stdio.h></span> +<span class="ot">#include <stdlib.h></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 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 < <span class="dv">0</span>) { + puts(<span class="st">"brrr"</span>); + } <span class="kw">else</span> <span class="kw">if</span>(temperature < <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><expression></em> <code class="backtick">==</code> <em><small constant></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 <stdio.h></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 <stdio.h></span> +<span class="ot">#include <stdlib.h></span> +<span class="ot">#include <time.h></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() & <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 < <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 >= <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 < 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 < 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 < n; i++) { + <span class="kw">for</span>(j = <span class="dv">0</span>; j < 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 < <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 < <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 < 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 <stdio.h></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 <= 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 < n; i++) { + <span class="kw">for</span>(j = <span class="dv">0</span>; j < 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 < 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 > 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 > 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 < 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 < <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 < 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 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 "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) < 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 < 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 > 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 < <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 <= 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">&</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 = &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 = &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 = &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 *</code> first using a cast (see below for <code class="backtick">void *</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 <stdio.h></span> +<span class="ot">#include <stdlib.h></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">"&G = %p</span><span class="ch">\n</span><span class="st">"</span>, (<span class="dt">void</span> *) &G); + printf(<span class="st">"&s = %p</span><span class="ch">\n</span><span class="st">"</span>, (<span class="dt">void</span> *) &s); + printf(<span class="st">"&a = %p</span><span class="ch">\n</span><span class="st">"</span>, (<span class="dt">void</span> *) &a); + 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">"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>&G = 0x100001078 +&s = 0x10000107c +&a = 0x7fff5fbff2bc +&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 <stdio.h></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 <stdio.h></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">/* 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">&</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> &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> &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 *</code> pointers and <code class="backtick">char *</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 *</code> or both <code class="backtick">char *</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"><</code>, <code class="backtick">></code>, <code class="backtick"><=</code>, or <code class="backtick">>=</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 *</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 = &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 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 < 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 a[10]</code> and <code class="backtick">int *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 a[]</code> is just <a href="http://en.wikipedia.org/wiki/Syntactic_sugar">syntactic sugar</a> for <code class="backtick">int *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 < 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 **</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 <stdio.h></span> +<span class="ot">#include <stdlib.h></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 < 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 < rows; i++) { + <span class="kw">for</span>(j = <span class="dv">0</span>; j < cols; j++) { + a[i][j] = i - j; + } + } + + <span class="kw">for</span>(i = <span class="dv">0</span>; i < rows; i++) { + <span class="kw">for</span>(j = <span class="dv">0</span>; j < 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 < 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 < rows; i++) { + <span class="kw">for</span>(j = <span class="dv">0</span>; j < 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 < rows; i++) { + <span class="kw">for</span>(j = <span class="dv">0</span>; j < 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 < 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 < 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 < 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 < 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 *</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 *</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 *</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 *</code> variable from an expression of any pointer type; conversely, a <code class="backtick">void *</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&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 *</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 <stdio.h></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 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 *</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 <stdlib.h></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 *</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>, &n) == <span class="dv">1</span>) { + <span class="co">/* is there room? */</span> + <span class="kw">while</span>(mycount >= 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 <stdio.h></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 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 <stdio.h></span> +<span class="ot">#include <stdlib.h></span> +<span class="ot">#include <assert.h></span> +<span class="ot">#include <limits.h></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 < 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 -O3 -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 *</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 char *</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" "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 <stdio.h></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 <stdio.h></span> +<span class="ot">#include <stdlib.h></span> +<span class="ot">#include <assert.h></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 && c != <span class="ch">'\n'</span>) { + <span class="kw">if</span>(length >= 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 *</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++ = *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 < 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 < 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 == 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 && *s2 && *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 **</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 <stdio.h></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 < 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 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 string</code>, the compiler allocates enough space to hold both an <code class="backtick">int</code> and a <code class="backtick">char *</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 = s2;</code> is equivalent to <code class="backtick">s1.length = s2.length; s1.data = s2.data;</code> and <code class="backtick">s1 == s2</code> is equivalent to <code class="backtick">s1.length == s2.length && s1.data = 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 = &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 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->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 string *</code> without specifying the components of a <code class="backtick">struct 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 string *</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 string</code> were defined:</p> +<div> +<div class="sourceCode"><pre class="sourceCode c"><code class="sourceCode c"><span class="ot">#include <stdlib.h></span> +<span class="ot">#include <string.h></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->length = strlen(s); + + s2->data = malloc(s2->length); + <span class="kw">if</span>(s2->data == <span class="dv">0</span>) { + free(s2); + <span class="kw">return</span> <span class="dv">0</span>; + } + + strncpy(s2->data, s, s2->length); + + <span class="kw">return</span> s2; +} + +<span class="dt">void</span> +destroyString(<span class="kw">struct</span> string *s) +{ + free(s->data); + free(s); +} + +<span class="dt">int</span> +stringLength(<span class="kw">struct</span> string *s) +{ + <span class="kw">return</span> s->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 < <span class="dv">0</span> || index >= s->length) { + <span class="kw">return</span> -<span class="dv">1</span>; + } <span class="kw">else</span> { + <span class="kw">return</span> s->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 string *</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 <stdio.h></span> +<span class="ot">#include <stdlib.h></span> +<span class="ot">#include <stddef.h></span> +<span class="ot">#include <assert.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> 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 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 color</code> to indicate their intended interpretation.</p> +<p>Despite declaring a variable <code class="backtick">enum color 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 <stdio.h></span> +<span class="ot">#include <stdlib.h></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 *</code> strings or some even more complicated type (<code class="backtick">union string **some_string[2];</code>), you will need to go back and replace ever occurrence of <code class="backtick">struct string *</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 string *</code> all the time, especially if your fingers slip and give you <code class="backtick">struct 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, 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 <stdio.h></span> +<span class="ot">#include <stdlib.h></span> +<span class="ot">#include <assert.h></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)) < <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 <stdlib.h></span> +<span class="ot">#include <assert.h></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->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->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&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 <stdio.h></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) > (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 < 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) < (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 x"), 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 <stdio.h></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"><</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 < *bb) return -1; \</span> +<span class="ot"> else if(*bb < *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 <stdio.h></span> +<span class="ot">#include <stdlib.h></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 < N; i++) { + a[i] = N-i; + } + + int_sort(a, N); + + <span class="kw">for</span>(i=<span class="dv">0</span>; i < 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 <stdio.h></span> +<span class="ot">#include <assert.h></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 <stdio.h></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 <stdio.h></span> + +<span class="dt">int</span> +main(<span class="dt">int</span> argc, <span class="dt">char</span> **argv) +{ +<span class="ot">#if VERBOSITY >= 3 && 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 -E 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 -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>)<<em>c</em> ⋅ <em>g</em>(<em>n</em>)</span> when <span class="math inline"><em>n</em> > <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> > 100</span>, <span class="math inline">3<em>n</em> + 12 < 4<em>n</em></span>. But <span class="math inline">3<em>n</em> + 12 < 4<em>n</em></span> holds precisely when <span class="math inline">12 < <em>n</em></span>, which is implied by our assumption that <span class="math inline"><em>n</em> > 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 < 5<em>n</em><sup>2</sup></span>, or <span class="math inline">23<em>n</em> + 15 < <em>n</em><sup>2</sup></span>. But <span class="math inline"><em>n</em> > 100</span> means that <span class="math inline"><em>n</em><sup>2</sup> > 100<em>n</em> = 50<em>n</em> + 50<em>n</em> > 50<em>n</em> + 5000 > 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>)<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>)<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> < <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> > 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> > 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 <= i and i < 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 <= i and i < 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 < 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 <= i and i < 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 < n; i++) { + <span class="kw">for</span>(j = <span class="dv">0</span>; j < 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 < <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>)><em>c</em> ⋅ <em>g</em>(<em>n</em>)</span> when <span class="math inline"><em>n</em> > <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 <stdio.h></span> +<span class="ot">#include <stdlib.h></span> +<span class="ot">#include <assert.h></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->value = value; + e->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)->value; + + <span class="co">/* patch out first element */</span> + e = *s; + *s = e->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->next) { + printf(<span class="st">"%d "</span>, e->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 < <span class="dv">5</span>; i++) { + printf(<span class="st">"push %d</span><span class="ch">\n</span><span class="st">"</span>, i); + stackPush(&s, i); + stackPrint(&s); + } + + <span class="kw">while</span>(!stackEmpty(&s)) { + printf(<span class="st">"pop gets %d</span><span class="ch">\n</span><span class="st">"</span>, stackPop(&s)); + stackPrint(&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,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" 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->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,iVBORw0KGgoAAAANSUhEUgAAAbUAAABTCAYAAAAYwJn2AAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAN1wAADdcBQiibeAAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAABAASURBVHic7d17sF1lecfx7y8EEgQSkItBiwEBAwlEhIBci8hNoCNSC1PoyOC0KhZqqaVFEJCiKOVSwIIjKhIQmFhkimBtFJAgIhcZ7qBUuQSEQKdKTAIhIcmvf7zrcDYn57LP2Wuvd2Wv5zOzZ52zzz7v+5x99l7Petd+1vsK2Jt6e8P2vbmDaAJJ1wFH545jBHfY/mC3Gpd0EnBRt9ovyXO2p3a7E0n3ALt2u58OfdH2l7vdiaSpwLPd7qdDy21P6GYHklYC47rZR6fGA3cCK3IHMgQVt7VyB9IgT9iekTuIwUiaV1FXC21vVFFfoyLpa8DhFXW3ATAP+IeK+hut24D1KuzPtmu5Q5d0KPCfFXX3PtuPVNTXiIoDjmuAZcD+4wFsr501qiFI2hu4I3ccITTYojrtwFpJquvBeKiIpKOBS4DzgQuAVePzhhRCCCGMjqQNgMuA3YAP236guL/e50ZDCCGEVpJ2Bx4ClgI79yW0PjFSCyGEUHuS1gJOA04Ajrd942CPi6QWQgih1lqKQV4njc5eHOqxcfoxhBBCbRXFIL8EfgAcNFxCgxiphRBCqKGWYpBdgYNtP9jO78VILYQQQq1I2oNUDPIasEu7CQ1ipBZCCKEmimKQLwCfIRWD/GC0bURSCyGEkF1LMUhfqf6CsbQTpx9Do0malDuG3OI5SCStJUm546iLKl8XRTHIfaSpvg4ea0KDSGqNJGnr3DHUyBxJ10v6M0lNPXNxvqS5ko6WtG7uYDIaBzwg6WxJ2+QOpgaOknS/pBMlbdyNDiRtIOlq4AxSMvs32+6kzaa+iZvu7yUdCFwFfNf2C2V3IGkXYNOSm3170faHS2zzadLFnH8BvAI8T0nvC0nbAVuW0VaLqcDEkp+D3wGfAg4GXpV0J/DNEttH0gyg7Dlm1wbeIWmnEtt8gbSDPUPSQ8DNwMUlto+kdwE7ltkmsAswruTXxWJg56LtiyTdS4kTzBfFINcAPyEVgywto93SkpqkLYFpwJNtbKcDj5L+scNt9yja/ghwPzBrhO0HgLuAvdrc/ilwO7BfG9tbSW/6H7exPQy4CfhIm9sjgOuBI9vYzgH+Cri2je2xwJXAJwZslwHbAV8FzpH0K+Acyl0N4QjS/6VM7yq2J5XYZmvi3QiYDKyU9G7bz3XY9r6k56FM2wOTKPc5WL/l6/WAg4r7JpbYxyXAJiW2B+l/dRhpx1uWzVq+3gmYSTowOa/EPqZT7v8P0ut4XMntClhJyhPjSftNSPvltqsRV2v0rcUgn7Z9U4dxvkWZI7XJwFbAS21styatTTTS9p1F29sAv25juy2pDLTd7TTgnja3d5J2KPPa2E4H5o5iOwO4sc3tWqSk3872faQX5sDtFv3/NsaRjv5nAqWderJ9ellt9elbesZ2aUejki4n7bxuB2aTXnOnlpDQsH05cHmn7bTqW3qm5OfgVNIO6z7S6H2O7T9IerysPmwfUFZbfSQtAGbbPrXENu8ANgd+Tnou/sP2oqKIoRS2bwFuKas96F96puTXxX6kA5ynSM/F1aQzGz/voM2ppAPuV+mgGGQktk0db6QFTFfmjqPXbsCXgSWkF+kBwLji/uuAx3PHN0zc84B5Jbf5N8AWLd+fBLyS+28dJt6vAfNLbvMYYLtB7n+ctKPM/ncPEfcC4KsltjcROBPYepCfTQVW5f6bh4n9UGBZyW0eAOw94L6VwMwxtnc08DJpfT516XlwfKbWTLcC59pekjuQ3Gx/O3cMudm+LncMdWD7deDs3HHUhe1by2inqKK8jHSa+CDbD5fR7lCi+rGBbM+LhBZC6LaiGORBYBEwq9sJDaL6MYQQQslaikGOJxWD3FxV3zFSCyGE8CZJEyXdKOmYsVy3WFTC3wHsSSoGqSyhQSS1EEJoFEnjisQ16K142DhSleJLkq6UtH+bbR8D3At8HzjE9kvd+SuGFqcfQwihWfYhXcKyfJjH9F2zOgk4DjhO0qArTcNbikHeDxxo+5FyQh29GKmFEELz/Mz2xKFupFk+IM2w8q/ADrYHnUigpRjkj6RikGwJDWKkFkIITTPs3IrFKcgXgQOBn9peNcTjWotBPmX7h2UHOhaR1EIIoXmGXI2guF7vk8P+cioGuYY0P+T7bb9cZnCdiNOPIYTQLB3Ngk+aveRe0ny0h9YpoUGM1EIIoYlGvW5cUd4v0tRyB9h+tPSoShBJLbTaGHivpNKXoinJxqRVHrrdx+QaPweTSSsDV2E94EOSsn7wP4xNgA0r6msCoBq/LibQ/iobZgxJjf5qycnA3LqupzoeQNLruQMZghjbkx/G5nnS7Nl1nUJrAmntr25aALxOfZ8DkdZ9q8IfSUl+SkX9jdYqUoxVWFr0V9fXxXLKX6/uLWyvlLSMNOXVim721Ym+kdq8nEEMY13SAnWhGvcDK2wfnzuQwUg6q4JungDus/3BCvoaNUl/CXy0ou7uBq60XeoimWUprpu6p6LuFgOLbU+rqL9RKRakHfI6sgHGOlKDdBCxV46LqtshKc3S7xLX4ClTUWFT1Ys2hBDCGi6qH0MIoVk6GanVXiS1EEJolk5L+mstqh9DqSRNBrYnrRRs4LfAk7ZfzRpYhSRtCOwIbAZsQCpuedr201kDqwFJG5CqKiF9RtWI14WkTRh5f7vI9mtVxEMNRmqSNgV2I71PFgPzgQdsr+yk3UhqoRSSjiUt174/q1dhLZF0AXBhLy9OKmlXYDYpqa+205B0D3CW7R9XHFotSFofeJR0wANwCnBevogqdTewzQiP+Tvg0gpiyTpSk/QnwMWkgqeBlyEslHS47Z+Ntf1IaqEsF5KuG1oB/Lq4LQNmAVsDZwH7Sdq/0yOxGpsCTCeVfz9MGqG9Brwb2AvYHfiRpEMbmtjOpT+hNdVC0vtiMFWN0iDTSE3SDNIKAZuSLpF4gvReeRswDdiOdBnJmEVSC2X5PfAN4NLWaXMkjQNOJs30vS/p6PwrWSLsvseADwG/sP2WHZekLYD/Ip2WnA1sXnl0GUnaB/hb0g5tB9JOrYk+XoOJf7OM1IpTzz8i/e//B/hz248PeMwMOkzuUSgSyjLT9hkD54Gzvcr2eaQdOqR543qS7Wds3z4woRU/ex74bPHtFEnbVhtdPsWs798mjVA+TY8XKqwhcozUziCdtXgF+MDAhAZg+3Hbz3TSSSS1UArbwy04CP0X+M/ocih19tuWr5s0UvkX4L3Al2z/JncwofqS/uLA5q+Lby+xvbBbfUVSC1V5T7Ht6ChsDbd3sV0KrHaU2oskzQL+kXRq9vzM4dSCpPUkbZY7jortDry9+Hp2352SJkkqdXqvSGqh6yRNAA4pvr07Zyw5SFpH0lHAvxd3nW27qjkLsyl2VleQRgWftP1G5pDq4Fuk8vWXJS2S9EtJJxQLblYlx8XXOxXbV4EXJJ0t6WFS4cwSSY9IOrmM5yGSWqjC+cCWpHnjzskbSjUk/VDSs5IWkEZm3wP+D/iE7XPzRleZU4GZwNdtx3R3yRTSZ0qLSdcwziKV8T8g6Z05A+uyvr/tOeD7pM/XtgEeJD0XO5L2E7+QtN6gLbQpklroKkkfI11/A/B52y/mjKdCm5PK16fQ/z4bR1rWJvuFr90maQfgC6TLGk7LHE4dfI90tmJ92xvbnkTa0V8IvEFK/t+qKJYcI7VJxXZ74HDS9Ykb2t7F9ibAcaTVMXYDvthJR5HUQtdI2o+05DvAN21/I2c8FdsX2Ii049qTdOpxS9JFp9/JF1b3FaeQrgDWAU6wvThzSNnZPt323NYZVGwvsH0y6TIXgEMlVTG5fI7q00UtX//E9imtp6NtX0X/Z64nSRrztWqlJDVJaxVTnoQAgKTdgZuAicC1wGfyRlQt20tsLyx2XHfb/ixwTPHj4yTtnzO+LjuJdMR9g+2bcgezBriYtI4fVLfUVtUjtdalaoY6qLu82K5NmsRgTMq6+HoLUgFAoy4oDYOTtBPw38D6wA3AcbZX5Y0qP9s3SHqMdPHxYcBtmUPqlmOL7dskzR7k532noo6SNB1YYvvESiKrIduW9CBp/7l9FV1W0MdAC1q+HqoC+kXStYwTSJeA3DmWjspKaiIuqAy8+VnKLcCGpJHa0bZru0puBvNJSe0duQOpwCEj/HyX4vYK0NikVuhL9FWdqq16pPZcy9frDvGY8fTPGzvm5yGSWihNcdR9G2kOyLnAkVHGvZqZxfaJrFF01ymkg5qhXE7aiV8H3MzQcyE2QrGqQ1/J+2MVdJljX3038BRpHtjpwB2DPGZ7+j8SG/P7I5JaKIWkaaSEtlmxPaKNWUZ6iqRth5sxQ9I/k07VQw+v6G577nA/l3QJKak9bHtONVHlU8z7+Tvbq+0ji6Kay0in6lcAP60qrIr6AdJ0eZK+Tqr2/JykKwbZP5xebOcDT461r0hqoWOS1iFNVDuFVJ78APD5YSrXz6tw3agq3SjpdWAOaUqs+aTZx6cCHwcOLh4323avfp4WVncmaYWKq0kjkPmkAqoZpNOufVPHfcn2ryqIJ9fK198h/b3bAHdJOoW0FNGWwOeAI4vHndjJGZ5IaqEMa9NfJLQ28E8jPP5Sql1mo0o7F7fBrACuBk6oLpxQE1uT5sAczFLgEnp39QoAbC+UtCdpcvNZrF4otRQ4rdNVDCKphTIsZ+g37GB6NaHtQ1okdT/S0ecU0t/6HPA0cKXtp7JFVx/nk0633ZU7kIqcSZrQey9gK9Jk1suB35BOs11l+4UK48k1UsP2S5L2BT4G7EE6AFxA+ixxdhkTXpe5nloktYYqThWclTuO3Gz/Abi+uIUh2L4gdwxVsr2AdK3mtbljqQPbS4CrilvpyppRJEZqIYSwZsg2UqtCmUkthBBC/fX0ACRGaiGE0Dw9OxCJQpEw0LqSpuQOYgjrA0sq6GedGj8Hk3MH0GCq8etik1E8ttN99aZ1XmhiPLw5+Wwn3gNMKKGdgWIuyWq9RrqW6uCRHphRt4sMlpNezw91uZ9O3FhhXxdJuqjC/kZrdkX9rCKVnNf5dTGaysGxZqX/JU2DV1cvi3JmNliXNAHlwyW0NdDvbR/WhXZDCKFxJM0A5tjeMXcs3TDedsejK0k7kpaZKHukFkIIoXz1PX/YoSgUCSGEZomS/jZEUgshhJBdJLUQQmiWGKm1IZJaCCGE7CKphRBCs8RIrU2R1EIIof56el8dI7UQQmieGKmNIJJaCCGsGXp6Xx1JLYQQmidGaiPo2ScohBB6TE8PQGKkFkIIzdOzA5FIaiGE0CxR0t+GSGohhBCyi6QWQgjNEiO1NkRSCyGEkF0ktRBCaJYYqbUhkloIIawZenpfHUkthBCaJ0ZqbYikFkII9dfT++rxJbUjYCdJz9D/hLVuR7qv059X9Tt1iSNib3YcEXuz4xhz7Lb77uvZkZr6/8YOGpEmAlP6vm3ZDvV1u/fF78TvxO/E78TvlP87z9reih70/29GMT13bLliAAAAAElFTkSuQmCC" 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 <stdio.h></span> +<span class="ot">#include <stdlib.h></span> +<span class="ot">#include <assert.h></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->head = q->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->value = value; + + <span class="co">/* Because I will be the tail, nobody is behind me */</span> + e->next = <span class="dv">0</span>; + + <span class="kw">if</span>(q->head == <span class="dv">0</span>) { + <span class="co">/* If the queue was empty, I become the head */</span> + q->head = e; + } <span class="kw">else</span> { + <span class="co">/* Otherwise I get in line after the old tail */</span> + q->tail->next = e; + } + + <span class="co">/* I become the new tail */</span> + q->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->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->head->value; + + <span class="co">/* patch out first element */</span> + e = q->head; + q->head = e->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->head; e != <span class="dv">0</span>; e = e->next) { + printf(<span class="st">"%d "</span>, e->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 < <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 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->next) { + puts(elt->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->next) { + s2 = stackPush(s2, elt->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->next); + + <span class="co">/* then print the first element */</span> + puts(first->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 <stdlib.h></span> +<span class="ot">#include <assert.h></span> +<span class="ot">#include <stddef.h> </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->next[DEQUE_FRONT] = d->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->next[direction] = d->next[direction]; + e->next[!direction] = d; + e->value = value; + + d->next[direction] = e; + e->next[direction]->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->next[direction]; + + <span class="kw">if</span>(e == d) { + <span class="kw">return</span> DEQUE_EMPTY; + } + + <span class="co">/* else remove it */</span> + d->next[direction] = e->next[direction]; + e->next[direction]->next[!direction] = d; + + retval = e->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->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 <stdlib.h></span> +<span class="ot">#include <assert.h></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->base = <span class="dv">0</span>; + d->length = <span class="dv">0</span>; + d->size = size; + + d->contents = malloc(<span class="kw">sizeof</span>(<span class="dt">int</span>) * d->size); + assert(d->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->length == d->size) { + <span class="co">/* nope */</span> + d2 = dequeCreateInternal(d->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->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->base is unsigned, so we have to check for zero first */</span> + <span class="kw">if</span>(d->base == <span class="dv">0</span>) { + d->base = d->size - <span class="dv">1</span>; + } <span class="kw">else</span> { + d->base--; + } + + d->length++; + + d->contents[d->base] = value; + } <span class="kw">else</span> { + d->contents[(d->base + d->length++) % d->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->contents[d->base]; + + d->base = (d->base<span class="dv">+1</span>) % d->size; + d->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->contents[(d->base + --d->length) % d->size]; + } +} + +<span class="dt">int</span> +dequeIsEmpty(<span class="dt">const</span> Deque *d) +{ + <span class="kw">return</span> d->length == <span class="dv">0</span>; +} + +<span class="dt">void</span> +dequeDestroy(Deque *d) +{ + free(d->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 <stdlib.h></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->next[LEFT] = e->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->next[RIGHT]->next[LEFT] = e->next[LEFT]; + e->next[LEFT]->next[RIGHT] = e->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->next[dir] = head->next[dir]; + e->next[!dir] = head; + + <span class="co">/* make neigbhors point back at e */</span> + e->next[dir]->next[!dir] = e; + e->next[!dir]->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->next[RIGHT]->next[LEFT] = e1->next[LEFT]; + e1->next[LEFT]->next[RIGHT] = e2->next[RIGHT]; + + <span class="co">/* fix up the ends */</span> + e2->next[RIGHT] = e1; + e1->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->next[LEFT]->next[RIGHT] = e1->next[RIGHT]; + e1->next[RIGHT]->next[LEFT] = e2->next[LEFT]; + + <span class="co">/* fix up e1 and e2 */</span> + e1->next[RIGHT] = e2; + e2->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->next[RIGHT]; target != e; target = next) { + next = target->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->next[RIGHT]->next[LEFT] == check); + assert(check->next[LEFT]->next[RIGHT] == check); + + <span class="co">/* on to the next */</span> + check = check->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 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 fancyElt</code> looks like a <code class="backtick">struct elt</code>, any code that expects a <code class="backtick">struct 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->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 *</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 < 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 <stdlib.h></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->next = init; + s->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->next; + s->next += s->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 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 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 <stdio.h></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 < 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 main.c 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 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> < 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 >= 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 >= 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 = h * MULTIPLIER + *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 >= 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> && i < MAX_BITS; us++) { + c = *us; + <span class="kw">for</span>(shift = <span class="dv">0</span>; shift < BITS_PER_CHAR; shift++, i++) { + <span class="co">/* is low bit of c set? */</span> + <span class="kw">if</span>(c & <span class="bn">0x1</span>) { + h ^= x[i]; + } + + <span class="co">/* shift c to get new bit in lowest position */</span> + c >>= <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 <stdlib.h></span> +<span class="ot">#include <assert.h></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->size = size; + + <span class="co">/* clear the hash table */</span> + <span class="kw">for</span>(i = <span class="dv">0</span>; i < size; i++) { + list->ids[i] = NULL_ID; + } + + <span class="co">/* load it up */</span> + <span class="kw">for</span>(i = <span class="dv">0</span>; i < n; i++) { + + assert(unsortedIdList[i] >= MIN_ID); + assert(unsortedIdList[i] <= 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->size; + list->ids[probe] != NULL_ID; + probe = (probe + <span class="dv">1</span>) % list->size); + + assert(list->ids[probe] == NULL_ID); + + list->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->ids[probe] != NULL_ID; + probe = (probe + <span class="dv">1</span>) % size) { + <span class="kw">if</span>(list->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 <stdlib.h></span> +<span class="ot">#include <assert.h></span> +<span class="ot">#include <string.h></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->size = size; + d->n = <span class="dv">0</span>; + d->table = malloc(<span class="kw">sizeof</span>(<span class="kw">struct</span> elt *) * d->size); + + assert(d->table != <span class="dv">0</span>); + + <span class="kw">for</span>(i = <span class="dv">0</span>; i < d->size; i++) d->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 < d->size; i++) { + <span class="kw">for</span>(e = d->table[i]; e != <span class="dv">0</span>; e = next) { + next = e->next; + + free(e->key); + free(e->value); + free(e); + } + } + + free(d->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->size * GROWTH_FACTOR); + + <span class="kw">for</span>(i = <span class="dv">0</span>; i < d->size; i++) { + <span class="kw">for</span>(e = d->table[i]; e != <span class="dv">0</span>; e = e->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->key, e->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->key = strdup(key); + e->value = strdup(value); + + h = hash_function(key) % d->size; + + e->next = d->table[h]; + d->table[h] = e; + + d->n++; + + <span class="co">/* grow table if there is not enough room */</span> + <span class="kw">if</span>(d->n >= d->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->table[hash_function(key) % d->size]; e != <span class="dv">0</span>; e = e->next) { + <span class="kw">if</span>(!strcmp(e->key, key)) { + <span class="co">/* got it */</span> + <span class="kw">return</span> e->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 = &(d->table[hash_function(key) % d->size]); + *prev != <span class="dv">0</span>; + prev = &((*prev)->next)) { + <span class="kw">if</span>(!strcmp((*prev)->key, key)) { + <span class="co">/* got it */</span> + e = *prev; + *prev = e->next; + + free(e->key); + free(e->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 <stdio.h></span> +<span class="ot">#include <assert.h></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 < <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 *</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 *</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 *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 *</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 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, &x, &y);</span> +<span class="co"> * printf("%d", *dictGet(d, &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 *</code>, the operations in <code>DictStringOps</code> to expect <code>char *</code> cast to <code>void *</code>, and the operations in <code>dictMemOps(size)</code> will expect <code>void *</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, &x, &y);</span> +<span class="co"> * printf("%d", *dictGet(d, &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 <stdlib.h></span> +<span class="ot">#include <string.h></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->tableSize = INITIAL_TABLESIZE; + d->numElements = <span class="dv">0</span>; + d->keyOps = keyOps; + d->valueOps = valueOps; + d->table = malloc(<span class="kw">sizeof</span>(*(d->table)) * d->tableSize); + <span class="kw">if</span>(d->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 < d->tableSize; i++) d->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 < d->tableSize; i++) { + <span class="kw">for</span>(e = d->table[i]; e != <span class="dv">0</span>; e = next) { + next = e->next; + d->keyOps.delete(e->key, d->keyOps.arg); + d->valueOps.delete(e->value, d->valueOps.arg); + free(e); + } + } + free(d->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->keyOps.hash(key, d->keyOps.arg); + i = h % d->tableSize; + <span class="kw">for</span>(e = d->table[i]; e != <span class="dv">0</span>; e = e->next) { + <span class="kw">if</span>(e->hash == h && d->keyOps.equal(key, e->key, d->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->table; + old_size = d->tableSize; + + <span class="co">/* make new table */</span> + d->tableSize *= TABLESIZE_MULTIPLIER; + d->table = malloc(<span class="kw">sizeof</span>(*(d->table)) * d->tableSize); + <span class="kw">if</span>(d->table == <span class="dv">0</span>) { + <span class="co">/* put the old one back */</span> + d->table = old_table; + d->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 < d->tableSize; i++) d->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 < old_size; i++) { + <span class="kw">for</span>(e = old_table[i]; e != <span class="dv">0</span>; e = next) { + next = e->next; + <span class="co">/* find the position in the new table */</span> + new_pos = e->hash % d->tableSize; + e->next = d->table[new_pos]; + d->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->valueOps.delete(e->value, d->valueOps.arg); + e->value = value ? d->valueOps.copy(value, d->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->hash = d->keyOps.hash(key, d->keyOps.arg); + e->key = d->keyOps.copy(key, d->keyOps.arg); + e->value = value ? d->valueOps.copy(value, d->valueOps.arg) : <span class="dv">0</span>; + + <span class="co">/* link it in */</span> + tablePosition = e->hash % d->tableSize; + e->next = d->table[tablePosition]; + d->table[tablePosition] = e; + + d->numElements++; + + <span class="kw">if</span>(d->numElements > d->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->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 < len; i++) { + h = (h << <span class="dv">13</span>) + (h >> <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 <stdio.h></span> +<span class="ot">#include <stdlib.h></span> +<span class="ot">#include <assert.h></span> + +<span class="co">/* all of these routines print numbers i where start <= i < 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 < 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 < 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 < 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 < 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 < 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, 10)</code>, 0 is printed only after the results of <code class="backtick">printRangeRecursiveReversed(1, 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> < <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, 10)</code>, it will print 0, call itself with <code class="backtick">printRangeRecursiveBad(1, 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, 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, 1)</code>; it will set <code class="backtick">mid</code> to 0, and while the recursive call to <code class="backtick">printRangeRecursiveSplitBad(0, 0)</code> will work just fine, the recursive call to <code class="backtick">printRangeRecursiveSplitBad(0, 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 < 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 < 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 < 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 <stddef.h></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 < 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 <stddef.h></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 < 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 <stdio.h></span> +<span class="ot">#include <stdlib.h></span> +<span class="ot">#include <string.h></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 < n1 || i2 < n2) { + <span class="kw">if</span>(i2 >= n2 || ((i1 < n1) && (a1[i1] < 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 < <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 < N; i++) { + a[i] = N-i<span class="dv">-1</span>; + } + + <span class="kw">for</span>(i = <span class="dv">0</span>; i < 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 < 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->left); + doSomethingToAllNodes(root->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->left) + treeSize(root->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->left); + rh = treeHeight(root->right); + <span class="kw">return</span> <span class="dv">1</span> + (lh > 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 <stdio.h></span> +<span class="ot">#include <stdlib.h></span> +<span class="ot">#include <assert.h></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>) < n && a[Child(pos, <span class="dv">1</span>)] > 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>)] > 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>) < n && a[Child(pos, <span class="dv">0</span>)] > 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 >= <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 > <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 < N; i++) { a[i] = (i*MULTIPLIER) % N; } + + <span class="kw">for</span>(i = <span class="dv">0</span>; i < 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 < 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->key == target) { + <span class="kw">return</span> root; + } <span class="kw">else</span> <span class="kw">if</span>(root->key > target) { + <span class="kw">return</span> treeSearch(root->left, target); + } <span class="kw">else</span> { + <span class="kw">return</span> treeSearch(root->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> && root->key != target) { + <span class="kw">if</span>(root->key > target) { + root = root->left; + } <span class="kw">else</span> { + root = root->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->key = key; + newNode->left = <span class="dv">0</span>; + newNode->right = <span class="dv">0</span>; + + <span class="kw">for</span>(;;) { + <span class="kw">if</span>(root->key > key) { + <span class="co">/* try left child */</span> + <span class="kw">if</span>(root->left) { + root = root->left; + } <span class="kw">else</span> { + <span class="co">/* put it in */</span> + root->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->right) { + root = root->right; + } <span class="kw">else</span> { + <span class="co">/* put it in */</span> + root->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 + / \ <==> / \ + 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> < <em>x</em> < <em>B</em> < <em>y</em> < <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 + / \ ===> / \ ===> / \ + 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>)><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 > 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 + / \ ===> / \ + 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 + / \ ===> / \ ===> / \ + 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 + / \ ===> / \ ===> / \ + 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 <stdio.h></span> +<span class="ot">#include <stdlib.h></span> +<span class="ot">#include <assert.h></span> +<span class="ot">#include <stdint.h></span> +<span class="ot">#include <stdlib.h></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->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 < TREE_NUM_CHILDREN; i++) { + childHeight = treeHeight(root->child[i]); + <span class="kw">if</span>(childHeight > 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->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 < TREE_NUM_CHILDREN; i++) { + size += treeSize(root->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->height = treeComputeHeight(root); + root->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 <=> 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->child[direction]; assert(x); + b = x->child[!direction]; + + <span class="co">/* do the rotation */</span> + *root = x; + x->child[!direction] = y; + y->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 < TREE_NUM_CHILDREN; tallerChild++) { + <span class="kw">if</span>(treeHeight((*root)->child[tallerChild]) >= treeHeight((*root)->child[!tallerChild]) + <span class="dv">2</span>) { + + <span class="co">/* which grandchild is the problem? */</span> + <span class="kw">if</span>(treeHeight((*root)->child[tallerChild]->child[!tallerChild]) + > treeHeight((*root)->child[tallerChild]->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(&(*root)->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)->child[LEFT]) - treeHeight((*root)->child[RIGHT])) <= <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 < TREE_NUM_CHILDREN; i++) { + treeDestroy(&(*root)->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->key = newElement; + e->child[LEFT] = e->child[RIGHT] = <span class="dv">0</span>; + + *root = e; + } <span class="kw">else</span> <span class="kw">if</span>((*root)->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(&(*root)->child[(*root)->key < 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 && t->key != target) { + t = t->child[t->key < 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)->child[LEFT]) { + <span class="co">/* recurse on left subtree */</span> + retval = treeDeleteMin(&(*root)->child[LEFT]); + } <span class="kw">else</span> { + <span class="co">/* delete the root */</span> + toFree = *root; + retval = toFree->key; + *root = toFree->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)->key == target) { + <span class="kw">if</span>((*root)->child[RIGHT]) { + <span class="co">/* replace root with min value in right subtree */</span> + (*root)->key = treeDeleteMin(&(*root)->child[RIGHT]); + } <span class="kw">else</span> { + <span class="co">/* patch out root */</span> + toFree = *root; + *root = toFree->child[LEFT]; + free(toFree); + } + } <span class="kw">else</span> { + treeDelete(&(*root)->child[(*root)->key < 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->child[LEFT], depth<span class="dv">+1</span>); + + <span class="kw">for</span>(i = <span class="dv">0</span>; i < 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->key, root->height, root->size, (<span class="dt">void</span> *) root); + + treePrintIndented(root->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 && t->key != target) { + <span class="kw">if</span>(t->key < 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->child[LEFT])); + t = t->child[RIGHT]; + } <span class="kw">else</span> { + <span class="co">/* go left */</span> + t = t->child[LEFT]; + } + } + + <span class="co">/* we must also count left subtree */</span> + <span class="kw">return</span> rank + treeSize(t->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 < 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->child[LEFT]))) { + <span class="kw">if</span>(rank < leftSize) { + t = t->child[LEFT]; + } <span class="kw">else</span> { + t = t->child[RIGHT]; + rank -= (leftSize + <span class="dv">1</span>); + } + } + + <span class="kw">return</span> t->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->height == treeComputeHeight(root)); + assert(root->size == treeComputeSize(root)); + + assert(abs(treeHeight(root->child[LEFT]) - treeHeight(root->child[RIGHT])) < <span class="dv">2</span>); + + <span class="kw">for</span>(i = <span class="dv">0</span>; i < TREE_NUM_CHILDREN; i++) { + treeSanityCheck(root->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 < n; i++) { + assert(!treeContains(root, i)); + treeInsert(&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 < 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 < n; i++) { + assert(treeContains(root, i)); + treeDelete(&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(&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 < randTrials; i++) { + treeInsert(&root, rand() % randRange); + treeDelete(&root, rand() % randRange); + } + + treeSanityCheck(root); + treeDestroy(&root); + +<span class="ot">#ifdef TEST_USE_STDIN</span> + <span class="kw">while</span>(scanf(<span class="st">"%d"</span>, &key) == <span class="dv">1</span>) { + <span class="co">/* insert if positive, delete if negative */</span> + <span class="kw">if</span>(key > <span class="dv">0</span>) { + treeInsert(&root, key); + assert(treeContains(root, key)); + } <span class="kw">else</span> <span class="kw">if</span>(key < <span class="dv">0</span>) { + treeDelete(&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(&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 <stdio.h></span> +<span class="ot">#include <stdlib.h></span> +<span class="ot">#include <assert.h></span> +<span class="ot">#include <limits.h></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)->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 <=> 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->child[direction]; assert(x); + b = x->child[!direction]; + + <span class="co">/* do the rotation */</span> + *root = x; + x->child[!direction] = y; + y->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->child[!d] = <span class="dv">0</span>; + hook[d] = &node->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 < TREE_NUM_CHILDREN; d++) { + top[d] = <span class="dv">0</span>; + hook[d] = &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->key != target && (child = t->child[dChild = t->key < target]) != <span class="dv">0</span>) { + <span class="co">/* child is not null */</span> + grandchild = child->child[dGrandchild = child->key < 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->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(&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 < TREE_NUM_CHILDREN; d++) { + *hook[d] = t->child[d]; + t->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> && (*root)->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 && t->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->key = newElement; + + <span class="kw">if</span>(t == <span class="dv">0</span>) { + e->child[LEFT] = e->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)->key > newElement; + e->child[d] = t; + e->child[!d] = t->child[!d]; + t->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 && (*root)->key == target) { + <span class="co">/* save pointers to kids */</span> + left = (*root)->child[LEFT]; + right = (*root)->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(&left, INT_MAX); + + <span class="co">/* now paste in right subtree */</span> + left->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->child[LEFT], depth<span class="dv">+1</span>); + + <span class="kw">for</span>(i = <span class="dv">0</span>; i < INDENTATION_LEVEL*depth; i++) { + putchar(' '); + } + printf(<span class="st">"%d (%p)</span><span class="ch">\n</span><span class="st">"</span>, root->key, (<span class="dt">void</span> *) root); + + treePrintIndented(root->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 < n; i++) { + assert(!treeContains(&root, i)); + treeInsert(&root, i); + assert(treeContains(&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 < n; i++) { + assert(treeContains(&root, i)); + treeDelete(&root, i); + assert(!treeContains(&root, i)); + treePrint(root); + puts(<span class="st">"==="</span>); + } + + treeDestroy(&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 <stdlib.h></span> +<span class="ot">#include <assert.h></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->n = n; + g->m = <span class="dv">0</span>; + + <span class="kw">for</span>(i = <span class="dv">0</span>; i < n; i++) { + g->alist[i] = malloc(<span class="kw">sizeof</span>(<span class="kw">struct</span> successors)); + assert(g->alist[i]); + + g->alist[i]->d = <span class="dv">0</span>; + g->alist[i]->len = <span class="dv">0</span>; + g->alist[i]->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 < g->n; i++) free(g->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 >= <span class="dv">0</span>); + assert(u < g->n); + assert(v >= <span class="dv">0</span>); + assert(v < g->n); + + <span class="co">/* do we need to grow the list? */</span> + <span class="kw">while</span>(g->alist[u]->d >= g->alist[u]->len) { + g->alist[u]->len = g->alist[u]->len * <span class="dv">2</span> + <span class="dv">1</span>; <span class="co">/* +1 because it might have been 0 */</span> + g->alist[u] = + realloc(g->alist[u], + <span class="kw">sizeof</span>(<span class="kw">struct</span> successors) + <span class="kw">sizeof</span>(<span class="dt">int</span>) * g->alist[u]->len); + } + + <span class="co">/* now add the new sink */</span> + g->alist[u]->list[g->alist[u]->d++] = v; + g->alist[u]->isSorted = <span class="dv">0</span>; + + <span class="co">/* bump edge count */</span> + g->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->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->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 >= <span class="dv">0</span>); + assert(source < g->n); + + <span class="kw">return</span> g->alist[source]->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 >= <span class="dv">0</span>); + assert(source < g->n); + assert(sink >= <span class="dv">0</span>); + assert(sink < g->n); + + <span class="kw">if</span>(graphOutDegree(g, source) >= BSEARCH_THRESHOLD) { + <span class="co">/* make sure it is sorted */</span> + <span class="kw">if</span>(! g->alist[source]->isSorted) { + qsort(g->alist[source]->list, + g->alist[source]->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(&sink, + g->alist[source]->list, + g->alist[source]->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 < g->alist[source]->d; i++) { + <span class="kw">if</span>(g->alist[source]->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 >= <span class="dv">0</span>); + assert(source < g->n); + + <span class="kw">for</span>(i = <span class="dv">0</span>; i < g->alist[source]->d; i++) { + f(g, source, g->alist[source]->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 <stdio.h></span> +<span class="ot">#include <stdlib.h></span> +<span class="ot">#include <assert.h></span> +<span class="ot">#include <stdint.h></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 < g->n; v++) { + free(g->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->n = n; + g->v = malloc(<span class="kw">sizeof</span>(<span class="kw">struct</span> node) * n); + assert(g->v); + + <span class="kw">for</span>(v = <span class="dv">0</span>; v < n; v++) { + g->v[v].parent = VERTEX_NULL; + + <span class="co">/* fill in neighbors */</span> + g->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->v[v].neighbors[i++] = v/<span class="dv">2</span>; } + <span class="kw">if</span>(<span class="dv">3</span>*v < n) { g->v[v].neighbors[i++] = <span class="dv">3</span>*v; } + <span class="kw">if</span>(v<span class="dv">+1</span> < n) { g->v[v].neighbors[i++] = v<span class="dv">+1</span>; } + g->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 < g->n; u++) { + <span class="kw">for</span>(i = <span class="dv">0</span>; g->v[u].neighbors[i] != VERTEX_NULL; i++) { + printf(<span class="st">"%d -> %d;</span><span class="ch">\n</span><span class="st">"</span>, u, g->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->v[u].parent; + } <span class="kw">while</span>(g->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 < g->n; u++) { + <span class="kw">if</span>(g->v[u].parent != VERTEX_NULL) { + printf(<span class="st">"%d -> %d;</span><span class="ch">\n</span><span class="st">"</span>, u, g->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->v[child].parent == VERTEX_NULL) { + g->v[child].parent = parent; + <span class="kw">for</span>(i = <span class="dv">0</span>; (neighbor = g->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->n); + assert(q); + + head = tail = <span class="dv">0</span>; + + <span class="co">/* push root onto q */</span> + g->v[root].parent = root; + q[tail++] = root; + + <span class="kw">while</span>(head < tail) { + current = q[head++]; + + <span class="kw">for</span>(i = <span class="dv">0</span>; (nbr = g->v[current].neighbors[i]) != VERTEX_NULL; i++) { + <span class="kw">if</span>(g->v[nbr].parent == VERTEX_NULL) { + <span class="co">/* haven't seen this guy */</span> + <span class="co">/* push it */</span> + g->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/u7u6ioxCpgmBurUZEREREKotlmIiIiIhUFsswEREREakslmEiIiIiUlksw0RERESksliGiYiIiEhlsQwTERERkcpiGSYiIiIilcUyTEREREQqi2WYiIiIiFQWyzARERERqSyWYSIiIiJSWSzDRERERKSyWIaJiIiISGWxDBMRERGRymIZJiIiIiKVxTJMRERERCqLZZiIiIiIVBbLMBERERGpLJZhIiIiIlJZLMNEREREpLJYhomIiIhIZbEMExEREZHKYhkmIiIiIpXFMkxEREREKotlmIiIiIhUFsswEREREakslmEiIiIiUlksw0RERESksliGiYiIiEhl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" 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+w7BGMODhliA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" 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 < 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 <stdlib.h></span> +<span class="ot">#include <assert.h></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 < 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->graph = g; + s->reached = <span class="dv">0</span>; + + n = graphVertexCount(g); + + s->preorder = createEmptyArray(n); + s->time = createEmptyArray(n); + s->parent = createEmptyArray(n); + s->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->depth); + free(s->parent); + free(s->time); + free(s->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->top < graphEdgeCount(g) + <span class="dv">1</span>); + + q->e[q->top].u = u; + q->e[q->top].v = v; + q->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->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->graph, root, root, &q); + + <span class="co">/* while q.e not empty */</span> + <span class="kw">while</span>(q.bottom < 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->parent[cur.v] != SEARCH_INFO_NULL) <span class="kw">continue</span>; + + <span class="co">/* no */</span> + assert(r->reached < graphVertexCount(r->graph)); + r->parent[cur.v] = cur.u; + r->time[cur.v] = r->reached; + r->preorder[r->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->depth[cur.v] = <span class="dv">0</span>; + } <span class="kw">else</span> { + r->depth[cur.v] = r->depth[cur.u] + <span class="dv">1</span>; + } + + <span class="co">/* push all outgoing edges */</span> + graphForeach(r->graph, cur.v, pushEdge, &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 < <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 < <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 <= 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 <stdlib.h></span> +<span class="ot">#include <assert.h></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 < 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 < i; j++) { + <span class="kw">if</span>(a[j] < a[i] && table[j].length + <span class="dv">1</span> > 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 < n; i++) { + <span class="kw">if</span>(table[i].length > 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 < best_length; i++) { + assert(scan >= <span class="dv">0</span>); + assert(scan < 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 <stdio.h></span> +<span class="ot">#include <stdlib.h></span> +<span class="ot">#include <assert.h></span> +<span class="ot">#include <string.h></span> +<span class="ot">#include <limits.h></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 < xLen; i++) { + <span class="kw">for</span>(j = <span class="dv">0</span>; j < 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 > <span class="dv">0</span> && j > <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 = &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 > <span class="dv">0</span> && best[i<span class="dv">-1</span>][j].length > 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 = &best[i<span class="dv">-1</span>][j]; + best[i][j].newChar = <span class="dv">0</span>; + } + + <span class="kw">if</span>(j > <span class="dv">0</span> && best[i][j<span class="dv">-1</span>].length > 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 = &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 = &best[xLen<span class="dv">-1</span>][yLen<span class="dv">-1</span>]; p; p = p->prev) { + <span class="kw">if</span>(p->newChar) { + assert(outPos >= <span class="dv">0</span>); + lcs[outPos--] = p->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 <stdio.h></span> +<span class="ot">#include <stdlib.h></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 <stdio.h></span> +<span class="ot">#include <stdlib.h></span> +<span class="ot">#include <time.h></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 <stdio.h></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(&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 <stdio.h></span> +<span class="ot">#include <stdlib.h></span> +<span class="ot">#include <assert.h></span> +<span class="ot">#include <time.h></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()) >= 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 < <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 <stdio.h></span> +<span class="ot">#include <stdlib.h></span> +<span class="ot">#include <assert.h></span> +<span class="ot">#include <time.h></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 <= 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 < <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()) & <span class="bn">0x70000000</span>) != (pattern & <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 & <span class="bn">0x70000000</span>) != (pattern & <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 <stdio.h></span> +<span class="ot">#include <stdlib.h></span> +<span class="ot">#include <assert.h></span> + +<span class="co">/* reorder an array to put elements <= pivot</span> +<span class="co"> * before elements > pivot.</span> +<span class="co"> * Returns number of elements <= 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 >= <span class="dv">0</span>); + + <span class="co">/* Dutch Flag algorithm */</span> + <span class="co">/* swap everything <= pivot to bottom of array */</span> + <span class="co">/* invariant is i < lo implies a[i] <= pivot */</span> + <span class="co">/* and i > hi implies a[i] > pivot */</span> + lo = <span class="dv">0</span>; + hi = n<span class="dv">-1</span>; + + <span class="kw">while</span>(lo <= hi) { + <span class="kw">if</span>(a[lo] <= 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> <= k); + assert(k < 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 <= pivot */</span> + <span class="kw">if</span>(k < 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 <= <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 > <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 < N; i++) { + a[i] = i; + } + + shuffle(N, a); + + <span class="kw">for</span>(i = <span class="dv">0</span>; i < 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 < 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 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 <stdlib.h></span> +<span class="ot">#include <assert.h></span> +<span class="ot">#include <limits.h></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 < MAX_HEIGHT && 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 > <span class="dv">0</span>); + assert(height <= 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->key = key; + s->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->height = <span class="dv">1</span>; + + <span class="kw">for</span>(i = <span class="dv">0</span>; i < MAX_HEIGHT; i++) { + s->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->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->height - <span class="dv">1</span>; level >= <span class="dv">0</span>; level--) { + <span class="kw">while</span>(s->next[level] && s->next[level]->key <= key) { + s = s->next[level]; + } + } + + <span class="kw">return</span> s->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->height > s->height) { + s->height = elt->height; + } + + <span class="co">/* search through levels taller than elt */</span> + <span class="kw">for</span>(level = s->height - <span class="dv">1</span>; level >= elt->height; level--) { + <span class="kw">while</span>(s->next[level] && s->next[level]->key < key) { + s = s->next[level]; + } + } + + <span class="co">/* now level is elt->height - 1, we can start inserting */</span> + <span class="kw">for</span>(; level >= <span class="dv">0</span>; level--) { + <span class="kw">while</span>(s->next[level] && s->next[level]->key < key) { + s = s->next[level]; + } + + <span class="co">/* s is last entry on this level < new element */</span> + <span class="co">/* do list insert */</span> + elt->next[level] = s->next[level]; + s->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->height - <span class="dv">1</span>; level >= <span class="dv">0</span>; level--) { + <span class="kw">while</span>(target->next[level] && target->next[level]->key < key) { + target = target->next[level]; + } + } + + <span class="co">/* take one extra step at bottom */</span> + target = target->next[<span class="dv">0</span>]; + + <span class="kw">if</span>(target == <span class="dv">0</span> || target->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->height - <span class="dv">1</span>; level >= <span class="dv">0</span>; level--) { + <span class="kw">while</span>(s->next[level] && s->next[level]->key < key) { + s = s->next[level]; + } + + <span class="kw">if</span>(s->next[level] == target) { + s->next[level] = target->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 < HASH_PREFIX_LENGTH && us[i] != '\<span class="dv">0</span>'; i++) { + h ^= d->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 <stdio.h></span> +<span class="ot">#include <stdlib.h></span> +<span class="ot">#include <string.h></span> +<span class="ot">#include <assert.h></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]) & (0x1 << (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)->kids[0] == 0 && (t)->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 && !IsLeaf(trie); bit++) { + <span class="co">/* keep going */</span> + trie = trie->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->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->key = my_strdup(key); + assert(t->key); + } <span class="kw">else</span> { + t->key = <span class="dv">0</span>; + } + + <span class="kw">for</span>(i = <span class="dv">0</span>; i < TRIE_BASE; i++) t->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->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->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->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->key; +<span class="ot">#ifdef EXCESSIVE_TIDINESS</span> + t->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->kids[bitvalue] = kid; + bit++; + t = kid; + } + + <span class="co">/* then split */</span> + t->kids[bitvalue] = make_trie_node(key); + t->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 < TRIE_BASE; i++) { + trie_destroy(trie->kids[i]); + } + + <span class="kw">if</span>(IsLeaf(trie)) { + free(trie->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 < bit; i++) putchar(' '); + puts(t->key); + } <span class="kw">else</span> { + <span class="kw">for</span>(kid = <span class="dv">0</span>; kid < TRIE_BASE; kid++) { + trie_print_internal(t->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 <stdio.h></span> +<span class="ot">#include <stdlib.h></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> && c != EOF) { + <span class="kw">while</span>(n >= 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 && 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 && !IsLeaf(t)) { + <span class="kw">if</span>(t->bit >= 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->kids[GET_BIT(key, t->bit)]; + } + } + + <span class="kw">return</span> t && !strcmp(t->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 <stdio.h></span> +<span class="ot">#include <stdlib.h></span> +<span class="ot">#include <assert.h></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] < 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] > 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 < t->key) { + t = t->lt; + } <span class="kw">else</span> <span class="kw">if</span>(*key > t->key) { + t = t->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->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)->key = *key; + (*t)->lt = (*t)->eq = (*t)->gt = <span class="dv">0</span>; + } + + <span class="co">/* now follow search */</span> + <span class="kw">if</span>(*key < (*t)->key) { + tst_insert_recursive(&(*t)->lt, key); + } <span class="kw">else</span> <span class="kw">if</span>(*key > (*t)->key) { + tst_insert_recursive(&(*t)->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(&(*t)->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)->key = *key; + (*t)->lt = (*t)->eq = (*t)->gt = <span class="dv">0</span>; + } + + <span class="co">/* now follow search */</span> + <span class="kw">if</span>(*key < (*t)->key) { + t = &(*t)->lt; + } <span class="kw">else</span> <span class="kw">if</span>(*key > (*t)->key) { + t = &(*t)->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 = &(*t)->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(&t, key); +<span class="ot">#else</span> + tst_insert_iterative(&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->lt); + tst_destroy(t->eq); + tst_destroy(t->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 <assert.h></span> +<span class="ot">#include <limits.h></span> +<span class="ot">#include <string.h></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 > <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 < 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 < UCHAR_MAX<span class="dv">+1</span>; i++) { + <span class="kw">if</span>(count[i] > count[mode]) { + mode = i; + } + } + + <span class="kw">if</span>(count[mode] < 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 < 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] <= j < top[i] implies a[j][k] == i */</span> + <span class="kw">for</span>(i = <span class="dv">0</span>; i < UCHAR_MAX<span class="dv">+1</span>; i++) { + <span class="kw">while</span>(top[i] < 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 < 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 sort < /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 <stdlib.h></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->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 >= <span class="dv">0</span> && element < n->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 - 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 += 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->bound + <span class="dv">1</span>)); + <span class="kw">for</span>(i = <span class="dv">0</span>; i < n->bound; i++) a[i] = i; + a[n->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 >= n->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 < n->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 *</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> *) &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->next = next; + s->data = data; + + <span class="kw">return</span> s; +} + +<span class="dt">int</span> +sequence_next(Sequence s) +{ + <span class="kw">return</span> s->next(s->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->cur += d->step; + + <span class="kw">return</span> d->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->cur = x - a; <span class="co">/* back up so first value returned is x */</span> + d->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->x; + d->x = d->f(d->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->x = x0; + d->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->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> &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->cur = ic->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->cur; + ic->cur = ic->f(ic->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->reset = ifs_reset; + ic->next = ifs_next; + ic->destroy = (<span class="dt">void</span> (*)(<span class="kw">struct</span> counter *)) free; + + ic->init = init; + ic->cur = init; + ic->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 < <span class="dv">10</span>; i++) { + printf(<span class="st">"%d</span><span class="ch">\n</span><span class="st">"</span>, c->next(c)); + } + + c->reset(c); + + <span class="kw">for</span>(i = <span class="dv">0</span>; i < <span class="dv">20</span>; i++) { + printf(<span class="st">"%d</span><span class="ch">\n</span><span class="st">"</span>, c->next(c)); + } + + c->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 --> 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 -> b ab -> br abr -> 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 a1 b1 r1 a3 c1 a4 d1 a2 b2 r2 a5 $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 --> 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->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 <stdlib.h></span> +<span class="ot">#include <assert.h></span> +<span class="ot">#include <string.h></span> +<span class="ot">#include <limits.h></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->n = strlen(s) + <span class="dv">1</span>; + sa->string = s; + + sa->suffix = malloc(<span class="kw">sizeof</span>(*sa->suffix) * sa->n); + assert(sa->suffix); + + <span class="co">/* construct array of pointers to suffixes */</span> + <span class="kw">for</span>(i = <span class="dv">0</span>; i < sa->n; i++) { + sa->suffix[i] = s+i; + } + + <span class="co">/* this could be a lot more efficient */</span> + qsort(sa->suffix, sa->n, <span class="kw">sizeof</span>(*sa->suffix), saCompare); + + <span class="kw">return</span> sa; +} + +<span class="dt">void</span> +suffixArrayDestroy(SuffixArray sa) +{ + free(sa->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] <= substring < suffix[hi] */</span> + lo = <span class="dv">0</span>; + hi = sa->n; + + <span class="kw">while</span>(lo + <span class="dv">1</span> < hi) { + mid = (lo+hi)/<span class="dv">2</span>; + cmp = strncmp(sa->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 > <span class="dv">0</span> && strncmp(sa->suffix[lo<span class="dv">-1</span>], substring, len) == <span class="dv">0</span>; lo--); + <span class="kw">for</span>(hi = mid; hi < sa->n && strncmp(sa->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 < <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->n); + assert(bwt); + + <span class="kw">for</span>(i = <span class="dv">0</span>; i < sa->n; i++) { + <span class="kw">if</span>(sa->suffix[i] == sa->string) { + <span class="co">/* wraps around to nul */</span> + bwt[i] = '\<span class="dv">0</span>'; + } <span class="kw">else</span> { + bwt[i] = sa->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 <= UCHAR_MAX; c++) { + count[c] = <span class="dv">0</span>; + } + + <span class="kw">for</span>(i = <span class="dv">0</span>; i < 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 <= 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 < 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 < 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 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 <iostream></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 << <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 <stdio.h></code> is replaced by <code class="backtick">#include <iostream></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 << "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"><<</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 << 37</code>, <code class="backtick">std::cout << 'q'</code>, <code class="backtick">std::cout << 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 namespace 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 <iostream></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 << <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> &x) +{ + x++; +}</code></pre></div> +<p>The <code class="backtick">int &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">&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 &huge) +{ + cout << 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 << <span class="st">"hi"</span> << <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"><<</code> operator is an <code class="backtick">ostream &</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 <iostream></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 << <span class="st">"The type of "</span> << <span class="dv">3</span> << <span class="st">" is "</span> << typeName(<span class="dv">3</span>) << <span class="st">".</span><span class="ch">\n</span><span class="st">"</span>; + cout << <span class="st">"The type of "</span> << <span class="fl">3.1</span> << <span class="st">" is "</span> << typeName(<span class="fl">3.1</span>) << <span class="st">".</span><span class="ch">\n</span><span class="st">"</span>; + cout << <span class="st">"The type of "</span> << <span class="st">'c'</span> << <span class="st">" is "</span> << typeName(<span class="st">'c'</span>) << <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 <iostream></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 << <span class="st">"counter de-allocated with value "</span> << value << <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 << <span class="st">"c starts at "</span> << c.read() << <span class="st">'</span><span class="ch">\n</span><span class="st">'</span>; + c.increment(); + cout << <span class="st">"c after one increment is "</span> << c.read() << <span class="st">'</span><span class="ch">\n</span><span class="st">'</span>; + + cout << <span class="st">"c10 starts at "</span> << c10.read() << <span class="st">'</span><span class="ch">\n</span><span class="st">'</span>; + c.increment(); + c.increment(); + cout <<<span class="st">"c10 after two increments is "</span> << c10.read() << <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 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 *</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 c;</code>), you get the constructor with no arguments. If you create an instance with arguments (as in the declaration <code class="backtick">Counter 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 + 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 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 <iostream></span> +<span class="ot">#include <algorithm> </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 &); + MaxPlus <span class="kw">operator</span>*(<span class="dt">const</span> MaxPlus &); + <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 &other) +{ + <span class="kw">return</span> MaxPlus(value + other.value); +} + +MaxPlus +MaxPlus::<span class="kw">operator</span>+(<span class="dt">const</span> MaxPlus &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 << <span class="st">"2+3 == "</span> << (MaxPlus(<span class="dv">2</span>) + MaxPlus(<span class="dv">3</span>)) << <span class="st">'</span><span class="ch">\n</span><span class="st">'</span>; + cout << <span class="st">"2*3 == "</span> << (MaxPlus(<span class="dv">2</span>) * MaxPlus(<span class="dv">3</span>)) << <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 <<</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 << (MaxPlus(<span class="dv">2</span>) + <span class="dv">3</span>) << <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 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 *</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 <class T></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> <<span class="kw">class</span> T> +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 << <span class="st">"add1(3) == "</span> << add1(<span class="dv">3</span>) << <span class="st">'</span><span class="ch">\n</span><span class="st">'</span>; + cout << <span class="st">"add1(3.1) == "</span> << add1(<span class="fl">3.1</span>) << <span class="st">'</span><span class="ch">\n</span><span class="st">'</span>; + cout << <span class="st">"add1('c') == "</span> << add1(<span class="st">'c'</span>) << <span class="st">'</span><span class="ch">\n</span><span class="st">'</span>; + cout << <span class="st">"add1(MaxPlus(0)) == "</span> << add1(MaxPlus(<span class="dv">0</span>)) << <span class="st">'</span><span class="ch">\n</span><span class="st">'</span>; + cout << <span class="st">"add1(MaxPlus(2)) == "</span> << add1(MaxPlus(<span class="dv">2</span>)) << <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 << <span class="st">"add1<int>(3.1) == "</span> << add1<<span class="dt">int</span>>(<span class="fl">3.1</span>) << <span class="st">'</span><span class="ch">\n</span><span class="st">'</span>;</code></pre></div> +<p>produces</p> +<pre><code>add1<int>(3.1) == 4</code></pre> +<p>because <code class="backtick">add1<int></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 <iostream></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 << fail() << <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 << <span class="st">"Caught error: "</span> << s << <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 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 []</code> <em>pointer-to-base-of-array</em>. Mixing <code class="backtick">new</code> with <code class="backtick">delete []</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 <iostream></span> +<span class="ot">#include <cassert></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 << <span class="st">"Noisy object created with id "</span> << id << <span class="st">'</span><span class="ch">\n</span><span class="st">'</span>; +} + +Noisy::~Noisy() { + cout << <span class="st">"Noisy object destroyed with id "</span> << id << <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 < n; i++) { + a[i] = i; + } + + <span class="kw">for</span>(<span class="dt">int</span> i = <span class="dv">0</span>; i < 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 T &)</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 T &)</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 = 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 = b = 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> <<span class="kw">class</span> T> +<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 &); <span class="co">/* copy constructor */</span> + Stack& <span class="kw">operator</span>=(<span class="dt">const</span> Stack &); <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> <<span class="kw">class</span> T> +Stack<T>::Stack() +{ + size = initialSize; + top = <span class="dv">0</span>; + contents = <span class="kw">new</span> T[size]; +} + +<span class="kw">template</span> <<span class="kw">class</span> T> +Stack<T>::~Stack() +{ + <span class="kw">delete</span> [] contents; +} + +<span class="kw">template</span> <<span class="kw">class</span> T> +Stack<T>::Stack(<span class="dt">const</span> Stack<T> &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 < top; i++) { + contents[i] = other.contents[i]; + } +} + +<span class="kw">template</span> <<span class="kw">class</span> T> +Stack<T> & +Stack<T>::<span class="kw">operator</span>=(<span class="dt">const</span> Stack<T> &other) +{ + <span class="kw">if</span>(&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 < top; i++) { + contents[i] = other.contents[i]; + } + } + + <span class="kw">return</span> *<span class="kw">this</span>; +} + +<span class="kw">template</span> <<span class="kw">class</span> T> +<span class="dt">void</span> +Stack<T>::push(T elt) +{ + <span class="kw">if</span>(top >= 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 < top; i++) { + newContents[i] = contents[i]; + } + + <span class="kw">delete</span> [] contents; + + contents = newContents; + size = newSize; + } + + contents[top++] = elt; +} + +<span class="kw">template</span> <<span class="kw">class</span> T> +T +Stack<T>::pop() +{ + <span class="kw">if</span>(top > <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 <iostream></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<<span class="dt">int</span>> s; + Stack<<span class="dt">int</span>> 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 << s.pop() << <span class="st">'</span><span class="ch">\n</span><span class="st">'</span>; + cout << s.pop() << <span class="st">'</span><span class="ch">\n</span><span class="st">'</span>; + cout << s.pop() << <span class="st">'</span><span class="ch">\n</span><span class="st">'</span>; + + cout << s2.pop() << <span class="st">'</span><span class="ch">\n</span><span class="st">'</span>; + cout << s2.pop() << <span class="st">'</span><span class="ch">\n</span><span class="st">'</span>; + cout << s2.pop() << <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 << <span class="st">"Caught expected exception "</span> << err << <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 < <span class="dv">1000</span>; i++) { + s.push(i); + } + + cout << s.pop() << <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 << <span class="st">"Caught error "</span> << err << <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 <stack></code>.</p> +<div> +<div class="sourceCode"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span class="ot">#include <iostream></span> +<span class="ot">#include <stack></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<<span class="dt">int</span>> s; + stack<<span class="dt">int</span>> 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 << s.top() << <span class="st">'</span><span class="ch">\n</span><span class="st">'</span>; s.pop(); + cout << s.top() << <span class="st">'</span><span class="ch">\n</span><span class="st">'</span>; s.pop(); + cout << s.top() << <span class="st">'</span><span class="ch">\n</span><span class="st">'</span>; s.pop(); + + cout << s2.top() << <span class="st">'</span><span class="ch">\n</span><span class="st">'</span>; s2.pop(); + cout << s2.top() << <span class="st">'</span><span class="ch">\n</span><span class="st">'</span>; s2.pop(); + cout << s2.top() << <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 < <span class="dv">1000</span>; i++) { + s.push(i); + } + + cout << s.top() << <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 <stdio.h></span> +<span class="ot">#include <stdlib.h></span> +<span class="ot">#include <assert.h></span> +<span class="ot">#include "counter.h"</span> + +<span class="ot">#include <stdint.h></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->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->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->value == COUNTER_MAX) { + <span class="kw">return</span> <span class="dv">0</span>; + } <span class="kw">else</span> { + c->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->value == <span class="dv">0</span>) { + <span class="kw">return</span> <span class="dv">0</span>; + } <span class="kw">else</span> { + c->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->value == <span class="dv">0</span>); + assert(counterIncrement(c) == <span class="dv">1</span>); <span class="co">/* 1 */</span> + assert(c->value == <span class="dv">1</span>); + assert(counterIncrement(c) == <span class="dv">1</span>); <span class="co">/* 2 */</span> + assert(c->value == <span class="dv">2</span>); + assert(counterDecrement(c) == <span class="dv">1</span>); <span class="co">/* 1 */</span> + assert(c->value == <span class="dv">1</span>); + assert(counterDecrement(c) == <span class="dv">1</span>); <span class="co">/* 0 */</span> + assert(c->value == <span class="dv">0</span>); + assert(counterDecrement(c) == <span class="dv">0</span>); <span class="co">/* 0 */</span> + assert(c->value == <span class="dv">0</span>); + assert(counterIncrement(c) == <span class="dv">1</span>); <span class="co">/* 1 */</span> + assert(c->value == <span class="dv">1</span>); + + <span class="co">/* force counter value to COUNTER_MAX to test for overflow protection */</span> + c->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->value == COUNTER_MAX); + assert(counterDecrement(c) == <span class="dv">1</span>); <span class="co">/* COUNTER_MAX-1 */</span> + assert(c->value == COUNTER_MAX<span class="dv">-1</span>); + assert(counterIncrement(c) == <span class="dv">1</span>); <span class="co">/* COUNTER_MAX */</span> + assert(c->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 <stdio.h></span> +<span class="ot">#include <setjmp.h></span> +<span class="ot">#include <signal.h></span> +<span class="ot">#include <unistd.h></span> + +<span class="ot">#include <stdlib.h></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 < STRESS_TEST_ITERATIONS; i++) { + stack_push(s, i); + } + <span class="kw">for</span>(i = <span class="dv">0</span>; i < 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 >= <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 <stdlib.h> </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 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) -> 1 but expected 0 +test-stack.c:33: TEST FAILED: stack_pop(s) -> -1 but expected 3 +test-stack.c:34: TEST FAILED: stack_isempty(s) -> 1 but expected 0 +test-stack.c:35: TEST FAILED: stack_pop(s) -> -1 but expected 2 +test-stack.c:36: TEST FAILED: stack_isempty(s) -> 1 but expected 0 +test-stack.c:37: TEST FAILED: stack_pop(s) -> -1 but expected 1 +test-stack.c:45: TEST FAILED: stack_isempty(s) -> 1 but expected 0 +test-stack.c:46: TEST FAILED: stack_pop(s) -> -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 <stdlib.h> </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->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->data[(s->top)++] = elem; +} + +<span class="dt">int</span> +stack_pop(Stack s) +{ + <span class="kw">return</span> s->data[--(s->top)]; +} + +<span class="dt">int</span> +stack_isempty(Stack s) +{ + <span class="kw">return</span> s->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) -> 0 but expected 1 +test-stack.c:41: TEST FAILED: stack_pop(s) -> 409 but expected -1 +test-stack.c:47: TEST FAILED: stack_isempty(s) -> 0 but expected 1 +test-stack.c:48: TEST FAILED: stack_pop(s) -> 0 but expected -1 +test-stack.c:49: TEST FAILED: stack_isempty(s) -> 0 but expected 1 +test-stack.c:74: Segmentation fault (signal 11) +test-stack.c:76: TEST FAILED: stack_isempty(s) -> 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->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->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->data[--(s->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) -> 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 <stdlib.h> </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->top = <span class="dv">0</span>; + s->size = INITIAL_STACK_SIZE; + s->data = malloc(s->size * <span class="kw">sizeof</span>(*(s->data))); + <span class="kw">if</span>(s->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->data); + free(s); +} + +<span class="dt">void</span> +stack_push(Stack s, <span class="dt">int</span> elem) +{ + <span class="kw">if</span>(s->top == s->size) { + <span class="co">/* need more space */</span> + s->size *= STACK_SIZE_MULTIPLIER; + s->data = realloc(s->data, s->size * <span class="kw">sizeof</span>(*(s->data))); + <span class="kw">if</span>(s->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->data[s->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->data[--(s->top)]; + } +} + +<span class="dt">int</span> +stack_isempty(Stack s) +{ + <span class="kw">return</span> s->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 <setjmp.h></span> +<span class="co"> * #include <stdio.h></span> +<span class="co"> * #include <signal.h></span> +<span class="co"> * #include <unistd.h></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"> && (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 -> %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 <stdio.h></span> +<span class="ot">#include <signal.h></span> +<span class="ot">#include <string.h></span> +<span class="ot">#include <setjmp.h></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 > <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 < 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 > <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 < n; i++) { + <span class="kw">if</span>(prefix_max < 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 & 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>]><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 *</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]) & (0x1 << ((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 << ((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]) &= ~(0x1 << ((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 << 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) >> BITS_PER_BYTE * (n)) & 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) >> (i)) & ((1 << 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 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 <stdio.h></span> +<span class="ot">#include <stdlib.h></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 < <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 < <span class="dv">0</span> || c >= 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 < NUM_COUNTERS; i++) { + fscanf(f, <span class="st">"%d"</span>, &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 < 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) * 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 <stdio.h></span> +<span class="ot">#include <stdlib.h></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 < <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 < <span class="dv">0</span> || c >= 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 if=/dev/zero of=/tmp/hit bs=400 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 <stdio.h></span> +<span class="ot">#include <stdlib.h></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 < <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 < <span class="dv">0</span> || c >= 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(&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(&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 <stdio.h></span> +<span class="ot">#include <stdlib.h></span> +<span class="ot">#include <sys/types.h></span> +<span class="ot">#include <sys/stat.h></span> +<span class="ot">#include <fcntl.h></span> +<span class="ot">#include <sys/mman.h> </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 < <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 < <span class="dv">0</span> || c >= 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 < <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 *</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 *</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 <stdio.h></span> +<span class="ot">#include <stdlib.h></span> +<span class="ot">#include <string.h></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> && c != EOF) { + <span class="kw">while</span>(n >= 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 && 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 < 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>(<>) { + <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(<>)</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 $_)' < /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 <ctype.h></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 < test.in > 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 > file +$ cat file +hi +$ od -t x1z file +0000000 68 69 0a >hi.< +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 <stdio.h></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' <= c) && (c <= 'z')) { + putchar(((c - 'a') + offset) % MODULUS + 'a'); + offset = (offset + LOWERCASE_STEP) % MODULUS; + } <span class="kw">else</span> <span class="kw">if</span>(('A' <= c) && (c <= '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 <stdlib.h></span> +<span class="ot">#include <assert.h></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 < 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 < 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 < n && ++(combination[i]) >= 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 < 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" < 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 < hail-satan.in | sort > 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 >= 0, at least one of c1 and c2 is > 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 <stdio.h></span> +<span class="ot">#include <stdlib.h></span> +<span class="ot">#include <string.h></span> +<span class="ot">#include <assert.h></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 < 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 < 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 < 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 >= 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 < 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", &row, &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>, &row, &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 <stdio.h></span> +<span class="ot">#include <stdlib.h></span> +<span class="ot">#include <assert.h></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->top = <span class="dv">0</span>; + q->size = QUEUE_INITIAL_SIZE; + + q->pixels = malloc(<span class="kw">sizeof</span>(<span class="kw">struct</span> pixel) * q->size); + assert(q->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->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->top >= q->size) { + q->size *= <span class="dv">2</span>; + q->pixels = realloc(q->pixels, <span class="kw">sizeof</span>(<span class="kw">struct</span> pixel) * q->size); + assert(q->pixels); + } + + q->pixels[q->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 < q->top; i++) { + <span class="kw">while</span>(outputRow < q->pixels[i].row) { + putchar(<span class="ch">'\n'</span>); + outputRow++; + outputCol = <span class="dv">0</span>; + } + <span class="kw">while</span>(outputCol < q->pixels[i].col) { + putchar(' '); + outputCol++; + } + putchar(q->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 < left->top && r < right->top) { + <span class="kw">if</span>(left->pixels[l].row < right->pixels[r].row) { + queuePush(q, left->pixels[l++]); + } <span class="kw">else</span> <span class="kw">if</span>(left->pixels[l].row == right->pixels[r].row) { + <span class="kw">if</span>(left->pixels[l].col < right->pixels[r].col) { + queuePush(q, left->pixels[l++]); + } <span class="kw">else</span> <span class="kw">if</span>(left->pixels[l].col == right->pixels[r].col) { + <span class="co">/* right wins but both increment */</span> + queuePush(q, right->pixels[r++]); + l++; + } <span class="kw">else</span> { + <span class="co">/* right is earlier */</span> + queuePush(q, right->pixels[r++]); + } + } <span class="kw">else</span> { + <span class="co">/* right is earlier */</span> + queuePush(q, right->pixels[r++]); + } + } + + <span class="co">/* clean out whichever tail is still nonempty */</span> + <span class="kw">while</span>(l < left->top) { + queuePush(q, left->pixels[l++]); + } + + <span class="kw">while</span>(r < right->top) { + queuePush(q, right->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 < q->top; i++) { + q->pixels[i].row += r; + q->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>, &row, &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 <action><direction><new-state></span> +<span class="co"> *</span> +<span class="co"> * where <action> 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"> * <direction> 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 <stdio.h></span> +<span class="ot">#include <stdlib.h></span> +<span class="ot">#include <string.h></span> +<span class="ot">#include <assert.h></span> +<span class="ot">#include <sys/types.h></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->tapeLength; + newTape = malloc(newTapeLength); + assert(newTape); + + <span class="kw">for</span>(i = <span class="dv">0</span>; i < newTapeLength; i++) { + newTape[i] = <span class="dv">0</span>; + } + + <span class="co">/* copy old tape */</span> + offset = newTapeLength / <span class="dv">2</span> - c->current; + + <span class="kw">for</span>(i = c->leftmost; i <= c->rightmost; i++) { + newTape[i + offset] = c->tape[i]; + } + + oldTape = c->tape; + c->tape = newTape; + c->tapeLength = newTapeLength; + c->current += offset; + c->leftmost += offset; + c->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->state = <span class="dv">1</span>; + c->tapeLength = INITIAL_TAPE_LENGTH; + c->leftmost = c->rightmost = c->current = c->tapeLength / <span class="dv">2</span>; + c->tape = malloc(c->tapeLength); + assert(c->tape); + + <span class="kw">for</span>(i = <span class="dv">0</span>; i < c->tapeLength; i++) { + c->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->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->leftmost; i < c->current; i++) { + putchar(' '); + } + putchar(STATE_BASE + c->state); + putchar(<span class="ch">'\n'</span>); + + <span class="kw">for</span>(i = c->leftmost; i <= c->rightmost; i++) { + putchar(SYMBOL_BASE + c->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->state != <span class="dv">0</span>) { + steps++; + + <span class="co">/* execute the next transition */</span> + assert(c->state < argc); + + cellValue = c->tape[c->current]; + assert(<span class="dv">0</span> <= cellValue); + assert(<span class="dv">3</span>*(cellValue<span class="dv">+1</span>) <= strlen(argv[c->state])); + + transition = argv[c->state] + <span class="dv">3</span>*c->tape[c->current]; + + c->tape[c->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->current == <span class="dv">0</span>) { + configurationExpand(c); + } + c->current--; + <span class="kw">if</span>(c->current < c->leftmost) { + c->leftmost = c->current; + } + <span class="kw">break</span>; + <span class="kw">case</span> '+': + <span class="kw">if</span>(c->current == c->tapeLength - <span class="dv">1</span>) { + configurationExpand(c); + } + c->current++; + <span class="kw">if</span>(c->current > c->rightmost) { + c->rightmost = c->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->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 <stdint.h> 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 <stdio.h></span> +<span class="ot">#include <stdlib.h></span> +<span class="ot">#include <assert.h></span> +<span class="ot">#include <stdint.h></span> +<span class="ot">#include <inttypes.h></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>, &s.topLeft.x, &s.topLeft.y, &s.direction, &s.length, &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>, &p.x, &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 <stdlib.h></span> +<span class="ot">#include <assert.h></span> +<span class="ot">#include <string.h></span> +<span class="ot">#include <stdint.h></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->size = initialSize; + f->occupancy = <span class="dv">0</span>; + + f->table = malloc(<span class="kw">sizeof</span>(<span class="kw">struct</span> elt *) * f->size); + + <span class="kw">for</span>(i = <span class="dv">0</span>; i < f->size; i++) { + f->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 < f->size; i++) { + <span class="kw">for</span>(e = f->table[i]; e != <span class="dv">0</span>; e = next) { + next = e->next; + free(e); + } + } + + free(f->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->size; + + e = malloc(<span class="kw">sizeof</span>(<span class="kw">struct</span> elt)); + assert(e); + + e->ship = s; + e->next = f->table[h]; + f->table[h] = e; + f->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 > MAX_SHIP_LENGTH + || (s.direction == HORIZONTAL && s.topLeft.x > COORD_MAX - (s.length - <span class="dv">1</span>)) + || (s.direction == VERTICAL && s.topLeft.y > 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->occupancy >= f->size * MAX_ALPHA) { + <span class="co">/* grow the field */</span> + f2 = fieldCreateInternal(f->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 < f->size; i++) { + <span class="kw">for</span>(e = f->table[i]; e != <span class="dv">0</span>; e = e->next) { + <span class="co">/* skip testing for occupancy or intersections */</span> + fieldInsertShip(f2, e->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 < 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 = &f->table[hash(p) % f->size]; *prev != <span class="dv">0</span>; prev = &((*prev)->next)) { + <span class="kw">if</span>((*prev)->ship.topLeft.x == p.x && (*prev)->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 <= <span class="dv">1</span>; direction++) { + <span class="kw">for</span>(i = <span class="dv">0</span>; i < MAX_SHIP_LENGTH && i <= (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)->ship.length > i && (*prev)->ship.direction == direction) { + <span class="co">/* got it */</span> + freeMe = *prev; + *prev = freeMe->next; + + name = freeMe->ship.name; + free(freeMe); + + f->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->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 <stdint.h></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 <stdio.h></span> +<span class="ot">#include <stdlib.h></span> +<span class="ot">#include <assert.h></span> +<span class="ot">#include <stdint.h></span> +<span class="ot">#include <string.h></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->n = <span class="dv">0</span>; + s->size = size; + s->table = calloc(s->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 < s->size; i++) { + <span class="kw">if</span>(s->table[i]) { + free(s->table[i]); + } + } + + free(s->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->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->size; s->table[h] && strcmp(s->table[h], elt); h = (h<span class="dv">+1</span>) % s->size); + + <span class="co">/* check if not already present */</span> + <span class="kw">if</span>(s->table[h] == <span class="dv">0</span>) { + s->table[h] = elt; + s->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->n >= s->size * MAX_ALPHA) { + <span class="co">/* rebuild the table */</span> + s2 = orderedSetCreateInternal(s->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 < s->size; h++) { + <span class="kw">if</span>(s->table[h]) { + orderedSetInsertInternal(s2, s->table[h]); + } + } + + <span class="co">/* free the table and then do a brain transplant */</span> + free(s->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->size; s->table[h] && strcmp(s->table[h], elt); h = (h<span class="dv">+1</span>) % s->size); + + <span class="co">/* if we reached a nonempty slot, it must be our target */</span> + <span class="kw">if</span>(s->table[h] != <span class="dv">0</span>) { + <span class="co">/* remove the initial element */</span> + free(s->table[h]); + s->table[h] = <span class="dv">0</span>; + s->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->size; s->table[h] ; h = (h<span class="dv">+1</span>) % s->size) { + later = s->table[h]; + s->table[h] = <span class="dv">0</span>; + s->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->size); + assert(a); + + top = <span class="dv">0</span>; + + <span class="kw">for</span>(h = <span class="dv">0</span>; h < s->size; h++) { + <span class="kw">if</span>(s->table[h]) { + a[top++] = s->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 < 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 <stdio.h></span> +<span class="ot">#include <stdlib.h></span> +<span class="ot">#include <assert.h></span> +<span class="ot">#include <math.h></span> +<span class="ot">#include <limits.h></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 && 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)->a[(pos).y * (m)->size.x + (pos).x])</span> +<span class="ot">#define Mget(m, pos) (assert((pos).x >= 0 && (pos).y >= 0 && (pos).x < (m)->size.x && (pos).y < (m)->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->x = source.x + dir.x; + target->y = source.y + dir.y; + + <span class="kw">return</span> target->x >= <span class="dv">0</span> && target->y >= <span class="dv">0</span> && target->x < m->size.x && target->y < m->size.y; +} + +<span class="co">/* free a maze */</span> +<span class="dt">void</span> +destroyMaze(<span class="kw">struct</span> maze *m) +{ + free(m->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>, &m->size.x, &m->size.y); + + m->a = malloc(<span class="kw">sizeof</span>(<span class="kw">struct</span> square) * m->size.y * m->size.x); + + <span class="kw">for</span>(i.y = <span class="dv">0</span>; i.y < m->size.y; i.y++) { + <span class="kw">for</span>(i.x = <span class="dv">0</span>; i.x < m->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->size.x, m->size.y); + + <span class="kw">for</span>(i.y = <span class="dv">0</span>; i.y < m->size.y; i.y++) { + <span class="kw">for</span>(i.x = <span class="dv">0</span>; i.x < m->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 < DIRECTIONS; i++) { + <span class="kw">if</span>(offset(m, &q, p, directions[i]) && 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->size.x; + r.y = rand() % m->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->size = size; + m->a = malloc(<span class="kw">sizeof</span>(<span class="kw">struct</span> square) * m->size.x * m->size.y); + assert(m->a); + + <span class="co">/* start with all WALL */</span> + <span class="kw">for</span>(i.y = <span class="dv">0</span>; i.y < m->size.y; i.y++) { + <span class="kw">for</span>(i.x = <span class="dv">0</span>; i.x < m->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 > <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 && 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->size.x * m->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 < m->size.y; current.y++) { + <span class="kw">for</span>(current.x = <span class="dv">0</span>; current.x < m->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 < 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 < DIRECTIONS; i++) { + <span class="kw">if</span>(offset(m, &neighbor, current, directions[i]) && Mget(m, neighbor).contents == PATH && !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 < <span class="dv">0</span> ? -seed : seed); + m = generateMaze(size); + <span class="kw">if</span>(seed >= <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 <james.c.terry@yale.edu> +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 <string.h> +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 > shouldn't +really be a >=. +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 log</code>.<a href="#fnref4">↩</a></p></li> +<li id="fn5"><p>Technically I can use <code class="backtick">git reset</code> to get rid of the commit, but <code class="backtick">git 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 string *</code>, there is no particular reason why it can't interpret <code class="backtick">sp.length</code> as <code class="backtick">sp->length</code>. But it doesn't do this, so you will have to remember to write <code class="backtick">sp->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) = (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 |
