A Love Letter to C’s Square Brackets

<p>I want to share my favorite bit of &ldquo;forbidden code&rdquo;, because when you understand it, you&rsquo;ll never be confused about pointers and arrays again, and you&rsquo;ll appreciate how much mileage the designers of C squeezed out of a few subtle bits of syntax.</p> <p>I hope to make you doubt that C has arrays at all, and then prove to you that it really does &mdash; just not in the way you might have thought. Take a look:</p> <pre> #include &lt;stdio.h&gt; struct { int zero_squared; int one_squared; int two_squared; int three_squared; int four_squared; int five_squared; int six_squared; } squares = {0,1,4,9,16,25,36}; int main() { printf(&quot;4 squared is %d\n&quot;, 4[(&amp;squares.zero_squared)] ); }</pre> <pre> 4 squared is 16</pre> <p>When you first read it, this expression feels like total nonsense:</p> <pre> 4[(&amp;squares.zero_squared)]</pre> <p>There are no arrays here, so what are those brackets doing? And even if you suspend disbelief for a moment and pretend it&rsquo;s an array, then why is&nbsp;<code>4</code>, which should be the index into the array, sitting&nbsp;<em>outside</em>&nbsp;the brackets? Isn&rsquo;t this just a pile of syntax errors?</p> <p>Let&rsquo;s work up an understanding of why this totally legal, and learn how pointer arithmetic and arrays&nbsp;<em>really</em>&nbsp;work while we&rsquo;re at it.</p> <h2>The Bracket Operator and Pointer Arithmetic</h2> <p>First, consider a regular old array on the stack:</p> <pre> int squares[5] = {0, 1, 4, 9, 16};</pre> <p>The usual way to access elements in the array is with brackets:</p> <pre> int one_squared = squares[1];</pre> <p>But, you might be familiar with another way to access elements:</p> <pre> int two_squared = *(squares + 2);</pre> <p>This works by doing some simple arithmetic with pointers.&nbsp;<code>squares</code>&nbsp;is &ldquo;just a pointer&rdquo; to the beginning of the array. So&nbsp;<code>squares[2]</code>&nbsp;is just&nbsp;<code>sizeof(int)*2</code>bytes later. Since addition is commutative, this also works:</p> <pre> int three_squared = *(3 + squares);</pre> <p>You can&rsquo;t see the multiply-by-sizeof calculation in these expressions, but it&rsquo;s there! When you add a pointer and an integer, the integer gets multiplied by the size of the type the pointer points to, precisely to make these expressions cleaner.</p> <p><a href="https://medium.com/@jondsmith22/a-love-letter-to-cs-square-brackets-462e16f168ae">Click Here</a></p>