0% found this document useful (0 votes)
59 views42 pages

CP Chapter 6

Pointers provide an indirect way to access and manipulate data in memory. A pointer variable stores the memory address of another variable. The & operator returns the memory address of a variable. The * operator accesses the value at the memory address stored in a pointer. Pointers must be declared with a data type specifying what type of data they will point to. Dynamic memory allocation with operators new and delete allow programs to determine memory needs at runtime rather than compile time.

Uploaded by

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

CP Chapter 6

Pointers provide an indirect way to access and manipulate data in memory. A pointer variable stores the memory address of another variable. The & operator returns the memory address of a variable. The * operator accesses the value at the memory address stored in a pointer. Pointers must be declared with a data type specifying what type of data they will point to. Dynamic memory allocation with operators new and delete allow programs to determine memory needs at runtime rather than compile time.

Uploaded by

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

Pointers

1
2
Pointers …. Definition
 Pointer: - A variable that stores address of another variable
 A pointer is simply the address of a memory location and
provides an indirect way of accessing data in memory.
 Variables are locations in the computer's memory which can be
accessed by their identifier (their name).
 When a variable is declared, the memory needed to store its value
is assigned a specific location in memory (its memory address).
 The memory allocation is the task of an operating system
eg. int myvar=25;
3 Cont..

Reference operator (&)


 The address of a variable can be obtained by preceding the name
of a variable with an ampersand sign (&), known as reference
operator, and which can be literally translated as "address of".
For example:

x myvar
x = &myvar;

 This would assign the address of variable myvar to x ; we are no


longer assigning the content of the variable itself to x, but its
address.
4 Cont..

 Let's assume that myvar is placed during runtime in the memory


address 1776.
Consider the following code fragment:
myvar = 25;
foo = &myvar;
bar = myvar;

 The variable that stores the address of another variable (like


foo in the previous example) is called a pointer.
5 Cont..
Dereference operator (*)
 Pointers are said to "point to" the variable whose address they
store.
 pointers can also be used to access the value of the variable they
point to.
 This is done by preceding the pointer name with the dereference
operator (*). The operator itself can be read as "value pointed to
by".
 Therefore, following with the values of the previous example, the
following statement:
6 Cont..
baz = *foo; // baz equal to value pointed to by foo (25)
 This could be read as: "baz equal to value pointed to by foo", and
the statement would actually assign the value 25 to baz, since foo
is 1776(address), and the value pointed to by 1776 (following the
example above) would be 25.
7

Declaring Pointers
 Due to the ability of a pointer to directly refer to the value that it
points to, a pointer has different properties when it points to a
char than when it points to an int or a float.
 Once dereferenced, the type needs to be known. And for that, the
declaration of a pointer needs to include the data type the pointer
is going to point to.
 The declaration of pointers follows this syntax:
type * name;
8 Cont..
 where type is the data type pointed to by the pointer. This type is
not the type of the pointer itself, but the type of the data the
pointer points to. For example:
int * num;
char * ch;
double * dec;
 These are three declarations of pointers. Each one is intended to
point to a different data type, but, in fact, all of them are pointers.
 The value of a pointer variable is the address to which it points.
For example, given the definitions
int a;
we can write:
 num= &a;
9 Cont..
num= &a;
 The symbol & is the address operator; it takes a variable as
argument and returns the memory address of that variable. The
effect of the above assignment is that the address of a is assigned
to num.
 *num is equivalent to a
 In general, the type of a pointer must match the type of the
data it is set to point to. A pointer of type void*, however, will
match any type.
 This is useful for defining pointers which may point to data of
different types, or whose type is originally unknown
10 Cont..
 A pointer may be cast (type converted) to another type. For
example, depending above three different declaration
ch= (char*) num;
converts num to char pointer before assigning it to ch.
11 Example

#include <iostream.h>
int main ()
{ int firstvalue, secondvalue;
int * mypointer; Output
mypointer = &firstvalue; firstvalue is 10
*mypointer = 10; secondvalue is 20
mypointer = &secondvalue;
*mypointer = 20;
cout << "firstvalue is " << firstvalue << '\n';
cout << "secondvalue is " << secondvalue << '\n';
return 0;
}
12 Example 2
#include <iostream.h>
int main () Output
{ int firstvalue = 5, secondvalue = 15; firstvalue is 10
int * p1, * p2; Secondvalue is 20
p1 = &firstvalue; // p1 = address of firstvalue
p2 = &secondvalue; // p2 = address of secondvalue
*p1 = 10; // value pointed to by p1 = 10
*p2 = *p1; // value pointed to by p2 = value pointed by p1
p1 = p2; // p1 = p2 (value of pointer is copied)
*p1 = 20; // value pointed by p1 = 20
cout << "firstvalue is " << firstvalue << '\n';
cout << "secondvalue is " << secondvalue << '\n';
return 0;
}
13

Dynamic Memory
 All memory needs were determined before program
execution by defining the variables needed.
 But there may be cases where the memory needs of a
program can only be determined during runtime.
 dynamic memory is program stack and heap.
 static memory is program stack.
 program stack is used for storing global variables and
stack frames for function calls.
 The heap is used for dynamically allocating memory
blocks during program execution.
E.g. when the memory needed depends on user input.
14 Cont..
 On dynamic memory cases, programs need to dynamically
allocate memory, for which the C++ language integrates
the operators new and delete.
Operators new and new[]
 Dynamic memory is allocated using operator new. new is
followed by a data type specifier and, if a sequence of more than
one element is required, the number of these within brackets []. It
returns a pointer to the beginning of the new block of memory
allocated. Its syntax is:
pointer = new type;
pointer = new type [number_of_elements];
The first expression is used to allocate memory to contain one single
element of type .
The second one is used to allocate a block (an array) of elements of
type , where number_of_elements is an integer value representing the
amount of these.
15 Cont..
 For example:
int * foo;
foo = new int [5];
In this case, the system dynamically allocates space for five elements
of type int and returns a pointer to the first element of the sequence,
which is assigned to foo (a pointer).
Therefore, foo now points to a valid block of memory with space for
five elements of type int.
16 Cont..
 Here, foo is a pointer, and thus, the first element pointed to by foo
can be accessed either with the expression foo[0] or the
expression *foo (both are equivalent).
 The second element can be accessed either with foo[1] or
*(foo+1), and so on...
 There is a substantial difference between declaring a normal array
and allocating dynamic memory for a block of memory using
new.
 The most important difference is that the size of a regular array
needs to be a constant expression, and thus its size has to be
determined at compile time, whereas the dynamic memory
allocation performed by new allows to assign memory during
runtime using any variable value as size.
17 Cont..
Operators delete and delete[]
 In most cases, memory allocated dynamically is only needed
during specific periods of time within a program; once it is no
longer needed, it can be freed so that the memory becomes
available again for other requests of dynamic memory.
 This is the purpose of operator delete, whose syntax is:
delete pointer;
delete[ ] pointer;
18 Cont..
delete pointer;
delete[ ] pointer;
 The first statement releases the memory of a single element
allocated using new, and
 the second one releases the memory allocated for arrays of
elements using new and a size in brackets ([ ]).
 The value passed as argument to delete shall be either a pointer to
a memory block previously allocated with new, or a null pointer
(in the case of a null pointer, delete produces no effect).
Example
19
#include <iostream.h>
int main ()
{ int i,n;
int * p;
cout << "How many numbers would you like to type? ";
cin >> i;
p= new int[i];
for (n=0; n<i; n++)
{
cout << "Enter number: ";
cin >> *(p+n);
}
cout << "You have entered: ";
for (n=0; n<i; n++)
cout << *(p+n) << ", ";
delete[ ] p;
return 0;
}
20 Exercise

 Write a program to receive n integers from the user and display


smallest number from the array. [Use an array of integers whose
size is determined dynamically]
 Write a program to receive n integers from the user and display
them in ascending order. [Use an array of integers whose size is
determined dynamically]
21 Pointer Arithmetic
 Only addition and subtraction operations are allowed (++,--, +,-).
 Both addition and subtraction have a slightly different behavior with
pointers, according to the size of the data type to which they point.
 Pointer arithmetic is not the same as integer arithmetic, because the
outcome depends on the size of the object pointed to.
For example: char always has a size of 1 byte, short is generally larger
than that, and int and long are even larger; the exact size of these being
dependent on the system.
 let's imagine that in a given system, char takes 1 byte, short takes 2
bytes, and long takes 4 bytes. And the following declaration:
char *mychar;
short *myshort;
long *mylong;
 Assume also that they point to the memory locations 1000, 2000, and
3000, respectively. Therefore, if we write:
22
Cont..
++mychar;

++myshort;

++mylong;
23 Cont..
 *p++ // same as *(p++): increment pointer, and dereference
unincremented address
 *++p // same as *(++p): increment pointer, and dereference
incremented address
 ++*p // same as ++(*p): dereference pointer, and increment the
value it points to
 (*p)++ // dereference pointer, and post-increment the value it points to

*p = *q;
*p++ = *q++; ++p;
is Equivalent to:
++q;
 Like always, parentheses reduce confusion by adding legibility to
expressions.
Example
24 char *str = "HELLO";
int nums[] = {10, 20, 30, 40};
int *ptr = &nums[0]; // pointer to first element
 str++ advances str by one char (i.e., 1 byte) so that it points to
the second character of "HELLO", whereas ptr++ advances ptr
by one int (i.e., 4 bytes) so that it points to the second element of
nums.
For str for ptr
25 Cont..
 It follows, therefore, that the elements of "HELLO" can be
referred to as *str, *(str + 1), *(str + 2), etc. Similarly, the
elements of nums can be referred to as *ptr, *(ptr + 1), *(ptr + 2),
and *(ptr + 3).
 For example: depending above example subtracting two
pointers of the same type.
int *ptr1 = &nums[1];// ptr1= 0x23ff38
int *ptr2 = &nums[3];// ptr2= 0x23ff40
int n = ptr2 - ptr1; // n becomes 2
26 Pointers and Arrays
 Arrays work like pointers to their first elements.
 An array can always be implicitly converted to the pointer of the
proper type.
int myarray [20];
int * mypointer;
The following assignment operation would be valid:
mypointer = myarray; this means mypointer = &myarray[0];
 The main difference is mypointer can be assigned a different
address, whereas myarray can never be assigned anything, and
will always represent the same block of 20 elements of type int.
myarray = mypointer; // this is invalid
27
Cont..
 For example:
int iarray[3] = {400, 657, 888};
int *iptr = iarray;// *iptr =& iarray[0];
assume address is given in the table so we can access address and array
elements as the following table .and also * (iarray+1) or *(iptr++) can
access value.
28 Example
#include <iostream.h>
int main ()
{
int numbers[5];
Output
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] << ", ";
return 0;
}
29 Pointers and String literals
 String literals are arrays that contain all its characters plus the
terminating null-character.
Example: The following statement:
char * foo = "hello";
 This declares an array with the literal representation for "hello",
and then a pointer to its first element is assigned to foo. Assume
“hello” is stored at 1702 memory address:
30 Cont..

char * foo = "hello";


 foo can be used to access the characters in the same way arrays of
null-terminated character sequences are. For example:
*(foo+4)
foo[4]
 Both expressions have a value of 'o' (the fifth element of the
array).
31 Pointers and Function
1. Calling by reference using pointer
 A pointer can be a parameter. It works like a reference parameter
to allow change to argument from within function.
When Pointers are used as Function Parameters, it is similar to a call
by reference.
#include <iostream>
using namespace std;
void swap(int *x,int *y)
{ int temp;
temp = *x;
*x = *y;
*y = temp;
}
32 Cont..
int main()
Output
{
num1=5 num2=9
int num1=5,num2=9; num1=9 num2=5
cout<<"num1="<<num1;
cout<<"\t num2="<<num2<<endl;
swap(&num1, &num2);
cout<<"num1="<<num1;
cout<<"\t num2="<<num2<<endl;
return 0;
}
33 2. Function Pointers

 C++ allows operations with pointers to functions.


 The typical use of this is for passing a function as an
argument to another function.
 Pointers to functions are declared with the same syntax as a
regular function declaration, except that the name of the function
is enclosed between parentheses () and an asterisk (*) is inserted
before the name:
int (*fptr)(int,int);
34 Example
#include <iostream>
using namespace std;
int addition (int a, int b) Output
{ return (a+b); }
int subtraction (int a, int b) 8
{ return (a-b); }
int operation (int x, int y, int
(*functocall)(int,int))
{
int g;
g = (*functocall)(x,y);
return (g);
}
int main ()
{
int m,n;
int (*minus)(int,int) = subtraction;
m = operation (7, 5, addition);
n = operation (20, m, minus);
cout <<n;
return 0;
}
35 Reference
 A reference variable is an alias, that is, another name for an already
existing variable. Once a reference is initialized with a variable,
either the variable name or the reference name may be used to refer
to the variable.
References vs Pointers
 References are often confused with pointers but three major
differences between references and pointers are:
 You cannot have NULL references. You must always be able to
assume that a reference is connected to a legitimate piece of
storage.
 Once a reference is initialized to an object, it cannot be changed to
refer to another object. Pointers can be pointed to another object at
any time.
 A reference must be initialized when it is created. Pointers can be
initialized at any time.
36 Cont..
Creating References in C++
 Think of a variable name as a label attached to the variable's
location in memory. You can then think of a reference as a second
label attached to that memory location. Therefore, you can access
the contents of the variable through either the original variable
name or the reference.
 The notation for defining references is similar to that of
pointers, except that & is used instead of *.
 For example, suppose we have the following example:
int i = 17;
We can declare reference variables for i as follows.
int &r = i;
Read the & in these declarations as reference. Thus, read
declaration as "r is an integer reference initialized to i"
37
Example
#include<iostream>
using namespace std; Output
int main ()
{ Value of i:5
// declare simple variables Value of i reference : 5
int i;
// declare reference variables
int &r = i;
i = 5;
cout << "Value of i : " << i << endl;
cout << "Value of i reference : " << r << endl;
return 0;
}
38
Example 2 (calling reference without
pointer)

#include <iostream>
using namespace std;
void Swap(int &x, int &y){ // pass-by-reference Output
int temp = x; 20, 10
x = y;
y = temp;
}
int main()
{
int i = 10, j = 20;
Swap(i,j);
cout <<i<< ", " <<j<< '\n';
return 0;
}
39 Typedefs
 Typedef is a syntactic facility for introducing symbolic names for
data types. Just as a reference defines an alias for an object, a
typedef defines an alias for a type.
 Its main use is to simplify otherwise complicated type
declarations as an aid to improved readability.
 Here are a few examples:
typedef char *String;
Typedef char Name[12];
typedef unsigned int uint;
40 Cont..
 The effect of these definitions is that String becomes an alias for
char*, Name becomes an alias for an array of 12 chars, and
uint becomes an alias for unsigned int.
Therefore: Stringstr;// is the same as: char *str;
Name name;// is the same as: char name[12];
uint n;// is the same as: unsigned int n;
41 Example:
#include <iostream>
using namespace std;
double Average (int nums[], int size)
{
typedef int Register;
double average = 0;
for (Register i = 0; i < size; ++i)
average += nums[i];
return average/size;
}
42 Cont..

int main()
{
int nums[3] = {5, 10, 15};
cout << Average (nums,3) << endl;
return 0;
}

You might also like