Fundamental C - Starting Pointers
Written by Harry Fairhead   
Monday, 15 June 2020
Article Index
Fundamental C - Starting Pointers
Address Operator
Arrays As Pointers

This extract, from my book on programming C in an IoT context, goes deeper into pointers. A topic that can be expanded on almost forever, but we have to start somewhere.

Fundamental C: Getting Closer To The Machine

Now available as a paperback and ebook from Amazon.

  1. About C
      Extract Dependent v Independent
                  & Undefined Behavio
  2. Getting Started With C Using NetBeans
  3. Control Structures and Data
  4. Variables
      Extract Variables
  5. Arithmetic  and Representation
      Extract Arithmetic and Representation
  6. Operators and Expression
      Extract: Expressions
      Extract Side Effects, Sequence Points And Lazy Evaluation
      First Draft of Chapter: Low Down Data
  7. Functions Scope and Lifetime
  8. Arrays
      Extract  Simple Arrays
      Extract  Ennumerations
  9. Strings
      Extract  Simple Strings
     
    Extract: String I/O ***NEW!!
  10. Pointers
      Extract  Starting Pointers
      Extract  Pointers, Cast & Type Punning
  11. Structs
      Extract Basic Structs
      Extract Typedef
  12. Bit Manipulation
      Extract Basic Bits
      Extract Shifts And Rotates 
  13. Files
     Extract Files
     
    Extract Random Access Files 
  14. Compiling C – Preprocessor, Compiler, Linker
     Extract Compilation & Preprocessor

Also see the companion volume: Applying C

<ASIN:1871962609>

<ASIN:1871962463>

<ASIN:1871962617>

<ASIN:1871962455>

 

Cbookcover

Pointers are the construct that makes C so useful for low-level and system programming. They allow you to do things that high-level languages usually forbid or make difficult. In a sense it is the pointer that allows you to use C rather than have to resort to a machine-specific assembler. Of course, with such power comes great responsibility to not crash your program, or indeed the entire machine. It is probably the pointer and its incorrect, or careless, use that causes C to be thought of as a “dangerous” language.

In this chapter we look at the C pointer and how it relates to C’s memory model.

Declaring a Pointer – The Dereference Operator

You have probably been using variables ever since you learned to program and you probably think of them as some sort of “box” that a value can be stored in. That is, when you write:

int myVar=123;

you think of myVar as in some sense “containing” or storing the value 123.
In fact what is happening is the int type declaration causes the compiler to allocate two (or more) bytes and store the binary equivalent of 123 in it. From this point on the label myVar is a synonym for the address of the allocated memory location – as explained in Chapter 4 a variable is a constant pointer.

This is a subtle shift in understanding. No storage is allocated to store the address of the variable, it is just inserted into the machine code as part of the instruction. When you write:

int myVar;
myVar=0;

the compiler issues the assembler:

main+14: movl   $0x0,0xc(%esp)

This moves a value of zero into memory at 0xC relative to the current stack frame. You can see that myVar is replaced though out the program by the use of memory location 0xC in the stack frame.

Standard variables do for most things, but occasionally you need to refer to a memory location that changes during the course of the program. For this you need a pointer.

A pointer is a variable that stores the address of a memory location and it differs from a variable in that some storage is allocated to store the address.

In C you use the * or the dereference operator to indicate that a variable is a pointer.

For example:

int *myPointer;

declares myPointer as a pointer to int. Notice that no int is created by this declaration. What is created is an area of memory that can store the address of an int, and myPointer is a label that gives the address of this area. That is, myPointer is a variable that stores the address of an int.

This implies that all pointers take the same amount of memory irrespective of what they point at, as an address nearly always occupies the same number of bits.

Why then do we have to state that myPointer is a pointer to int and not something else?

After all, myPointer is just going to store an address and all addresses are the same sort of thing and occupy the same storage space. The reason is that the compiler needs to know what to do with the memory that the pointer points at.

To be more precise, the dereference operator accesses that memory that the pointer points at. That is:

myPointer

is a pointer to int and:

*myPointer 

is the actual int that myPointer points at.

Once you have dereferenced a pointer you can use it as if it was the type that is the target of the pointer.

For example:

*myPointer=42;

stores 42 as an int in the memory location addressed by myPointer.

Before you rush away to try it out – this doesn’t work because myPointer, as far as we have defined it, may be a pointer but it doesn’t actually point at any usable memory. Declaring a pointer creates an uninitialized pointer just like declaring any variable declares an uninitialized variable.

So how can we initialize a pointer?



Last Updated ( Monday, 15 June 2020 )