<p>What you have there is an excellent start, and is completely appropriate.  I would go next into a puzzle to try to get them hooked.  I would type the following code in front of them on your projector, and ask them to pair with a neighbor to try to figure out what will happen next.</p>
<p><em>(Note, for this to work properly, you must turn off stack security in <code>gcc</code>, which according to <a href="https://unix.stackexchange.com/a/46721">this somewhat dated post</a> might involve the flags <code>-fno-stack-protector</code> and <code>-fno-stack-protector-all</code>.)</em></p>
<pre><code>#include &lt;stdio.h&gt;

int main() {
    int a = 15;
    int b = 30;
    int c = 45;

    int *whatsthis = &amp;a;
    printf(&quot;whatsthis is: %d\n&quot;,*whatsthis);

    whatsthis = whatsthis + 4;
    printf(&quot;whatsthis is: %d\n&quot;,*whatsthis);

    return 0;
}
</code></pre>
<p><em>(Depending on your compiler and environment, you may have to muck around with the code a bit to get <code>45</code> as your output for the second <code>printf</code>)</em></p>
<p>If your kids are like mine, they probably won't be able to figure this out.  But once you compile it and execute, ask them to go back to their neighbor and try to figure out what in the world happened.</p>
<p>At this point, several of the groups should be able to figure out that it has something to do with the ints being stored next to each other, and, if pressed just a bit, that the number <code>4</code> was derived using the byte size of an <code>int</code>.</p>
<p>This gives you a perfect segue into arrays.  Since you're taking all of this trouble to go into some depth (using references to get at arrays), I would try for a few takeaways from the lesson:</p>
<ol>
<li>Pointer arithmetic means changing the address you're looking at.</li>
<li>The actual formula used to find the location of spot <code>n</code> in an array (which shows why that first address needs to be <code>0</code>: <code>(startlocation + (n * itemsize))</code></li>
<li>Therefore, indexing in arrays can be characterized as a distance from the start.</li>
<li>Array items are packed together with <em>no wasted space</em> and <em>no separators</em> between the data.</li>
<li>That, in fact, these are the <em>only two tools that computers possess</em> to locate themselves in memory: having items packed next to each other so that they can go from one item to the next, to the next, or saving pointers in memory so that we can go back to places later.  Every other thing that computers do with memory can be reduced to one of these two actions.</li>
</ol>

CC BY-SA 3.0
2017-06-18T06:31:56.133Z
@Peter The code example is wrong, because the unit for pointer arithmetic is the size of the pointed-to type. whatsthis + 4 points 4 ints ahead of whatsthis (Or, rather, it would if whatsthis were pointing into an array large enough to do that. The code as written invokes undefined behavior.)
Eric M Schmidt
CC BY-SA 3.0
2017-06-18T14:38:49.537Z
@EricMSchmidt I believe Ben I. was aware of this when posting the example. Even the undefined behavior can be teachable for students to learn pointers (and the precautions that one must take with them). At least I think this was intentional...
Peter
CC BY-SA 3.0
2017-06-18T15:00:41.040Z
Yes, the undefined behavior was the purpose of the exercise.  By arranging the demonstration so that the wrong variable gets modified, it should both pique their interest and give a great entrée to the idea of separating a memory address from the data it stores.
Ben I.
CC BY-SA 3.0
2017-07-25T20:12:35.490Z
I don't get why you're adding 4 to go from *a* to *c* when they should be *two* addresses apart, and yet you say it's *four* bytes per int.  Where is *b*, then?  (Nevertheless, +1 for a great illustration.)
Wildcard
CC BY-SA 3.0
2017-07-25T20:44:48.807Z
@Wildcard I tried to clarify the text.  IIRC, on my compiler (I tested my code when I wrote this), ints were 2 byes.
Ben I.
CC BY-SA 3.0
2017-07-25T20:57:04.773Z
Got it, thanks.  It wasn't the answer text that caused the confusion; it was your earlier comment: *"Mine used a 4-byte integer, which is also permitted."*  I understand now that was just a slip.  Thanks for clarifying!  :)
Wildcard
CC BY-SA 3.0
2017-12-22T18:39:09.973Z
Uh, how can we know what the distance is between the two variables, at all? Couldn't they be anywhere in the address space, in any order?
SilverWolf
CC BY-SA 3.0
2017-12-22T20:08:00.970Z
@seaturtle gcc can disable stack protections: https://stackoverflow.com/q/2340259/4151129
Ben I.
CC BY-SA 3.0
2017-12-23T00:45:00.387Z
Huh. I didn't know that was on _purpose_, I always figured that was just how it was, like file fragmentation on disk. Thanks. (:
SilverWolf
CC BY-SA 4.0
2021-03-24T14:58:59.697Z
I must say that I'm still very confused by this example. It's never explicitly stated here: What do you *expect* this code to print? I'll point out that on my current GCC compiler, if I add one or more printf statements *after* these lines, then the positions of a, b, c in memory get re-ordered -- and so I can get this same code to print out any of 30, 45, or 0 (i.e., anything). If your point is truly that this is undefined and might do anything, then what do you actually mean by "be able to figure this out" for the students in this context?
Daniel R. Collins
CC BY-SA 4.0
2021-03-24T17:14:38.683Z
@DanielR.Collins With modern, stack-randomizing compilers, you are correct, and I will add a caveat to that effect.  Because of my schedule, I typically teach this as part of a computer security class on stack-based attacks, and we purposefully use dated virtual machines without stack randomization for exactly the reason you cite.  I wasn't thinking about that when I wrote the answer, though.  Oops!
Ben I.
CC BY-SA 4.0
2021-03-28T15:20:02.220Z
@BenI.: Is that really a stack-randomizing issue, though? With my current stock copy of GCC, the ordering is fixed/deterministic with any particular piece of code. However, there are some complicated rules which are opaque to predict. For example, if I make 4 int variables and print any or all values, then GCC puts them in declaration order. But if I print out the address of one of them, then GCC puts that one in the top slot on the stack. Etc.
Daniel R. Collins
CC BY-SA 4.0
2021-03-28T15:21:01.220Z
Perhaps you should put more detail/a link with the "you must turn off stack randomization in gcc" piece, because my other searches for that aren't getting hits.
Daniel R. Collins
CC BY-SA 4.0
2021-03-28T16:44:45.673Z
@DanielR.Collins I edited the post again!  I'm not aware of all of the protections used for stacks, tbh.  Like I said, I do this on old virtual machines that have no stack protections built into GCC at all for exactly these pedagogic demonstration purposes, so there may be fine distinctions that I am missing here in more modern setups.
Ben I.
CC BY-SA 4.0
2021-03-28T20:00:30.743Z
@BenI.: Probably good that you removed the word "randomization" there. Unfortunately I'm still skeptical that the current detail is correct. (a) "-fno-stack-protector-all" isn't a valid GCC flag (see comments to what you linked for that). (b) I don't think there's any sign that these buffer protections involve re-ordering the stack (I just tested and see no difference)...
Daniel R. Collins
CC BY-SA 4.0
2021-03-28T20:06:53.377Z
Note that any time a question gets asked about GCC stack ordering in particular, the answers usually are some form of "there is absolutely no way to tell or control it without looking into the GCC code about how it makes its choices". E.g.: https://stackoverflow.com/questions/66793187/why-does-gcc-order-integers-on-the-stack-in-this-way
Daniel R. Collins
CC BY-SA 4.0
2017-05-30T23:34:36.720Z
2021-03-28T16:40:19.440Z
2021-03-28T16:40:19.440Z
Ben I.
<p>I would teach the use of arrays and array indices first (with pictures of a long row of physical mailboxes, or school lockers, etc.)  Then later explain that all of a computer's and/or C program's (process) memory can be thought of as one big array with a pointer being a form of index (locker number) into that (virtual) memory array.</p>

<p>You can then draw a picture of how arrays of char (bytes) might be allocated in memory.  And then show why pointers might be necessary in order to tell a standard string function how to find (or modify) a substring in an arbitrary C string array.</p>

CC BY-SA 3.0
2017-07-04T15:27:00.793Z
An interesting question is whether memory is an example of a concrete array, or an array is an example of a concrete memory system (of capacitors, electron wells, magnets, sound waves, beads, knots, etc.)
hotpaw2
CC BY-SA 3.0
2017-05-31T02:04:29.940Z
2017-07-19T20:04:53.757Z
2017-07-19T20:04:53.757Z
hotpaw2
<p>I would use more visual examples that target conceptual knowledge first. I would do a TON of memory diagrams with code tracing. Then, introduce the idea of pointers as memory addresses like you do in your example.</p>

<p>I am a big fan of <a href="http://cslibrary.stanford.edu/" rel="nofollow noreferrer">Nick Parlante's pointer materials</a>. I know they are vintage at this point, but I haven't found anything better at explaining pointers conceptually or at targeting common pointer errors like dereferencing pointers that don't point to anything (<em>seg fault!</em>). </p>

<h2>Binky Pointer Fun video</h2>

<p>This claymation video (<a href="http://cslibrary.stanford.edu/104/" rel="nofollow noreferrer">Original webpage</a>, <a href="https://www.youtube.com/watch?v=5VnDaHBi8dM" rel="nofollow noreferrer">YouTube version in C</a>) is hilarious and a crowd-pleaser, but also explains pointers conceptually---without talking about memory addresses explicitly. For that reason, it has versions in C, C++, Java, and more.</p>

<h2>Three Pointer Rules</h2>

<p>This is my version of Nick Parlante's Three Pointer Rules. Definitely see the <a href="http://cslibrary.stanford.edu/106/" rel="nofollow noreferrer">Pointer Basics document</a> for full details and the original rules.</p>

<p><strong>1) Drawing Pointers and Pointees</strong></p>

<p>Draw a pointer as a box. [C-specific modification] Before it points to anything, that box has a "?" in it. </p>

<pre><code>int *x;
</code></pre>

<p><a href="https://i.sstatic.net/7P5Oam.png" rel="nofollow noreferrer"><img src="https://i.sstatic.net/7P5Oam.png" alt="enter image description here"></a> </p>

<p>When you allocate memory (make a pointee), draw it in the heap. Setting that pointee equal to x makes an arrow go from the pointer to the pointee.</p>

<pre><code>x = malloc(sizeof(int));
</code></pre>

<p><a href="https://i.sstatic.net/rUMd9m.png" rel="nofollow noreferrer"><img src="https://i.sstatic.net/rUMd9m.png" alt="enter image description here"></a></p>

<p>Dereferencing changes the pointee---the thing the pointer points to (see next rule)</p>

<pre><code>*x = 42;
</code></pre>

<p><a href="https://i.sstatic.net/PKaOkm.png" rel="nofollow noreferrer"><img src="https://i.sstatic.net/PKaOkm.png" alt="enter image description here"></a></p>

<p><strong>2) Dereferencing</strong></p>

<p>The dereference operation starts at the pointer and <strong>follows</strong> its arrow
 over to access its pointee. <strong>Important: The dereference operation on a
 pointer only works if the pointer has a pointee</strong> -- the pointee must be
 allocated and the pointer must be set to point to it. You will save students so many seg faults if you emphasize this!</p>

<p><strong>3) Pointer Assignment</strong></p>

<p>Pointer assignment between two pointers makes them point to the same
 pointee. So the assignment y = x; makes y point to the same pointee as
 x.</p>

<h2>Connecting Pointer rules to code</h2>

<p>To drive it home, walk through code line-by-line while drawing diagrams. Have students work on their own code tracing and diagrams in groups. </p>

<p>Note that Nick Parlante emphasizes dynamically allocated memory in his code examples (<code>malloc</code>), and avoids the "address of" operator <code>&amp;</code> . I think this is a smart choice because it's what is most common in real code. But of course <code>&amp;</code> can be introduced in this method. </p>

<p>Here are some simple sample code snippets to start the walk-throughs and memory drawings:</p>

<pre><code>// non-pointer code
double num;
num = 42.7;
printf(num);

// pointer code
double* num_ptr;;
num_ptr = malloc(sizeof(double));
*num_ptr = 42.7;
printf(*num_ptr);

// Binky's code
int* x;
int* y;
x = malloc(sizeof(int));
*x = 42;
*y = 13; // yes it crashes, but that's the point &gt;:)
y = x;
*y = 13;
</code></pre>

CC BY-SA 3.0
2017-07-19T14:58:45.680Z
2017-07-19T16:47:21.757Z
2017-07-19T16:47:21.757Z
nova
<p>Obviously, beginners in C will have to deal with addresses and pointers really soon.</p>
<p>First, you owe them an explanation about <strong>addresses</strong> for</p>
<pre><code>int aNumber;
scanf (&quot;%d&quot;, &amp; aNumber);   // an address  
printf(&quot;%s&quot;,   aNumber);   // a value
</code></pre>
<p>which will appear in your first examples. So the &quot;address of&quot; operator is known from the start.</p>
<p>Second, <strong>pointers</strong> appear as soon as you define functions with parameters &quot;by reference&quot;.</p>
<p>Defining functions is a fundamental activity in programming. It is about giving names to pieces of code, thus introducing &quot;user defined abstractions&quot; to reduce the complexity of problems. And choosing them well so they can be reused. So the introduction of functions should come very quickly.</p>
<p>Third: historically arrays (in prehistoric C) were introduced after pointers. An array is (was) simply a pointer automatically initialized with the address of the first byte of an empty space automatically allocated on the call stack. Later in C it became a constant pointer (except in function parameters....). This poor conception explains why arrays in C have a strange status (you can't assign them like structures, for example - but when you pass them as arguments, you don't need the stinking &amp;) which is a difficulty for beginners.  Maybe the problem is with the arrays, not with pointers.</p>
<p>Four: As long as you use pointers for arguments transmission, you don't have any necessity to talk about dynamic allocation, which is an entirely different topic.  Except you use a pointer to store the result of malloc().</p>
<p>And last: another point is the data structures built from pointers (linked lists, trees,...) and the basic algorithms.</p>
<p>EDIT: as an answer to your question: in general I try to avoid artificial examples, because students don't see the link with their usual programming tasks. Function that modify their arguments are more natural: swapping/ordering things, modifying a struct, etc.</p>

CC BY-SA 4.0
2017-07-20T13:26:08.943Z
2021-03-17T05:56:39.660Z
2021-03-17T05:56:39.660Z
Michel Billaud
<p>Yours is a fine first lesson, although it does not show the value of pointers. I would suggest also demonstrating how pointers can be used to implement a swap function.</p>

<p>Ask the students (or step them through) what this code does:</p>

<pre><code>void swap(int x, int y) {
    int temp = x;
    x = y;
    y = temp;
}

int main() {
    int a = 1;
    int b = 2;
    printf("Before calling swap(): a = %d, b = %d\n", a, b);
    swap(a, b);
    printf("After calling swap(): a = %d, b = %d\n", a, b);
}
</code></pre>

<p>As you know, the local variables <code>a</code> and <code>b</code> do not get changed, because C uses call by value.</p>

<p>At that point, I show and discuss this cartoon:</p>

<p><a href="https://i.sstatic.net/HTC5n.gif" rel="nofollow noreferrer"><img src="https://i.sstatic.net/HTC5n.gif" alt="Cartoon in which doctor tells patient: &quot;Your x-ray shows a broken rib, but we fixed it with photoshop.&quot;"></a></p>

<p>(<a href="https://www.jantoo.com/cartoon/07634755" rel="nofollow noreferrer">This cartoon</a> might be too risqué.)</p>

<p>I then teach and step through the correct way to write and call a swap procedure:</p>

<pre><code>void swap(int *x, int *y) {
    int temp = *x;
    *x = *y;
    *y = temp;
}

int main() {
    int a = 1;
    int b = 2;
    printf("Before calling swap(): a = %d, b = %d\n", a, b);
    swap(&amp;a, &amp;b);
    printf("After calling swap(): a = %d, b = %d\n", a, b);
}
</code></pre>

<p>This provides a simple demonstration of the benefits of pointers and will help them understand why primitives (not counting pointers) are passed by value, while everything else appears to be passed by reference.</p>

CC BY-SA 3.0
2017-07-20T16:44:59.443Z
2017-07-20T16:44:59.443Z
Ellen Spertus
<p>Thanks to feedback in <a href="https://cseducators.stackexchange.com/questions/211/lesson-idea-arrays-pointers-and-syntactic-sugar">this thread</a>, I'm beginning to plan how to integrate a <strong>basic</strong> introduction to pointers into my unit on arrays. Here's a sample program I just wrote up:</p>

<pre><code>#include &lt;stdio.h&gt;

int main(void)
{
    int number = 42;
    printf("Value of number: %d\n", number);
    printf("Address of number: %p\n", &amp;number);

    int *pNumber = &amp;number;
    printf("Value of number pointer: %p\n", pNumber); 
    printf("Value at address of number pointer: %d\n", *pNumber);    
}
</code></pre>

<p>I will probably add comments before actually presenting it and making it available to students. Seeing how the address of <code>number</code> and the value of <code>pNumber</code> always correspond will hopefully reinforce how pointers work. The first and last line will match as well. The idea is to show as clear and simple an example as possible. </p>

<p>My question comes in two parts:</p>

<ol>
<li><p>Is this an appropriate example for introducing pointers?</p></li>
<li><p>Do you have suggestions for similar simple examples of basic pointer
usage?</p></li>
</ol>

<lesson-ideas><c><pointers><code-example>
Simple Pointer Examples in C
# Simple Pointer Examples in C

(Asked by: username_0 on 2017-05-30)

Thanks to feedback in this thread, I'm beginning to plan how to integrate a basic introduction to pointers into my unit on arrays. Here's a sample program I just wrote up:
#include 

int main(void)
{
    int number = 42;
    printf("Value of number: %d\n", number);
    printf("Address of number: %p\n", &number);

    int *pNumber = &number
    printf("Value of number pointer: %p\n", pNumber); 
    printf("Value at address of number pointer: %d\n", *pNumber);    
}

I will probably add comments before actually presenting it and making it available to students. Seeing how the address of number and the value of pNumber always correspond will hopefully reinforce how pointers work. The first and last line will match as well. The idea is to show as clear and simple an example as possible. 
My question comes in two parts:

Is this an appropriate example for introducing pointers?
Do you have suggestions for similar simple examples of basic pointer
usage?

**Tags:** lesson-ideas, c, pointers, code-example


---

## 5 answers

### Answer by username_6 on 2017-05-31. Score: 8

I would teach the use of arrays and array indices first (with pictures of a long row of physical mailboxes, or school lockers, etc.) Then later explain that all of a computer's and/or C program's (process) memory can be thought of as one big array with a pointer being a form of index (locker number) into that (virtual) memory array.

You can then draw a picture of how arrays of char (bytes) might be allocated in memory. And then show why pointers might be necessary in order to tell a standard string function how to find (or modify) a substring in an arbitrary C string array.

> **Comments:**
> **username_6**: An interesting question is whether memory is an example of a concrete array, or an array is an example of a concrete memory system (of capacitors, electron wells, magnets, sound waves, beads, knots, etc.)  

---

### Answer by username_1 on 2017-05-30. Score: 6

What you have there is an excellent start, and is completely appropriate.  I would go next into a puzzle to try to get them hooked.  I would type the following code in front of them on your projector, and ask them to pair with a neighbor to try to figure out what will happen next.
(Note, for this to work properly, you must turn off stack security in gcc, which according to this somewhat dated post might involve the flags -fno-stack-protector and -fno-stack-protector-all.)
#include 

int main() {
    int a = 15;
    int b = 30;
    int c = 45;

    int *whatsthis = &a
    printf("whatsthis is: %d\n",*whatsthis);

    whatsthis = whatsthis + 4;
    printf("whatsthis is: %d\n",*whatsthis);

    return 0;
}

(Depending on your compiler and environment, you may have to muck around with the code a bit to get 45 as your output for the second printf)
If your kids are like mine, they probably won't be able to figure this out.  But once you compile it and execute, ask them to go back to their neighbor and try to figure out what in the world happened.
At this point, several of the groups should be able to figure out that it has something to do with the ints being stored next to each other, and, if pressed just a bit, that the number 4 was derived using the byte size of an int.
This gives you a perfect segue into arrays.  Since you're taking all of this trouble to go into some depth (using references to get at arrays), I would try for a few takeaways from the lesson:

Pointer arithmetic means changing the address you're looking at.
The actual formula used to find the location of spot n in an array (which shows why that first address needs to be 0: (startlocation + (n * itemsize))
Therefore, indexing in arrays can be characterized as a distance from the start.
Array items are packed together with no wasted space and no separators between the data.
That, in fact, these are the only two tools that computers possess to locate themselves in memory: having items packed next to each other so that they can go from one item to the next, to the next, or saving pointers in memory so that we can go back to places later.  Every other thing that computers do with memory can be reduced to one of these two actions.

> **Comments:**
> **username_2**: @username_0 The code example is wrong, because the unit for pointer arithmetic is the size of the pointed-to type. whatsthis + 4 points 4 ints ahead of whatsthis (Or, rather, it would if whatsthis were pointing into an array large enough to do that. The code as written invokes undefined behavior.)  
> **username_0**: @EricMSchmidt I believe username_1 was aware of this when posting the example. Even the undefined behavior can be teachable for students to learn pointers (and the precautions that one must take with them). At least I think this was intentional...  
> **username_1**: Yes, the undefined behavior was the purpose of the exercise.  By arranging the demonstration so that the wrong variable gets modified, it should both pique their interest and give a great entrée to the idea of separating a memory address from the data it stores.  
> **username_3**: I don't get why you're adding 4 to go from *a* to *c* when they should be *two* addresses apart, and yet you say it's *four* bytes per int.  Where is *b*, then?  (Nevertheless, +1 for a great illustration.)  
> **username_1**: @username_3 I tried to clarify the text.  IIRC, on my compiler (I tested my code when I wrote this), ints were 2 byes.  
> **username_3**: Got it, thanks.  It wasn't the answer text that caused the confusion; it was your earlier comment: *"Mine used a 4-byte integer, which is also permitted."*  I understand now that was just a slip.  Thanks for clarifying!  :)  
> **username_4**: Uh, how can we know what the distance is between the two variables, at all? Couldn't they be anywhere in the address space, in any order?  
> **username_1**: @seaturtle gcc can disable stack protections: https://stackoverflow.com/q/2340259/4151129  
> **username_4**: Huh. I didn't know that was on _purpose_, I always figured that was just how it was, like file fragmentation on disk. Thanks. (:  
> **username_5**: I must say that I'm still very confused by this example. It's never explicitly stated here: What do you *expect* this code to print? I'll point out that on my current GCC compiler, if I add one or more printf statements *after* these lines, then the positions of a, b, c in memory get re-ordered -- and so I can get this same code to print out any of 30, 45, or 0 (i.e., anything). If your point is truly that this is undefined and might do anything, then what do you actually mean by "be able to figure this out" for the students in this context?  
> **username_1**: @DanielR.Collins With modern, stack-randomizing compilers, you are correct, and I will add a caveat to that effect.  Because of my schedule, I typically teach this as part of a computer security class on stack-based attacks, and we purposefully use dated virtual machines without stack randomization for exactly the reason you cite.  I wasn't thinking about that when I wrote the answer, though.  Oops!  
> **username_5**: @BenI.: Is that really a stack-randomizing issue, though? With my current stock copy of GCC, the ordering is fixed/deterministic with any particular piece of code. However, there are some complicated rules which are opaque to predict. For example, if I make 4 int variables and print any or all values, then GCC puts them in declaration order. But if I print out the address of one of them, then GCC puts that one in the top slot on the stack. Etc.  
> **username_5**: Perhaps you should put more detail/a link with the "you must turn off stack randomization in gcc" piece, because my other searches for that aren't getting hits.  
> **username_1**: @DanielR.Collins I edited the post again!  I'm not aware of all of the protections used for stacks, tbh.  Like I said, I do this on old virtual machines that have no stack protections built into GCC at all for exactly these pedagogic demonstration purposes, so there may be fine distinctions that I am missing here in more modern setups.  
> **username_5**: @BenI.: Probably good that you removed the word "randomization" there. Unfortunately I'm still skeptical that the current detail is correct. (a) "-fno-stack-protector-all" isn't a valid GCC flag (see comments to what you linked for that). (b) I don't think there's any sign that these buffer protections involve re-ordering the stack (I just tested and see no difference)...  
> **username_5**: Note that any time a question gets asked about GCC stack ordering in particular, the answers usually are some form of "there is absolutely no way to tell or control it without looking into the GCC code about how it makes its choices". E.g.: https://stackoverflow.com/questions/66793187/why-does-gcc-order-integers-on-the-stack-in-this-way  

---

### Answer by username_7 on 2017-07-19. Score: 4

I would use more visual examples that target conceptual knowledge first. I would do a TON of memory diagrams with code tracing. Then, introduce the idea of pointers as memory addresses like you do in your example.
I am a big fan of Nick Parlante's pointer materials. I know they are vintage at this point, but I haven't found anything better at explaining pointers conceptually or at targeting common pointer errors like dereferencing pointers that don't point to anything (seg fault!). 
Binky Pointer Fun video
This claymation video (Original webpage, YouTube version in C) is hilarious and a crowd-pleaser, but also explains pointers conceptually---without talking about memory addresses explicitly. For that reason, it has versions in C, C++, Java, and more.
Three Pointer Rules
This is my version of Nick Parlante's Three Pointer Rules. Definitely see the Pointer Basics document for full details and the original rules.
1) Drawing Pointers and Pointees
Draw a pointer as a box. [C-specific modification] Before it points to anything, that box has a "?" in it. 
int *x;

 
When you allocate memory (make a pointee), draw it in the heap. Setting that pointee equal to x makes an arrow go from the pointer to the pointee.
x = malloc(sizeof(int));


Dereferencing changes the pointee---the thing the pointer points to (see next rule)
*x = 42;


2) Dereferencing
The dereference operation starts at the pointer and follows its arrow
 over to access its pointee. Important: The dereference operation on a
 pointer only works if the pointer has a pointee -- the pointee must be
 allocated and the pointer must be set to point to it. You will save students so many seg faults if you emphasize this!
3) Pointer Assignment
Pointer assignment between two pointers makes them point to the same
 pointee. So the assignment y = x; makes y point to the same pointee as
 x.
Connecting Pointer rules to code
To drive it home, walk through code line-by-line while drawing diagrams. Have students work on their own code tracing and diagrams in groups. 
Note that Nick Parlante emphasizes dynamically allocated memory in his code examples (malloc), and avoids the "address of" operator & . I think this is a smart choice because it's what is most common in real code. But of course & can be introduced in this method. 
Here are some simple sample code snippets to start the walk-throughs and memory drawings:
// non-pointer code
double num;
num = 42.7;
printf(num);

// pointer code
double* num_ptr;;
num_ptr = malloc(sizeof(double));
*num_ptr = 42.7;
printf(*num_ptr);

// Binky's code
int* x;
int* y;
x = malloc(sizeof(int));
*x = 42;
*y = 13; // yes it crashes, but that's the point >:)
y = x;
*y = 13;


---

### Answer by username_8 on 2017-07-20. Score: 4

Obviously, beginners in C will have to deal with addresses and pointers really soon.
First, you owe them an explanation about addresses for
int aNumber;
scanf ("%d", & aNumber);   // an address  
printf("%s",   aNumber);   // a value

which will appear in your first examples. So the "address of" operator is known from the start.
Second, pointers appear as soon as you define functions with parameters "by reference".
Defining functions is a fundamental activity in programming. It is about giving names to pieces of code, thus introducing "user defined abstractions" to reduce the complexity of problems. And choosing them well so they can be reused. So the introduction of functions should come very quickly.
Third: historically arrays (in prehistoric C) were introduced after pointers. An array is (was) simply a pointer automatically initialized with the address of the first byte of an empty space automatically allocated on the call stack. Later in C it became a constant pointer (except in function parameters....). This poor conception explains why arrays in C have a strange status (you can't assign them like structures, for example - but when you pass them as arguments, you don't need the stinking &) which is a difficulty for beginners.  Maybe the problem is with the arrays, not with pointers.
Four: As long as you use pointers for arguments transmission, you don't have any necessity to talk about dynamic allocation, which is an entirely different topic.  Except you use a pointer to store the result of malloc().
And last: another point is the data structures built from pointers (linked lists, trees,...) and the basic algorithms.
EDIT: as an answer to your question: in general I try to avoid artificial examples, because students don't see the link with their usual programming tasks. Function that modify their arguments are more natural: swapping/ordering things, modifying a struct, etc.


---

### Answer by username_9 on 2017-07-20. Score: 4

Yours is a fine first lesson, although it does not show the value of pointers. I would suggest also demonstrating how pointers can be used to implement a swap function.
Ask the students (or step them through) what this code does:
void swap(int x, int y) {
    int temp = x;
    x = y;
    y = temp;
}

int main() {
    int a = 1;
    int b = 2;
    printf("Before calling swap(): a = %d, b = %d\n", a, b);
    swap(a, b);
    printf("After calling swap(): a = %d, b = %d\n", a, b);
}

As you know, the local variables a and b do not get changed, because C uses call by value.
At that point, I show and discuss this cartoon:

(This cartoon might be too risqué.)
I then teach and step through the correct way to write and call a swap procedure:
void swap(int *x, int *y) {
    int temp = *x;
    *x = *y;
    *y = temp;
}

int main() {
    int a = 1;
    int b = 2;
    printf("Before calling swap(): a = %d, b = %d\n", a, b);
    swap(&a, &b);
    printf("After calling swap(): a = %d, b = %d\n", a, b);
}

This provides a simple demonstration of the benefits of pointers and will help them understand why primitives (not counting pointers) are passed by value, while everything else appears to be passed by reference.


---

