Why do we need POINTERS ? Argument passing in functions Return value from a function Dynamic memory allocations Data structures Arrays Efficient more compact code call by ref use cautiously new and delete linked-list, stacks, queue, trees, etc An array is really a pointer pointer variable to process arrays, dispatch tables, API Pointer is a type. Type defines a range of values and a defined set of operations that can be used on the values. range of values: the entire set of byte addresses on your computer. set of operations: = * & + ++ += = == != < <= > >= [] 687315516 Assignment is used to initialize pointer variables Indirection on a pointer produces an expression of the object pointed at. Address of Arithmetic You can add integer expression to a pointer and the resulting expression is still a pointer. The integer represents an offset from the object pointed at. Often used in accessing array elements Arithmetic You can subtract integer expression to a pointer and the resulting expression is still a pointer. The integer represents an offset from the object pointed at. Often used in accessing array elements Arithmetic increment has the side effect of changing the pointer to point to the next object in the sequence. Often used in accessing array elements Arithmetic decrement has the side effect of changing the pointer to point to the previous object in the sequence. Often used in accessing array elements Arithmetic Op-Assignments add has the side effect of changing the pointer to point to a new object in the sequence. The right hand side operand is a displacement from the current object. Often used in accessing array elements Arithmetic Op-Assignments subtract has the side effect of changing the pointer to point to a new object in the sequence. The right hand side operand is a displacement from the current object. Often used in accessing array elements Arithmetic The difference between two pointers in the context of the same array is an integer whose value is the number of elements between the two pointers. Equality bool: Two pointer with the same value non Equality bool: Two pointer with different value Less bool: Two pointer in the context of the same array Less | Equal bool: Two pointer with different value Greater bool: Two pointer with different value Greater | Equal bool: Two pointer with different value Index can be applied to any pointer. Evaluates to indirection and offset from the current position. POINTER VARIABLE a pointer variable is variable whose value is the address of another variable declaring a pointer variable: type *identifier; Pointer rvalues come from the set of byte addresses of the computer's memory and are compatible at the void pointer level. Pointer expressions that evaluate to rvalue (pointer constants) There are only 3 pointer expressions that evaluate to a constant( rvalue ) &expression array names NULL pointer ( C++ also recognizes value 0 to be a NULL pointer) defining | declaring pointer variables When you indirect | dereference a pointer it should generally evaluate to an lvalue, that is it will locate and type a region of storage. The pointer’s value is a memory address and thus the locate part of lvalue is satisfied. What is lacking is the type part of lvalue. The solution is to provide a type expression as part of the pointer declaration. Defining a pointer variable involves using complex declaration rules. (see lecture notes ComplexDcl.doc) We create pointer declarations by adding the pointer declarator * to the declaration. Syntax rules requires that this operator be applied on the left side of the identifier. int zot // zot is an int int *zot // add pointer operator to zot, transforms zot into // a pointer to an int void pointer The void pointer is “typeless”. It can hold address values but has no type associated with the address. You cannot indirect | dereference a void pointer. Levels of indirection When you indirect / dereference a pointer the expression evaluates to the type of object the pointer was pointing at. int *zot; // pointer variable int ozo = 10; // int variable value 10 zot = &ozo; //zot is pointing at ozo zot *zot //this expression is a pointer to an int //this expression is an int variable (lvalue) ie ozo 687315516 The concise definition of Call by Value and Call by Reference Call by Value Call by Reference the callers arguments are rvalues (type only) the callers arguments are lvalues (location and type) Call by reference In call by reference you pass lvalue arguments. When you use call by reference you are signaling that you expect the called function to directly change the value of a variable in the caller’s scope. Call by reference (pointer parameter) Call by reference is implemented by declaring pointer parameters in the function’s parameter list and passing pointer arguments in the call operation. Accessing the data values requires explicit indirection applied to the parameter. Side Bar Note: The expression of the pointer parameter behaves as a local automatic. The expression of the indirected / dereferenced pointer parameter behaves as a variable in the scope of the caller. If you unintentionally change the value of this pointer you may destroy data in the caller’s context which causes undefined behavior. This kind of run time bug will drive you crazy. Call by reference (reference parameter) A reference parameter behaves like a pointer with implicit indirection. The compiler will implicitly convert the arguments in the call to a reference to match the reference parameter types. A reference is a pointer that is guaranteed to be initialized when defined. The caller’s arguments are the reference’s defacto initializer. When the reference is used in an expression the pointer is automatically de-referenced (indirection applied) as part of expression evaluation. Unsafe code Using an un-initialized pointer is extremely dangerous and causes undefined behavior at run time. Obfuscate code – Documentation and Comments are not optional The reason you want to use pointers is power and efficiency (speed). The price you pay is your code is obscure. Pointers create layer(s) of indirection. To reach the data that you are working on you must navigate using indirection. These expressions can blow your mind. Multiple levels of indirection Pointers can point at other pointers which point to other pointers which eventually point to some nonpointer object. This occurs mostly when we pass arguments by reference and the argument is a complex declaration. Other examples of multi-level pointers are multi-dimensional arrays. 687315516 int zot = 10; int *foo; int **ozo; // one level of indirection // two levels of indirection foo = &zot; ozo = &foo; ozo *ozo **ozo; 687315516 // pointer to a pointer to an int // pointer to an int // int variable