Date post: | 21-Jan-2018 |
Category: |
Education |
Upload: | hemantha-kulathilake |
View: | 15 times |
Download: | 0 times |
COM1407
Computer ProgrammingLecture 11
Working with Pointers
K.A.S.H. Kulathilake B.Sc. (Hons) IT, MCS , M.Phil., SEDA(UK)
Rajarata University of Sri Lanka Department of Physical Sciences
1
Objectives
• At the end of this lecture students should be able to;
▫ Define the C pointers and its usage in computer programming.
▫ Describe pointer declaration and initialization.
▫ Apply C pointers for expressions.
▫ Experiment on pointer operations.
▫ Identify NULL pointer concept.
▫ Experiment on pointer to pointer, pointer arrays, arrays with pointers and functions with pointers.
▫ Apply taught concepts for writing programs.
2
Introduction
• To understand how to use pointers, you must have a basic knowledge of how a computer stores information in memory.
• Pointers closely relate to memory manipulation. • Basically, a personal computer RAM consists
thousands of sequential storage locations, with each location being identified by a unique address.
• Computer’s processor also has their own memory, normally called registers and cache.
• They differ in term of access speed, price and their usage.
3
Introduction (Cont…)
• Computer memory is used for storage, when program runs on the computer and for processing data and instructions.
• In a very simple way, each program requires two portions of the memory that is: (2+2)
1. Data portion – for data or operands. (2,2)2. The instruction code portion – what to do to the data
such as operators etc. (+)
• Each portion is referred to as a memory segment, so there is:
1. A data segment (normally called data segment). 2. An instruction code segment (normally called text segment).
4
Introduction (Cont…)
• When the programmer declares a variable in a C/C++ program, the compiler sets aside a memory location with a unique address to store that variable.
• The compiler associates that address with the variable’s name.
• When the program uses the variable name, it automatically accesses the proper memory location.
• The locations address remains hidden from the programmer, and the programmer need not be concerned with it.
• What we are going to do is to manipulate the memory addresses by using pointers.
5
Introduction (Cont…)
• Let say we declare one variable named rate of type integer and assign an initial value as follows:
int rate = 100;
• Memory allocation for the above variable can be depicted as follows
6
Introduction (Cont…)
• You can see, the memory address of the variable rate (or any other variable) is a number, so can be treated like any other number in C/C++.
• Normally the number is in hexadecimal format.
• Then, if a variable’s memory address is known, the programmer can create a second variable for storing a memory address of the first variable.
• We can declare another variable to hold the memory address of variable rate; let say, s_rate
7
Introduction (Cont…)
• At the beginning, s_rate is uninitialized.
• So, storage has been allocated for s_rate, but its value is undetermined, as shown below.
8
Introduction (Cont…)
• Let store the memory address of variable rate, in variable s_rate, so, s_rate now contains the memory address of rate, which indicates its storage location in memory where the actual data (100) is stored.
• Finally, in C/C++ vocabulary, s_rate is pointing to rate or is said a pointer to rate.
9
Introduction (Cont…)
• In simplified form ..
10
Declaring a Pointer Variable
• So the declaration of the pointer variable becomes something like this:
int *s_rate;
• The asterisk (*) is used to show that is it the pointer variable instead of normal variable.
• A pointer is a variable that contains the memory address of another variable, where, the actual data is stored.
11
Declaring a Pointer Variable (Cont…)
• A pointer is a numeric variable and like other variables, must be declared and initialized before it can be used.
• The following is a general form for declaring a pointer variable:
data_type *pointer_variable_name;
For e.g. char* x;
int * type_of_car;
float *value;
12
x is a pointer to a variable of type char.
*, is valid for all the three positions
The asterisk (*) is called indirection operator,
Declaring a Pointer Variable (Cont…)
• Pointers can be declared along with non pointer variables as shown below:
char *ch1, *ch2;
// ch1 and ch2 both are pointers to type char.
float *value, percent;
// value is a pointer to type float, and percent
is an ordinary float variable.
13
Initializing Pointers
• Once a pointer is declared, the programmer must initialize the pointer, that is, make the pointer point to something.
• Don’t make it point to nothing; it is dangerous.
• Like regular variables, uninitialized pointers will not cause a compiler error, but using an uninitialized pointer could result in unpredictable and potentially disastrous outcomes.
• Until pointer holds an address of a variable, it isn’t useful.
14
Initializing Pointers (Cont…)
• C/C++ uses two pointer operators: 1. Indirection operator (*) – has been explained.
2. Address-of-operator (&) – means return the address of.
• When & placed before the name of a variable, the address-of-operator returns the memory address of the variable/operand
15
Initializing Pointers (Cont…)
• Hence, a pointer variable can be initialize as follows;
pointer_variable_name = &variable;
e.g.
s_rate = &rate;
16
Initializing Pointers (Cont…)
#include <stdio.h>
int main ()
{
int n;
int *x;
printf("n===> %i\n",n);
printf("&n==> %i\n",&n);
n =10;
printf("n===> %i\n",n);
printf("&n==> %i\n",&n);
x = &n;
printf("x===> %i\n",x);
printf("*x ==> %i\n",*x);
return 0;
}
17
Initializing Pointers (Cont…)
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
int *m;
int location = 200;
m = &location;
printf("The data, *m = %i\n",*m);
printf("The address where the data pointed to,
m = %i\n", m);
system("pause");
return 0;
}
18
Initializing Pointers (Cont…)
• Pointer variable m receives the address of variable location or the memory address of the variable location is assigned to pointer variable m.
19
Initializing Pointers (Cont…)
#include <stdio.h>
int main (void)
{
/*Following declaration is also legal*/
int count = 10, x,*int_pointer;
int_pointer = &count;
x = *int_pointer;
printf ("count = %i, x = %i\n",
count, x);
return 0;
}
20
Initializing Pointers (Cont…)
#include <stdio.h>
int main (void)
{
char c = 'Q';
char *char_pointer = &c;
printf ("%c %c\n", c, *char_pointer);
c = '/';
printf ("%c %c\n", c, *char_pointer);
*char_pointer = '(';
printf ("%c %c\n", c, *char_pointer);
return 0;
}
21
Initializing Pointers (Cont…)
• Where Pointers?
▫ The * operator appears before a pointer variable in only two places: When declaring a pointer variable.
When dereferencing a pointer variable (to find the data it points to).
22
Using Pointers in Expressions #include <stdio.h>
int main ()
{
int var = 34;
int *ptr,*ptr2;
ptr = &var;
printf("Direct access, var = %i\n", var);
printf("Indirect access, *ptr = %i\n", *ptr);
printf("The memory address of variable var = %i\n", &var);
printf("Pointing address of ptr = %i\n", ptr);
ptr2=ptr;
printf("The value of ptr2 %i\n",*ptr2);
printf("Pointing address of ptr2 %i\n",ptr2);
return 0;
}
23
Using Pointers in Expressions (Cont…)
• From the above example, we can: 1. Access the contents of a variable by using the
variable name (var) and is called direct access.
2. Access the contents of a variable by using a pointer to the variable (*ptr or *ptr2) and is called indirect access or indirection.
24
Using Pointers in Expressions (Cont…)
#include <stdio.h>
int main (void)
{
int i1, i2;
int *p1, *p2;
i1 = 5;
p1 = &i1;
i2 = *p1 / 2 + 10;p2 = p1;
printf ("i1 = %i, i2 = %i, *p1 = %i,
*p2 = %i\n", i1, i2, *p1, *p2);
return 0;
}
25
The Keyword const and Pointers
char c = 'X';
char *charPtr = &c;
• The pointer variable charPtr is set pointing to the variable c.
• If the pointer variable is always set pointing to c, it can be declared as a const pointer as follows:char * const charPtr = &c;
• Read this as “charPtr is a constant pointer to a character.”
• So, a statement like this:charPtr = &d; // not valid
*charPtr = 'Y‘; // valid
26
The Keyword const and Pointers (Cont…)• Now if, instead, the location pointed to by charPtr will
not change through the pointer variable charPtr, that can be noted with a declaration as follows:
const char *charPtr = &c;
• Read this as “charPtr points to a constant character.”• Now of course, that doesn’t mean that the value cannot
be changed by the variable c, which is what charPtr is set pointing to.
• It means, however, that it won’t be changed with a subsequent statement like this:
*charPtr = 'Y'; // not valid
charPtr = &d // valid
27
The Keyword const and Pointers (Cont…)#include <stdio.h>
int main ()
{
char c = 'X', d = 'T';
char * const charPtr = &c;
const char *charPtr2 = &c;
charPtr = &d; //invalid statement
*charPtr = 'Y'; // Valid statement
charPtr2 = &d; // Valid statement
*charPtr2 = 'Y'; // Invalid statement
return 0;
}
28
Pointer Operation
• Only two arithmetic operations, that are addition and subtraction available
• Addition Operation (Increment)▫ Each time the pointer is incremented, it points to
the next integer and similarly, when a pointer is decremented, it points to the previous integer.
• Differencing ▫ For example, two pointers that point to different
elements of the same array can be subtracted to find out how far apart they are.
29
Pointer Operation (Cont…)
#include <stdio.h>
const int MAX = 3;
int main () {
int var[] = {10, 100, 200};
int i, *ptr;
/* let us have array address in pointer */
ptr = var;
for ( i = 0; i < MAX; i++)
{
printf("Address of var[%d] = %x\n", i, ptr );
printf("Value of var[%d] = %i\n", i, *ptr );
/* move to the next location */
ptr++;}
return 0;
}
30
Pointer Operation (Cont…)
#include <stdio.h>
const int MAX = 3;
int main ()
{
int var[] = {10, 100, 200};
int i, *ptr;
/* let us have array address in pointer */
ptr = &var[MAX-1];
for ( i = MAX; i > 0; i--)
{
printf("Address of var[%d] = %x\n", i-1, ptr );
printf("Value of var[%d] = %d\n", i-1, *ptr );
/* move to the previous location */
ptr--;}
return 0;
}
31
Pointer Operation (Cont…)
• Pointer Comparison ▫ The comparison is valid only between pointers that point to
the same array. ▫ Under this circumstances, the following relational
operators work for pointers operation. ==, !=, >, <, >= and <=
▫ A lower array element that is those having a smaller subscript, always have a lower address than the higher array elements.
▫ Thus if ptr1 and ptr2 point to elements of the same array, the following comparison: ptr1 < ptr2 is TRUE
▫ If ptr1 points to an earlier member of the array than ptr2 does.
32
Pointer Operation (Cont…)
#include <stdio.h>
int main ()
{
int *m;
int *n;
int q,r = 35;
m = &q;
n = &r;
printf ("m contains : %i\n",m);
printf ("n contains : %i\n",n);
if ( m <n ){
printf ("m before n\n");
}
else{
printf ("n before m\n");
}
return 0;
}
33
Pointer Operation (Cont…)
• Many arithmetic operations that can be performed with regular variables, such as multiplication and division, do not work with pointers and will generate errors in C/C++.
• The following table is a summary of pointer operations.
34
NULL Pointers
• It is always a good practice to assign a NULL value to a pointer variable in case you do not have an exact address to be assigned.
• This is done at the time of variable declaration.
• A pointer that is assigned NULL is called a nullpointer.
• The NULL pointer is a constant with a value of zero defined in several standard libraries.
35
NULL Pointers (Cont…)
#include <stdio.h>
int main () {
int *ptr = NULL;
printf("The value of ptr is : %x\n", ptr );
printf("The value of ptr is : %i\n", ptr );
return 0;
}
36
NULL Pointers (Cont…)
• In most of the operating systems, programs are not permitted to access memory at address 0 because that memory is reserved by the operating system.
• However, the memory address 0 has special significance; it signals that the pointer is not intended to point to an accessible memory location.
• But by convention, if a pointer contains the null (zero) value, it is assumed to point to nothing.
• To check for a null pointer, you can use an 'if' statement as follows −if(ptr) /* succeeds if p is not null */
if(!ptr) /* succeeds if p is null */
• To play safe, you can also set a pointer to NULL to indicate that it’s no longer in use.
37
Pointers & Arrays
• The main reasons for using pointers to arrays are ones of notational convenience and of program efficiency.
• Pointers to arrays generally result in code that uses less memory and executes faster.
• The real power of using pointers to arrays comes into play when you want to sequence through the elements of an array.
38
Pointers & Arrays (Cont…)
• An array name without brackets is a pointer to the array’s first element.
• So, if a program declared an array data[], data (array’s name) is the address of the first array element and is equivalent to the expression &data[0] that means references the address of the array’s first element.
• data equivalent to &data[0] or a pointer to the array’s first element.
• The array’s name is, therefore a pointer to the array’s first element.
39
Pointers & Arrays (Cont…)
int values [100] = {1,2,…, 100};
int *valuesPtr;
valuesPtr = values;
Or
valuesPtr = &values[0];
If you do following
valuesPtr = &values[1];
It points to second element
40
Pointers & Arrays (Cont…)
• Element of an array are stored in sequential memory locations with the first element in the lowest address.
• Array of type int occupies 2 byte of memory and a type float occupies 4 byte.
41
Pointers & Arrays (Cont…)
• to access successive elements of an array of a particular data type, a pointer must be increased by the sizeof(data_type).
• sizeof() function returns the size in bytes of a C/C++ data type.
42
For example, relationship
between array storage and
addresses for a 6-elements intarray and a 3-elements float
array is illustrated in this diagram.
Pointers & Arrays (Cont…)
#include <stdio.h>
int main ()
{
int i[10], x;
float f[10];
double d[10];
printf("\nArray's el. add of i[x] add of f[x] add of d[x]");
printf("\n|================================");
printf("======================|");
for(x=0; x<10; x++)
printf("\nElement %i:\t%p\t%p\t%p",x,&i[x],&f[x],&d[x]);
printf("\n|================================");
printf("======================|\n");
printf("\nLegends:");
printf("\nel.- element, add - address\n");
printf("\ndifferent pc, shows different addresses\n");
return 0;
}
43
Pointers & Arrays (Cont…)
• Notice the difference between the element addresses. ▫ 0027FF04 – 0027FF08 = 4 bytes for int▫ 0027FEE0 – 0027FEE4 = 4 bytes float ▫ 0027FE90 – 0027FE98 = 8 bytes double
[The size of the data type depends on the specification of your compiler, whether your target is 16, 32 or 64 bits systems, the output of the program may be different for different PC]
44
Pointers & Arrays (Cont…)
#include <stdio.h>
#define MAX 10
int main()
{
int array1[MAX] = {0,1,2,3,4,5,6,7,8,9};
int *ptr1, count;
float array2[MAX] = {0.0,0.1,0.2,0.3,0.4,0.5,0.6,0.7,0.8,0.9};
float *ptr2;
ptr1 = array1;
ptr2 = array2;
printf("\narray1 values array2 values");
printf("\n-------------------------");
for(count = 0; count < MAX; count++)
printf("\n%i\t\t%f", *ptr1++, *ptr2++);
printf("\n-------------------------\n");
return 0;
}
45
The increment and decrement operators are particularly handy when dealing with pointers. Applying the increment operator to a pointer has the same effect as adding one to the pointer, while applying the decrement operator has the same effect as subtracting one from the pointer.
Pointers & Arrays (Cont…)
#include <stdio.h>
int main()
{
char name[50]= "RAJARATA UNIVERSITY OF SRI LANKA";
printf("%s\n\n",name);
printf("%s,%i\n\n",name,&name);
printf("%c,%i,%i\n\n",name[0],name[0],&name[0]);
printf("%c,%i,%i\n\n",name[1],name[1],&name[1]);
return 0;
}
46
Pointers & Arrays (Cont…)
• Generally, the relationship is as follows: *(array1) == array1 [0] //first element
*(array1 + 1) == array1 [1] //second element
*(array1+ 2) == array1 [2] //third element
…
…
*(array1 + n) == array1[n] //the nth element
47
Pointers & Arrays (Cont…)
#include <stdio.h>
int main (void)
{
int sum = 0, *ptr;
int values[10] = { 3, 7, -9, 3, 6, -1, 7, 9,
1, -5 };
int * const arrayEnd = values + 10;
for ( ptr = values; ptr < arrayEnd; ++ptr )
sum += *ptr;
printf ("The sum is %i\n", sum);
return 0;
}
48
Pointers & Arrays (Cont…)
• In general, the process of indexing an array takes more time to execute than does the process of accessing the contents of a pointer.
• In fact, this is one of the main reasons why pointers are used to access the elements of an array—the code that is generated is generally more efficient.
• Of course, if access to the array is not generally sequential, pointers accomplish nothing, as far as this issue is concerned, because the expression *(pointer + j) takes just as long to execute as does the expression array[j].
49
Pointer Arrays
• Pointers may be arrayed like any other data type. • The declaration for an int pointer array of size 20 is:
int *arrayPtr[20];
• To assign the address of an integer variables called var to the first element of the array, we could write something like this:
arrayPtr[0] = &var;
• To find the value stored in var, we could write something like this: *arrayPtr[0]
50
Pointers to Pointers
• Graphically, the construct of a pointer to pointer can be depicted as shown below.
• pointer_one is the first pointer, pointing to the second pointer, pointer_two and finally pointer_two is pointing to a normal variable num that hold integer 10.
51
Pointers to Pointers (Cont…)
• In order to indirectly access the target value pointed to by a pointer to a pointer, the asterisk operator must be applied twice.
• For example, the following declaration: int **SecondPtr;
• Tell the compiler that SecondPtr is a pointer to a pointer of type integer.
• Pointer to pointer is rarely used but you will find it regularly in programs that accept argument(s) from command line.
52
Pointers to Pointers (Cont…)
• Consider the following declarations: char chs; /* a normal character variable */ char *ptchs; /* a pointer to a character */ char **ptptchs; /* a pointer to a pointer to a character */
• If the variables are related as shown below:
• We can do some assignment like this: chs = ‘A’; ptchs = &chs; ptptchs = ptchs;
53
Pointers to Pointers (Cont…)
#include <stdio.h>
int main ()
{
int **theptr;
int *anotherptr;
int data = 200;
anotherptr = &data;
theptr = &anotherptr;
printf("The actual data, **theptr = %i\n", **theptr);
printf("The actual data, *anotherptr = %i\n", *anotherptr);
printf("The theptr holding address = %p\n", theptr);
printf("The theptr own address = %p\n", &theptr);
printf("The anotherptr holding address = %p\n", anotherptr);
printf("The &anotherptr own address = %p\n", &anotherptr);
printf("The address of the normal variable = %p\n", &data);
printf("Normal variable, the data = %i\n", data);
return 0;
}
54
Pointers & Functions
• You can pass a pointer as an argument to a function in the normal fashion, and you can also have a function return a pointer as its result.
• The pointers can be passed as formal parameters to a function in the same way as a normal pointer variable.
• The value of the pointer is copied into the formal parameter when the function is called.
• Therefore, any change made to the formal parameter by the function does not affect the pointer that was passed to the function.
• Although the pointer cannot be changed by the function, the data elements that the pointer references can be changed!
55
Pointers & Functions (Cont…)
#include <stdio.h>
void test (int*);
void test (int *int_pointer)
{
*int_pointer = 100;
}
int main (void)
{
int i = 50, *p = &i;
printf ("Before the call to test i = %i\n", i);
test (p);
printf ("After the call to test i = %i\n", i);
return 0;
}
56
Pointers & Functions (Cont…)
#include <stdio.h>
void exchange (int * const, int * const);
void exchange (int * const pint1, int * const pint2)
{
int temp;
temp = *pint1;
*pint1 = *pint2;
*pint2 = temp;
}
int main (void)
{
int i1 = -5, i2 = 66, *p1 = &i1, *p2 = &i2;
printf ("i1 = %i, i2 = %i\n", i1, i2);
exchange (p1, p2);
printf ("i1 = %i, i2 = %i\n", i1, i2);
exchange (&i1, &i2);
printf ("i1 = %i, i2 = %i\n", i1, i2);
return 0;
}
57
Pointers & Functions (Cont…)
• Similarly, C also allows to return a pointer from a function.#include<stdio.h>
int *fun();int main()
{
int *ptr;
ptr=fun();printf("%i",*ptr);
return 0;
}
int *fun()
{
int *point;
int p = 12;
point=&p;
return point;
}
58
What happen here?
int *fun()
{
int *point;
*point=12; <<< Program is crashed here
return point;
}
In order to get rid from crashing we can write the same function as follows;
int *fun()
{
int *point =
malloc (sizeof *point);
*point=12;
return point;
}
Pointers to Character Strings
• One of the most common applications of using a pointer to an array is as a pointer to a character string.
• The reasons are ones of notational convenience and efficiency.
• To show how easily pointers to character strings can be used, write a function called copyString to copy one string into another.
59
Pointers to Character Strings (Cont…)
#include <stdio.h>
void copyString (char *, char *);
void copyString (char *to, char *from)
{
for ( ; *from != '\0'; ++from, ++to )
*to = *from;
*to = '\0';
}
int main (void)
{
char string1[] = "A string to be copied.";
char string2[50];
copyString (string2, string1);
printf ("%s\n", string2);
copyString (string2, "So is this.");
printf ("%s\n", string2);
return 0;
}
60
pointer to that constantcharacter string is passedhere.
Whenever a constantcharacter string is usedin C, it is a pointer tothat character string thatis produced.
Pointers to Character Strings (Cont…)
• So, if textPtr is declared to be a character pointer, as in
char *textPtr;
then the statement
textPtr = "A character string.";
assigns to textPtr a pointer to the constant character string "A character string."
61
Pointers to Character Strings (Cont…)
• Be careful to make the distinction here between character pointers and character arrays, as the type of assignment just shown is not valid with a character array.
• So, for example, if text is defined instead to be an array of chars, with a statement such as
char text[80];
then you could not write a statement such astext = "This is not valid.";
• The only time that C lets you get away with performing this type of assignment to a character array is when initializing it, as in
char text[80] = "This is okay.";
62
Pointers to Character Strings (Cont…)
• If text is a character pointer, initializing text with the statement
char *text = "This is okay.";
assigns to it a pointer to the character string "This is okay.“• As another example of the distinction between character
strings and character string pointers, the following sets up an array called days, which contains pointers to the names of the days of the week.
char *days[] = { "Sunday", "Monday",
"Tuesday", "Wednesday", "Thursday",
"Friday","Saturday" };
• So days[0] contains a pointer to the character string "Sunday", days[1] contains a pointer to the string "Monday", and so on.
63
Pointers to Character Strings (Cont…)
64
Objective Re-cap
• Now you should be able to:▫ Define the C pointers and its usage in computer
programming.▫ Describe pointer declaration and initialization. ▫ Apply C pointers for expressions. ▫ Experiment on pointer operations. ▫ Identify NULL pointer concept. ▫ Experiment on pointer to pointer, pointer arrays,
arrays with pointers and functions with pointers. ▫ Apply taught concepts for writing programs.
65
Reference
• Chapter 11 - Programming in C, 3rd Edition, Stephen G. Kochan
66
Next: Structures, Unions & Dynamic Memory Allocation
67