Fundamental C - Starting Pointers |
Written by Harry Fairhead | ||||
Monday, 15 June 2020 | ||||
Page 1 of 3 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 MachineNow available as a paperback and ebook from Amazon.
Also see the companion volume: Applying C <ASIN:1871962609> <ASIN:1871962463> <ASIN:1871962617> <ASIN:1871962455>
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 OperatorYou 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. 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 ) |