1
0
Fork 0
cl-sites/w3.cs.jmu.edu/kirkpams/OpenCSF/Books/csf/html/Arrays.html
2025-01-28 10:11:14 +01:00

1030 lines
No EOL
96 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!DOCTYPE html>
<html lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>10.4. Arrays, Structs, Enums, and Type Definitions &mdash; Computer Systems Fundamentals</title>
<link rel="stylesheet" href="_static/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous" />
<link rel="stylesheet" href="_static/css/pygments.css" type="text/css" />
<link rel="stylesheet" href="_static/css/normalize.css" type="text/css" />
<link rel="stylesheet" href="../../../JSAV/css/JSAV.css" type="text/css" />
<link rel="stylesheet" href="../../../lib/odsaMOD-min.css" type="text/css" />
<link rel="stylesheet" href="_static/css/jquery-1.11.4-smoothness-ui.css" type="text/css" />
<link rel="stylesheet" href="../../../lib/odsaStyle-min.css" type="text/css" />
<link rel="stylesheet" href="_static/css/csf.css" type="text/css" />
<style>
.underline { text-decoration: underline; }
</style>
<script type="text/javascript">
var DOCUMENTATION_OPTIONS = {
URL_ROOT: './',
VERSION: '0.4.1',
COLLAPSE_INDEX: false,
FILE_SUFFIX: '.html',
HAS_SOURCE: true
};
</script>
<script type="text/x-mathjax-config">
MathJax.Hub.Config({
tex2jax: {
inlineMath: [['$','$'], ['\\(','\\)']],
displayMath: [ ['$$','$$'], ["\\[","\\]"] ],
processEscapes: true
},
"HTML-CSS": {
scale: "80"
}
});
</script>
<link rel="shortcut icon" href="_static/favicon.ico"/>
<link rel="index" title="Index" href="genindex.html" />
<link rel="search" title="Search" href="search.html" />
<link rel="index" title="Computer Systems Fundamentals" href="index.html" />
<link rel="next" title="5. Functions and Scope" href="Functions.html" />
<link rel="prev" title="3. Basic Types and Pointers" href="BasicTypes.html" />
</head><body>
<nav class="navbar navbar-expand-md navbar-dark navbar-custom fixed-top">
<a class="navbar-brand py-0" href="index.html"><img src="_static/CSF-Logo-Square-Text.png" alt="OpenCSF Logo" height="40em" class="py-1 px-2 mb-0 align-center rounded-lg bg-white" /></a>
<!-- Show a navbar toggler on mobile -->
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#defaultNavbars" aria-controls="defaultNavbars" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="defaultNavbars">
<ul class="navbar-nav mr-auto">
<li class="nav-item dropdown">
<a class="nav-link dropdown-toggle jmu-gold rounded" href="Arrays.html#" id="navbarDropdownChapters" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">Contents</a>
<div class="dropdown-menu scrollable-menu" role="menu" aria-labelledby="navbarDropdownChapters">
<a class="dropdown-item" tabindex="-1" href="Arrays.html#"><b>Chapter 1</b></a>
<a class="dropdown-item" href="IntroConcSysOverview.html">&nbsp;&nbsp;&nbsp;1.1. Introduction to Concurrent Systems</a>
<a class="dropdown-item" href="SysAndModels.html">&nbsp;&nbsp;&nbsp;1.2. Systems and Models</a>
<a class="dropdown-item" href="Themes.html">&nbsp;&nbsp;&nbsp;1.3. Themes and Guiding Principles</a>
<a class="dropdown-item" href="Architectures.html">&nbsp;&nbsp;&nbsp;1.4. System Architectures</a>
<a class="dropdown-item" href="StateModels.html">&nbsp;&nbsp;&nbsp;1.5. State Models in UML</a>
<a class="dropdown-item" href="SequenceModels.html">&nbsp;&nbsp;&nbsp;1.6. Sequence Models in UML</a>
<a class="dropdown-item" href="StateModelImplementation.html">&nbsp;&nbsp;&nbsp;1.7. Extended Example: State Model Implementation</a>
<div class="dropdown-divider"></div>
<a class="dropdown-item disabled"><b>Chapter 2</b></a>
<a class="dropdown-item" href="ProcessesOverview.html">&nbsp;&nbsp;&nbsp;2.1. Processes and OS Basics</a>
<a class="dropdown-item" href="Multiprogramming.html">&nbsp;&nbsp;&nbsp;2.2. Processes and Multiprogramming</a>
<a class="dropdown-item" href="KernelMechanics.html">&nbsp;&nbsp;&nbsp;2.3. Kernel Mechanics</a>
<a class="dropdown-item" href="Syscall.html">&nbsp;&nbsp;&nbsp;2.4. System Call Interface</a>
<a class="dropdown-item" href="ProcessCycle.html">&nbsp;&nbsp;&nbsp;2.5. Process Life Cycle</a>
<a class="dropdown-item" href="UnixFile.html">&nbsp;&nbsp;&nbsp;2.6. The UNIX File Abstraction</a>
<a class="dropdown-item" href="EventsSignals.html">&nbsp;&nbsp;&nbsp;2.7. Events and Signals</a>
<a class="dropdown-item" href="Extended2Processes.html">&nbsp;&nbsp;&nbsp;2.8. Extended Example: Listing Files with Processes</a>
<div class="dropdown-divider"></div>
<a class="dropdown-item disabled"><b>Chapter 3</b></a>
<a class="dropdown-item" href="IPCOverview.html">&nbsp;&nbsp;&nbsp;3.1. Concurrency with IPC</a>
<a class="dropdown-item" href="IPCModels.html">&nbsp;&nbsp;&nbsp;3.2. IPC Models</a>
<a class="dropdown-item" href="Pipes.html">&nbsp;&nbsp;&nbsp;3.3. Pipes and FIFOs</a>
<a class="dropdown-item" href="MMap.html">&nbsp;&nbsp;&nbsp;3.4. Shared Memory With Memory-mapped Files</a>
<a class="dropdown-item" href="POSIXvSysV.html">&nbsp;&nbsp;&nbsp;3.5. POSIX vs. System V IPC</a>
<a class="dropdown-item" href="MQueues.html">&nbsp;&nbsp;&nbsp;3.6. Message Passing With Message Queues</a>
<a class="dropdown-item" href="ShMem.html">&nbsp;&nbsp;&nbsp;3.7. Shared Memory</a>
<a class="dropdown-item" href="IPCSems.html">&nbsp;&nbsp;&nbsp;3.8. Semaphores</a>
<a class="dropdown-item" href="Extended3Bash.html">&nbsp;&nbsp;&nbsp;3.9. Extended Example: Bash-lite: A Simple Command-line Shell</a>
<div class="dropdown-divider"></div>
<a class="dropdown-item disabled"><b>Chapter 4</b></a>
<a class="dropdown-item" href="SocketsOverview.html">&nbsp;&nbsp;&nbsp;4.1. Networked Concurrency</a>
<a class="dropdown-item" href="FiveLayer.html">&nbsp;&nbsp;&nbsp;4.2. The TCP/IP Internet Model</a>
<a class="dropdown-item" href="NetApps.html">&nbsp;&nbsp;&nbsp;4.3. Network Applications and Protocols</a>
<a class="dropdown-item" href="Sockets.html">&nbsp;&nbsp;&nbsp;4.4. The Socket Interface</a>
<a class="dropdown-item" href="TCPSockets.html">&nbsp;&nbsp;&nbsp;4.5. TCP Socket Programming: HTTP</a>
<a class="dropdown-item" href="UDPSockets.html">&nbsp;&nbsp;&nbsp;4.6. UDP Socket Programming: DNS</a>
<a class="dropdown-item" href="AppBroadcast.html">&nbsp;&nbsp;&nbsp;4.7. Application-Layer Broadcasting: DHCP</a>
<a class="dropdown-item" href="Extended4CGI.html">&nbsp;&nbsp;&nbsp;4.8. Extended Example: CGI Web Server</a>
<div class="dropdown-divider"></div>
<a class="dropdown-item disabled"><b>Chapter 5</b></a>
<a class="dropdown-item" href="InternetOverview.html">&nbsp;&nbsp;&nbsp;5.1. The Internet and Connectivity</a>
<a class="dropdown-item" href="AppLayer.html">&nbsp;&nbsp;&nbsp;5.2. Application Layer: Overlay Networks</a>
<a class="dropdown-item" href="TransLayer.html">&nbsp;&nbsp;&nbsp;5.3. Transport Layer</a>
<a class="dropdown-item" href="NetSec.html">&nbsp;&nbsp;&nbsp;5.4. Network Security Fundamentals</a>
<a class="dropdown-item" href="NetLayer.html">&nbsp;&nbsp;&nbsp;5.5. Network Layer: IP</a>
<a class="dropdown-item" href="LinkLayer.html">&nbsp;&nbsp;&nbsp;5.6. Link Layer</a>
<a class="dropdown-item" href="Wireless.html">&nbsp;&nbsp;&nbsp;5.7. Wireless Connectivity: Wi-Fi, Bluetooth, and Zigbee</a>
<a class="dropdown-item" href="Extended5DNS.html">&nbsp;&nbsp;&nbsp;5.8. Extended Example: DNS client</a>
<div class="dropdown-divider"></div>
<a class="dropdown-item disabled"><b>Chapter 6</b></a>
<a class="dropdown-item" href="ThreadsOverview.html">&nbsp;&nbsp;&nbsp;6.1. Concurrency with Multithreading</a>
<a class="dropdown-item" href="ProcVThreads.html">&nbsp;&nbsp;&nbsp;6.2. Processes vs. Threads</a>
<a class="dropdown-item" href="RaceConditions.html">&nbsp;&nbsp;&nbsp;6.3. Race Conditions and Critical Sections</a>
<a class="dropdown-item" href="POSIXThreads.html">&nbsp;&nbsp;&nbsp;6.4. POSIX Thread Library</a>
<a class="dropdown-item" href="ThreadArgs.html">&nbsp;&nbsp;&nbsp;6.5. Thread Arguments and Return Values</a>
<a class="dropdown-item" href="ImplicitThreads.html">&nbsp;&nbsp;&nbsp;6.6. Implicit Threading and Language-based Threads</a>
<a class="dropdown-item" href="Extended6Input.html">&nbsp;&nbsp;&nbsp;6.7. Extended Example: Keyboard Input Listener</a>
<a class="dropdown-item" href="Extended6Primes.html">&nbsp;&nbsp;&nbsp;6.8. Extended Example: Concurrent Prime Number Search</a>
<div class="dropdown-divider"></div>
<a class="dropdown-item disabled"><b>Chapter 7</b></a>
<a class="dropdown-item" href="SynchOverview.html">&nbsp;&nbsp;&nbsp;7.1. Synchronization Primitives</a>
<a class="dropdown-item" href="CritSect.html">&nbsp;&nbsp;&nbsp;7.2. Critical Sections and Peterson's Solution</a>
<a class="dropdown-item" href="Locks.html">&nbsp;&nbsp;&nbsp;7.3. Locks</a>
<a class="dropdown-item" href="Semaphores.html">&nbsp;&nbsp;&nbsp;7.4. Semaphores</a>
<a class="dropdown-item" href="Barriers.html">&nbsp;&nbsp;&nbsp;7.5. Barriers</a>
<a class="dropdown-item" href="Condvars.html">&nbsp;&nbsp;&nbsp;7.6. Condition Variables</a>
<a class="dropdown-item" href="Deadlock.html">&nbsp;&nbsp;&nbsp;7.7. Deadlock</a>
<a class="dropdown-item" href="Extended7Events.html">&nbsp;&nbsp;&nbsp;7.8. Extended Example: Event Log File</a>
<div class="dropdown-divider"></div>
<a class="dropdown-item disabled"><b>Chapter 8</b></a>
<a class="dropdown-item" href="SynchProblemsOverview.html">&nbsp;&nbsp;&nbsp;8.1. Synchronization Patterns and Problems</a>
<a class="dropdown-item" href="SynchDesign.html">&nbsp;&nbsp;&nbsp;8.2. Basic Synchronization Design Patterns</a>
<a class="dropdown-item" href="ProdCons.html">&nbsp;&nbsp;&nbsp;8.3. Producer-Consumer Problem</a>
<a class="dropdown-item" href="ReadWrite.html">&nbsp;&nbsp;&nbsp;8.4. Readers-Writers Problem</a>
<a class="dropdown-item" href="DiningPhil.html">&nbsp;&nbsp;&nbsp;8.5. Dining Philosophers Problem and Deadlock</a>
<a class="dropdown-item" href="CigSmokers.html">&nbsp;&nbsp;&nbsp;8.6. Cigarette Smokers Problem and the Limits of Semaphores and Locks</a>
<a class="dropdown-item" href="Extended8ModExp.html">&nbsp;&nbsp;&nbsp;8.7. Extended Example: Parallel Modular Exponentiation</a>
<div class="dropdown-divider"></div>
<a class="dropdown-item disabled"><b>Chapter 9</b></a>
<a class="dropdown-item" href="ParallelDistributedOverview.html">&nbsp;&nbsp;&nbsp;9.1. Parallel and Distributed Systems</a>
<a class="dropdown-item" href="ParVConc.html">&nbsp;&nbsp;&nbsp;9.2. Parallelism vs. Concurrency</a>
<a class="dropdown-item" href="ParallelDesign.html">&nbsp;&nbsp;&nbsp;9.3. Parallel Design Patterns</a>
<a class="dropdown-item" href="Scaling.html">&nbsp;&nbsp;&nbsp;9.4. Limits of Parallelism and Scaling</a>
<a class="dropdown-item" href="DistTiming.html">&nbsp;&nbsp;&nbsp;9.5. Timing in Distributed Environments</a>
<a class="dropdown-item" href="DistDataStorage.html">&nbsp;&nbsp;&nbsp;9.6. Reliable Data Storage and Location</a>
<a class="dropdown-item" href="DistConsensus.html">&nbsp;&nbsp;&nbsp;9.7. Consensus in Distributed Systems</a>
<a class="dropdown-item" href="Extended9Blockchain.html">&nbsp;&nbsp;&nbsp;9.8. Extended Example: Blockchain Proof-of-Work</a>
<div class="dropdown-divider"></div>
<a class="dropdown-item disabled"><b>Appendix A</b></a>
<a class="dropdown-item" href="CLangOverview.html">&nbsp;&nbsp;&nbsp;A.1. C Language Reintroduction</a>
<a class="dropdown-item" href="Debugging.html">&nbsp;&nbsp;&nbsp;A.2. Documentation and Debugging</a>
<a class="dropdown-item" href="BasicTypes.html">&nbsp;&nbsp;&nbsp;A.3. Basic Types and Pointers</a>
<a class="dropdown-item" href="Arrays.html">&nbsp;&nbsp;&nbsp;A.4. Arrays, Structs, Enums, and Type Definitions</a>
<a class="dropdown-item" href="Functions.html">&nbsp;&nbsp;&nbsp;A.5. Functions and Scope</a>
<a class="dropdown-item" href="Pointers.html">&nbsp;&nbsp;&nbsp;A.6. Pointers and Dynamic Allocation</a>
<a class="dropdown-item" href="Strings.html">&nbsp;&nbsp;&nbsp;A.7. Strings</a>
<a class="dropdown-item" href="FunctionPointers.html">&nbsp;&nbsp;&nbsp;A.8. Function Pointers</a>
<a class="dropdown-item" href="Files.html">&nbsp;&nbsp;&nbsp;A.9. Files</a>
</div>
</li>
</ul>
</div>
<ul class="navbar-nav flex-row ml-md-auto d-none d-md-flex">
<li class="nav-item"><a class="nav-link jmu-gold" href="https://w3.cs.jmu.edu/kirkpams/OpenCSF/Books/csf/source/Arrays.rst"
target="_blank" rel="nofollow">Show Source</a></li>
</ul>
</nav>
<div class="container center">
«&#160;&#160;<a id="prevmod" href="BasicTypes.html">10.3. Basic Types and Pointers</a>
&#160;&#160;::&#160;&#160;
<a class="uplink" href="index.html">Contents</a>
&#160;&#160;::&#160;&#160;
<a id="nextmod" href="Functions.html">10.5. Functions and Scope</a>&#160;&#160;»
</div>
<br />
<script type="text/javascript" src="_static/js/jquery-2.1.4.min.js"></script>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.1/MathJax.js?config=TeX-AMS-MML_HTMLorMML"></script>
<script type="text/javascript" src="_static/js/jquery-1.11.4-ui.min.js"></script>
<script type="text/javascript" src="_static/js/forge-0.7.0.min.js"></script>
<script type="text/javascript" src="../../../JSAV/lib/jquery.transit.js"></script>
<script type="text/javascript" src="../../../JSAV/lib/raphael.js"></script>
<script type="text/javascript" src="../../../JSAV/build/JSAV-min.js"></script>
<script type="text/javascript" src="_static/js/config.js"></script>
<script type="text/javascript" src="../../../lib/odsaUtils-min.js"></script>
<script type="text/javascript" src="../../../lib/odsaMOD-min.js"></script>
<script type="text/javascript" src="_static/js/d3-4.13.0.min.js"></script>
<script type="text/javascript" src="_static/js/d3-selection-multi.v1.min.js"></script>
<script type="text/javascript" src="../../../lib/dataStructures.js"></script>
<div class="container">
<script>ODSA.SETTINGS.DISP_MOD_COMP = true;ODSA.SETTINGS.MODULE_NAME = "Arrays";ODSA.SETTINGS.MODULE_LONG_NAME = "Arrays, Structs, Enums, and Type Definitions";ODSA.SETTINGS.MODULE_CHAPTER = "Appendix A"; ODSA.SETTINGS.BUILD_DATE = "2021-06-14 17:15:26"; ODSA.SETTINGS.BUILD_CMAP = false;JSAV_OPTIONS['lang']='en';JSAV_EXERCISE_OPTIONS['code']='java';</script><div class="section" id="arrays-structs-enums-and-type-definitions">
<h1>10.4. Arrays, Structs, Enums, and Type Definitions<a class="headerlink" href="Arrays.html#arrays-structs-enums-and-type-definitions" title="Permalink to this headline"></a></h1>
<p>As with other common typed languages (such as Java), C supports arrays of other types. When
declaring an array, the compiler must be able to determine the exact length. One way to do this is
to specify the length inside the brackets of the declaration (such as <code class="docutils literal notranslate"><span class="pre">int</span> <span class="pre">array[10];</span></code>). Another
way is to provide an explicit initialization array. <a class="reference external" href="Arrays.html#cla-11">Code Listing A.11</a> demonstrates this
second technique, omitting the length from inside the brackets on line 6 (although it could be
included here).</p>
<div class="highlight-c border border-dark rounded-lg bg-light px-0 mb-3 notranslate" id="cla-11"><table class="highlighttable"><tr><td class="linenos px-0 mx-0"><div class="linenodiv"><pre class="mb-0">1
2
3
4
5
6
7
8
9</pre></div></td><td class="code"><div class="highlight bg-light"><pre class="mb-0"><span></span><span class="cm">/* Code Listing A.11:</span>
<span class="cm"> C array names are implicitly pointers to their first entry</span>
<span class="cm"> */</span>
<span class="cm">/* Instantiate an array and print its starting address */</span>
<span class="kt">uint32_t</span> <span class="n">data</span><span class="p">[]</span> <span class="o">=</span> <span class="p">{</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">3</span><span class="p">,</span> <span class="mi">4</span><span class="p">,</span> <span class="mi">5</span> <span class="p">};</span>
<span class="n">printf</span> <span class="p">(</span><span class="s">&quot;data = %p</span><span class="se">\n</span><span class="s">&quot;</span><span class="p">,</span> <span class="n">data</span><span class="p">);</span>
<span class="n">printf</span> <span class="p">(</span><span class="s">&quot;&amp;data = %p</span><span class="se">\n</span><span class="s">&quot;</span><span class="p">,</span> <span class="o">&amp;</span><span class="n">data</span><span class="p">);</span>
<span class="n">printf</span> <span class="p">(</span><span class="s">&quot;&amp;data[0] = %p</span><span class="se">\n\n</span><span class="s">&quot;</span><span class="p">,</span> <span class="o">&amp;</span><span class="n">data</span><span class="p">[</span><span class="mi">0</span><span class="p">]);</span>
</pre></div>
</td></tr></table></div>
<p><a class="reference external" href="Arrays.html#cla-11">Code Listing A.11</a> illustrates a key aspect of the relationship between arrays and
pointers: <strong>Array names are implicitly pointers to their first element</strong>. To see this, consider
lines 7 9; line 7 prints the <em>value</em> of <code class="docutils literal notranslate"><span class="pre">data</span></code>, line 8 prints the address of data, and line 9
prints the <em>address</em> of <code class="docutils literal notranslate"><span class="pre">data[0]</span></code>. When this program is run, these three lines produce the same
value as the output. The convention in C is that any array variable is an alias for the starting
address. All three of these notations can be used (and frequently are) depending on the context and
style preferences of the programmer.</p>
<p><a class="reference external" href="Arrays.html#cla-12">Code Listing A.12</a> extends the previous example to explore the relationship between
arrays and pointers further. Line 7 starts by declaring a pointer and initializing it to point to
the array. On this line, we could also initialize <code class="docutils literal notranslate"><span class="pre">u32ptr</span> <span class="pre">=</span> <span class="pre">&amp;data[0]</span></code>, but (due to convoluted type
checking rules) it is a compiler warning to initialize <code class="docutils literal notranslate"><span class="pre">u32ptr</span> <span class="pre">=</span> <span class="pre">&amp;data</span></code> (despite the fact that
data and &amp;data are the same). Line 8 sets the <code class="docutils literal notranslate"><span class="pre">walker</span></code> pointer in the same way.</p>
<div class="highlight-c border border-dark rounded-lg bg-light px-0 mb-3 notranslate" id="cla-12"><table class="highlighttable"><tr><td class="linenos px-0 mx-0"><div class="linenodiv"><pre class="mb-0"> 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23</pre></div></td><td class="code"><div class="highlight bg-light"><pre class="mb-0"><span></span><span class="cm">/* Code Listing A.12:</span>
<span class="cm"> C arrays and pointer arithmetic work identically</span>
<span class="cm"> */</span>
<span class="cm">/* Make two pointers to data, which also means they point to</span>
<span class="cm"> the first element in the array */</span>
<span class="kt">uint32_t</span> <span class="o">*</span><span class="n">u32ptr</span> <span class="o">=</span> <span class="n">data</span><span class="p">;</span> <span class="c1">// &amp;data[0] is also ok, &amp;data is not</span>
<span class="kt">uint32_t</span> <span class="o">*</span><span class="n">walker</span> <span class="o">=</span> <span class="n">data</span><span class="p">;</span> <span class="c1">// a second pointer to data</span>
<span class="cm">/* Loop through the elements, observing that array bracket</span>
<span class="cm"> notation and pointer arithmetic behave identically; after</span>
<span class="cm"> each time through the loop, advance the walker pointer */</span>
<span class="k">for</span> <span class="p">(</span><span class="kt">size_t</span> <span class="n">i</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="n">i</span> <span class="o">&lt;</span> <span class="mi">5</span><span class="p">;</span> <span class="n">i</span><span class="o">++</span><span class="p">,</span> <span class="n">walker</span><span class="o">++</span><span class="p">)</span>
<span class="p">{</span>
<span class="n">printf</span> <span class="p">(</span><span class="s">&quot;data[%zd] address %p and value %08&quot;</span> <span class="n">PRIx32</span> <span class="s">&quot;</span><span class="se">\n</span><span class="s">&quot;</span><span class="p">,</span>
<span class="n">i</span><span class="p">,</span> <span class="o">&amp;</span><span class="n">data</span><span class="p">[</span><span class="n">i</span><span class="p">],</span> <span class="n">data</span><span class="p">[</span><span class="n">i</span><span class="p">]);</span>
<span class="n">printf</span> <span class="p">(</span><span class="s">&quot;u32ptr[%zd] address %p and value %08&quot;</span> <span class="n">PRIx32</span> <span class="s">&quot;</span><span class="se">\n</span><span class="s">&quot;</span><span class="p">,</span>
<span class="n">i</span><span class="p">,</span> <span class="o">&amp;</span><span class="n">u32ptr</span><span class="p">[</span><span class="n">i</span><span class="p">],</span> <span class="n">u32ptr</span><span class="p">[</span><span class="n">i</span><span class="p">]);</span>
<span class="n">printf</span> <span class="p">(</span><span class="s">&quot;u32ptr+%zd address %p and value %08&quot;</span> <span class="n">PRIx32</span> <span class="s">&quot;</span><span class="se">\n\n</span><span class="s">&quot;</span><span class="p">,</span>
<span class="n">i</span><span class="p">,</span> <span class="n">u32ptr</span> <span class="o">+</span> <span class="n">i</span><span class="p">,</span> <span class="o">*</span><span class="p">(</span><span class="n">u32ptr</span> <span class="o">+</span> <span class="n">i</span><span class="p">));</span>
<span class="n">printf</span> <span class="p">(</span><span class="s">&quot;walker address %p and value %08&quot;</span> <span class="n">PRIx32</span> <span class="s">&quot;</span><span class="se">\n\n</span><span class="s">&quot;</span><span class="p">,</span>
<span class="n">walker</span><span class="p">,</span> <span class="o">*</span><span class="n">walker</span><span class="p">);</span>
<span class="p">}</span>
</pre></div>
</td></tr></table></div>
<p>Lines 13 23 in <a class="reference external" href="Arrays.html#cla-12">Code Listing A.12</a> demonstrate the equivalency between array
dereferencing and <em>pointer arithmetic</em>. That is, when C performs an operation like <code class="docutils literal notranslate"><span class="pre">u32ptr</span> <span class="pre">+</span>
<span class="pre">5</span></code>, it is not simply the value of <code class="docutils literal notranslate"><span class="pre">u32ptr</span></code> plus the number 5 in standard arithmetic; instead,
<code class="docutils literal notranslate"><span class="pre">u32ptr</span> <span class="pre">+</span> <span class="pre">5</span></code> requires taking the value of <code class="docutils literal notranslate"><span class="pre">u32ptr</span></code> (which is an address) and adding 5 times the
size of what <code class="docutils literal notranslate"><span class="pre">u32ptr</span></code> points to. In this case, if u32ptr stores the address <code class="docutils literal notranslate"><span class="pre">0x7ffee0000720</span></code>,
<code class="docutils literal notranslate"><span class="pre">u32ptr</span> <span class="pre">+</span> <span class="pre">5</span></code> would add 20 to this value (since <code class="docutils literal notranslate"><span class="pre">u32ptr</span></code> is a pointer to 4-byte <code class="docutils literal notranslate"><span class="pre">uint32_t</span></code>
values), yielding <code class="docutils literal notranslate"><span class="pre">0x7ffee0000734</span></code>. In general terms, for an arbitrary pointer <code class="docutils literal notranslate"><span class="pre">ptr</span></code>,
<code class="docutils literal notranslate"><span class="pre">&amp;ptr[n]</span></code> and <code class="docutils literal notranslate"><span class="pre">ptr+n</span></code> are identical for any integer <code class="docutils literal notranslate"><span class="pre">n</span></code>; <code class="docutils literal notranslate"><span class="pre">ptr[n]</span></code> and <code class="docutils literal notranslate"><span class="pre">*(ptr+n)</span></code> also
yield the same value. (As the bracket notation tends to be more familiar, many C programmers use it
whenever pointer arithmetic is needed.)</p>
<p>Lines 21 and 22 do not require adding any value to the <code class="docutils literal notranslate"><span class="pre">walker</span></code> pointer so that it accesses the
correct location. Instead, walker is set up to <em>walk through</em> the array, accessing one element at a
time. Specifically, line 8 initializes <code class="docutils literal notranslate"><span class="pre">walker</span></code> to point to the first element, and the increment
field of the <code class="docutils literal notranslate"><span class="pre">for</span></code>-loop causes walker to advance after each iteration (line 13). (Observe that it is
possible to specify multiple increments in a <code class="docutils literal notranslate"><span class="pre">for</span></code>-loop, separated by a comma as shown with <code class="docutils literal notranslate"><span class="pre">i++</span></code>,
<code class="docutils literal notranslate"><span class="pre">walker++</span></code>.) A subtle aspect of this increment is that it does not simply add 1 to the address
<code class="docutils literal notranslate"><span class="pre">walker</span></code> is pointing to; rather, just like the additions on lines 18 and 20, <code class="docutils literal notranslate"><span class="pre">walker++</span></code> will
increment the address by the size of a <code class="docutils literal notranslate"><span class="pre">uint32_t</span></code>. Consequently, this incrementing style is a
common technique to use a pointer to traverse through the elements of an array.</p>
<p>Although pointer variables can be treated as arrays, the reverse is not true. That is, even though
an array name is implicitly a pointer to the first element of the array, we cannot use pointer
notation for a variable declared as an array. In <a class="reference external" href="Arrays.html#cla-11">Code Listing A.11</a> and <a class="reference external" href="Arrays.html#cla-12">A.12</a>, trying to access <code class="docutils literal notranslate"><span class="pre">*data</span></code> or <code class="docutils literal notranslate"><span class="pre">*(data+i)</span></code> would produce a compiler error.</p>
<p><a class="reference external" href="Arrays.html#cla-13">Code Listing A.13</a> illustrates a slight variation on <a class="reference external" href="Arrays.html#cla-12">Code Listing A.12</a>. In
this scenario, <code class="docutils literal notranslate"><span class="pre">data</span></code> is declared as an array of 32-bit values. Since the array consists of two of
these values, the array occupies eight consecutive bytes of memory. Line 12 declares a pointer like
before, but the pointer is a <code class="docutils literal notranslate"><span class="pre">uint8_t*</span></code>, so it points to 8-bit values. Lines 13 19 will traverse
through all of the bytes of the <code class="docutils literal notranslate"><span class="pre">data</span></code> array, but accessing it a byte at a time instead of just
examining the two 32-bit entries. One advantage of this approach is that using a <code class="docutils literal notranslate"><span class="pre">uint8_t*</span></code>
pointer provides a mechanism to explore the endianness of multi-byte integers. In this example,
<code class="docutils literal notranslate"><span class="pre">data[0]</span></code> stores the 32-bit value <code class="docutils literal notranslate"><span class="pre">0x01020304</span></code>, spread across four memory locations. Assuming
this runs on a little-endian architecture (such as x86), 0x04 is stored at the first of these four
byte locations; consequently, <code class="docutils literal notranslate"><span class="pre">u8ptr[0]</span></code> accesses <code class="docutils literal notranslate"><span class="pre">0x04</span></code>, <code class="docutils literal notranslate"><span class="pre">u8ptr[1]</span></code> access <code class="docutils literal notranslate"><span class="pre">0x03</span></code>, and so
on. Once the loop would get to <code class="docutils literal notranslate"><span class="pre">u8ptr[4]</span></code>, the result would be 0x08, which is the first byte
stored for <code class="docutils literal notranslate"><span class="pre">data[1]</span></code>.</p>
<div class="highlight-c border border-dark rounded-lg bg-light px-0 mb-3 notranslate" id="cla-13"><table class="highlighttable"><tr><td class="linenos px-0 mx-0"><div class="linenodiv"><pre class="mb-0"> 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19</pre></div></td><td class="code"><div class="highlight bg-light"><pre class="mb-0"><span></span><span class="cm">/* Code Listing A.13:</span>
<span class="cm"> Using a pointer to traverse an array of a different size</span>
<span class="cm"> */</span>
<span class="cm">/* Instantiate an array of two 32-bit integers */</span>
<span class="kt">uint32_t</span> <span class="n">data</span><span class="p">[]</span> <span class="o">=</span> <span class="p">{</span> <span class="mh">0x01020304</span><span class="p">,</span> <span class="mh">0x05060708</span> <span class="p">};</span>
<span class="n">printf</span> <span class="p">(</span><span class="s">&quot;data starts at %p</span><span class="se">\n</span><span class="s">&quot;</span><span class="p">,</span> <span class="n">data</span><span class="p">);</span>
<span class="n">printf</span> <span class="p">(</span><span class="s">&quot;data[0] address %p and value %08&quot;</span> <span class="n">PRIx32</span> <span class="s">&quot;</span><span class="se">\n</span><span class="s">&quot;</span><span class="p">,</span> <span class="o">&amp;</span><span class="n">data</span><span class="p">[</span><span class="mi">0</span><span class="p">],</span> <span class="n">data</span><span class="p">[</span><span class="mi">0</span><span class="p">]);</span>
<span class="n">printf</span> <span class="p">(</span><span class="s">&quot;data[1] address %p and value %08&quot;</span> <span class="n">PRIx32</span> <span class="s">&quot;</span><span class="se">\n\n</span><span class="s">&quot;</span><span class="p">,</span> <span class="o">&amp;</span><span class="n">data</span><span class="p">[</span><span class="mi">1</span><span class="p">],</span> <span class="n">data</span><span class="p">[</span><span class="mi">1</span><span class="p">]);</span>
<span class="cm">/* Make a pointer to the first byte of the array */</span>
<span class="kt">uint8_t</span> <span class="o">*</span><span class="n">u8ptr</span> <span class="o">=</span> <span class="p">(</span><span class="kt">uint8_t</span> <span class="o">*</span><span class="p">)</span><span class="n">data</span><span class="p">;</span>
<span class="k">for</span> <span class="p">(</span><span class="kt">size_t</span> <span class="n">i</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="n">i</span> <span class="o">&lt;</span> <span class="mi">8</span><span class="p">;</span> <span class="n">i</span><span class="o">++</span><span class="p">)</span>
<span class="p">{</span>
<span class="n">printf</span> <span class="p">(</span><span class="s">&quot;u8ptr[%zd] address %p and value %02&quot;</span> <span class="n">PRIx8</span> <span class="s">&quot;</span><span class="se">\n</span><span class="s">&quot;</span><span class="p">,</span>
<span class="n">i</span><span class="p">,</span> <span class="o">&amp;</span><span class="n">u8ptr</span><span class="p">[</span><span class="n">i</span><span class="p">],</span> <span class="n">u8ptr</span><span class="p">[</span><span class="n">i</span><span class="p">]);</span>
<span class="n">printf</span> <span class="p">(</span><span class="s">&quot;u8ptr+%zd address %p and value %02&quot;</span> <span class="n">PRIx8</span> <span class="s">&quot;</span><span class="se">\n\n</span><span class="s">&quot;</span><span class="p">,</span>
<span class="n">i</span><span class="p">,</span> <span class="n">u8ptr</span> <span class="o">+</span> <span class="n">i</span><span class="p">,</span> <span class="o">*</span><span class="p">(</span><span class="n">u8ptr</span> <span class="o">+</span> <span class="n">i</span><span class="p">));</span>
<span class="p">}</span>
</pre></div>
</td></tr></table></div>
<div class="topic border border-dark rounded-lg alert-danger px-2 mb-3">
<div class="figure align-left">
<a class="reference internal image-reference" href="_images/CSF-Images-BugWarning.png"><img alt="Decorative bug warning" src="_images/CSF-Images-BugWarning.png" style="width: 90%;" /></a>
</div>
<p class="topic-title first pt-2 mb-1">Bug Warning</p><hr class="mt-1" />
<p>It is critical to understand that C does not explicitly store the length of an array anywhere, so
there is no way to learn this information for a pointer to an arbitrary array. Consider the
<code class="docutils literal notranslate"><span class="pre">data</span></code> and <code class="docutils literal notranslate"><span class="pre">ptr</span></code> variables as declared below. By examining this code, we can determine that the
<code class="docutils literal notranslate"><span class="pre">data</span></code> array takes up 16 bytes and consists of four consecutive 32-bit values; i.e., this portion
of source code makes it clear that the length of the array is four.</p>
<div class="highlight-c border border-dark rounded-lg bg-light px-0 mb-3 notranslate"><table class="highlighttable"><tr><td class="linenos px-0 mx-0"><div class="linenodiv"><pre class="mb-0">1
2
3
4
5
6
7</pre></div></td><td class="code"><div class="highlight bg-light"><pre class="mb-0"><span></span><span class="kt">uint32_t</span> <span class="n">data</span><span class="p">[</span><span class="mi">4</span><span class="p">];</span> <span class="c1">// an array of four 4-byte ints</span>
<span class="kt">uint32_t</span> <span class="o">*</span><span class="n">ptr</span> <span class="o">=</span> <span class="n">data</span><span class="p">;</span>
<span class="n">printf</span> <span class="p">(</span><span class="s">&quot;sizeof(data) = %zd</span><span class="se">\n</span><span class="s">&quot;</span><span class="p">,</span> <span class="k">sizeof</span> <span class="p">(</span><span class="n">data</span><span class="p">));</span> <span class="c1">// 16, NOT 4</span>
<span class="n">printf</span> <span class="p">(</span><span class="s">&quot;sizeof(ptr) = %zd</span><span class="se">\n</span><span class="s">&quot;</span><span class="p">,</span> <span class="k">sizeof</span> <span class="p">(</span><span class="n">ptr</span><span class="p">));</span> <span class="c1">// 8, NOT 4</span>
<span class="n">printf</span> <span class="p">(</span><span class="s">&quot;number of elemenst = %zd</span><span class="se">\n</span><span class="s">&quot;</span><span class="p">,</span> <span class="k">sizeof</span> <span class="p">(</span><span class="n">data</span><span class="p">)</span> <span class="o">/</span> <span class="k">sizeof</span> <span class="p">(</span><span class="kt">uint32_t</span><span class="p">));</span> <span class="c1">// SUCCESS!</span>
</pre></div>
</td></tr></table></div>
<p>A very common mistake is to try to use <code class="docutils literal notranslate"><span class="pre">sizeof()</span></code> as shown on lines 4 and 5. With one exception
(shown on line 7), <code class="docutils literal notranslate"><span class="pre">sizeof()</span></code> <strong>cannot be used to determine the length of an array</strong>.
Recall that <code class="docutils literal notranslate"><span class="pre">sizeof()</span></code> returns the number of bytes for a variable; it is not aware of the
subdivision of those bytes into an array of consecutive elements. As such, the <code class="docutils literal notranslate"><span class="pre">sizeof(data)</span></code> on
line 4 returns 16, which is the total number of bytes for the array. Similarly, the <code class="docutils literal notranslate"><span class="pre">sizeof(ptr)</span></code>
on line 5 returns 8, which is the size of a pointer (i.e., an address) on a 64-bit CPU
architecture. Neither of these return the number of elements in the array.</p>
<p>Line 7 is successful because we know the total amount of space for data (<code class="docutils literal notranslate"><span class="pre">sizeof(data)</span></code> =
16 bytes) and we know data is an array of <code class="docutils literal notranslate"><span class="pre">uint32_t</span></code> items (<code class="docutils literal notranslate"><span class="pre">sizeof(uint32_t)</span></code> = 4 bytes for
each item). Having both of these pieces of information allows us to perform this calculation. We
cannot perform this same calculation using <code class="docutils literal notranslate"><span class="pre">sizeof(ptr)</span></code>, however. That is, if we are given a
pointer (such as <code class="docutils literal notranslate"><span class="pre">ptr</span></code>) and we know that it is pointing to an array of <code class="docutils literal notranslate"><span class="pre">uint32_t</span></code> items, we
cannot determine the length of the array. The problem is that ptr technically does not point to an
array; rather, it points only to the <em>first element</em> of the array. There is no way to attach the
additional information of the size of the array to the pointer.</p>
<p>This point becomes really important later, when we discuss the relationship of arrays and functions.
Specifically, arrays cannot be directly passed as an argument to a function call. Rather, arrays
are always passed as pointers. Because of this fact, the length of the array must be passed
explicitly as a separate parameter. The simplest example of this is the parameter list of
<code class="docutils literal notranslate"><span class="pre">main()</span></code>, which consists of an array (<code class="docutils literal notranslate"><span class="pre">argv</span></code>) and its array length (<code class="docutils literal notranslate"><span class="pre">argc</span></code>).</p>
<div class="highlight-c border border-dark rounded-lg bg-light px-0 mb-3 notranslate"><table class="highlighttable"><tr><td class="linenos px-0 mx-0"><div class="linenodiv"><pre class="mb-0">1
2
3
4
5</pre></div></td><td class="code"><div class="highlight bg-light"><pre class="mb-0"><span></span><span class="kt">int</span>
<span class="nf">main</span> <span class="p">(</span><span class="kt">int</span> <span class="n">argc</span><span class="p">,</span> <span class="kt">char</span> <span class="o">*</span><span class="n">argv</span><span class="p">[])</span>
<span class="p">{</span>
<span class="p">...</span>
<span class="p">}</span>
</pre></div>
</td></tr></table></div>
</div>
<div class="section" id="two-dimensional-arrays">
<h2>10.4.1. Two-dimensional Arrays<a class="headerlink" href="Arrays.html#two-dimensional-arrays" title="Permalink to this headline"></a></h2>
<p>One side effect of C not storing array lengths is the complexity of working with multi-dimensional
arrays. Consider <a class="reference external" href="Arrays.html#cla-14">Code Listing A.14</a> as an example. Line 6 declares an array that
contains two rows of three columns each. When declaring <code class="docutils literal notranslate"><span class="pre">data</span></code> on this line, the 3 must be
specified within the brackets to indicate the number of columns per row. That is, this declaration
could not be written as <code class="docutils literal notranslate"><span class="pre">data[][]</span></code>, even with the explicit initialization on the right side of the line.</p>
<div class="highlight-c border border-dark rounded-lg bg-light px-0 mb-3 notranslate" id="cla-14"><table class="highlighttable"><tr><td class="linenos px-0 mx-0"><div class="linenodiv"><pre class="mb-0"> 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25</pre></div></td><td class="code"><div class="highlight bg-light"><pre class="mb-0"><span></span><span class="cm">/* Code Listing A.14:</span>
<span class="cm"> Traversing through a two-dimensional array</span>
<span class="cm"> */</span>
<span class="cm">/* Instantiate a2-d array and print its starting address */</span>
<span class="kt">uint32_t</span> <span class="n">data</span><span class="p">[][</span><span class="mi">3</span><span class="p">]</span> <span class="o">=</span> <span class="p">{</span> <span class="p">{</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">3</span> <span class="p">},</span> <span class="p">{</span> <span class="mi">4</span><span class="p">,</span> <span class="mi">5</span><span class="p">,</span> <span class="mi">6</span> <span class="p">}</span> <span class="p">};</span>
<span class="n">printf</span> <span class="p">(</span><span class="s">&quot;data starts at %p</span><span class="se">\n\n</span><span class="s">&quot;</span><span class="p">,</span> <span class="n">data</span><span class="p">);</span>
<span class="cm">/* Make u32ptr point to data, but observe that this causes a</span>
<span class="cm"> compiler warning; the warning can be fixed by casting data</span>
<span class="cm"> ((uint32_t *)data) or using one layer of brackets (data[0]) */</span>
<span class="kt">uint32_t</span> <span class="o">*</span><span class="n">u32ptr</span> <span class="o">=</span> <span class="n">data</span><span class="p">;</span>
<span class="cm">/* Loop through the elements, observing that array bracket</span>
<span class="cm"> notation and pointer arithmetic behave identically */</span>
<span class="k">for</span> <span class="p">(</span><span class="kt">size_t</span> <span class="n">i</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="n">i</span> <span class="o">&lt;</span> <span class="mi">2</span><span class="p">;</span> <span class="n">i</span><span class="o">++</span><span class="p">)</span>
<span class="k">for</span> <span class="p">(</span><span class="kt">size_t</span> <span class="n">j</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="n">j</span> <span class="o">&lt;</span> <span class="mi">3</span><span class="p">;</span> <span class="n">j</span><span class="o">++</span><span class="p">)</span>
<span class="p">{</span>
<span class="n">printf</span> <span class="p">(</span><span class="s">&quot;data[%zd][%zd] address %p, value %08&quot;</span> <span class="n">PRIx32</span> <span class="s">&quot;</span><span class="se">\n</span><span class="s">&quot;</span><span class="p">,</span>
<span class="n">i</span><span class="p">,</span> <span class="n">j</span><span class="p">,</span> <span class="o">&amp;</span><span class="n">data</span><span class="p">[</span><span class="n">i</span><span class="p">][</span><span class="n">j</span><span class="p">],</span> <span class="n">data</span><span class="p">[</span><span class="n">i</span><span class="p">][</span><span class="n">j</span><span class="p">]);</span>
<span class="n">printf</span> <span class="p">(</span><span class="s">&quot;u32ptr[%zd] address %p, value %08&quot;</span> <span class="n">PRIx32</span> <span class="s">&quot;</span><span class="se">\n</span><span class="s">&quot;</span><span class="p">,</span>
<span class="n">i</span> <span class="o">*</span> <span class="mi">3</span> <span class="o">+</span> <span class="n">j</span><span class="p">,</span> <span class="o">&amp;</span><span class="n">u32ptr</span><span class="p">[</span><span class="n">i</span> <span class="o">*</span> <span class="mi">3</span> <span class="o">+</span> <span class="n">j</span><span class="p">],</span> <span class="n">u32ptr</span><span class="p">[</span><span class="n">i</span> <span class="o">*</span> <span class="mi">3</span> <span class="o">+</span> <span class="n">j</span><span class="p">]);</span>
<span class="n">printf</span> <span class="p">(</span><span class="s">&quot;u32ptr+%zd address %p, value %08&quot;</span> <span class="n">PRIx32</span> <span class="s">&quot;</span><span class="se">\n\n</span><span class="s">&quot;</span><span class="p">,</span>
<span class="n">i</span> <span class="o">*</span> <span class="mi">3</span> <span class="o">+</span> <span class="n">j</span><span class="p">,</span> <span class="n">u32ptr</span> <span class="o">+</span> <span class="p">(</span><span class="n">i</span><span class="o">*</span><span class="mi">3</span><span class="o">+</span><span class="n">j</span><span class="p">),</span> <span class="o">*</span><span class="p">(</span><span class="n">u32ptr</span> <span class="o">+</span><span class="p">(</span><span class="n">i</span><span class="o">*</span><span class="mi">3</span><span class="o">+</span><span class="n">j</span><span class="p">)));</span>
<span class="p">}</span>
</pre></div>
</td></tr></table></div>
<div class="figure mb-2 align-right" id="id12" style="width: 40%">
<span id="twodptr"></span><a class="reference internal image-reference" href="_images/CSF-Images.A.2.png"><img class="p-3 mb-2 align-center border border-dark rounded-lg" alt="Creating a virtual 2-d array with an array of pointers" src="_images/CSF-Images.A.2.png" style="width: 95%;" /></a>
<p class="caption align-center px-3"><span class="caption-text"> Figure 10.4.2: Creating a virtual 2-d array with an array of pointers</span></p>
</div>
<p>The rest of <a class="reference external" href="Arrays.html#cla-14">Code Listing A.14</a> is modeled off of the structure of <a class="reference external" href="Arrays.html#cla-12">Code Listing A.12</a>. As in that example, there is a <code class="docutils literal notranslate"><span class="pre">u32ptr</span></code> that is set to point to the array (line 12).
Based on the declaration, though, <code class="docutils literal notranslate"><span class="pre">u32ptr</span></code> is a pointer to a <code class="docutils literal notranslate"><span class="pre">uint32_t</span></code>. Because of this
declaration, it can be used as a one-dimensional array, but not as a two dimensional array. That is
not a problem in this case, because C stores arrays in <em>row-major order</em>; in this order, the
first element of the second row is placed immediately after the last element of the first row. That
is, <code class="docutils literal notranslate"><span class="pre">data[1][0]</span></code> (the same as <code class="docutils literal notranslate"><span class="pre">u32ptr[3]</span></code>) immediately follows <code class="docutils literal notranslate"><span class="pre">data[0][2]</span></code> (the same as
<code class="docutils literal notranslate"><span class="pre">u32ptr[2]</span></code>). Thus, a one-dimensional array pointer like u32ptr can navigate the two-dimensional
structure by calculating its index as <code class="docutils literal notranslate"><span class="pre">i</span> <span class="pre">*</span> <span class="pre">3</span> <span class="pre">+</span> <span class="pre">j</span></code> (row times columns/row, plus the column number
of the current row). This requires, of course, knowledge of the number of columns per row. When
two-dimensional arrays are passed as arguments to functions, this additional information must be
passed explicitly as separate parameters.</p>
<p><a class="reference external" href="Arrays.html#cla-15">Code Listing A.15</a> demonstrates a common variation on two-dimensional arrays. In this
case, data is not declared as a two-dimensional array; rather, it is one-dimensional array of two
pointers. Its initialization in line 10 provides those two pointers: the addresses of the two arrays
<code class="docutils literal notranslate"><span class="pre">row0</span></code> and <code class="docutils literal notranslate"><span class="pre">row1</span></code>. Unlike the declaration structure of <a class="reference external" href="Arrays.html#cla-14">Code Listing A.14</a>, this
version does not guarantee that the elements can all be accessed in row-major order. The <code class="docutils literal notranslate"><span class="pre">row0</span></code>
and <code class="docutils literal notranslate"><span class="pre">row1</span></code> arrays are not guaranteed to be in any particular order in memory; consequently, we
cannot say that <code class="docutils literal notranslate"><span class="pre">row1[0]</span></code> immediately follows <code class="docutils literal notranslate"><span class="pre">row0[2]</span></code>. <a href="Arrays.html#twodptr">Figure 10.4.2</a>
illustrates the pointer structure of this declaration.</p>
<div class="highlight-c border border-dark rounded-lg bg-light px-0 mb-3 notranslate" id="cla-15"><table class="highlighttable"><tr><td class="linenos px-0 mx-0"><div class="linenodiv"><pre class="mb-0"> 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18</pre></div></td><td class="code"><div class="highlight bg-light"><pre class="mb-0"><span></span><span class="cm">/* Code Listing A.15:</span>
<span class="cm"> Two-dimensional arrays as arrays of pointers</span>
<span class="cm"> */</span>
<span class="cm">/* Instantiate the rows separate */</span>
<span class="kt">uint32_t</span> <span class="n">row0</span><span class="p">[]</span> <span class="o">=</span> <span class="p">{</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">3</span> <span class="p">};</span>
<span class="kt">uint32_t</span> <span class="n">row1</span><span class="p">[]</span> <span class="o">=</span> <span class="p">{</span> <span class="mi">4</span><span class="p">,</span> <span class="mi">5</span><span class="p">,</span> <span class="mi">6</span> <span class="p">};</span>
<span class="cm">/* data is an array of two pointers, NOT a 2-d array */</span>
<span class="kt">uint32_t</span> <span class="o">*</span><span class="n">data</span><span class="p">[]</span> <span class="o">=</span> <span class="p">{</span> <span class="n">row0</span><span class="p">,</span> <span class="n">row1</span> <span class="p">};</span>
<span class="cm">/* But we can still treat data as a 2-d array */</span>
<span class="k">for</span> <span class="p">(</span><span class="kt">size_t</span> <span class="n">i</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="n">i</span> <span class="o">&lt;</span> <span class="mi">2</span><span class="p">;</span> <span class="n">i</span><span class="o">++</span><span class="p">)</span>
<span class="p">{</span>
<span class="n">printf</span> <span class="p">(</span><span class="s">&quot;data[%zd] = %p</span><span class="se">\n</span><span class="s">&quot;</span><span class="p">,</span> <span class="n">i</span><span class="p">,</span> <span class="n">data</span><span class="p">[</span><span class="n">i</span><span class="p">]);</span>
<span class="k">for</span> <span class="p">(</span><span class="kt">size_t</span> <span class="n">j</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="n">j</span> <span class="o">&lt;</span> <span class="mi">3</span><span class="p">;</span> <span class="n">j</span><span class="o">++</span><span class="p">)</span>
<span class="n">printf</span> <span class="p">(</span><span class="s">&quot;&amp;data[%zd][%zd] = %d &lt;%p&gt;</span><span class="se">\n</span><span class="s">&quot;</span><span class="p">,</span> <span class="n">i</span><span class="p">,</span> <span class="n">j</span><span class="p">,</span> <span class="n">data</span><span class="p">[</span><span class="n">i</span><span class="p">][</span><span class="n">j</span><span class="p">],</span> <span class="o">&amp;</span><span class="n">data</span><span class="p">[</span><span class="n">i</span><span class="p">][</span><span class="n">j</span><span class="p">]);</span>
<span class="p">}</span>
</pre></div>
</td></tr></table></div>
<div class="figure mb-2 align-right" id="id13" style="width: 40%">
<span id="argvptrs"></span><a class="reference internal image-reference" href="_images/CSF-Images.A.3.png"><img class="p-3 mb-2 align-center border border-dark rounded-lg" alt="The argv array of command-line arguments is an array of pointers" src="_images/CSF-Images.A.3.png" style="width: 95%;" /></a>
<p class="caption align-center px-3"><span class="caption-text"> Figure 10.4.3: The <code class="docutils literal notranslate"><span class="pre">argv</span></code> array of command-line arguments is an array of pointers</span></p>
</div>
<p>Despite this more complex inner structure, lines 13 18 illustrate that the array can still be
treated like a two-dimensional array for accessing elements. This code works as an artifact of an
earlier point in this section: pointers can be dereferenced using bracket notation. In this case,
data is declared as an array of <code class="docutils literal notranslate"><span class="pre">uint32_t*</span></code> elements, so <code class="docutils literal notranslate"><span class="pre">data[0]</span></code> is a pointer storing the
address of <code class="docutils literal notranslate"><span class="pre">row0</span></code>. Accessing <code class="docutils literal notranslate"><span class="pre">data[0][1]</span></code>, then, is the same as accessing <code class="docutils literal notranslate"><span class="pre">row0[1]</span></code> because of
the pointer dereferencing.</p>
<p><a href="Arrays.html#argvptrs">Figure 10.4.3</a> illustrates a familiar example for this same concept. Consider the
command line to list files as <code class="docutils literal notranslate"><span class="pre">&quot;ls</span> <span class="pre">-ltr&quot;</span></code>. In this case, <code class="docutils literal notranslate"><span class="pre">argv[0]</span></code> is <code class="docutils literal notranslate"><span class="pre">&quot;ls&quot;</span></code> and <code class="docutils literal notranslate"><span class="pre">argv[1]</span></code>
is <code class="docutils literal notranslate"><span class="pre">&quot;-ltr&quot;</span></code> internal in the process that runs this program. Since the parameter is declared <code class="docutils literal notranslate"><span class="pre">char</span>
<span class="pre">*argv[]</span></code> (i.e., an array of pointers to <code class="docutils literal notranslate"><span class="pre">chars</span></code>), we can see that each element is a pointer to a
string.</p>
</div>
<div class="section" id="structs-and-packing">
<h2>10.4.2. Structs and Packing<a class="headerlink" href="Arrays.html#structs-and-packing" title="Permalink to this headline"></a></h2>
<p>Elements in an array are, by definition, all of the same type. Given the declaration <code class="docutils literal notranslate"><span class="pre">int</span>
<span class="pre">data[5]</span></code>, we know that the five elements are <code class="docutils literal notranslate"><span class="pre">int</span></code>s and these elements occupy a single block of
consecutive bytes in memory. The total size of this block is exactly the number of elements (5)
times the size of each element (an int is typically 4 bytes). To distinguish the elements within an
array, each element has a unique index that can be used in the bracket notation. As described
previously, bracket notation is semantically equivalent to calculating the offset to a memory
location using pointer arithmetic. That is, <code class="docutils literal notranslate"><span class="pre">data[2]</span></code> is equivalent to <code class="docutils literal notranslate"><span class="pre">*(data</span> <span class="pre">+</span> <span class="pre">2)</span></code>, and both
notations refer to the calculation of a particular offset from the starting address of <code class="docutils literal notranslate"><span class="pre">data</span></code>.</p>
<p>Like arrays, structs are used to create a chunk of contiguous data in memory, but with two
differences. First, the fields (rather than elements) of a <code class="docutils literal notranslate"><span class="pre">struct</span></code> are accessed with a name,
rather than an index. Second, the fields in a <code class="docutils literal notranslate"><span class="pre">struct</span></code> do not have to adhere to the same type.
<a class="reference external" href="Arrays.html#cla-16">Code Listing A.16</a> illustrates both of these facts with a <code class="docutils literal notranslate"><span class="pre">struct</span></code> declaration for
keeping track of time records. It is important to emphasize that lines 5 8 only define the
structure of one of these structs (similar to defining a class in an object-oriented language like
Java), rather than creating an instance of a <code class="docutils literal notranslate"><span class="pre">struct</span></code> in memory. In contrast, line 13 creates an
instance as a local variable, with lines 14 and 15 initializing the fields of this struct. This
declaration and initialization could be done on a single line, similar to initializing an array;
line 13 could be extended to read <code class="docutils literal notranslate"><span class="pre">ts</span> <span class="pre">=</span> <span class="pre">{</span> <span class="pre">100,</span> <span class="pre">258.9275</span> <span class="pre">}</span></code>, though this style requires knowing the
specific order of elements in the <code class="docutils literal notranslate"><span class="pre">struct</span></code>.</p>
<div class="highlight-c border border-dark rounded-lg bg-light px-0 mb-3 notranslate" id="cla-16"><table class="highlighttable"><tr><td class="linenos px-0 mx-0"><div class="linenodiv"><pre class="mb-0"> 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20</pre></div></td><td class="code"><div class="highlight bg-light"><pre class="mb-0"><span></span><span class="cm">/* Code Listing A.16:</span>
<span class="cm"> A struct declaration to keep track of a time record</span>
<span class="cm"> */</span>
<span class="k">struct</span> <span class="n">timestamp</span> <span class="p">{</span>
<span class="kt">int</span> <span class="n">date</span><span class="p">;</span> <span class="c1">// days since a given start data</span>
<span class="kt">double</span> <span class="n">time</span><span class="p">;</span> <span class="c1">// seconds since midnight of the current day</span>
<span class="p">};</span>
<span class="kt">int</span>
<span class="nf">main</span> <span class="p">(</span><span class="kt">void</span><span class="p">)</span>
<span class="p">{</span>
<span class="k">struct</span> <span class="n">timestamp</span> <span class="n">ts</span><span class="p">;</span>
<span class="n">ts</span><span class="p">.</span><span class="n">date</span> <span class="o">=</span> <span class="mi">100</span><span class="p">;</span>
<span class="n">ts</span><span class="p">.</span><span class="n">time</span> <span class="o">=</span> <span class="mf">258.9275</span><span class="p">;</span>
<span class="n">printf</span> <span class="p">(</span><span class="s">&quot;Time stamp: %d:%lf</span><span class="se">\n</span><span class="s">&quot;</span><span class="p">,</span> <span class="n">ts</span><span class="p">.</span><span class="n">date</span><span class="p">,</span> <span class="n">ts</span><span class="p">.</span><span class="n">time</span><span class="p">);</span>
<span class="k">return</span> <span class="mi">0</span><span class="p">;</span>
<span class="p">}</span>
</pre></div>
</td></tr></table></div>
<p>In the computer systems field, this view of structs as <em>objects without methods</em> is not necessarily
sufficient. In particular, when two different machines are exchanging data, the two systems need to
agree on the layout and interpretation of the bytes without the <code class="docutils literal notranslate"><span class="pre">struct</span></code>. This agreement is not
necessarily guaranteed, even if the same source code is used. Different compilers may arrange the
fields in different orders, and the CPU may interpret multi-byte sequences differently due to
endianness issues. <a class="reference external" href="Arrays.html#cla-17">Code Listing A.17</a> demonstrates how to perform introspection into the
layout of a <code class="docutils literal notranslate"><span class="pre">struct</span></code> in code.</p>
<div class="highlight-c border border-dark rounded-lg bg-light px-0 mb-3 notranslate" id="cla-17"><table class="highlighttable"><tr><td class="linenos px-0 mx-0"><div class="linenodiv"><pre class="mb-0"> 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18</pre></div></td><td class="code"><div class="highlight bg-light"><pre class="mb-0"><span></span><span class="cm">/* Code Listing A.17:</span>
<span class="cm"> Exploring the size and layout of a struct</span>
<span class="cm"> */</span>
<span class="k">struct</span> <span class="n">alternating</span> <span class="p">{</span>
<span class="kt">uint8_t</span> <span class="n">a</span><span class="p">;</span>
<span class="kt">uint32_t</span> <span class="n">b</span><span class="p">;</span>
<span class="kt">uint16_t</span> <span class="n">c</span><span class="p">;</span>
<span class="kt">uint8_t</span> <span class="n">d</span><span class="p">;</span>
<span class="p">};</span>
<span class="k">struct</span> <span class="n">alternating</span> <span class="n">alt</span> <span class="o">=</span> <span class="p">{</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">3</span><span class="p">,</span> <span class="mi">4</span> <span class="p">};</span>
<span class="n">printf</span> <span class="p">(</span><span class="s">&quot;sizeof(alt) = %zd</span><span class="se">\n</span><span class="s">&quot;</span><span class="p">,</span> <span class="k">sizeof</span> <span class="p">(</span><span class="n">alt</span><span class="p">));</span>
<span class="n">printf</span> <span class="p">(</span><span class="s">&quot;alt.a at %p, value %&quot;</span> <span class="n">PRId8</span> <span class="s">&quot;</span><span class="se">\n</span><span class="s">&quot;</span><span class="p">,</span> <span class="o">&amp;</span><span class="n">alt</span><span class="p">.</span><span class="n">a</span><span class="p">,</span> <span class="n">alt</span><span class="p">.</span><span class="n">a</span><span class="p">);</span>
<span class="n">printf</span> <span class="p">(</span><span class="s">&quot;alt.b at %p, value %&quot;</span> <span class="n">PRId32</span> <span class="s">&quot;</span><span class="se">\n</span><span class="s">&quot;</span><span class="p">,</span> <span class="o">&amp;</span><span class="n">alt</span><span class="p">.</span><span class="n">b</span><span class="p">,</span> <span class="n">alt</span><span class="p">.</span><span class="n">b</span><span class="p">);</span>
<span class="n">printf</span> <span class="p">(</span><span class="s">&quot;alt.c at %p, value %&quot;</span> <span class="n">PRId16</span> <span class="s">&quot;</span><span class="se">\n</span><span class="s">&quot;</span><span class="p">,</span> <span class="o">&amp;</span><span class="n">alt</span><span class="p">.</span><span class="n">c</span><span class="p">,</span> <span class="n">alt</span><span class="p">.</span><span class="n">c</span><span class="p">);</span>
<span class="n">printf</span> <span class="p">(</span><span class="s">&quot;alt.d at %p, value %&quot;</span> <span class="n">PRId8</span> <span class="s">&quot;</span><span class="se">\n</span><span class="s">&quot;</span><span class="p">,</span> <span class="o">&amp;</span><span class="n">alt</span><span class="p">.</span><span class="n">d</span><span class="p">,</span> <span class="n">alt</span><span class="p">.</span><span class="n">d</span><span class="p">);</span>
</pre></div>
</td></tr></table></div>
<p>Line 14 prints the size of one <code class="docutils literal notranslate"><span class="pre">struct</span> <span class="pre">alternating</span></code> instance, <code class="docutils literal notranslate"><span class="pre">alt</span></code>. Reading lines 5 10
suggests that line 14 will indicate that the size of <code class="docutils literal notranslate"><span class="pre">alt</span></code> is 8 bytes (4 for <code class="docutils literal notranslate"><span class="pre">a</span></code>, 1 for <code class="docutils literal notranslate"><span class="pre">b</span></code>, 2
for <code class="docutils literal notranslate"><span class="pre">c</span></code>, and 1 for <code class="docutils literal notranslate"><span class="pre">d</span></code>). This intuition is wrong for typical compilers and modern hardware.
Using both the <code class="docutils literal notranslate"><span class="pre">clang</span></code> and <code class="docutils literal notranslate"><span class="pre">gcc</span></code> compilers on an x86 architecture, the compiled code indicates
that <code class="docutils literal notranslate"><span class="pre">alt</span></code> is 12 bytes in size. The specific layout of the memory for <code class="docutils literal notranslate"><span class="pre">alt</span></code> is shown in <a class="reference external" href="Arrays.html#tblA-4">Table A.4</a>.
To be precise, the address of <code class="docutils literal notranslate"><span class="pre">alt</span></code> is the address of the byte on the left,
containing the value <code class="docutils literal notranslate"><span class="pre">0x01</span></code>; the memory addresses increase from left to right in this table. As
x86 is a little-endian architecture, the bytes of the multi-byte fields <code class="docutils literal notranslate"><span class="pre">b</span></code> and <code class="docutils literal notranslate"><span class="pre">c</span></code> are
structured with the least-significant byte on the left (indicating a lower address offset within the
<code class="docutils literal notranslate"><span class="pre">struct</span></code>).</p>
<center>
<table class="table table-bordered">
<thead class="jmu-dark-purple-bg text-light">
<tr>
<th class="py-0 center"><code class="text-light">a</code></th>
<th class="py-0 center"><code class="text-light">??</code></th>
<th class="py-0 center"><code class="text-light">??</code></th>
<th class="py-0 center"><code class="text-light">??</code></th>
<th class="py-0 center" colspan="4"><code class="text-light">b</code></th>
<th class="py-0 center" colspan="2"><code class="text-light">c</code></th>
<th class="py-0 center"><code class="text-light">d</code></th>
<th class="py-0 center"><code class="text-light">??</code></th>
</tr>
</thead>
<tbody>
<tr>
<td class="py-0 center" width="8.3%"><code>01</code></td>
<td class="py-0 center" width="8.3%"><code>??</code></td>
<td class="py-0 center" width="8.3%"><code>??</code></td>
<td class="py-0 center" width="8.3%"><code>??</code></td>
<td class="py-0 center" width="8.3%"><code>02</code></td>
<td class="py-0 center" width="8.3%"><code>00</code></td>
<td class="py-0 center" width="8.3%"><code>00</code></td>
<td class="py-0 center" width="8.3%"><code>00</code></td>
<td class="py-0 center" width="8.3%"><code>03</code></td>
<td class="py-0 center" width="8.3%"><code>00</code></td>
<td class="py-0 center" width="8.3%"><code>04</code></td>
<td class="py-0 center"><code>??</code></td>
</tr>
</tbody>
</table>
<p>Table A.4: The layout of an unpacked struct with padding bytes</p>
</center>
<br /><p>The fields shown as <code class="docutils literal notranslate"><span class="pre">??</span></code> in <a class="reference external" href="Arrays.html#tblA-4">Table A.4</a> indicate additional bytes of padding. The
compiler injects this padding because of how memory is physically access by the CPU. The compiler
can also (but does not in this case, re-order the fields if necessary. Generally speaking, bytes
that are stored in the same <em>memory word</em> can be accessed in a single CPU cycle. A memory word
is a sequence of four consecutive bytes, but these bytes need to begin at a <em>word boundary</em>
(an address that is evenly divisible by four). If we assume that alt begins at address
<code class="docutils literal notranslate"><span class="pre">0x7ffe000027c0</span></code> (which is a word boundary), the three bytes of padding just after the <code class="docutils literal notranslate"><span class="pre">a</span></code>
ensure that <code class="docutils literal notranslate"><span class="pre">b</span></code> starts at another word boundary, <code class="docutils literal notranslate"><span class="pre">0x7ffe000027c4</span></code>. If b, instead, began
immediately after <code class="docutils literal notranslate"><span class="pre">a</span></code> at address <code class="docutils literal notranslate"><span class="pre">0x7ffe000027c1</span></code>, then the contents of <code class="docutils literal notranslate"><span class="pre">b</span></code> would span two
distinct memory words. As a result, accessing <code class="docutils literal notranslate"><span class="pre">b</span></code> would now require two CPU cycles instead of just
one. This additional cycle might sound trivial (since there are billions of cycles per second), but
the cumulative effect over all programs would be significant. The padding after the d rounds up the
size of the <code class="docutils literal notranslate"><span class="pre">struct</span></code> to be an exact multiple of three words. This padding helps ensure other data
on the stack around the <code class="docutils literal notranslate"><span class="pre">alt</span></code> variable also begin at word boundaries.</p>
<p>But what if the code needs to adhere to a specification that the <code class="docutils literal notranslate"><span class="pre">struct</span> <span class="pre">alternating</span></code> cannot have
padding? That is, each <code class="docutils literal notranslate"><span class="pre">struct</span></code> instance needs to be exactly eight bytes, interpreted in the order
defined by the <code class="docutils literal notranslate"><span class="pre">struct</span></code>. In this case, the <code class="docutils literal notranslate"><span class="pre">struct</span></code> needs to be declared as <em>packed</em>,
meaning that there is no padding or re-ordering allowed. To declare the <code class="docutils literal notranslate"><span class="pre">struct</span></code> as packed, the
only change is to modify the first line of <a class="reference external" href="Arrays.html#cla-17">Code Listing A.17</a> with the packed attribute:</p>
<div class="highlight-c border border-dark rounded-lg bg-light px-2 mb-3 notranslate"><div class="highlight bg-light"><pre class="mb-0"><span></span><span class="k">struct</span> <span class="nf">__attribute__</span><span class="p">((</span><span class="n">__packed__</span><span class="p">))</span> <span class="n">alternating</span> <span class="p">{</span>
</pre></div>
</div>
<div class="topic border border-dark rounded-lg bg-light px-2 mb-3">
<div class="figure align-left">
<a class="reference internal image-reference" href="_images/CSF-Images-Note.png"><img alt="Decorative note icon" src="_images/CSF-Images-Note.png" style="width: 100%;" /></a>
</div>
<p class="topic-title first pt-2 mb-1">Note</p><hr class="mt-1" />
<p>Computer systems frequently take advantage of very compact data representations, particular in the
networking domain. Bit masks, for instance, use the individual bits within a byte to represent
distinct pieces of information. Within the <code class="docutils literal notranslate"><span class="pre">struct</span></code> declaration, the individual field names are
append with <code class="docutils literal notranslate"><span class="pre">:n</span></code> to indicate that the field occupies <code class="docutils literal notranslate"><span class="pre">n</span></code> bits. Packed structs also help with
this data compression by ensuring that there is no padding added. Consider the following example:</p>
<div class="highlight-c border border-dark rounded-lg bg-light px-0 mb-3 notranslate"><table class="highlighttable"><tr><td class="linenos px-0 mx-0"><div class="linenodiv"><pre class="mb-0"> 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16</pre></div></td><td class="code"><div class="highlight bg-light"><pre class="mb-0"><span></span><span class="k">struct</span> <span class="nf">__attribute__</span><span class="p">((</span><span class="n">__packed__</span><span class="p">))</span> <span class="n">bits</span> <span class="p">{</span>
<span class="kt">unsigned</span> <span class="nl">type</span><span class="p">:</span><span class="mi">2</span><span class="p">;</span> <span class="c1">// can be 0, 1, 2, or 3</span>
<span class="kt">unsigned</span> <span class="nl">urgent</span><span class="p">:</span><span class="mi">1</span><span class="p">;</span> <span class="c1">// can be true (1) or false (0)</span>
<span class="kt">unsigned</span> <span class="nl">length</span><span class="p">:</span><span class="mi">7</span><span class="p">;</span> <span class="c1">// anywhere from 0 to 31</span>
<span class="p">};</span>
<span class="k">struct</span> <span class="n">bits</span> <span class="n">data</span><span class="p">;</span>
<span class="n">memset</span> <span class="p">(</span><span class="o">&amp;</span><span class="n">data</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="k">sizeof</span> <span class="p">(</span><span class="n">data</span><span class="p">));</span> <span class="c1">// ensure all bits init to 0</span>
<span class="n">data</span><span class="p">.</span><span class="n">type</span> <span class="o">=</span> <span class="mi">3</span><span class="p">;</span>
<span class="n">data</span><span class="p">.</span><span class="n">urgent</span> <span class="o">=</span> <span class="nb">false</span><span class="p">;</span>
<span class="n">data</span><span class="p">.</span><span class="n">length</span> <span class="o">=</span> <span class="mi">27</span><span class="p">;</span>
<span class="n">printf</span> <span class="p">(</span><span class="s">&quot;Size of data is %zd</span><span class="se">\n</span><span class="s">&quot;</span><span class="p">,</span> <span class="k">sizeof</span> <span class="p">(</span><span class="n">data</span><span class="p">));</span>
<span class="cm">/* Cast the address of data to a uint16_t* and dereference it */</span>
<span class="n">printf</span> <span class="p">(</span><span class="s">&quot;data as a hex int is %04&quot;</span> <span class="n">PRIx16</span> <span class="s">&quot;</span><span class="se">\n</span><span class="s">&quot;</span><span class="p">,</span> <span class="o">*</span><span class="p">((</span><span class="kt">uint16_t</span><span class="o">*</span><span class="p">)</span> <span class="o">&amp;</span><span class="n">data</span><span class="p">));</span>
</pre></div>
</td></tr></table></div>
<p>The declaration of <code class="docutils literal notranslate"><span class="pre">struct</span> <span class="pre">bits</span></code> indicates that one instance requires 10 bits. Since we cannot
actually allocate data at this bit level, this instance would be padded to make it exactly two
bytes (16 bits) in size. Among those 16 bits, the C standard does not specify an exact order. The
fields should only be accessed through their names, as shown in line 9 11. It is possible,
however, to determine the layout on a particular system through trial and error. The <code class="docutils literal notranslate"><span class="pre">printf()</span></code>
call on lines 15 and 16 reveal that one possible layout is as follows:</p>
<center>
<table class="table table-bordered">
<thead class="jmu-dark-purple-bg text-light">
<tr>
<th class="py-0 center" colspan="8">First byte</th>
<th class="py-0 center" colspan="8">Second byte</th>
</tr>
<tr>
<th class="py-0 center" colspan="6"><em>[unnamed and unused]</em></th>
<th class="py-0 center" colspan="7"><code class="text-light">length</code></th>
<th class="py-0 center"><code class="text-light">urg</code></th>
<th class="py-0 center" colspan="2"><code class="text-light">type</code></th>
</tr>
</thead>
<tbody>
<tr>
<td class="py-0 center" width="6.25%"><code>0</code></td>
<td class="py-0 center" width="6.25%"><code>0</code></td>
<td class="py-0 center" width="6.25%"><code>0</code></td>
<td class="py-0 center" width="6.25%"><code>0</code></td>
<td class="py-0 center" width="6.25%"><code>0</code></td>
<td class="py-0 center" width="6.25%"><code>0</code></td>
<td class="py-0 center" width="6.25%"><code>0</code></td>
<td class="py-0 center" width="6.25%"><code>0</code></td>
<td class="py-0 center" width="6.25%"><code>1</code></td>
<td class="py-0 center" width="6.25%"><code>1</code></td>
<td class="py-0 center" width="6.25%"><code>0</code></td>
<td class="py-0 center" width="6.25%"><code>1</code></td>
<td class="py-0 center" width="6.25%"><code>1</code></td>
<td class="py-0 center" width="6.25%"><code>0</code></td>
<td class="py-0 center" width="6.25%"><code>1</code></td>
<td class="py-0 center" width="6.25%"><code>1</code></td>
</tr>
<tr>
<td class="py-0 center" colspan="4"><code>0</code></td>
<td class="py-0 center" colspan="4"><code>0</code></td>
<td class="py-0 center" colspan="4"><code>d</code></td>
<td class="py-0 center" colspan="4"><code>b</code></td>
</tr>
</tbody>
</table>
</center><p>Based on this illustration, the seven bits of the <code class="docutils literal notranslate"><span class="pre">length</span></code> field spans the two bytes, whereas
<code class="docutils literal notranslate"><span class="pre">urgent</span></code> and <code class="docutils literal notranslate"><span class="pre">type</span></code> both reside in the second byte. The bottom line shows the hexadecimal
representation of four bits at a time. Printing the full value, as on lines 15 and 16, produces the
output <code class="docutils literal notranslate"><span class="pre">0x00db</span></code>.</p>
</div>
</div>
<div class="section" id="enums-and-type-definitions">
<h2>10.4.3. Enums and Type Definitions<a class="headerlink" href="Arrays.html#enums-and-type-definitions" title="Permalink to this headline"></a></h2>
<p>From the programmers perspective, Cs built-in types and <code class="docutils literal notranslate"><span class="pre">struct</span></code>s are low-level primitives that
make it difficult to read and understand the code. For instance, in the case of <code class="docutils literal notranslate"><span class="pre">struct</span></code>s, the
type is always the full name consisting of <code class="docutils literal notranslate"><span class="pre">struct</span></code> and the identifier following it. In the case
of <code class="docutils literal notranslate"><span class="pre">alt</span></code> from <a class="reference external" href="Arrays.html#cla-17">Code Listing A.17</a>, its type is <code class="docutils literal notranslate"><span class="pre">struct</span> <span class="pre">alternating</span></code>; its type is not
<code class="docutils literal notranslate"><span class="pre">struct</span></code>, nor is its type <code class="docutils literal notranslate"><span class="pre">alternating</span></code>. Copying the word <code class="docutils literal notranslate"><span class="pre">struct</span></code> around gets tedious and it
detracts from the readability. As for the primitive types, an int indicates an integer value, but
what if there are only certain integers that are valid? For instance, consider a variable that is
used to keep track of the day of the week (Sunday through Saturday) as an integer (Sunday is 1,
Saturday is 7). Referring to day 37 might lead to an unpredictable error.</p>
<p>To start with the latter problem, the solution is to define an enumerated type, or <code class="docutils literal notranslate"><span class="pre">enum</span></code>. An
<code class="docutils literal notranslate"><span class="pre">enum</span></code> is a custom integer type that allows the programmer to use names instead of numeric
constants. <a class="reference external" href="Arrays.html#cla-18">Code Listing A.18</a> declares an <code class="docutils literal notranslate"><span class="pre">enum</span></code> for the days of the week as
previously described. In the declaration, the values in the <code class="docutils literal notranslate"><span class="pre">enum</span></code> are automatically incremented.
By setting <code class="docutils literal notranslate"><span class="pre">SUN</span></code> = 1 (instead of allowing the default starting value of 0), <code class="docutils literal notranslate"><span class="pre">MON</span></code> would be 2,
<code class="docutils literal notranslate"><span class="pre">TUE</span></code> would be 3, and so on. The advantage of the <code class="docutils literal notranslate"><span class="pre">enum</span></code> is that we can use these meaningful
names (<code class="docutils literal notranslate"><span class="pre">MON</span></code>, <code class="docutils literal notranslate"><span class="pre">TUE</span></code>, <code class="docutils literal notranslate"><span class="pre">WED</span></code>, …) instead of memorizing numeric values. We can also declare
variables using the <code class="docutils literal notranslate"><span class="pre">enum</span></code> type as shown on line 6.</p>
<div class="highlight-c border border-dark rounded-lg bg-light px-0 mb-3 notranslate" id="cla-18"><table class="highlighttable"><tr><td class="linenos px-0 mx-0"><div class="linenodiv"><pre class="mb-0">1
2
3
4
5
6
7</pre></div></td><td class="code"><div class="highlight bg-light"><pre class="mb-0"><span></span><span class="cm">/* Code Listing A.18:</span>
<span class="cm"> Declaring the days of the week as an enumerated type</span>
<span class="cm"> */</span>
<span class="k">enum</span> <span class="n">days</span> <span class="p">{</span> <span class="n">SUN</span> <span class="o">=</span> <span class="mi">1</span><span class="p">,</span> <span class="n">MON</span><span class="p">,</span> <span class="n">TUE</span><span class="p">,</span> <span class="n">WED</span><span class="p">,</span> <span class="n">THU</span><span class="p">,</span> <span class="n">FRI</span><span class="p">,</span> <span class="n">SAT</span> <span class="p">};</span>
<span class="k">enum</span> <span class="n">days</span> <span class="n">today</span> <span class="o">=</span> <span class="n">WED</span><span class="p">;</span>
<span class="n">printf</span> <span class="p">(</span><span class="s">&quot;Tomorrow is %d</span><span class="se">\n</span><span class="s">&quot;</span><span class="p">,</span> <span class="n">today</span> <span class="o">+</span> <span class="mi">1</span><span class="p">);</span>
</pre></div>
</td></tr></table></div>
<p>To be clear, <code class="docutils literal notranslate"><span class="pre">enum</span></code>s are a syntactical mechanism of convenience, not security. Internally, an
<code class="docutils literal notranslate"><span class="pre">enum</span></code> is just an <code class="docutils literal notranslate"><span class="pre">int</span></code>, and C does not perform any bounds checking to ensure that the values of
an <code class="docutils literal notranslate"><span class="pre">enum</span></code> variable (such as today) match the names or the range in the definition. Line 6 could
initialize today to be 37, or line 7 could be changed to use <code class="docutils literal notranslate"><span class="pre">today</span> <span class="pre">-</span> <span class="pre">452</span></code>; either would be allowed,
as today is ultimately just an <code class="docutils literal notranslate"><span class="pre">int</span></code> variable.</p>
<p>The <code class="docutils literal notranslate"><span class="pre">enum</span></code> keyword has the same problem as the <code class="docutils literal notranslate"><span class="pre">struct</span></code> keyword, in that it must be included in
the type name and passed around throughout the code. In <a class="reference external" href="Arrays.html#cla-18">Code Listing A.18</a>, the type of
the today variable is <code class="docutils literal notranslate"><span class="pre">enum</span> <span class="pre">days</span></code>, not <code class="docutils literal notranslate"><span class="pre">enum</span></code> or <code class="docutils literal notranslate"><span class="pre">days</span></code>. To make the code more readable for
both <code class="docutils literal notranslate"><span class="pre">enum</span></code>s and <code class="docutils literal notranslate"><span class="pre">struct</span></code>s, we can declare a new custom type name with the <code class="docutils literal notranslate"><span class="pre">typedef</span></code>
keyword. <a class="reference external" href="Arrays.html#cla-19">Code Listing A.19</a> uses <code class="docutils literal notranslate"><span class="pre">typedef</span></code> on the <code class="docutils literal notranslate"><span class="pre">enum</span></code> from <a class="reference external" href="Arrays.html#cla-18">A.18</a> and
the <code class="docutils literal notranslate"><span class="pre">struct</span></code> from <a class="reference external" href="Arrays.html#cla-17">A.17</a>.</p>
<div class="highlight-c border border-dark rounded-lg bg-light px-0 mb-3 notranslate" id="cla-19"><table class="highlighttable"><tr><td class="linenos px-0 mx-0"><div class="linenodiv"><pre class="mb-0"> 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15</pre></div></td><td class="code"><div class="highlight bg-light"><pre class="mb-0"><span></span><span class="cm">/* Code Listing A.19:</span>
<span class="cm"> Simplifying enum and struct type names with a typedef</span>
<span class="cm"> */</span>
<span class="k">typedef</span> <span class="k">enum</span> <span class="n">days</span> <span class="p">{</span> <span class="n">SUN</span> <span class="o">=</span> <span class="mi">1</span><span class="p">,</span> <span class="n">MON</span><span class="p">,</span> <span class="n">TUE</span><span class="p">,</span> <span class="n">WED</span><span class="p">,</span> <span class="n">THU</span><span class="p">,</span> <span class="n">FRI</span><span class="p">,</span> <span class="n">SAT</span> <span class="p">}</span> <span class="n">day_t</span><span class="p">;</span>
<span class="n">day_t</span> <span class="n">today</span> <span class="o">=</span> <span class="n">WED</span><span class="p">;</span>
<span class="k">typedef</span> <span class="k">struct</span> <span class="n">alternating</span> <span class="p">{</span>
<span class="kt">uint8_t</span> <span class="n">a</span><span class="p">;</span>
<span class="kt">uint32_t</span> <span class="n">b</span><span class="p">;</span>
<span class="kt">uint16_t</span> <span class="n">c</span><span class="p">;</span>
<span class="kt">uint8_t</span> <span class="n">d</span><span class="p">;</span>
<span class="p">}</span> <span class="n">alt_t</span><span class="p">;</span>
<span class="n">alt_t</span> <span class="n">alt</span> <span class="o">=</span> <span class="p">{</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">3</span><span class="p">,</span> <span class="mi">4</span> <span class="p">};</span>
</pre></div>
</td></tr></table></div>
<p>The general structure for declaring a new type is <code class="docutils literal notranslate"><span class="pre">typedef</span> <span class="pre">[existing</span> <span class="pre">type]</span> <span class="pre">[new</span> <span class="pre">type</span> <span class="pre">name];</span></code>. By
convention, the new type name typically ends with <code class="docutils literal notranslate"><span class="pre">_t</span></code> to indicate that this is a type. Observe
that there are many such type definitions in the C standard library. For instance, the <code class="docutils literal notranslate"><span class="pre">size_t</span></code>
type is defined (indirectly, as there are several chained type definitions involved) in the
<code class="docutils literal notranslate"><span class="pre">ctype.h</span></code> header as shown below. The advantage of using the type definition is that it provides
additional semantics. A variable declared as a <code class="docutils literal notranslate"><span class="pre">size_t</span></code> is not just being used as an integer, but
as the size of something.</p>
<div class="highlight-c border border-dark rounded-lg bg-light px-2 mb-3 notranslate"><div class="highlight bg-light"><pre class="mb-0"><span></span><span class="k">typedef</span> <span class="kt">int32_t</span> <span class="kt">size_t</span><span class="p">;</span>
</pre></div>
</div>
<p>One common problem with type definitions for <code class="docutils literal notranslate"><span class="pre">struct</span></code>s,`in particular, is when there are circular
dependencies. Consider <a class="reference external" href="Arrays.html#cla-20">Code Listing A.20</a> that defines a <code class="docutils literal notranslate"><span class="pre">person_t</span></code> type and an
<code class="docutils literal notranslate"><span class="pre">age_t</span></code> type. In this application, each person (<code class="docutils literal notranslate"><span class="pre">person_t</span></code>) has a unique name and age, but each
<code class="docutils literal notranslate"><span class="pre">age_t</span></code> has and unique year and pointers to up to 5 people. In other words, the person_t
definition needs to know about the <code class="docutils literal notranslate"><span class="pre">age_t</span></code> type, while the <code class="docutils literal notranslate"><span class="pre">age_t</span></code> definition needs to know
about the <code class="docutils literal notranslate"><span class="pre">person_t</span></code> type. The problem is that the definition of <code class="docutils literal notranslate"><span class="pre">person_t</span></code> (lines 7 10) comes
before the C compiler has learned about the <code class="docutils literal notranslate"><span class="pre">age_t</span></code> type (line 15); the C compiler cannot look
ahead, so using age_t on line 9 would be a compiler error.</p>
<div class="highlight-c border border-dark rounded-lg bg-light px-0 mb-3 notranslate" id="cla-20"><table class="highlighttable"><tr><td class="linenos px-0 mx-0"><div class="linenodiv"><pre class="mb-0"> 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15</pre></div></td><td class="code"><div class="highlight bg-light"><pre class="mb-0"><span></span><span class="cm">/* Code Listing A.20:</span>
<span class="cm"> Defining two structs with a circular definition</span>
<span class="cm"> */</span>
<span class="k">struct</span> <span class="n">age</span><span class="p">;</span> <span class="c1">// dummy struct definition</span>
<span class="k">typedef</span> <span class="k">struct</span> <span class="n">person</span> <span class="p">{</span>
<span class="kt">char</span> <span class="o">*</span><span class="n">name</span><span class="p">;</span>
<span class="k">struct</span> <span class="n">age</span> <span class="o">*</span><span class="n">age</span><span class="p">;</span>
<span class="p">}</span> <span class="n">person_t</span><span class="p">;</span>
<span class="k">typedef</span> <span class="k">struct</span> <span class="n">age</span> <span class="p">{</span>
<span class="kt">int</span> <span class="n">year</span><span class="p">;</span>
<span class="n">person_t</span> <span class="o">*</span><span class="n">people</span><span class="p">[</span><span class="mi">5</span><span class="p">];</span>
<span class="p">}</span> <span class="n">age_t</span><span class="p">;</span>
</pre></div>
</td></tr></table></div>
<p>The solution is to use a dummy <code class="docutils literal notranslate"><span class="pre">struct</span></code> definition on line 5 that matches the name on line 12. (It
is vital that the name of both <code class="docutils literal notranslate"><span class="pre">struct</span></code> types match.) By structuring the code this way, the
compiler is able to correctly link the type of the age field within <code class="docutils literal notranslate"><span class="pre">person_t</span></code> as a pointer to an
<code class="docutils literal notranslate"><span class="pre">age_t</span></code> instance later. Once this is done, the circular definition can be ignored, as shown in
<a class="reference external" href="Arrays.html#cla-21">Code Listing A.21</a>. The <code class="docutils literal notranslate"><span class="pre">person_t</span></code> instance is able to set its age field to the
address of an <code class="docutils literal notranslate"><span class="pre">age_t</span></code> instance without causing a compiler error or warning.</p>
<div class="highlight-c border border-dark rounded-lg bg-light px-0 mb-3 notranslate" id="cla-21"><table class="highlighttable"><tr><td class="linenos px-0 mx-0"><div class="linenodiv"><pre class="mb-0"> 1
2
3
4
5
6
7
8
9
10
11
12</pre></div></td><td class="code"><div class="highlight bg-light"><pre class="mb-0"><span></span><span class="cm">/* Code Listing A.21:</span>
<span class="cm"> When using the structs, the circular definition is not visible</span>
<span class="cm"> */</span>
<span class="n">person_t</span> <span class="n">person</span><span class="p">;</span>
<span class="n">age_t</span> <span class="n">age</span><span class="p">;</span>
<span class="n">person</span><span class="p">.</span><span class="n">name</span> <span class="o">=</span> <span class="s">&quot;Gustavo&quot;</span><span class="p">;</span>
<span class="n">person</span><span class="p">.</span><span class="n">age</span> <span class="o">=</span> <span class="o">&amp;</span><span class="n">age</span><span class="p">;</span>
<span class="n">age</span><span class="p">.</span><span class="n">year</span> <span class="o">=</span> <span class="mi">35</span><span class="p">;</span>
<span class="n">age</span><span class="p">.</span><span class="n">people</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">=</span> <span class="o">&amp;</span><span class="n">person</span><span class="p">;</span>
</pre></div>
</td></tr></table></div>
</div>
</div>
</div>
<div class="container">
<div class="mt-4 container center">
«&#160;&#160;<a id="prevmod1" href="BasicTypes.html">10.3. Basic Types and Pointers</a>
&#160;&#160;::&#160;&#160;
<a class="uplink" href="index.html">Contents</a>
&#160;&#160;::&#160;&#160;
<a id="nextmod1" href="Functions.html">10.5. Functions and Scope</a>&#160;&#160;»
</div>
</div>
<br />
<div class="row jmu-dark-purple-bg">
<div class="col-md-12">
<center>
<a id="contact_us" class="btn button-link-no-blue jmu-gold" rel="nofollow" href="mailto:webmaster@opencsf.org" role="button">Contact Us</a>
<a id="license" class="btn button-link-no-blue jmu-gold" rel="nofollow" href="https://w3.cs.jmu.edu/kirkpams/OpenCSF/lib/license.html" target="_blank">License</a>
</center>
</div>
</div>
<script src="_static/js/popper.js-1.14.7-min.js" integrity="sha384-UO2eT0CpHqdSJQ6hJty5KVphtPhzWj9WO1clHTMGa3JDZwrnQq4sF86dIHNDz0W1" crossorigin="anonymous"></script>
<script src="_static/js/bootstrap.min.js" integrity="sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM" crossorigin="anonymous"></script>
</body>
</html>