C Programming/Pointers
Objective[edit | edit source]This lecture will give you knowledge on:
|
Lesson[edit | edit source]Pass by value vs Pass by reference; why we need to use pointer ?[edit | edit source]In this example, we want the function #include <stdio.h>
int add (int number);
main () {
int number = 6;
add(number);
printf("%d \n", number);//6
printf("add(number): %d \n", add(number));//add(number): 7
}
int add(int number){
number = number + 1;
return number;
}
From the result, we can see that variable The operation above is called pass-by value. What is sent to the function For function In both C and C++, a reference is defined as a value to stores the address of an object, e.g a variable, function, class object,... that is located elsewhere in memory.[1] Pointers are the most primitive type of reference. The parameter to a function can be a copy of a value that is represented by a variable, which is known as pass-by value, or can be a reference to a memory space that stores value of variable, which is known as pass-by reference. What is pointer ?[edit | edit source]A pointer is a variable holding a specific memory location. Most often, this memory location is that of a variable or array and it can also be the location of a function. Pointers refer to memory addresses, as opposed to specific values. They are denoted by the use of an asterisk (*). Consider the following piece of code: int i = 1;
int *k = &i;
int m = i;
printf("i (%p): %d\n", &i, i);
printf("k (%p): %d\n", k, *k);
printf("m (%p): %d\n\n", &m, m);
i++;
printf("i (%p): %d\n", &i, i);
printf("k (%p): %d\n", k, *k);
printf("m (%p): %d\n", &m, m);
/* OUTPUT
i (0x7fff62b5fa54): 1
k (0x7fff62b5fa54): 1
m (0x7fff62b5fa50): 1
i (0x7fff62b5fa54): 2
k (0x7fff62b5fa54): 2
m (0x7fff62b5fa50): 1
*/
In this code, In the brackets can also be seen the memory address of the variable, which shows that
Back to the introduction example, when we want a function to be able to change the value of a variable as parameter passed to this function. With the knowledge of pointers and pass-by reference, we have the solutions for that: Using pass-by reference #include <stdio.h>
int add (int *number);
main () {
int number = 6;
add(&number);
printf("%d", number);//7
}
int add(int *number){
*number = *number + 1;
return *number;
}
Assign pointer to the variable #include <stdio.h>
int number = 9;
int *pointer = &number;
int add(int *number);
main () {
add(pointer);
printf("%d", number); //10
}
int add(int *number){
*number = *number + 1;
return *number;
}
Pointers as array iterators[edit | edit source]When pointers are learned, we can use then for manipulating arrays effectively. Note that due to alignment, an array will require a memory alignment equal to the Pointers can be incremented, which makes them a natural choice for iterating an array. Consider the following piece of code: int a[5] = {0,2,5,8,11};
int *ptr = &a[0];
for (int i = 0; i < 5; i++) {
printf("%p: %d\n", ptr, *ptr);
ptr++;
}
/* OUTPUT
0x7fff645ffa40: 0
0x7fff645ffa44: 2
0x7fff645ffa48: 5
0x7fff645ffa4c: 8
0x7fff645ffa50: 11
*/
Accessing address Also note that arrays are always allocated with offset going upwards in RAM locations, your stack doesn't need to grow upwards for this. Must not set value at an arbitrary memory location[edit | edit source]Based on the pointer concept, a pointer stores the value of another variable so directly setting the value for its dereferencing is a useless act and results in Segmentation fault // THIS IS A WRONG IMPLEMENTATION AND IS ONLY USED FOR EDUCATIONAL PURPOSE. MUST NOT PRACTICE THIS IN REAL-LIFE APPLICATIONS
int *p = 9;//Segmentation fault
Modern computer systems use virtual memory techniques so that physical register addresses can't be set arbitrarily.[2] The following example is to arbitrarily setting value at a specific register address is the wrong implementation and must not be done in real-life applications: // THIS IS A WRONG IMPLEMENTATION AND IS ONLY USED FOR EDUCATIONAL PURPOSE. MUST NOT PRACTICE THIS IN REAL-LIFE APPLICATIONS
// The target of this example is to set the value at register address 6295624
#include <stdio.h>
int *ptr;
int main()
{
ptr = (int *)6295624;
*ptr = 12;//Segmentation fault
return 0;
}
To work with the program above with an address like ``6295624``, the address ``6295624`` must be the GCC allowable address. User must find the allowable address first with ``&`` for a dummy variable. E.g: int dummy_variable;
printf("%d", &pdummy_variable);//print out the address of dummy_variable first to find the allowable address
Function Pointers[edit | edit source]Before we start with function pointers, it's worth mentioning that functions do have address: void displayString(){
printf("Hello, World !\n");
}
int main(int argc, char *argv[]) {
printf("%d\n", displayString);//0x7fed62b5fa54, displayString has same value with &displayString
printf("%d\n", &displayString);//0x7fed62b5fa54, &displayString has same value with displayString
}
In addition to other ways that pointers can be used, they can also reference a function. While this may not seem very useful at first, it can be used to either embed a function in to a struct that uses it exclusively, or to allow a function to return a function or use a function as input to another function. This is a very complex sub-topic and can create a lot of bugs in your program if poorly implemented. |
Assignments[edit | edit source]Linked Lists[edit | edit source]A linked list is a list of data, comprised of nodes which specify their data, and the address of the next node, or NULL to specify the last node. We will use our knowledge on pointer to build a linked list. Consider the following code: #include <stdio.h>
#include <stdlib.h>
struct Node {
int data;
struct Node * next;
};
int main() {
struct Node * head = malloc(sizeof(struct Node));
head->data = 0;
struct Node * curr = head;
for (int i = 1; i < 5; i++) {
struct Node * new = malloc(sizeof(struct Node));
new->data = 5*i;
curr->next = new;
curr = curr->next;
}
curr = head;
while (curr != NULL) {
printf("%d\n", curr->data);
curr = curr->next;
}
return 0;
}
In this code, we defined a A linked list is a good visualisation of pointers, but is also an effective data type for Last in First Out structures, such as stacks. Adding to a linked list is simply a matter of creating a new node, and setting its
|
|
Reference
[edit | edit source]- ↑ "References (C++)". learn.microsoft.com. Retrieved 2024-01-07.
- ↑ "Why does setting a value at an arbitrary memory location not work?". stackoverflow. Retrieved 2024-01-07.