<< Prev Next >>
What are pointers
For most new programmers, one of the most confusing things is pointers. It actually is a very simple concept. Let's look at an analogy: email addresses. Your email address is unique, which means no other one has the same email address. This also means emails sent to that email address will be correctly delivered with no confusion. Well, a pointer is also an address, but an address to main memory (RAM).
Main memory is a set of cells where each one has a unique address, represented by a number. Memory addresses (also called "pointers") start at 0 and go as high as the hardware allows. For example in x86-32, maximum memory allowed is 4 GiB, which means the highest memory address is 4,294,967,295 (2^32 - 1 ). Pointers (which are memory addresses, yes I know this is boring, but this must be incrusted in your mind) are usually represented using hexadecimal notation. I want to stress that hexadecimal are not different numbers from decimal or binary. All of them are the same numbers. It's only the way we represent the value that changes. So the previous highest memory address in x86-32 architecture would be written like 0xFFFFFFFF in hexadecimal (the leading 0x is just to denote that the following number is written in hexadecimal).
In previous lesson we already used pointers. Character strings are actually pointers. Let's check this:
Code: Select all
#include <stdio.h>
int main()
{
char* example = "Hello my friend!\n";
printf("%d, %x\n", example, example);
return 0;
}Code: Select all
4206692, 403064Ok so now we're going to do a nasty trick. We're going to assign this address to another pointer and print the contents. Of course this will print the "Hello my friend!\n" string because it's the data that resides at that address (remember an address is unique).
Code: Select all
#include <stdio.h>
int main()
{
char* example = "Hello my friend!\n";
printf("%d, %x\n", example, example);
char* example2 = 0x403064;
printf("%s\n", example2);
return 0;
}This shows:
Code: Select all
4206692, 403064
Hello my friend!Code: Select all
#include <stdio.h>
int main()
{
char* example = "Hello my friend!\n";
printf("%s\n", example);
char* example2 = example + 6;
printf("%s\n", example2);
return 0;
}We can specify a pointer to anything that resides in main memory, namely any data or even code. To do so, we use the * modifier, just like we used it in char*. In the following code, I will use a pointer to int data type, and also show other modifiers to work with pointers.
Code: Select all
#include <stdio.h>
int main()
{
int *a; // Pointer to int
int b = 2251;
a = &b; // Assigning to a the address of b
printf("%d\n", *a); // Printing the value pointed by a
return 0;
}Ok, but how do we make space (a.k.a. reserve memory) for our variables? Here comes malloc() and friends. malloc() stands for memory allocation. This system call is standard and allows us to reserve memory for our use. Since this is dynamic memory allocation (done during runtime and not during compile-time) we must also take care of freeing this memory using free(). Here's an example:
Code: Select all
#include <stdio.h>
#include <stdlib.h>
int main()
{
int *a = (int*) malloc(sizeof(int)); // Allocating sizeof(int) bytes of space
int b = 2251;
*a = b; // Copying content of b to a
printf("%d\n", *a);
free(a); // Free a's reserved memory
return 0;
}Code: Select all
#include <stdio.h>
int main()
{
// We have a string
char* string = "This is a pointer use example";
printf("String at memory address: 0x%08X -> '%s'\n", (unsigned int)string, string);
// Now let's have 2 different pointer types point to it as well
char* p1 = string;
int* p2 = (int*) string;
// We increment a char pointer -> incremented by sizeof(char) = 1 byte
p1++;
printf("p1 = 0x%08X, points at: '%s'\n", (unsigned int)p1, p1);
// We increment an int pointer -> incremented by sizeof(int) = 4 bytes (x86)
p2++;
printf("p2 = 0x%08X, points at: '%s'\n", (unsigned int)p2, (char*)p2);
return 0;
}Array decay convention
In C, arrays can "decay" into pointers and viceversa, which means that arrays are equivalent to pointers. Thus for example char[] is the equivalent of char*. Example:
Code: Select all
#include <stdio.h>
int main()
{
char *string = "This is a pointer use example";
printf("%s\n", string);
printf("%c, %c\n", string[1], string[5]); // Print second and sixth character
return 0;
}- Using only pointers: declare an array of signed integers and assing it a size of 50 integers.
- Same as the last exercise but also assign positions 5, 6, and 8, and then print them.
- Using only pointers: given a random string, print from the 5th character onwards.
- Given 2 strings of length 5, encrypt the first one using the second one using an XOR operation.
EDIT2: changed the exercises since we haven't seen flow control yet
<< Prev Next >>


