Pointers in C programming language
Pointers have huge value in C programming language. They allow many things that would be impossible to do without pointers. More modern languages hide pointers from the users and implements the pointers functionality with more high-level constructs.
Memory and variables in programming languages
When we work with variables, we work with memory of the computer. First of all - random access memory (RAM). There are other types of memory: long-term memory (hard drives) and processor memory (registers, cache).
When our program is started, operating system reserves memory for us. Memory consists of bytes. Program can have access to any byte as each byte has address. That's very simplified model of memory, but it's sufficient for us now.
Address is just a number. As byte is a tiny amount of memory and in modern computer there are billions of bytes (gigabytes) - addresses are very large numbers. For convenience addresses are written in hexadecimal system. Here is example of real address: 0x7fffb19c0cc4. 0x at the beginning tells that this number is hexadecimal. Now let's examine the example in which we'll see how C language code corresponds to memory. For this we need small chunk of memory:
0x7fffb19c0cc0 0x7fffb19c0cc1 0x7fffb19c0cc2 0x7fffb19c0cc3 0x7fffb19c0cc4 0x7fffb19c0cc5 0x7fffb19c0cc6 0x7fffb19c0cc7 0x7fffb19c0cc8 0x7fffb19c0cc9 0x7fffb19c0cca
Here is 9 bytes. When our program starts, these bytes may contain anything - empty space (zeroes), chunks of memory from another program (finished). Now let's create some variables in C code:
int a; int b = 10; short c = 1; char d = 'a';
Executing these statements one by one C program reserves memory for each variable. In real life these variables can be in different parts of memory, but we need to understand the principle:
0x7fffb19c0cc0 // here starts a 0x7fffb19c0cc1 // these bytes can contain anything 0x7fffb19c0cc2 // as a is not initialized 0x7fffb19c0cc3 // a variable ends here 0x7fffb19c0cc4 // b variable 0x7fffb19c0cc5 // it contains value 10 0x7fffb19c0cc6 0x7fffb19c0cc7 // b ends 0x7fffb19c0cc8 // c starts 0x7fffb19c0cc9 // c ends 0x7fffb19c0cca // d uses one byte and contains 97
Here we can see how variables maps to memory. Integer variables take 4 bytes, short - 2 bytes and char - 1 byte. As I mentioned earlier characters are stored as number internally. Letter 'a' has value 97.
Now we are ready to understand what is the pointer in C.
Pointer in C language
Contrary to variables, pointer contain address. We can have variable and we can have pointer to that variable. Let's create it:
int a = 1; int* p = &a;
Here we created pointer p to type int. Asterisk indicates that this is pointer. C language use asterisk for three different operators. First is multiplication, second is used with pointers and third, dereference, we'll discuss below. What asterisk means in specific situation depends on context. For pointers asterisk can be written different ways:
int a = 1; int* p1 = &a; int *p2 = &a;
Both pointers are valid. I prefer to write the asterisk right after the type name as it seems for me more natural as it's said: "pointer to type...".
Getting the address of variable
& is a special operator that takes address of operator. It allows to store the address of operator in pointer. We can print the address as any other value. printf has format specifier for pointers - %p:
int a = 1; printf("%p", &a);
Second line will print the address of variable a
Dereferencing the pointer in C language
As you can see we can get the address of variable. There is the opposite operation on pointer - we can get the value from pointer. It's called dereference. To get the value from pointer, put asterisk before it:
int a = 1; int* p = &a; int b = *p; printf("%i\n", b);
The last line will print 1.
Pointers is very important part of C language. In next tutorials we'll see how they used with different features of C.