A Love Letter to C’s Square Brackets
<p>I want to share my favorite bit of “forbidden code”, because when you understand it, you’ll never be confused about pointers and arrays again, and you’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 — just not in the way you might have thought. Take a look:</p>
<pre>
#include <stdio.h>
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("4 squared is %d\n",
4[(&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[(&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’s an array, then why is <code>4</code>, which should be the index into the array, sitting <em>outside</em> the brackets? Isn’t this just a pile of syntax errors?</p>
<p>Let’s work up an understanding of why this totally legal, and learn how pointer arithmetic and arrays <em>really</em> work while we’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. <code>squares</code> is “just a pointer” to the beginning of the array. So <code>squares[2]</code> is just <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’t see the multiply-by-sizeof calculation in these expressions, but it’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>