Background
When a program is executed on your computer, it needs a certain amount of data to be stored at any specific point in time.
We humans know this as computer memory. For the sake of this course, we are going to simplify it in terms of lockers; the same lockers that you see at your local gym or at your physical campus.
Lockers have the following properties:
- They are identified by a unique address.
- They store a certain data type.
Locker addresses are, at the most basic level, just another 8-byte integer data type. Do you recall this chart from Week 1? Now, we add another row!
Data Type | Defination | Memory | Value Range (AMD x64) |
---|---|---|---|
long | integer | 8 bytes | 18,446,744,073,709,551,615 |
address | integer | 8 bytes | 18,446,744,073,709,551,615 |
Data Type Declarations
Addresses, like char
, int
, and long
, are simply just another data type! Nothing has changed.
1
2
3
4
5
6
7
8
9
int main()
{
int* a;
char* b;
double* c;
double** d;
return 0;
}
An address data type, or pointer, is denoted by the *
notation. To differentiate the type of data stored at that specific address, we look at the prefix before the *
.
For instance, int* a
is the address of a locker that stores an int
data type.
For instance, double** d
is the address of a locker that stores a double*
data type.
The C Programming Language
C
is a very low level programming language. It allows our programs to freely access its memory space.
For example, I can ask my Operating System: Hey, can you go to locker X and either get or update it's contents?
1
2
3
4
5
6
7
int main()
{
int *locker = (int *)12345L;
int value = *locker;
printf("value=%d\n", value);
return 0;
}
Me > Hey, can you go to locker 12345 and get it's contents?
Operating System > Okay!
Memory Address of Variables
But wait, hold up. Why would I ever want to see what’s inside Locker 12345
? And you’re totally right! We wouldn’t. Locker 12345
is just a random locker in the middle of no-where that has absolutely no relevance to our code. So in practice, how can we apply this concept to real world scenarios?
It will be helpful to know the locker address of where our variables are stored.
1
2
3
4
5
6
7
int main()
{
int value = 12345;
int *address = &value;
printf("addr=%d\n", (int)address);
return 0;
}
addr=6422296
Here comes a plot twist. Array variables are actually just a memory address!
1
2
3
4
5
6
7
8
int main()
{
int arr[5] = {1, 2, 3, 4, 5};
int *head_addr_a = arr;
int *head_addr_b = &arr[0];
printf("%d %d\n", head_addr_a, head_addr_b);
return 0;
}
6422276 6422276
When the main()
function is called, 5
lockers that stores an int
are given to the variable arr
. These 5
lockers are sequential. This means that 0th
locker is at address arr
while the ith
locker is at address arr + i
.
1
2
3
4
5
6
int main()
{
int arr[5] = {1, 2, 3, 4, 5};
printf("%d %d\n", *arr, *(arr + 4));
return 0;
}
1 5
The locked with the name value
is located at address 6422296
and can store an int
data type.
The takeaway here is that arr
, while it is an array of int
, is also a int*
int address that stores the address of the 0th
element of the array.