0% found this document useful (0 votes)
3 views

chapter 7

Chapter Seven of the document covers pointers in computer programming, detailing their declaration, initialization, and arithmetic operations. It explains how pointers relate to arrays, pointers to pointers, and pointers to functions, including dynamic memory management. Key concepts such as the address operator (&), dereference operator (*), and void pointers are also discussed, along with examples to illustrate their usage.

Uploaded by

bayabayecha
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
3 views

chapter 7

Chapter Seven of the document covers pointers in computer programming, detailing their declaration, initialization, and arithmetic operations. It explains how pointers relate to arrays, pointers to pointers, and pointers to functions, including dynamic memory management. Key concepts such as the address operator (&), dereference operator (*), and void pointers are also discussed, along with examples to illustrate their usage.

Uploaded by

bayabayecha
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 51

Computer Programming

[ECEg-1052]

Chapter Seven:
Pointers

Compiled by Amanuel Z.(MSc.)


Outline
 Declaring variables of type pointer
 Pointers and Arrays
 Pointer initialization
 Arithmetic of pointers
 Pointers to pointers
 Pointers to functions
 Dynamic memory
Declaring variables of type pointer
 A pointer is a variable that holds a memory
address, usually the location of another variable in
a memory.

3
Cont’d...
Address (dereference) operator (&)
 It is used as a variable prefix to know where the variable is
stored and can be translated as "address of", thus:
&variable1 can be read as "address of variable1".
For example:
ted = &andy;

would assign to variable ted the address of variable andy

4
Cont’d...
 Suppose that andy has been placed in the memory
address 1776 and that we write the following:
andy = 25;
fred = andy;
ted = &andy;
the result is shown in the following diagram:

5
Cont’d...
A variable storing a memory address is called a pointer
(like ted in the previous example) as it points to a specific
memory location whose address it is storing under its
name.

6
Cont’d...
Reference operator (*)
 To access the value stored in the variable pointed by pointer
just by preceding the pointer identifier with the reference
operator asterisk(*), that can be literally translated to "value
pointed by".
* mypointer can be read as "value pointed by mypointer".
 Therefore, following with the values of the previous example,
if we write:
beth = *ted;
 Read as: "beth equal to value pointed by ted"
 beth would take the value 25, since ted is 1776, and the value
pointed by 1776 is 25.
7
Cont’d...

 Notice the difference of including or not including the


reference asterisk :
beth = ted; // beth equal to ted ( 1776 )
beth = *ted; // beth equal to value pointed by ted ( 25 )

8
Cont’d...
 At this point, and following with the same example initiated
above where:
andy = 25;
ted = &andy;
you should be able to clearly see that all the following
expressions are true:
andy == 25
&andy == 1776
ted == 1776
*ted == 25

9
Cont’d...
 The general form of a pointer declaration is:
type * pointer_name;
 where type is the type of data pointed, not the type of the
pointer itself.
For example:
int * a; //creates integer pointer a
char * b; // creates a character pointer b
float * c; // creates a float pointer c

Multiple pointers require multiple asterisks
int *myPtr1, *myPtr2; 10
Cont’d...
 Two special operators * and & are used with
pointers.
 The & returns the memory address of its operand
(usually a variable).
 The & is used to in initialize a pointer to point to a
variables address.
Example:
int i=25 ; // declares an int variable i
int * a ; // declares an int pointer a
a= & i ; // initialises a; stores the memory address of i into a
11
Cont’d...
 The pointer operator, *, does the reverse of &.
 The unary operator * returns the value of the variable
located at the address following it.
Example: Suppose address of i is 1776
Output:
int i =80;
7
int j; 80
int * a; 1776
a=&i;
j =* a ; // the value (80) stored in the address it points to
* a=7 ; // puts 7 at address (&i) pointed by a
cout << i<<endl;
cout << j<<endl;
cout << a <<endl; 12
Cont’d...
#include <iostream>
Output:
using namespace std;
Value1==10
// my first pointer
int main (){ value2==20
int value1 = 5, value2 = 15;
int * mypointer;
mypointer = &value1;
*mypointer = 10;
mypointer = &value2;
*mypointer = 20;
cout << "value1==" << value1 << endl;
cout<<"value2==" << value2;
} 13
Cont’d...
//Here is an example a bit more complicated:
#include <iostream> Output:
using namespace std; Value1==10
int main (){
value2==20
int value1 = 5, value2 = 15;
int *p1, *p2; // more pointers
p1 = &value1; // p1 = address of value1
p2 = &value2; // p2 = address of value2
*p1 = 10; // value pointed by p1 = 10
*p2 = *p1; // value pointed by p2 = value pointed by p1
p1 = p2; // p1 = p2 (v alue of pointer copied)
*p1 = 20; // value pointed by p1 = 20
cout << "value1==" << value1 << endl;
cout<<" value2==" << value2;
} 14
Pointers and Arrays

C++ interprets the name of an array as a pointer
pointing to the first element of the array.

For example, supposing these two declarations:
int numbers [20];
int * p;
the following allocation would be valid:
p = numbers;

15
Cont’d...
 The only difference is that we could assign another value
to the pointer p whereas numbers will always point to the
first of the 20 integer numbers of type int with which it
was defined.
 So, unlike p, that is an ordinary variable pointer, numbers
is a constant pointer (indeed an array name is a constant
pointer).
 Therefore, although the previous expression was valid, the
following allocation is not:
numbers = p;
 because numbers is an array (constant pointer), and no
values can be assigned to constant identifiers. 16
Cont’d...
 Due to the character of variables all the expressions that include pointers in the following
example are perfectly valid:
#include <iostream>
using namespace std;
int main (){ Output:
int numbers[5];
int * p;
10, 20, 30, 40, 50,
p = numbers;
*p = 10;
p++;
*p = 20;
p = &numbers[2];
*p = 30;
p = numbers + 3;
*p = 40;
p = numbers;
*(p+4) = 50;
for (int n=0; n<5; n++)
cout << numbers[n] << ", ";
}
17
Cont’d...
 Since name of an array (array name) is a pointer to its first
element, the array name +1 gives the address of the second
element of the array, array name +2 gives the address of
the third element and so forth.
 For example, both following expressions:
a[5] = 0; // a [offset of 5] = 0
*(a+5) = 0; // pointed by (a+5) = 0

are equivalent and valid either if a is a pointer or if it is
an array.

18
Pointer initialization
 When declaring pointers we may want to explicitly
specify to which variable we want them to point,
int number;
int *tommy = &number;
this is equivalent to:
int number;
int *tommy;
tommy = &number;

19
Cont’d….
 You must consider that at the moment of declaring a
pointer, the asterisk (*) indicates only that it is a pointer,
it in no case indicates the reference operator (*).
 Remember, they are two different operators, although they
are written with the same sign.
 Thus, we must take care not to confuse the previous with:
int number;
int *tommy;
*tommy = &number;
that anyway would not have much sense in this case.

20
Cont’d...
 As in the case of arrays, the compiler allows the special case
that we want to initialize the content at which the pointer points
with constants at the same moment as declaring the variable
pointer:
char * terry = "hello";
 In this case static storage is reserved for containing "hello" and
a pointer to the first char of this memory block (that
corresponds to 'h') is assigned to terry.

21
Cont’d...
 If we imagine that "hello" is stored at addresses 1702 and
following, the previous declaration could be outlined thus:

 It is important to indicate that terry contains the value


1702 and not 'h' nor "hello", although 1702 points to these
characters.

22
Cont’d...
 The pointer terry points to a string of characters and can be
used exactly as if it was an Array (remember that an array is
just a constant pointer).
 For example, if our temper changed and we wanted to replace
the 'o' by a '!' sign in the content pointed by terry, we could do
it by any of the following two ways:
terry[4] = '!';

*(terry+4) = '!';

23
Arithmetic of pointers

Only addition and subtraction operations are allowed
to be conducted.

When we saw the different data types that exist, we
saw that some occupy more or less space than others
in the memory.

For example, in the case of integer numbers, char
occupies 1 byte, short occupies 2 bytes and long
occupies 4.

Let's suppose that we have 3 pointers:
char *mychar;
short *myshort;
long *mylong;
24
Cont’d...

They point to memory locations 1000, 2000 and 3000
respectively.
So if we write:
mychar++;
myshort++;
mylong++;
 mychar, as you may expect, would contain the value 1001.
Nevertheless, myshort would contain the value 2002, and
mylong would contain 3004.
 The reason is that when adding 1 to a pointer we are making
it to point to the following element of the same type with
which it has been defined, and therefore the size in bytes of
the type pointed is added to the pointer.
25
Cont’d...

 This is applicable both when adding and subtracting any


number to a pointer. It would happen exactly the same if we
write:
mychar = mychar + 1;
myshort = myshort + 1;
mylong = mylong + 1;
26
Cont’d...

It is important to warn you that both increase (++) and
decrease (--) operators have a greater priority than
the reference operator asterisk (*), therefore the
following expressions may lead to confusion:
*p++;
*p++ = *q++;

The first one is equivalent to *(p++) and what it does
is to increase p (the address where it points to - not the
value that contains).

27
Cont’d...

In the second, because both increase operators (++) are
after the expressions to be evaluated and not before, first
the value of *q is assigned to *p and then both q and p are
increased by one. It is equivalent to:
*p = *q;
p++;
q++;

Like always, I recommend you use parenthesis () in order
to avoid unexpected results.

28
Pointers to pointers
 C++ allows the use of pointers that point to pointers,
that these, in its turn, point to data. In order to do that
we only need to add an asterisk (*) for each level of
reference:
char a;
char * b;
char ** c;
a = 'z';
b = &a;
c = &b;

29
Cont’d...

Supposing the randomly chosen memory locations of
7230, 8092 and 10502:


c is a variable of type (char **) with a value of 8092

*c is a variable of type (char*) with a value of 7230

**c is a variable of type (char) with a value of 'z'

30
void pointers
 The type of pointer void is a special type of pointer.
 Void pointers can point to any data type, from an
integer value or a float to a string of characters.
 Its sole limitation is that the pointed data cannot be
referenced directly (we can not use reference asterisk
* operator on them), since its length is always
undetermined, and

For that reason we will always have to resort to type
casting or

Assignations to turn our void pointer to a pointer of a
concrete data type to which we can refer.

31
Cont’d...
#include <iostream>
Output:
using namespace std;
9, 40
int main (){
int b = 9;
float c = 12.4;
float* d;
void* e;
d=&c;
*d=40;
e=&b;
cout << (*((int*)e)) << ","<<c;
} 32
Pointers to functions
 C++ allows operations with pointers to functions.
 In order to declare a pointer to a function we must
declare it like the prototype of the function except the
name of the function is enclosed between parenthesis
() and a pointer asterisk (*) is inserted before the
name.
 It might not be a very handsome syntax, but that is
how it is done in C++.
 Example
void centimize(double* ptrd)

33
Cont’d...
// arguments passed by pointer Output:
#include <iostream> Var = 10.0 inches
using namespace std; Var = 25.4 centimeters
void centimize(double* ptrd){
*ptrd *= 2.54; //*ptrd is the same as var
}
int main(){
double var = 10.0; //var has value of 10 inches
cout << "var = " << var << " inches" << endl;
centimize(&var); //change var to centimeters
cout << "var = " << var << " centimeters" << endl;
return 0;
} 34
Cont’d...
 The function centimize() is declared as taking an argument that is a
pointer to double : void centimize(double*) // argument is pointer to
double
 When main() calls the function, it supplies the address of the variable as
the argument: centimize(&var); Remember that this is not the variable
itself, as it is in passing by reference, but the variable’s address.
 Because the centimize() function is passed an address, it must use the
dereference operator,
 *ptrd , to access the value stored at this address:
 *ptrd *= 2.54; // multiply the contents of ptrd by 2.54 of course this is
the same as *ptrd = *ptrd * 2.54; // multiply the contents of ptrd by 2.54
where the standalone asterisk means multiplication.
 Passing a pointer as an argument to a function is in some ways similar
to passing a reference. They both permit the variable in the calling
program to be modified by the function.
35
Dynamic memory
■ Until now, in our programs, we have only had as much
memory as we have requested in declarations of variables,
arrays and other objects that we included, having the size
of all of them fixed before the execution of the program.
■ But, what if we need a variable amount of memory that
can only be determined during the program execution
(runtime), for example, in case that we need an user input
to determine the necessary amount of space?
■ The answer is dynamic memory, for which C++
integrates the operators new and delete.

36
Cont’d...
Operators new and new[ ]

In order to request dynamic memory, the operator new
exists.

new is followed by a data type and optionally the
number of elements required within brackets [].

It returns a pointer to the beginning of the new block of
assigned memory. Its form is:
pointer = new type
or
pointer = new type [elements]

The first expression is used to assign memory to contain
one single element of type.

The second one is used to assign a block (an array) of
elements of type.
37
Cont’d...
For example:
int * bobby;
bobby = new int [5];

In this case, the operating system has assigned space for 5
elements of type int in a heap and it has returned a pointer
to its beginning that has been assigned to bobby.

Therefore, now, bobby points to a valid block of memory
with space for 5 int elements.

38
Cont’d...
 You could ask what is the difference between declaring a
normal array and assigning memory to a pointer as we have
just done.
 The most important one is that the size of an array must be a
constant value, which limits its size to what we decide at the
moment of designing the program before its execution, whereas
the dynamic memory allocation allows assigning memory
during the execution of the program using any variable,
constant or combination of both as size.

39
Cont’d...

The dynamic memory is generally managed by the operating
system, and in multitask interfaces it can be shared between
several applications, so there is a possibility that the memory
exhausts.

If this happens and the operating system cannot assign the
memory that we request with the operator new, a null pointer
will be returned.

For that reason it is recommended to always check to see if the
returned pointer is null after a call to new.
int * bobby;
bobby = new int [5];
if (bobby == NULL) {
// error assigning memory. Take measures.
};
40
Cont’d...
Operator delete

Since the necessity of dynamic memory is usually limited
to concrete moments within a program, once it is no longer
needed it should be freed so that it becomes available for
future requests of dynamic memory.

The operator delete exists for this purpose, whose form
is:
delete pointer;
or
delete [] pointer;

The first expression: to delete memory allocated for a single
element, and

The second one for memory allocated for multiple elements
(arrays).
41
Cont’d...
#include <iostream> // introduces operator new
#include <cstring>
using namespace std;
int main(){
char* str = "Idle hands are the devil’s workshop.";
int len = strlen(str); //get length of str
char* ptr; //make a pointer to char
ptr = new char[len+1]; //set aside memory: string + ‘\0’
strcpy(ptr, str); //copy str to new memory area ptr
cout << "ptr=" << ptr << endl; //show that ptr is now in str
delete[] ptr; //release ptr’s memory
return 0;
Output:
}
Ptr= Idle hands are the devil’s workshop.
42
Cont’d...

NULL is a constant value defined in many fold C++ libraries
specially designed to indicate null pointers.

In case that this constant is not defined you can do it yourself
by defining it to 0:
#define NULL 0

It is indifferent to put 0 or NULL when checking pointers, but
the use of NULL with pointers is widely extended and it is
recommended for greater legibility.

The reason is that a pointer is rarely compared or set directly to
a numerical literal constant except precisely number 0, and this
way this action is symbolically masked.

43
Cont’d...
Dynamic memory in ANSI-C

Operators new and delete are exclusive of C++ and
they are not available in C language.

In C language, in order to assign dynamic memory we
have to resort to the library stdlib.h.

We are going to see them, since they are also valid in
C++ and they are used in some existing programs.

44
The function malloc
 It is the generic function to assign dynamic memory to
pointers.
 Its prototype is:
void * malloc (size_t nbytes);
 where nbytes is the number of bytes that we want to be
assigned to the pointer.
 The type size_t is defined in stdlib.h as, more or less, an
unsigned integer.
 The function returns a pointer of type void*, which is the
reason why we have to type cast the value to the type of the
destination pointer, for
Example:
char * ronny;
ronny = (char *) malloc (10);
45
Cont’d...

This assigns to ronny a pointer to an usable block of 10
bytes.

When we want to assign a block of data of a different type
other than char (different from 1 byte) we must multiply the
number of elements desired by the size of each element.
Luckily we have at our disposition the operator sizeof, that
returns the size of the type of a concrete datum.
int * bobby;
bobby = (int *) malloc (5 * sizeof(int));

This piece of code assigns to bobby a pointer to a block of 5
integers of type int, this size can be equal to 2, 4 or more
bytes according to the system where the program is
compiled.
46
The function calloc

calloc is very similar to malloc in its operation, its main
difference is in its prototype:
void * calloc (size_t nelements, size_t size);

since it admits 2 parameters instead of one.

These two parameters are multiplied to obtain the total size of
the memory block to be assigned.

Usually the first parameter (nelements) is the number of
elements and the second one (size) serves to specify the size of
each element.

For example, we could define bobby with calloc thus:
int * bobby;
bobby = (int *) calloc (5, sizeof(int));

Another difference between malloc and calloc is that calloc
initializes all its elements to 0.
47
The function realloc

It changes the size of a block of memory already
assigned to a pointer.
void * realloc (void * pointer, size_t size);

Pointer parameter receives a pointer to an already
assigned memory block or a null pointer, and size specifies
the new size that the memory block shall have.

The function assigns size bytes of memory to the pointer.

48
Cont’d...

The function may need to change the location of the
memory block so that the new size can fit, in that case
the present content of the block is copied to the new
one to guarantee that the existing data is not lost.

The new pointer is returned by the function.

If it has not been possible to assign the memory block
with the new size it returns a null pointer but the
pointer specified as parameter and its content remains
unchanged.

49
The function free

It releases a block of dynamic memory previously
assigned using malloc, calloc or realloc.
void free (void * pointer);

This function must only be used to release memory
assigned with functions malloc, calloc and realloc.

50
Thank You !

51

You might also like

pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy