#include<stdio.h> int main() { /* variables have rvalues and lvalues! * * "rvalue": value for right hand side of * side of an assignment * "lvalue": value for left hand side of * side of an assignemnt * * lvalue: memory address of the variable * rvalue: contents of that address */ int x; x = 6; printf("lvalue of x:\t %d\n",&x); printf("rvalue of x:\t %d\n",x); } #include<stdio.h> int main() { /* rvalues and lvalues are of different types: * type of rvalue of x: T * type of lvalue of x: *T * (read: pointer to T) */ int x; int* ptr; /* variable to hold lvalue of x */ ptr = &x; x = 6; printf("rvalue of x:\t %d\n",x); printf("lvalue of x:\t %d\n",&x); printf("rvalue of ptr:\t %d\n",ptr); /* question: what's the type of lvalue of ptr? */ printf("lvalue of ptr:\t %d\n",&ptr); } #include<stdio.h> int main() { /* given an lvalue, we want to retrieve * the corresponding rvalue. * The process is called dereferencing */ int x; int* ptr; ptr = &x; x = 6; /* `*' operator returns rvalue corresponding * to an lvalue, i.e. the contents of that * memory address ptr */ printf("x:\t%d\n", x); printf("*ptr:\t%d\n", *ptr); printf("ptr:\t%d\n", ptr); } #include<stdio.h> int main() { int x; int* ptr; ptr = &x; /* We've two ways of accessing the rvalue of x: * via x or * via ptr */ x = 6; (*ptr)++; printf("x:\t%d\n", x); printf("ptr:\t%d\n", *ptr); } #include<stdio.h> int main() { int x; int y; int* ptr; /* we can point the pointer to any * memory location. That's potentially * dangerous... why? */ x = 6; y = 8; ptr = &x; printf("ptr:\t%d\n", *ptr); ptr = &y; printf("ptr:\t%d\n", *ptr); } #include<stdio.h> void sum(int x, int y, int* sum) { /* returns x + y in variable pointed to * by sum. ``call by reference'' */ *sum = x + y; } int main() { int res = 0; sum(4,5,&res); printf("res:\t%d\n",res); } #include<stdio.h> int a; int* ptrToA() { /* returns the pointer to * global a as function value */ return &a; } int main() { a = 6; printf("a:\t%d\n", a); printf("&a:\t%d\n",&a); printf("prtToA:\t%d\n", ptrToA()); } #include<stdio.h> int a; void ptrToA(int** res) { /* returns the pointer to * a by reference */ (*res) = &a; } int main() { int* ptr; a = 6; printf("a:\t%d\n", a); printf("&a:\t%d\n",&a); ptrToA(&ptr); printf("ptr:\t%d\n", ptr); } #include<stdio.h> int a; void valueOfA(int* res) { /* returns value of A by reference */ (*res) = a; } int main() { int b = 0; printf("a:\t%d\n", a); printf("b:\t%d\n", b); valueOfA(&b); printf("b:\t%d\n", b); } #include<stdio.h> int* ptrToB() { int b = 5; int* ptr; /* return a pointer to b */ ptr = &b; printf("inside ptrToB:\n"); printf("ptr:\t%d\n", ptr); printf("(*ptr):\t%d\n\n", *ptr); return ptr; } int main() { int* ptr; ptr = ptrToB(); printf("inside main:\n"); printf("ptr:\t%d\n", ptr); printf("(*ptr):\t%d\n", *ptr); } #include<stdio.h> #include <stdlib.h> /* So far, all we've used pointers only as references * to other variables (aliasing). However, we can have * pointers pointing to user allocated memory locations. */ int main() { int* ptr; ptr = (int*) malloc(sizeof(int)); (*ptr) = 10; printf("ptr:\t%d\n",ptr); printf("(*ptr):\t%d\n",*ptr); } #include<stdio.h> #include <stdlib.h> int* ptrToInt() { int* ptr; /* return a pointer to b */ ptr = (int*) malloc(sizeof(int)); (*ptr) = 5; printf("inside ptrToInt:\n"); printf("ptr:\t%d\n", ptr); printf("(*ptr):\t%d\n\n", *ptr); return ptr; } int main() { int* ptr; ptr = ptrToInt(); printf("inside main:\n"); printf("ptr:\t%d\n", ptr); printf("(*ptr):\t%d\n", *ptr); } #include<stdio.h> #include<stdlib.h> /* Pointers can point to various types... */ int main() { int* ptrInt; float* ptrFloat; char* ptrChar; ptrInt = (int*) malloc(sizeof(int)); ptrFloat = (float*) malloc(sizeof(float)); ptrChar = (char*) malloc(sizeof(char)); (*ptrInt) = 10; (*ptrFloat) = 12.3; (*ptrChar) = 'A'; printf("ptrInt:\t%d\n",*ptrInt); printf("ptrFloat:\t%f\n",*ptrFloat); printf("ptrChar:\t%c\n",*ptrChar); } #include<stdio.h> #include<stdlib.h> /* Pointers can be used to implement data structures of * dynamic size */ int main() { int length = 10; char* A = (char*) calloc(length,sizeof(char)); char* iter; int i; iter = A; for (i = 0; i < length; ++i) { (*iter) = 'A'+i; /* points iter to next memory location */ ++iter; } /* use pointer notation */ for (i = 0; i < length; ++i) printf("char %i:\t%c\n",i,*(A+i)); printf("\n"); /* use array notation */ for (i = 0; i < length; ++i) printf("char %i:\t%c\n",i,A[i]); }