1.25k likes | 1.43k Views
Pointers. Every Computer has addressable memory locations. Identifiers are assigned to data and their contents are manipulated. Example In a C program, we can have. void main() {int a,b; /*variable is assigned a a=3; value & manipulated,
E N D
Pointers Every Computer has addressable memory locations. Identifiers are assigned to data and their contents are manipulated.
Example In a C program, we can have void main() {int a,b; /*variable is assigned a a=3; value & manipulated, printf(“%d”,a,&a); & is called ampersand */ a=5; b=a; printf(“%u”,b,&b); }
A Pointer is a derived datatype • It is a data type built from one of the standard types i.e. int, float, char, double • Pointer’s value is any of the addresses available in the computer for storing and accessing the data • Pointers are built on the concept of pointer constants or addresses
We can have a Character constant i.e any letter of the alphabet that can be drawn from universe of all characters A Character constant can be a value and stored In a variable say ‘G’ stored in achar, a variable given by the programmer. In 1 MB of computer’s memory, imagine 145600 to be a memory location in which character constant ‘G’ is stored.
A Program define 2 pointers and print their addresses as pointers #include <stdio.h> /*prg to print character */ int main() /*addresses*/ { char a,b; printf(“%p %p\n”,&a,&b); return 0; }
To access a variable through a ptr p, code int *p,a; p=&a • *->indirection operator • Indirection is a unary operator • Indirection and address operators are inverse of each other
Initialization Of Pointer Variables • C Language doesn’t initialize variables. • If at all it initializes , it is done by the system loader. • Hence when we start our program, all of our uninitialized variables have unknown garbage in them. • An OS clears the memory when it loads a program which cant be counted especially with programs that run on multiple systems
Figure-Uninitialized pointers-such errors are difficult to debug because it is delayed till program execution Some garbage: Unknown value ? int a; a Different garbage: Pointer to unknown value int *p; p ?
To correct the problem, always assign a valid address to the pointer. • Int a; • Int *p=&a; • *p=89; • Its also possible initialize pointers when they are declared and defined. Dv should be defined before the pointer variable.
Pointers and Functions • C uses Pass by value concept exclusively i.e. • Only direct way to send something back from a udf function is through return value. • Pass by address concept is simulated by passing address. • When we pass by address, we pass the pointer to the variable. • When we use pass by value method, the data is exchanged in the called function, but nothing changes in the calling function. We see unworkable & workable exchange programs xchg.c , xchg1.c
Pass By value No Change b a 5 7 7 5 y x temp Exchanged 5
Rather than pass values of 2 to be exchanged , we could pass pointer to the values 1 To exchange using pointers, create pointers using the address operator in the function call. xchg( &a , &b); 2.To use pass by address, the formal parameters in the called function are passed as pointer to variables void xchg(int *, int *); 3.To assign a value to a, dereference the pointer in xchg. This allows us to access data in the calling program using call by address. When we need to return more than 1 value from a function, we can use pointers
7 8 After Exchange &a &b temp 5
Functions Returning Pointers • We can have a function from returning a pointer to a calling function • As an Example , u have a program to find smaller of 2 variables. We pass 2 pointers to the function that uses a conditional expression to determine which value is smaller • Return value is the address of smallest no. as a pointer.
Example for Function returning pointers.Prototype declarationint *smaller(int *p1, int *p2); int main() int *smaller (int *px, int *py) {int a,b,*p; { Scanf(“%d %d”,&a, &b); return (*px<*py ? Px : py); P=smaller(&a,&b); } /*smaller*/ .. }
Pointers to Pointers-All our pointers have been pointing directly to data. With Advanced Data structures • With Advanced Data structures Its often necessary to use pointers that point to other pointers • Eg - We can have a pointer pointing to pointer to an integer.
This 2-level indirection is shown below and can continue upto many levels of indirection /*local declarations*/ int a,*p,**q; Pointer to integer integer variable a Pointer to Pointer to integer 234560 287650 58 234560 287650 397870
/*statements* ptop1.c,ptop.c/ a=58; p=&a; q=&p; int **q; Printf(“%3d”,a); Printf(“%3d”,*p); Printf(“%3d”,**q);
int a,*p,**q; 1. Each level of indirection require a separate indirection operator when it is derefenced. 2. To dereference a pointer using a pointer p, we dereference as *p. 3. To refer to a, using the pointer q, we have to dereference it twice to get the integer a because there are 2 levels of indirections (pointers) involved.
int a,*p,**q; • If we dereference it only once, u are referencing p i.e. pointer to integer i.e. q is a pointer to pointer to an integer. • Double dereference is shown in previous slide . r q p a Figure-Graphical representation of variables using pointers to pointers
Compatibility - It is important for pointers to have a type associated with them • They are not just pointer types , but are pointers to specific type like integer. • Each pointer takes on attribute of type to which it refers in addition to its own attributes. • Now we will see a program to print the size of the pointer and what it refers to.
Program Description for size of pointer • Note that variables a, c and x are never assigned any values i.e. sizes are independent of the values in a variable. i.e. sizes are dependent on type and not on values. • Size of all ptrs – 4 i.e. size of address in program on which it was run. • Data Size of the type is the same as size of pointer • Check sizeof(px) and sizeof(*px).
Compatibility and Void Pointer • It is invalid to assign a pointer of one type to a pointer of another type, even though the value in both cases are memory addresses and would hence seem to be fully compatible. • In C, we can’t use assignment operator with pointers to different types, if we try to do we get a compile error. • An exception to this is void pointers.
Void pointer is also known as Universal Pointer / Generic Pointer that can be used with any pointer. • A void pointer cannot be dereferenced. • It can be created – void *pVoid; • We can make explicit assignment between incompatible pointers types by using a cast.
Casting pointer- We can make explicit assignment between incompatible pointers types by using a cast. • Eg- we can make character pointer p to point to an integer(a) as shown below- int a; char *p; p=(char *)&a; unless we cast all operations that use p , u may create greater mounds of garbage. With exception of void pointer, pointers should never be casted
Following statements are valid, but are extremely dangerous and must be used carefully throughout the design /*local statements*/ Void *pvoid; Char *pchar; Int *pint /*statements */ Pvoid = pchar; Pint = pvoid; Pint = (int *) pchar;
Construct an example where we have 2 variables – 1 int , 1 char. The char has 1 ptr associated with it, the int has 2, one a second level pointer. These vars & their ptrs are shown char c; char *pc; int a; int *pa; int *ppa; pc=&c; pa=&a; ppa=&pa; /*Good & valid pointers*/ Fig- pointer compatibility
char c; int a; pc=&c;char *pc; int *pa; pa=&a; int *ppa; ppa=&pa; Pc c Z 123450 ppa a pa 287650 234560 58 287870 287650 234560
/*Invalid pointers will generate errors*/ pc=&a; /*Different types*/ ppa=&a; /*Different levels*/
Fig- pointer types must match a=4; pa=&a; *pa=4; *ppa=&pa ppa=&pa **ppa=4; a; *pa; pa; **ppa *ppa ppa int int int Int * int * int** Type: int Type: int* Type: int** ppa=&pa a=4 *pa=4 **ppa=4 pa=&a *ppa=&pa
LVALUE AND RVALUE • In C, an expression is either an l-value or r-value. Every expression has a value. • But value in an expression can be used in 2 different ways. • An lvalue expression must be used whenever an object is receiving value i.e. it is being modified. • An rvalue expression can be used to supply a value for further use i.e. to examine or copy its value.
Examples- for lvalue expressions a = … a[5] =… (a) = … *p =… Expressions that are not lvalue type are rvalues. Examples for rvalue expressions 5 a+2 a*6 a[2]+3 a++
Even if an expression is an lvalue, if it is used as part of larger expression in which operators create Only rvalue expressions, then whole expression is an rvalue Example-a[2] is an lvalue. But when it is used in Expression a[2]+3, the whole expression is an rvalue and not an lvalue.
Similarly in a++, the value of variable a is an lvalue while whole expression (a++) is an rvalue Reason to know l and rvalues- • Some operators need an lvalue as an operand • If we use 1 of these operators and use an rvalue in the place of operand, then we get a compiler error.
Pointer Arithmetic and Arrays • Besides Indexing, Programmers use another powerful method called Pointer Arithmetic to move through an array from element to element to use in searching an array sequentially.
Pointers and one-dimensional array • If a is an array, then a is constant pointing to the first element in the array and a+1 is a constant to the second element in the array. • If we have a pointer p, pointing to the second element of the array then p-1 is a pointer to the previous (first) element and p+1 is a pointer to the next (third) element.
Furthermore, given a, a+2 is the address , 2 elements away from a, and a+3 is address , 3 elements from a. General Notation – Given pointer p, p + n is a pointer to the value n elements away When n is added to a pointer value, we will get a Value that correspond to another index location n elements away. n-> offset from original pointer.
Figure for Pointer Arithmetic p p+1 p+2 p+3 2 a 4 a+1 6 a+2 a+3 8
How to determine the new value ? • C must know the size of the element that is identified by the type of pointer. Address Calculation Formula address = pointer + (offset * size of element) address = a + n * sizeof (one element))
Figure shows result of pointer arithmetic on different-sized elements Int a[3] a b c a+1 b+1 c+1 a+2
Char is implemented as 1 byte • Int is implemented as 4 bytes • Float is implemented as 6 bytes. • a+1 mean different things in different situations of data types. • We know how to get address of an array element using a pointer and an offset
Todays Topics • 2 prgs demonstrating moving through arrays using pointers • Ptr7.c - printing array forward and backward using ptrs. • Function to search with ptrs. • binsrch.txt in notepad,ptrs • 2-d arrays, Passing Array to a fn
Pointers and other operators • Following arithmetic operations are valid • P+5, 5+p, p-5, p1-p2, p++ ,--p • p1+p2 not allowed . Adding 2 ptrs is not valid in C. • 2 prgs demonstrating moving through arrays using pointers • Ptr7.c searching with ptrs. • binsrch.txt in notepad,ptrs and 2-d arrays, Passing Array to a fn
Assignment Questions- • Go through the Tips and Programming errors and Summary given in page 461 and page 462. • Maintain a separate Assignment Book. • Submit the assignment questions from Practice set given in Section 9.15 of the Text Book from page 463 to page 467 within the 24/8/10 at 11a.m.
Assignment Questions • Identify the Elementary and Group data items in atleast 3 real world applications in the form of table example given in next slide for a student studying in a college. Application Examples- • Insurance, RTO, Airline Reservation, Railway Reservation, e.t.c
Student studying in a college can have following details. • Regno – 5 digit integer – elementary data item • Name – array of 10 characters – Group item divided into Firstname, middlename and Lastname • Mks1,mks2,mks3 – integers – elementary data item that cannnot be further subdivided