0% found this document useful (0 votes)
72 views28 pages

Pointers

Pointers allow variables to be accessed indirectly through memory addresses. A pointer variable stores the address of another variable. Pointer arithmetic can be performed by adding or subtracting integers from pointers, which increments/decrements the address by the size of the pointed-to type. Pointers can be assigned, compared for equality, and dereferenced using asterisk to access the value at the addressed location. Dereferencing a null pointer causes undefined behavior.

Uploaded by

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

Pointers

Pointers allow variables to be accessed indirectly through memory addresses. A pointer variable stores the address of another variable. Pointer arithmetic can be performed by adding or subtracting integers from pointers, which increments/decrements the address by the size of the pointed-to type. Pointers can be assigned, compared for equality, and dereferenced using asterisk to access the value at the addressed location. Dereferencing a null pointer causes undefined behavior.

Uploaded by

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

Pointers

When you declare a variable in C, you are actually putting aside a portion of the
computer’s memory and labeling it with the variable name
 The amount of memory that is used depends on the type of the variable: an int is
4 bytes, a char is 1 byte, a double is 8 bytes.
 The location in memory is the memory address of the variable

For example, the declaration int x; results in 4 bytes of memory being put aside for
an integer
x

When you assign to the variable, you are storing a value in the memory at that address.
For example, x=5; results in
x
5

Normally a variable name in an expression stands for the value of that variable. For
example, x=x+4; should be read “set the value of x to be the old value of x plus 4”

When the & operator is placed before the name of a variable, the address-of operator
returns the memory address of the variable/operand.
For example, cout<<&x; we will not get the value stored by the variable, we get the
address of that variable, where it actually stores the data.

A pointer is a type of variable, special for holding the address of some other variable. In
the earlier example we retrieved the address of the ‘x’ variable by using ‘&x’. Now we
can store it in this special type of variable, the pointer.
We say that a pointer p “points” to a variable x if its value is the address of x.

To create (declare) a pointer to a variable,


 Specify the type of variable it actually points to (because a variable can occupy
more or less space in the memory depending on its type).
 The “*” is used to show that the variable is a pointer.
For example, the declaration int*p; means,
 p points to a variable of int type.
 The variable p must hold a memory address of an int.

To set the pointer p to point to the integer variable x, set the value of the pointer variable
p to be the address of x, p=&x;

x
p 5

1
Let’s see an example:
double i=6;
double*p; // p is a pointer to double
// p must hold a memory address of a double
i
6 p

To set the pointer p to point to the double variable i


p=&i;
i
p 6

Now, if we print the value of p, we see that it equals the address of i


cout<<p; is the same as cout<<&i;

To set a pointer to point to nothing, set it to the reserved value NULL or, alternatively, to
the value 0
P=NULL; or p=0;

Accessing a variable through a pointer


Because a pointer holds an address rather than a value, it has two parts:
 The pointer itself holds the address.
 That address points to a value.

Assume pointer p is a pointer pointing to variable i. We use the * operator (called the
dereferencing operator) to access i from p.
The expression *p can be read ”the value at the memory location pointed to by p”.
cout<<*p; is the same as cout<<i;

Warning- never dereferencing a pointer whose value is 0 or NULL.


For example,
int *w; //w is a pointer to int
w=NULL; //w points to nothing in memory
cout<<*w; //run-time error

Example,
int y=5; y
60000 5

int *yptr; //yptr is of type int *


//yptr is a pointer to int
yptr
50000

2
To set the pointer yptr to point to the variable y
yptr = &y; // yptr points to y
//yptr holds the address of y
yptr y
50000 60000 60000 5

y
5
yPtr

cout<<&y; //60000
cout<<yptr; //60000
We can access the content of the variable y using its pointer yptr
cout<<*yptr; //5

Examples,
int *w; //w is a pointer to int t
int t=5; 5
w=&t; //w points to t w
cout<<t; //5
cout<<*w; //5 t
6
t++; //t = 6 w
cout<<*w; //6
t
*w=*w+2; //*w is 8 8
cout<<*w; //8 w
cout<<t; //8

cout<<&t; // 0012FF78
cout<<w; //0012FF78
//The address displayed may be any address in memory. But it will be the same
for w or &t.
//* and & are inverses (they cancel each other out)
cout<<&*w; // 0012FF78
cout<<*&w; // 0012FF78

Example,
float r; int *w; //w is a pointer to int
w=&r; //syntax error
*w=5; //compiler error
Note: if several pointers are declared in the same line, each must be proceeded by a *:
int *w,*p,*z; //w is a pointer to int

3
Pointers Assignment/Comparison
 Assignment /comparison to other pointers of the same type is valid
 pointer1=pointer2 is valid, address is copied from pointer2 to pointer1, that
is both pointers points to the same value.
 pointer1<pointer2, pointer1>pointer2, pointer1==pointer2 is valid, the
result is true or false.
 Assignment /comparison to the value 0 ONLY is allowed pointer = =0,
pointer=0 is valid.

Example,
int i=2;
double j=3;
int *ip=&i;
double *jp=&j;
ip=jp; //syntax error
if(ip= =jp) //syntax error
ip=3000; //Error
Example,
int i=2;
int j=3;
int *ip=&i;
int *jp=&j;

0x002000 2 i
:
0x002008 3 j
:
0x002012 0x002000 ip
:
0x002020 0x002008 jp

After ip=jp; After *ip=*jp;


0x002000 2 i 0x002000 2 3 i
: :
0x002008 3 j 0x002008 3 j
: :
0x002012 0x002008 ip 0x002012 0x002000 ip
: :
0x002020 0x002008 jp 0x002020 0x002008 jp
cout<<ip;//0x002008 cout<<ip;//0x002000
cout<<jp; //0x002008 cout<<jp; //0x002008
cout<<*ip; //3 cout<<*ip; //3
cout<<*jp; //3 cout<<*jp; //3

4
Example, given:
int a=3;
int b=8;
int c=12;
int *ap=&a;
int *bp=&b;
int *cp=&c;
ap=bp;
*bp=*cp
Which of the following evaluates to true?
 b= =c? //true
 bp= =cp? //false
 *ap= =c? //true

Operations with pointers


1) Operations with the values pointed by pointers: the same as the operations with
normal variables.
Example,
double A=20;
double B=12;
double*Ap=&A;
double*Bp=&B;
(*Ap)++;
(*Bp)--;
(*Ap)-=(*Bp);
cout<<*Ap; //10
cout<<*Bp; //11

2) Operations with the addresses stored in the pointers


1. pointer+pointer=Error
2. pointer*pointer=Error
3. pointer/pointer=Error
4. pointer-pointer=integer
5. pointer+integer=pointer
6. pointer-integer=pointer
7. pointer*integer=Error
8. pointer/integer=Error

 From above no arithmetic operations are possible on pointers except subtraction.


pointer1-pointer2 is the number of values between the two addresses.
Subtraction Result = Difference/size of object to which the pointer refers

 When we add an integer value to a pointer, the pointer is not simply incremented by
the value of the integer, but by that integer times the size of the object to which the
pointer refers.
New Address = Old Address + (integer * size of object)

5
 When we subtract an integer value from a pointer, the pointer is not simply
decremented by the value of the integer, but by that integer times the size of the
object to which the pointer refers.
New Address = Old Address - (integer * size of object)

 An integer may be represented by 2 or 4 bytes. A float is represented by 4 bytes. A


double is represented by 8 bytes. A character is represented by 1 byte.

Example, given: sizeof(int)=4bytes,


int a=8,b=5;
int *ap=&a,*bp=&b;
//suppose that ap contains the address 3000, bp contains the address 3004
cout<<ap+bp; //Error
cout<<ap*bp; //Error
cout<<ap/bp; //Error
cout<<ap*2; //Error
cout<<ap/2; //Error

cout<<ap-bp; //prints 1 not 4 (the number of elements from ap to bp)


cout<<ap+2; //prints 3008 not 3002
cout<<ap-2; // prints 2992 not 2998

The Relationship between Pointers & Arrays


• The elements in an array are stored in contiguous locations in memory.
• The name of the array name is a constant pointer that always points to the first
element in the array (i.e. a constant pointer means you can not change its address).

int A[]={2,4,6,8,10};
The array name A is a constant pointer to A[0]
The array name A is the same as &A[0]
Example,
if (A = =&A[0]) {…} //is always true
int x=5;
A=&x; // error
A++; // error

• Initializing a pointer to point to an array is equivalent to initializing the pointer to


point to the first element of the array.

int *p = &A[0];
or
int *p = A;

6
e.g.1, Given: sizeof (int)=4 bytes.
int A[]={2,4,6,8,10};
int *p = A; or int *p=&A[0];
What the output of each of the following?

cout<< p; //3000 3000 3004 3008 3012 3016


cout<<*p; //A[0]
++p;
cout<<p; //3004
cout<<*p; //A[1]
P A[0] A[1] A[2] A[3] A[4]
--p;
cout<<p; //3000
cout<<*p; //A[0]

p=p+3; // address 3012 (3000 + (3*4))


cout<<*p; //A[3]
p=p-3; // address 3000 (3012 - (3*4))
cout<<*p; //A[0]

cout<<(p+0); //3000
cout<<(p+1); //3004
cout<<(p+2); //3008
cout<<(p+3); //3012
cout<<(p+4); //3016
cout<<*(p+0); //A[0]
cout<<*(p+1); //A[1]
cout<<*(p+2); //A[2]
cout<<*(p+3); //A[3]
cout<<*(p+4); //A[4]

cout<<*(A+0); //A[0]
cout<<*(A+1); //A[1]
cout<<*(A+2); //A[2]
cout<<*(A+3); //A[3]
cout<<*(A+4); //A[4]

You can access the array elements via a pointer by either


 Using the array notation
 Or by dereferencing our pointer (pointer /offset notation)
A[i]=*(A+i)

7
e.g.2,
Given:
int b[5]={12,7,4,11,16};
int* bPtr=b;
What is the output of each of the following?
cout<<b[3]; //11
cout<<*(bPtr+3); //11
cout<<*(b+3); //11
cout<<*b+3; //15
cout<<*bPtr+3; //15
cout<<b[0]+3; //15
bPtr=&b[2];
cout<<*(bPtr+2); //prints b[4]

e.g.3,
Given:
int x[]={6,9,2,3,5};
int *P = x+2;
6 9 2 3 5

p following?
What is the output of each of the
cout<<*(P + 2); //5
cout<<*P; //2
P+=2;
cout<<*P; //5
cout<<*(P - 2); //2
cout<<*P; //5
P-=2;
cout<<*P; //2

cout<<++(*P); //3
cout<<(*P)++; //3
cout<<*P; //4

cout<<*++P<<endl; //3
cout<<*P<<endl; //3

cout<<*P++<<endl; //3
cout<<*P<<endl; //5

8
e.g.4, Given:
int a[10]={3,9,2,4,5,1,2,4,9,10};
int *p; int*Q;
What the output of each of the following?

p=&a[4];
Q=p+3;
*(Q-3)=*Q;
int x=Q-p;
cout<<x; //3
cout<<*(Q-1)-*(p+1); //1
p=*(Q-2)+Q;
cout<<*p; //9

e.g.5, Given:
int a[]={2,4,1,3,2,1,6};
int*p=a+5;
What the output of each of the following?
p--;
cout<<*p<<endl; //2
cout<<*--p<<endl; //3
cout<<++*++p<<endl; //3
cout<<++*p++<<endl; //4
cout<<*p<<endl; //1

e.g.6, declare and initialize an array of 10 floats then do the following using pointer
notation:
 Find the average of the elements
 Find the min/max of the elements

float a[10];float*p=a;
for(int i=0;i<10;i++){cin>>*p;p++;}

p=a;
float max=*p,min=*p,sum=0;
for(i=0;i<10;i++){
sum+=*p;
if(*p>max)max=*p;
if(*p<min)min=*p;
p++;
}
cout<<min<<" "<<max<<endl;
cout<<(sum/(p-a))<<endl;

9
e.g.7, declare and initialize an array of 10 doubles then do the following using pointer
notation:
 Print each one cell and skip the next
 Swap each 2 adjacent cells

double a[10];double*p=a;
for(int i=0;i<10;i++){cin>>*p;p++;}

p=a;
for(i=0;i<10;i+=2){
cout<<*p;
p+=2;}

p=a; double t;
for(i=0;i<10;i+=2){
t=*p;
*p=*(p+1);
*(p+1)=t;
p+=2;}

p=a;
for( i=0;i<10;i++){cout<<*p<<endl;p++;}

e.g.8, Given
int a[]={3,9,-2,4,5,20,15,14};
Sort the array in ascending order using pointer notation. Then find min/max

int*p=a;
for(int i=0;i<8;i++){
for(int j=i+1;j<8;j++){
if(*(p+i)>*(p+j)){
int t=*(p+i);
*(p+i)=*(p+j);
*(p+j)=t;
}
}
}
cout<<"min = "<<*p<<endl;
cout<<"max = "<<*(p+7)<<endl;

10
The difference between pointers to characters and other pointers

Examples,

int x[] = {1, 2, 3, 4};


int *xp=x;

cout<<x; //address of element 0


cout<<xp; //address of element 0
cout<< &x[0]; //address of element 0

cout<< x+1; //address of element 1


cout<< xp+1; //address of element 1
cout<< &x[1]; //address of element 1

cout<<x[1]; //2
cout<<*(x+1); //2
cout<<*(xp+1); //2
-----------------------------------------------------------
char c[] = "hello";
char *cp = c; //or char *cp = ”hello”;

cout<<c; //hello
cout<<cp; //hello
cout<< &c[0]; //hello

cout<<c+1; //ello
cout<<cp+1; //ello
cout<<&c[1]; //ello

cout<<c[1]; //e
cout<<*(cp+1); //e
cout<<*(c+1); //e
-----------------------------------------------------------
NOTES:

int x[] = {1, 2, 3, 4};


//cin>>x; //compiler error

int *xp=x;
//cin>>xp; //compiler error
-----------------------------------------------------------
char c[10];
cin>>c; //will not produce an error
//because c contains a valid address
//string length 9

11
char c[]=”hello”;
cin>>c; //will not produce an error
//because c contains a valid address
//string length 5
-----------------------------------------------------------
char c[10];
char *cp=c;
cin>>cp; //will not produce an error
//because cp contains a valid address
//string length 9
-----------------------------------------------------------
char c[]=”hello”;
char *cp=c;
cin>>cp; //will not produce an error
//because cp contains a valid address
//string length 5
-----------------------------------------------------------
char *cp;
//cin>>*cp; //run-time error because cp does not
contain //a valid address
Examples,
e.g.1:
int A[5]={7,5,3,1,8};
char B[]=”abcde”;
int *aptr=A+2;
char *bptr=B+2;
cout<<A; // address of element 0
cout<<B; // abcde
cout<<*A; //7
cout<<*B; //a
cout<<aptr; //address of element 2
cout<<bptr; //cde
cout<<*(aptr+1); //1
cout<<*(bptr+1); //d
cout<<*aptr+1; //4
cout<<bptr+1; //de

e.g.2: Given
char c[] = "hello";
char *sp ;
Print each character of a string on a separate line using pointer notation
for (int i=0;*(c+i)!=’\0’;i++)
cout << *(c+i) << endl;
or
for (sp=c ; *sp!='\0'; sp++)
cout << *sp <<endl;

12
e.g.3: given a string convert it to upper case using pointer notation
char s[200];
char *sp=s;
cin>>s; //or cin>>sp;
for(;*sp;sp++){if(*sp>='a'&& *sp<='z')*sp-=32;}
cout<<s; //or sp=s; cout<<sp;
//what is the output of the following?
cout<<sp-s; //the length of the string

Matrices and pointers:

e.g.1,
double z[2][2]={{5,6},{3,4}};

&z[0][0], z[0], *(z+0) are the same


&z[0][1], z[0]+1, *(z+0)+1 are the same

&z[1][0], z[1], *(z+1) are the same


&z[1][1], z[1]+1, *(z+1)+1 are the same
-----------------------------------------------
z[0][0], *z[0], *(*(z+0)) are the same
z[0][1], *(z[0]+1), *(*(z+0)+1) are the same

z[1][0], *z[1], *(*(z+1)) are the same


z[1][1], *(z[1]+1), *(*(z+1)+1) are the same

In General, to print the elements of a matrix z of r rows and c columns


for(int i=0;i<r;i++){
for(int j=0;j<c;j++){
cout<<z[i][j]<<endl;
//cout<<*(z[i]+j)<<endl;
//cout<<*(*(z+i)+j)<<endl;
}
}

e.g.2, what is the output?


char s[2][80]={"ali","muna"};

cout<<*s<<endl; //ali
cout<<**s<<endl; //a
cout<<*(*s+2)<<endl; //i
cout<<*s+1<<endl; //li

cout<<*(s+1)<<endl; //muna
cout<<**(s+1)<<endl; //m
cout<<*(*(s+1)+1)<<endl; //u
cout<<*(s+1)+1<<endl; //una

13
e.g.3, Given,
int x[2][3]={1,2,3,4,5,7};
Write a code segment to count even numbers. Do not use [].
int c=0;
for(int i=0;i<2;i++){
for(int j=0;j<3;j++){
if(*(*(x+i)+j)%2==0)c++;
}
}
cout<<c;

e.g.4, Given,
char s[2][80]={"ali","muna"};
Write a code segment to capitalize the names. Do not use [].
for(int i=0;i<2;i++){
for(int j=0;*(*(s+i)+j);j++){
if(*(*(s+i)+j)>='a' && *(*(s+i)+j)<='z')
*(*(s+i)+j)-=32;
}
}

for(int i=0;i<2;i++){
cout<<*(s+i);
}

Using pointers for function parameters


– Pass-by-reference

e.g.1:
void square(int *x){*x =(*x)*(*x);}
void main(){int n=10;
square(&n);
cout<<n; //100
}
The address of n is copied in the pointer x, the function will operate on the original
argument n.

main() square(int*x)
Implied meaning
int *x=&n;
int n=10; *x=(*x)*(*x);
square(&n);
Points to
n x
10 &n
C++ style of Pass-by-reference

14
 In the C style we have seen that you need to make use of & and lots of * symbols
to pass by reference.
 In C++ we make use of the ‘reference parameter’ (or reference variable) and can
avoid the use of so many symbols. All what you need to do is to put & before
your function’s parameter.
e.g.1 (revisited),
void square(int &x){x=x*x;}
void main(){int n=10;
square(n);
cout<<n; //100
}
The function will operate on the original argument n.

e.g.2:
Write a code segment to get two numbers from the user and swap their values using a
function. The changes must be reflected in memory.
void swap1(int &x, int &y) { int temp=x;x=y;y=temp; }
void swap2(int *x, int *y) {int temp=*x;*x=*y;*y=temp;}
void main(){
int x=2,y=3;
swap1(x,y);
cout<<x<<y; //3 2
swap2(&x,&y);
cout<<x<<y; //2 3
}

e.g.3: Write a function to find the length of a string using pointer notation
int length(char *X){
int c=0;
for ( ; *X!=’\0’; X++) c++;
return c;
}
void main(){
char s1=”ali”; char *s2=”muna”;
cout<<length(s1);
cout<<length(s2);}

e.g.4: Write a function to copy a string to another string using pointer notation
void copy(char*p1,char*p2){
for(;*p2;p1++,p2++){*p1=*p2;}
*p1='\0';}
void main(){
char s[200];
char *sp="sami";
copy(s,sp);
cout<<s;}
e.g.5: Write a function to concatenate two strings using pointer notation

15
void con(char*p1,char*p2){
for(;*p1;p1++);
for(;*p2;p2++,p1++){*p1=*p2;}
*p1='\0';
}
void main(){
char s[200]="he";
char *sp="llo";
con(s,sp);
cout<<s;}

Using the const Qualifier with Pointers

16
– Nonconstant pointer to nonconstant data
– Nonconstant pointer to constant data
– Constant pointer to nonconstant data
– Constant pointer to constant data

Non-Constant Pointer to Non-Constant Data

int x=5;
int y=6;
int *p=&x;
cout<<*p; //5
p=&y;
cout<<*p; //6
*p=7;
cout<<*p; //7

Non-Constant Pointer to Constant Data

int x=5;
int y=6;
const int *p=&x;
cout<<*p; //5
p=&y;
cout<<*p; //6
*p=7; //error

Constant Pointer to Non-Constant Data

int x=5;
int y=6;
int *const p=&x;
cout<<*p; //5
p=&y; //error
*p=7;
cout<<*p; //7

Constant Pointer to Constant Data

int x=5;
int y=6;
const int *const p=&x;
cout<<*p; //5
p=&y; //error
*p=7; //error

String library functions (#include<string.h>)

17
– int strlen( const char *s )
• Returns number of characters in string (null is not included in length)

– int strcmp( const char *s1, const char *s2 )


• Compares character by character
• Returns
– Zero if strings equal
– Negative value if first string less than second string
– Positive value if first string greater than second string

– char *strcpy( char *s1, const char *s2 )


• Copies second argument into first argument
• First argument must be large enough to store string and null character
• Returns the value of s1

– char *strcat( char *s1, const char *s2 )


• Appends second argument to first argument
• First character of second argument replaces null character of first
argument
• Ensure first argument large enough to store result and null character
• The value of s1 is returned

– char *strtok(char *s1, const char *s2);


• Returns a pointer to the next "token" in s1, where s2 contains the
delimiters that determine the token.
• strtok() returns NULL if no token is found.
• In order to convert a string to tokens, the first call to strtok() should have
s1 point to the string to be tokenized. All calls after this should have s1 be
NULL.

e.g.1,
char s1[10] = "ali";
char *s2= "ahmad";
char *s3=”ali”;

cout<< strlen(s1) <<strlen(s2); //3 5


cout<<strcmp(s1,s2); //1
cout<<strcmp(s2,s1); //-1
cout<<strcmp(s1,s3); //0
strcat( s1, s2 );
cout<<s1; //aliahmad
strcpy( s1, s3 );
cout<<s1; //ali

e.g.2, use strtok function to separate the words in the line

18
char L[100]="hi ; how ,are;; you";
char*p=strtok(L," ,;\t\n");
while(p){
cout<<p<<endl;
p=strtok(NULL," ,;\t\n");
}
cout<<L; ??????

Standard I/O library (#include< stdio.h>)


gets (char *s)
inputs characters from the standard input into the array s until a new line, NULL
character is appended to the array

puts(char *s)
print the string s followed by new line character

int putchar(int c)
prints a character to the screen and returns it as an integer

int getchar()
takes the next character from the standard input and return it as an integer.

Examples,
e.g.1:
char sentence[80];
puts("Enter a line of text: ");
//cout<<"Enter a line of text: "<<endl;
gets(sentence); // until a new line
puts(sentence); // print the string
e.g.2:
Read a string char by char from KB
char ch;
char name[80];
int j=0;
ch=getchar();
while (ch!='\n'){
name[j]=ch;
j++;
ch=getchar();
}
name[j]=’\0’;

for(i=0;i<j;i++){
putchar (name[i]);
}
Character Handling Library (#include<ctype.h>)

19
int isdigit(int c) – returns true if c is a digit and false (0) otherwise
int isalpha(int c) – returns true if c is a letter and false (0) otherwise
int islower(int c) – returns true if c is lower case and false otherwise
int isupper(int c) – returns true if c is upper case and false otherwise
int toupper(int c) – returns corresponding uppercase character if original character
is lowercase; otherwise toupper returns original (uppercase) character

Example,
char p [] =“ABC123abc";
for(int j=0;j<strlen(p);j++){
if ( isupper(p[j]) ){ p[j] = tolower( p[j] ;}
//if ( isdigit(p[j]) ) cout<<p[j]; //123
//if ( isalpha(p[j]) ) cout<<p[j]; //abcabc
}

Array of Pointers

e.g.1,
int a=20,b=200,c=4,d=5;
int*p[4]={&a,&b,&c,&d};

/* or int*p[4];
p[0]=&a; p[1]=&b; p[2]=&c; p[3]=&d;*/

for(int i=0;i<4;i++){
cout<<p[i]<<endl;
//cout<<*(p+i)<<endl; }
for(i=0;i<4;i++){
cout<<*p[i]<<endl;
//cout<<*(*(p+i))<<endl; }

e.g.2,
//a list of names each of different size
char *N[2]={"ali", "ahmad"};

//To print the names each on a separate line


for(int i=0;i<2;i++){
cout<<N[i]<<endl;
//cout<<*(N+i)<<endl;}

//To print the individual characters in each name in the list


 for(i=0;i<2;i++){
for(int j=0; *(N[i]+j) ;j++){
cout<<*(N[i]+j)<<endl;
//cout<<*(*(N+i)+j)<<endl;
//cout<<N[i][j]<<endl; }}

20
e.g.3: Given
char * N[3 ]={"alia", "ahmad", “sami”};
what is the output?
cout<<*N<<endl; //alia
cout<<*(N+1)<<endl; //ahmad
cout<<N[1]<<endl; //ahmad
cout<<*(N+1)+2<<endl; //mad
cout<<*N+2<<endl; //ia
cout<<*(*(N+2)+2); //m
cout<<*N[2]; //s
cout<<**N; //a
cout<<**(N+1); //a
Note:
char *p[3];
for(int i=0;i<3;i++) cin>>p[i]; //run-time error.
//Invalid address

e.g.4: Given
char * N[3 ]={"alia", "ahmad", “sami”};
write a code segment to count the names in N starting and ending with letter 'a'
int count=0;
for (int i=0;i<3;i++){
for(int j=0;*(N[i]+j);j++);
if(*(N[i]+0)==‘a’ && *(N[i]+j-1)=='a') count++;
//if(*(*(N+i)+0)==‘a’ && *(*(N+i)+j-1)=='a') count++;
//if (N[i][0]=='a' && N[i][j-1]=='a') count++;

e.g.5: Given
char * N[3 ]={"ali", "ahmad", “sami”};
write a code segment to find the longest name in N
int max,L=0;
for(int j=0;*(N[0]+j);j++);
max=j;
for (int i=1;i<3;i++){
for(j=0; *(N[i]+j);j++);
if (j>max) {max=j; l=i;}
}
cout<<N[L];

21
Pointers to pointers

e.g.1:
int a=5;
int*p1=&a;
int**p2=&p1;
cout<<a<<*p1<<**p2;
cout<<&a<<p1<<*p2;

e.g.2:
int a=2,c=3;
int*ap1=&a;
int**ap2=&ap1;

int *cp1=&c;
int**cp2=&cp1;

What is the output of each of the following?

cout<<a<<*ap1<<**ap2<<endl;
cout<<&a<<ap1<<*ap2<<endl;

cout<<c<<*cp1<<**cp2<<endl;
cout<<&c<<cp1<<*cp2<<endl;

**ap2=*cp1+a;
cout<<**ap2<<endl; //5
cout<<*ap1<<endl; //5
cout<<a<<endl; //5

*ap2=cp1;
cout<<**ap2<<endl; //3
cout<<*ap1<<endl; //3
cout<<c<<endl; //3

22
Dynamic memory allocation
 Declaration is used to statically allocate memory
 The new operator is used to dynamically allocate memory

To allocate a single variable dynamically, use the ‘new’ operator


 the new operator returns the address of the variable that has been allocated
 the address can be stored in a pointer
 the pointer can be de-referenced to access the variable

int *p;
p
60000 ?????

p=new int;
p
60000 50000

memory heap (free store)


50000

*p=7; //or cin>>*p;


p
60000 50000

50000
7
:

To de-allocate the memory, use the ‘delete’ operator


 the delete operator does not delete the pointer
 the memory location may be given to another application (returned to the heap)
delete p;

This location is returned to the p


heap. The OS my may or may not 60000 50000
give it to another application
 *p may be 7 or trash...
(can’t guess) 50000 ?
:

p=’\0’;
p

23
60000 00000

50000
?
:

Example,
int *p=new int(30); //allocates memory and puts an initial value 30
p
4000 6000

6000 30
:

p=new int;
cin>>*P; //user entered 5
p
400 8000

Leaked memory
6000 30
:
8000 5

To allocate an array dynamically, use the ‘new[ ]’ operator

int *p;

24
p
60000 ?????

p=new int[2];
p
60000 50004

memory heap (free store)


50004
50008

*p=1;*p=2; //or for(int i=0;i<2;i+


+)cin>>*(p+i);
p
60000 50004

50004
50008 1
2

To de-allocate the memory, use the ‘delete[ ]’ operator


delete [] p;
p
60000 50004

50004 ?
50008 ?

P=’\0’;
p
60000 00000

50004 ?
50008 ?

Note:
Declaring arrays dynamically allows us to choose their size while program is
running

int n;
cin>>n;

25
int *p;
p=new int[n]; //n does not need to be constant
for(int i=0;i<n;i++)cin>>*(p+i);
delete [] p;
p=’\0’;

e.g.1: declare and initialize a dynamic array of 10 integers. Find the sum of the array
elements.

int *p;
p=new int[10];
int sum=0;
for(int i=0;i<10;i++){cin>>*(p+i);sum+=*(p+i);}
delete [] p; p=’\0’;

Another solution:

int *p;
p=new int[10];
int*M=p;
int sum=0;
for(int i=0;i<10;i++){cin>>*M;sum+=*M;M++;}
delete [] p; p=’\0’; //or M=p; delete [] M; M='\0';

e.g.2:
Given
char*a[2]={"ali","muna"};
Write a code segment to concatenate the two strings in one string. You must do the
following:
1. find the length of the resulting string,
2. allocate memory dynamically for it
3. then copy the strings a[0] then a[1] into it

int len=0;
for(int i=0;i<2;i++){
for(int j=0;*(a[i]+j);j++);
len+=j;
}
char*p; int k=0;
p=new char[len+1];
for(i=0;i<2;i++){
for(int j=0;*(a[i]+j);j++){
*(p+k)= *(a[i]+j);
k++;
}
}
*(p+k)='\0';

26
cout<<p;
delete [] p;
p='\0';

Matrices:
e.g.1:
Store rows x cols matrix of integers in a dynamic matrix
int rows,cols; cin>>rows>>cols;
int **p;
p=new int*[rows];

p
P+1

: :

P+rows-1

for(int i=0;i<rows;i++){
*(p+i)=new int[cols];}
p *P
P+1 *(p+1) 0 … Cols-1
0 … Cols-1
: :
P+rows-1
*(P+rows-1) //to initialize the
0 … Cols-1
matrix from KB
for(int i=0;i<rows;i++){
for(int j=0;j<cols;j++){
cin>>*(*(p+i)+j);}}

for( i=0;i<rows;i++){
delete [] *(p+i);}

delete [] p;
p=’\0’;

e.g.2:
Write a code segment to allow the user to enter the scores of n students. The number of
scores of each student must be entered by the user.
cout<<"enter of number of students"<<endl;
int n; cin>>n;
int**p;
p=new int*[n];

27
for(int i=0;i<n;i++){
cout<<"enter of number scores for student "<<i<<endl;
int m; cin>>m;
*(p+i)=new int[m];
for(int j=0;j<m;j++){
cin>>*(*(p+i)+j); }
}
for(int j=0;j<n;j++)
delete []*(p+j);
delete [] p;
p='\0';

e.g.3:
Write a code segment to allow the user to enter N strings. Then save the strings in a
dynamic matrix and sort them alphabetically in ascending order (a…z).

int N;cin>>N;
char s[80];

char **p;
p=new char*[N];

for(int i=0;i<N;i++){
cin>>s;
*(p+i)=new char[strlen(s)+1];
strcpy(*(p+i),s);
}

for(i=0;i<N;i++){
for(j=i+1;j<N;j++){
if(strcmp(*(p+i),*(p+j))== 1 ){
char*t=*(p+i);
*(p+i)=*(p+j);
*(p+j)=t;
}}}
for(i=0;i<N;i++)cout<<*(p+i)<<endl;

for( i=0;i<N;i++){
delete [] *(p+i);
}delete [] p; p=’\0’;

28

You might also like