80 likes | 101 Views
Module 2-3: Passing pointers. PASS BY VALUE (CASE 1) – Pass a simple variable by value. %p is the code for printing a Hexadecimal integer with a ‘0x’ prefix added. We need this as we are printing the ‘address of I ’ (& I ). #include <stdio.h> #include <stdlib.h> void FOO(int I) {
E N D
PASS BY VALUE (CASE 1) – Pass a simple variable by value. %p is the code for printing a Hexadecimal integer with a ‘0x’ prefix added. We need this as we are printing the ‘address of I’ (&I). #include <stdio.h> #include <stdlib.h> void FOO(int I) { printf("FOO: %d %p\n", I, &I); I = 42; printf("FOO: %d %p\n", I, &I); } int main(void) { int I; I = 55; printf("MAIN: %d %p\n", I, &I); FOO(I); printf("MAIN: %d %p\n", I, &I); return 0; } FOO: 55 0xb3e9b8dc FOO: 420xb3e9b8dc MAIN: 55 0xb3e9b904 MAIN: 55 0xb3e9b904 The address of I in FOO is different from the address of I in main. This tells us that the I in FOO is a copy of the I in main. Note how the change to I (I=42) in FOO is not returned to main where I is still 55. Note we are printing the value of I and the address of I.
PASS BY VALUE (CASE 2) - Pass a variable(referenced by a pointer) by value. #include <stdio.h> #include <stdlib.h> void FOO(int I) { printf("FOO: %d %p\n", I, &I); I = 42; printf("FOO: %d %p\n", I, &I); } int main(void) { int *I; I = (int*)calloc(1, sizeof(int)); *I = 99; printf("MAIN: %d %p\n", *I, &(*I)); printf("MAIN: %d %p\n", *I, I); FOO(*I); printf("MAIN: %d %p\n", *I, I); return 0; } FOO: 99 0xb3e9b8dc FOO: 42 0xb3e9b8dc MAIN: 99 0xae2010 MAIN: 99 0xae2010 MAIN: 99 0xae2010 The address of I in FOO is different from the address of I in main. This tells us that the I in FOO is a copy of the I in main. Note how the change to I (I=42) in FOO is not returned to main where I is still 99. Note that I is a pointer. Note that I and &(*I) do the same thing. Dereferencing I to get its value.
PASS BY REFERENCE (CASE 1) –Pass a simple variable by reference. #include <stdio.h> #include <stdlib.h> void BAR(int *I) { printf("BAR: %d %p\n", *I, &(*I)); *I = 42; printf("BAR: %d %p\n", *I, &(*I)); } int main(void) { int I; I = 55; printf("MAIN: %d %p\n", I, &I); BAR(&I); printf("MAIN: %d %p\n", I, &I); printf("\n"); return 0; } BAR: 55 0xb3e9b904 BAR: 420xb3e9b904 MAIN: 55 0xb3e9b904 MAIN: 42 0xb3e9b904 The address of I in BAR and I in main is the same. This tells us that they are in fact the same variable (refer to the same memory location). Note how the change to I (I=42) in BAR is returned to main. The address of I.
PASS BY REFERENCE (CASE 2) –Pass a variable (referenced by a pointer) by reference. #include <stdio.h> #include <stdlib.h> void BAR(int *I) { printf("BAR: %d %p\n", *I, &(*I)); *I = 42; printf("BAR: %d %p\n", *I, &(*I)); } int main(void) { int *I; I = (int*)calloc(1, sizeof(int)); *I = 99; printf("MAIN: %d %p\n", *I, I); BAR(I); printf("MAIN: %d %p\n", *I, I); printf("\n"); return 0; } BAR: 99 0xae2010 BAR: 420xae2010 MAIN: 99 0xae2010 MAIN: 42 0xae2010 The address of I in BAR and I in main is the same. This tells us that they are in fact the same variable (refer to the same memory location). Note how the change to I (I=42) in BAR is returned to main. Note that I is a pointer. Since I is a pointer, the name of the pointer gives us the address of the pointer.
PASS BY REFERENCE (CASE 3) – Pass a pointer (referenced by a pointer) by reference. We need to make sure the compiler understands that we do not want a 2-d array (**), so we use the notation *(*) to force the compiler to understand this is a pointer passed by reference. #include <stdio.h> #include <stdlib.h> void FOOBAR(int *(*I)) { printf("FOOBAR: %d %p\n", *(*I), *I); *I = (int*)calloc(1, sizeof(int)); *(*I) = 42; printf("FOOBAR: %d %p\n", *(*I), *I); } int main(void) { int *I; I = (int*)calloc(1, sizeof(int)); *I = 99; printf("MAIN: %d %p\n", *I, I); FOOBAR(&I); printf("MAIN: %d %p\n", *I, I); return 0; } FOOBAR: 99 0xae2030 FOOBAR: 420xae2050 MAIN: 99 0xae2030 MAIN: 420xae2050 The address of I in FOOBAR and I in main is the same. This tells us that they are in fact the same variable (refer to the same memory location). Note that I is a NEW pointer. Note how the change to I (I=42) in FOOBAR is returned to main. Note how the address of I in FOOBAR and main are now different! Note that I is a pointer. Note that the original address that I pointer to is now lost (dangling pointer) – not good!
REVIEW PASSING ------- // Simple variable. int main(void) { int i; i = 55; FOO(i); // By value BAR(&i); // By reference } // Simple pointer variable. int main(void) { int *j; j = (int*)calloc(1, sizeof(int)); *j = 100; FOO(*j); // By value BAR(&(*j)); // By reference BAR(j); // By reference } RECEIVING --------- // By value. void FOO(int I) { I = 42; printf("FOO: %d\n", I); } // By reference. void BAR(int *I) { *I = 42; printf("BAR: %d\n", *I); } Note the receiving end is usually the same regardless if a pointer or simple variable is being passed to the function. PASSING ------- // Pointer by reference. int main(void) { int *k; k = (int*)calloc(1, sizeof(int)); *k = 999; FOOBAR(&k); // Address by reference } RECEIVING --------- // Pointer by reference. void FOOBAR(int *(*I)) { *I = (int*)calloc(1, sizeof(int)); *(*I) = 42; printf("FOOBAR: %d\n", *(*I)); }