two-week iste workshop on effective teaching/learning of computer programming
DESCRIPTION
Dr Deepak B Phatak Subrao Nilekani Chair Professor Department of CSE, Kanwal Rekhi Building IIT Bombay Lectures 12, Pointers Tuesday 6 July 2010 [some slides courtesy Prof Milind Sohoni]. Two-week ISTE workshop on Effective teaching/learning of computer programming. Overview. - PowerPoint PPT PresentationTRANSCRIPT
Two-week ISTE workshop onEffective teaching/learning of computer
programming
Dr Deepak B PhatakSubrao Nilekani Chair Professor
Department of CSE, Kanwal Rekhi BuildingIIT Bombay
Lectures 12, Pointers
Tuesday 6 July 2010
[some slides courtesy Prof Milind Sohoni]
Overview
More on memory locations• Addresses and values
Notion of a pointer• Pointer variables• Pointer assignment, • Pointer arithmetic• Example program
Parameter passing in functions• Example of swapping values of two variable
Problem of separating names
Memory organization
Memory consists of ‘locations’, each of which has a unique address starting with 0. The smallest unit of addressable memory is a Byte (8 bits).
For our numerical values, we need a ‘larger’ location, typically 2, 4 or 8 bytes.
Consider int, float, and char variable and arrays.
int M ; float A[3]; char C[4] Let us assume these have been assigned some values
Location addresses
Suppose the first location has been allocated address 10000, then we would expect the addresses of these locations to be
10000 M 573
10004 A[0] 673.852
10008 A[1] 1.458E-12
10012 A[2] 2346.91E15
10016 C[0] ‘U’
10017 C[1] ‘N’
10018 C[2] ‘I’
10019 C[3] ‘X’
Pointers ...
These addresses are essentially ‘pointers’ in memory. Each points to a specific location containing value of a specific type• 10000 is a pointer to M (int)• 10016 is a pointer to A[2] (float)• 10021 is a pointer to C[1] (char)
Ordinarily, we have nothing to do with these pointers or absolute addresses• We use variable names and array elements in our
programs Programming languages C and C++ provide the facility to
use these pointers directly within a program
Pointers
We can declare special variable called pointer variables in our programs
int *p1; float *p2; char *p3 This will allocate separate memory location for these three
variables Each can contain an address, which itself is typically a 32
bit number, and can represent an address from 0 to 2 31 -1 Suppose now we write in our program
p1 = &M; // M has value 573 Then P1 will be assigned the value ..? ..
Pointers
We can declare special variable called pointer variables in our programs
int *p1; float *p2; char *p3 This will allocate separate memory location
for these three variables Each can contain an address, which itself
is typically a 32 bit number, and can represent an address from 0 to 2 31 -1
Suppose now we write in our program
p1 = &M; Then P1 will be assigned the value 10000 int q; q = *p1; will assign to q .. ? ..
10000 M 573
Pointers
We can declare special variable called pointer variables in our programs
int *p1; float *p2; char *p3 This will allocate separate memory
location for these three variables Each can contain an address, which itself
is typically a 32 bit number, and can represent an address from 0 to 2 31 -1
Suppose now we write in our program
p1 = &M; Then p1 will be assigned the value 10000 int q; q = *p1; will assign to q 573
10000 M 573
Pointers …
& is called “address” operator * is called “dereferencing” operator We can print the actual value of M cout << *p1; // will print 573 We can print the value of a pointer. The address stored
there will be printed cout << p1 // may print 0xbfde41a0 We can also say p2 = &A[0]; p2++; This will not increment the contents of p2 by 1, but rather by
the no of bytes (4) allocated to the associated ‘type’ cout << *p2 will print value of A[1]
Pointer example program
int main() { int M, N, A[3]; M = 573; N = -1234567; int *ptr1, *ptr2; cout << M << " and " << N << "\n"; ptr1 = &M; ptr2 = ptr1 + 1; cout << " the pointers have values \n"; cout << ptr1 << " " << ptr2 << “\n”; cout << "The corresponding data values are" cout << *ptr1 << " " << *ptr2 << “\n”; return 0; }
Program execution results
$ c++ pointerexample1.cpp
$ ./a.out
573 and -1234567
the pointers have values
0xbfcaf8ac 0xbfcaf8b0
The corresponding data values are
573 -1077217072
$
Why are we not getting the right value of N ?
A modified version
int main() { int M, N, A[3]; int *ptr1, *ptr2; M = 573; N = -1234567; cout << M << " and " << N << "\n"; ptr1 = &M; ptr2 = &N; cout << " the pointers have values " << "\n"; cout << ptr1 << " " << ptr2 << "\n"; cout << "The corresponding data values are" << "\n"; cout << *ptr1 << " " << *ptr2 << "\n";return 0;
Execution results
$ c++ pointerexample1a.cpp
$ ./a.out
573 and -1234567
the pointers have values
0xbfb2772c 0xbfb27728
The corresponding data values are
573 -1234567
$
Another example
int M, N, A[3];int *ptr1, *ptr2, *ptr3;A[0] = 573; A[1] = -1234567; A[2] = 94;cout << A[0] << ", " << A[1] << ", and " << A[2] << "\n"; ptr1 = &A[0]; ptr2 = ptr1 + 1; ptr3 = ptr1 + 2;cout << " the pointers have values " << "\n";cout << ptr1 << " " << ptr2 cout << " and " << ptr3 << "\n";cout << "The data values are" << "\n";cout << *ptr1 << " " << *ptr2 cout << " and " << *ptr3 << "\n";...
Execution results
$ ./a.out
573, -1234567, and 94
the pointers have values
0xbff77b5c 0xbff77b60 and 0xbff77b64
The corresponding data values are
573 -1234567 and 94
[Note that in case of arrays, incrementing a pointer by one points to the next successive element of the array. Array elements are ALWAYS allocated consecutive memory locations
Passing parameters to functions So far, we have seen parameters passed as values to the
functions. The only thing we get back is a single value which the function returns?
int f (int x, int y){ int sum; sum = 5*x + y%10; return sum; } To use this function in our program int A, B, C; cin >> A >> B; C = f(A, B); cout << C;
Problems with this approach What do we do if we need to get back more than one value
upon return. For example, if we wish to swap values of two variables x and y, we write
int x, y, temp; cin >> x >> y; temp = x; x = y; y = temp; cout << x << “ “ << y << "\n"; If we wish to write a swap function we may try int swap (int p, int q){ int t; t = p; p = q; q = t; return 0; }
Problems …
Now suppose we modify our program as int x, y; cin >> x >> y; swap(x,y); cout << x << “ “ << y << "\n";
Will we get the values of x and y swapped?
No! Because, when we invoke the function swap, the values of x and y are (copied and) sent to the function. Even if the function swaps these, the change is not reflected in the original values, since those values are not copied back!
A program which does not work
void trytoswap(int a, int b) { // Call by value int temp=a; a = b; b = temp; return; } int main() { int x=1, y=2; trytoswap(x, y); cout << "x=" << x << " y=" << y << "\n"; }
A program which does not work …
Values of x and y passed to function trytoswap. These values are assigned to local variables a and b
Updated values do NOT get copied back to x and y.
[Note: Type “void” for any function indicates that no value is
returned by the function. This is to be used when we expect parameters themselves to carry back calculated values, or when the function performs a task which does not require to send back values]
Pass by reference
How do arrays, passed to a function, come back with modified values?
The answer lies in passing pointers rather than values. Array name is automatically treated as a pointer to the first element of the array, when passed as a parameter
If we need to get back the modified values of (variable) parameters back in the calling program, we should pass their pointers. That way, the function ‘refers’ to original locations of these variables which were allocated in the calling program, thus modifying their contents
A program that works
void swap(int &a, int &b) { // call by reference
int temp=a;
a = b;
b = temp;
return;
}
int main() {
int x=1, y=2;
swap(x, y);
cout << "x=" << x
cout << " y=" << y << “\n”;
}
Problem of separating first and last name
Suppose we have prepared a text file of names of people as per following sample
Nandlal Sarda Moreshwar Bhujade Deepak Phatak Milind Sohoni Ajit Diwan
We wish to read each line in a char array in our program, and separate out the first and last names storing these in two separate char arrays
// first-last-name.cpp
// Program to find last and first names
// from a string containing the full name
// two parts are separated by one or more
// blanks
#include <iostream>
#include <cstring>
using namespace std;
//Separation of first and last name
int main () {
char namestr[256], *charptr;
char firstname[80],lastname[80];
int nchar, blankpos;
int lengthf, lengthl, i;
cout << " Type a name" << "\n";
gets(namestr);
nchar = strlen(namestr);
// locate the first space charptr = (char*)memchr(namestr, ' ', nchar); if (charptr != NULL){ // one blank found, get first name blankpos = charptr-namestr +1; cout<<"found blank at " << blankpos << “\n”; lengthf = blankpos; strncpy(firstname,namestr,lengthf); firstname[lengthf] = 0; cout << "first name is: "; for(i=0;i<lengthf;i++){ cout<<firstname[i];} cout << “\n”;
// skip consecutive blanks, if any
while(namestr[blankpos]==' ') {
blankpos++;
// check if end already reached
if (blankpos==nchar){
cout << "No last name" << "\n";
return 1;
}
}
//find and print last name lengthl = nchar-blankpos; strncpy(lastname,namestr+blankpos,lengthl); lastname[lengthl] = 0; cout << "last name is: "; for(i=0;i<lengthl;i++)cout<<lastname[i]; cout << "\n"; } else cout <<"name has only one word" << "\n"; return 0;}
Execution Results
$ ./a.out
Type a name
Nandlal Sarda
found blank at 8
first name is: Nandlal
last name is: Sarda
$
Execution Results …
$ ./a.out
Type a name
Deepak Phatak
found blank at 7
first name is: Deepak
last name is: Phatak
$
Execution Results …
$ ./a.out Type a nameSridhar name has only one word---------------------------------$ ./a.out Type a name Kavi Arya found blank at 1first name is: last name is: Kavi Arya
TEA BREAK