You are on page 1of 83

CSE 109

Computer Programming
Pointers
Prepared by
Johra Muhammad Moosa
Assistant Professor
CSE, BUET

Modified by
Madhusudan Basak
Assistant Professor
CSE, BUET
Pointer
• A pointer is a variable
– Holds the memory address of an object
– Address are whole numbers/integer
– Pointers should contain only whole numbers
– Size of a pointer is 4 bytes
• A variable p contains address of another variable q
• p is said to "point to" q
• Let q is at location 1017 in memory, then p would have the value 1017
• General form p q
– type *var_name;
1017 … 123
– type is the base type of the pointer
1001 1017
– base type: type of the object that the pointer can point to
• Example: int *p;
Pointer Operators
• Two special operators: * and &
• * operator (at address)
– Indirection operator/dereferencing operator
– Returns the value stored at the address it precedes
– No relation to the multiplication operator
– Let p is a pointer, points to q. If q contains value 67
– printf("%d\n", *p);
• Will print 67
Pointer Operators
• Two special operators: * and &
• & operator (address of)
– Returns the address of the variable it precedes
– Can not be applied to constants or expressions
– Let p is a pointer, points to q.
– p=&q;
• Assigns the address of q to p
Pointer Operators
• Two special operators: * and &
• & and * are complements of each other
• Applying both consecutively in either result yields same result
• &*p and *&p gives same result, value of p (check yourself!)

p q
1017 … 123
1001 1017
Pointer Declaration
• int *p;
– A pointer to an integer value
• int *p, i;
– i is an integer variable
– The indirection operator (*) does not distribute to all variable names in the
declaration
– Each pointer must be declared with the * prefixed to the name
Pointer Declaration
• float *fp;
– Dose not mean fp will contain floating point value
– fp will contain address of a floating point value
• int *ip;
– Intended as a mnemonic
– Expression *ip (value at ip) is an int
Pointer
#include<stdio.h>

int main()
{
int *p, q;
q=197; Assigns p the address of q
p=&q;
printf("%d\n", *p);
return 0;
} Print the value at
address p
Pointer
#include<stdio.h>

int main()
{
int *p, q;
q=197; Assigns p the address of q
p=&q;
printf("%d\n", *p);
return 0;
} Variable’s value is
referenced through a pointer
Pointer
#include<stdio.h>

int main()
{
int *p, q;
q=197; Assigns p the address of q
p=&q;
printf("%d\n", *p);
return 0;
} The process is called
indirection
Pointer
#include<stdio.h>

int main()
{
int *p, q;
Possible to use * operator at
p=&q; the left side of an assignment
*p=197; operation
printf("%d\n", q);
return 0;
}
Pointer
#include<stdio.h>

int main()
{
int *p, q;
Assigns value indirectly
p=&q;
*p=197;
printf("%d\n", q);
return 0;
}
Pointer
• Let q is located at address 210 and p is located at address 100
int *p, q;
p=&q;
*p=1046;
Pointer
• Let q is located at address 210 and p is located at address 100
int *p, q;
p=&q;
*p=1046;
• Now p and q contains nothing/garbage value

Location Contents
100 Unknown
210 Unknown
Pointer
• Let q is located at address 210 and p is located at address 100
int *p, q;
p=&q;
*p=1046;
• p contains the value 210

Location Contents
100 210
210 Unknown
p points to q
Pointer
• Let q is located at address 210 and p is located at address 100
int *p, q;
p=&q;
*p=1046;
• q contains the value 1046
• p has nothing to do with the value of q
• It holds the address of q

Location Contents
100 210
210 1046
p points to q
Pointer
• C allows any type of pointer to point anywhere in the memory
• Base type very important
– Determines how many bytes are in the object pointed to
Pointer
int q;
double *fp;
fp=&q;
*fp=100.23;
• Syntactically correct but wrong
Pointer
int q;
double *fp;
fp=&q;
*fp=100.23;
• Syntactically correct but wrong
• int shorter than double
Pointer
int q;
double *fp;
fp=&q;
*fp=100.23;
• Syntactically correct but wrong
• int shorter than double
• For example: let integer is 4 bytes, double is 8 bytes
Pointer
int q;
double *fp;
fp=&q;
*fp=100.23;
• Syntactically correct but wrong
• int shorter than double
• For example: let integer is 4 bytes, double is 8 bytes
• The assignment statement uses the 4 bytes allocated to q
Pointer
int q;
double *fp;
fp=&q;
*fp=100.23;
• Syntactically correct but wrong
• int shorter than double
• For example: let integer is 4 bytes, double is 8 bytes
• The assignment statement uses the 4 bytes allocated to q
• As well as it uses 4 adjacent bytes
– Causing an error
Pointer

p is an integer pointer
Pointer

Only 4 bytes transferred


Pointer
Pointer
int *p; Let address of p, temp, & q is
double temp, q; 3140, 4366 & 5682 respectively.
temp=1234.34; float is 8 bytes and int is 4 bytes
p=&temp; Location Contents

q=*p; 3140 5682


3144 Unknown
… p points to tem
4366 1234.34
4374 Unknown

5682 Wrong value
5690 Unknown
Pointer
float *fp, f;
fp=&f;
*fp=3.14
• Let address of fp & f is 3140 & 5682 respectively and float is 8 bytes
Location Contents
3140 5682
3144 Unknown
fp points to f

5682 3.14
5690 Unknown
Pointer
• Using a pointer before assigning: program may crash
• Declaring a pointer variable creates a variable capable of holding a memory
address
• No meaningful initial value is given

int main()
{
int *p
*p=197;
return 0;
}
• Incorrect: p is not pointing to anything
Pointer
• Pointer can be initialized to
– 0
– NULL
– An address
• Null value in pointer
– NULL: symbolic constant defined in <stdio.h>
– Assumed to be unused
– Points to nothing
– Assumed to be an invalid memory address
Pointer
• Pointer can be initialized to
– 0
– NULL
– An address
• 0 is equivalent to initializing using NULL
• NULL is preferred
• C guarantees that zero is never a valid address for data
• Pointers and integers are not interchangeable, zero is exception
• Zero can be assigned to and compared to a pointer
Pointer
int main()
{
int *p, q;
p=&q;
printf("%p\n",p);
return 0;
}
• %p conversion specifier is used to output the value of a pointer
• %p outputs memory location as a hexadecimal integer
Pointer
• Printing *(&i) is same as printing i
Pointer with Arrays
• Array name without index: a pointer to the start of the array
int a[5]={1,2,3,4,5};
int *p;
p=a;
printf("%d\n",*p);
printf("%d %d %d\n",a[0], a[1],a[2]);
Pointer Expression (Arithmetic Expression)
• Operators:
– ++
– +
– --
– -
• Only integer quantities can be added or subtracted
• multiplication, division, modulus operators can not be applied
Pointer Expression (Arithmetic Expression)
• Performed relative to base type of the pointer
• Each increment will cause the pointer to point to the next item
• Example: an integer pointer p contains the address 200
– Assuming integers are 4 bytes long
• After p++, p will have the value 204
Pointer Expression (Arithmetic Expression)
• Performed relative to base type of the pointer
• Each increment will cause the pointer to point to the next item
• Example: an integer pointer p contains the address 200
– Assuming integers are 4 bytes long
• p=p+204 causes p to point to the 204th integer past one pointing
Pointer Expression (Arithmetic Expression)
• Performed relative to base type of the pointer
• Each increment will cause the pointer to point to the next item
• Example: an integer pointer p contains the address 200
– Assuming integers are 4 bytes long
• p=p+204 causes p to point to the 204th integer past one pointing
– The value of p will be 812 (200+4*204)
Pointer Expression (Arithmetic Expression)
• Performed relative to base type of the pointer
• Each increment will cause the pointer to point to the next item

Location Contents
3140 5682
3144 Unknown
fp points to f

5682 3.14
5690 Unknown
Pointer Expression (Arithmetic Expression)
• Performed relative to base type of the pointer
• Each increment will cause the pointer to point to the next item
• After fp++

Location Contents
3140 5682
3144 Unknown
fp points to the next item

5682 3.14
5690 Unknown
Pointer Expression (Arithmetic Expression)
• Subtraction
• Example: an integer pointer p contains the address 200
– Assuming integers are 4 bytes long
• p=p+204 causes p to point to the 204th integer past one pointing
– The value of p will be 812 (200+4*204)
• p=p-204 would set p back to 200
Pointer Expression (Arithmetic Expression)
• Subtraction
• One pointer can be subtracted from other
– Number of elements separating them can be found
– Meaningless unless performed on an array
Pointer Expression (Arithmetic Expression)
• Operators can be applied to the pointer or the object to which it points
• x=*p++: first assigns the value contained inside the address pointed
by p and then increments the value of p (p points to the next element)
• x=(*p)++: first assigns the current value contained inside the address
pointed by p and then increments this value (p points to the same
address)
• x=++*p: first increments the value contained inside the address
pointed by p and then assigns it (p remains unchanged, points to the
same address)

Pointer_arithmetic.c
Pointer Expression (Arithmetic Expression)
• Operators can be applied to the pointer or the object to which it
points
• x=*++p: first increments the value of p (p points to the next
element) and then assigns the value contained inside the address
(now) pointed by p
• x=++(*p): first increments the value contained inside the address
pointed by p and then assigns this value (p remains unchanged,
points to the same address)
• x=++*p++: first increments the value contained inside the address
pointed by p, then assigns this value and finally increment the value
of p (p points to the next element)

Pointer_arithmetic.c
Pointer Expression (Arithmetic Expression)
• Pointer arithmetic that appears normal when char pointers are used
– char: one byte long
– Meaningless unless performed on an array
Pointer Expression (Comparison Expression)
• Two pointers can be compared using relational operators
• Make sense only if points to the same object
• Gives info about array indices of the pointed elements
• Can be compared to zero or NULL
Pointer Expression (Assignment Expression)
• One pointer can be assigned to other if both are of same base type
• Otherwise cast operator needed
• Exception is void pointer (void *)
– A generic pointer
– Can represent any pointer type
– Can be used in either side of assignment operation without using cast operator
– Can not be dereferenced
• Dose not know how many bytes to read
Pointer with Arrays
• Array name without index: a pointer to the start of the array
int a[5]={1,2,3,4,5};
int *p;
p=a;
printf("%d %d %d\n",*p, *(p+1), *(p+2));
printf("%d %d %d\n",a[0], a[1],a[2]);

• * has higher precedence then + so parentheses necessary


Pointer with Arrays
int main() Output:
{ 0. value=1, address=1638196
int num[]={1, 2, 3, 4, 5}; 1. value=2, address=1638200
int i=0; 2. value=3, address=1638204
for(i=0; i<5; i++) 3. value=4, address=1638208
4. value=5, address=1638212
{
printf("%d. value=%d, address=%d\n", i, num[i],
&num[i]);
}
return 0;
}
• Array elements are stored in contiguous memory location
• Address output will be in hexadecimal if %p is used
Pointer with Arrays
int main()
{ Output:
int num[]={1, 2, 3, 4, 5}; 0. value=1
int i, *p; 1. value=2
p=&num[0]; 2. value=3
for(i=0; i<5; i++) 3. value=4
4. value=5
{
printf("%d. value=%d\n", i, *p);
p++;
}
return 0;
}
Pointer with Arrays
int main()
{ Output:
int num[]={1, 2, 3, 4, 5}; 0. value=1
int i, *p; 1. value=2
p=num; 2. value=3
for(i=0; i<5; i++) 3. value=4
4. value=5
{
printf("%d. value=%d\n", i, *p);
p++;
}
return 0;
}
Pointer with Arrays
• Array name gives the base address of the array
• Array name always points to the beginning of the array
• An array name is a constant pointer
• Pointer is a variable but the array name is not
• Can not be modified by pointer arithmetic
• So the expression
– num++
– num+=3
are invalid
Pointer with Arrays
• Array name gives the base address of the array
• Base address: address of the first element/ element at index zero
• So *num/ *(num+0)/num[0] gives the value of the first element
• num[i]: compiler converts it to *(num+i)
• The following notations are same
• num[i]
• *(num+i)
• *(i+num)
• i[num]
Pointer with Arrays
int main()
{
int num[]={1, 2, 3, 4, 5, 7, 7, 8};
int *p, *q;
p=&num[2]; Location Contents Index
q=&num[5];
3140 1 0
printf("%d\n", q-p); p
3144 2 1
return 0; 3148 3 2
3152 4 3
} q 3156 5 4
• Returns 3, not 6, not 4 3160 7 5
3164 7 6
3168 8 7
Pointer with Arrays
int main()
{
int num[]={1, 2, 3, 4, 5, 7, 7, 8};
int *p, *q;
p=&num[2];
q=&num[5];
printf("%d\n", p-q);
return 0;
}
• Returns -3
Pointer and Multidimensional Array
int main()
{
int s[3][2]={{1, 2}, {3, 4}, {5, 6}};
for(int i=0; i<5; i++)
{
printf("address of %d th 1-d array: %d\n", i, s[i]);
} Output:
return 0; address of 0 th 1-d array: 1638192
} address of 1 th 1-d array: 1638200
• If integer size 4 byte address of 2 th 1-d array: 1638208
• So each row takes 8 bytes address of 3 th 1-d array: 1638216
• So s[1] is interpreted as *(s+1) address of 4 th 1-d array: 1638224
• Address output will be in hexadecimal if %p is used
Pointer and Multidimensional Array
• Accessing a multidimensional array using a pointer:
• float gpa[10][5];
• To access gpa[3][1] using a pointer
float *fp;
fp=(float*)gpa;
float my_gpa=*(p+(3*5)+1);
• The type of pointer generated by gpa is to a two dimensional array of
floats
• So cast is needed
Traversing 2-D Array using pointers

traverse_2D_Array1.c
Traversing 2-D Array using pointers

traverse_2D_Array2.c
Pointers and String
int main()
{
char str[]="CSE 109";
char *p; Output:
int i;
p=str;
CSE109CSE109
for(i=0; p[i]; i++)
{
printf("%c", p[i]); If the order of while loop and the for loop is
}
while(*p) exchanged the code will not work
{ Find out why?
printf("%c", *p++);
}
return 0;
}
Pointers and String
#include<stdio.h>

int main()
{
char *p;
p="CSE 109";
puts(p);
return 0;
}
• Stores "CSE 109" in memory, then assigns it’s address to p
String Functions: strlen
#include <stdio.h>
int strlen(char *s)
{
char *p=s;
while(*p)
p++;
return p-s;
}
int main()
{
printf("%d ", strlen("cse 109"));
return 0;
}
Array of Pointers
• Char *p[10];

p[0]
Each one is a character
pointer
p[1]
p[2]
p[3]
p[4]
p[5]
p[6]
p[7]
p[8]
p[9]
Array of Pointers
int main() • Pointer variable contains address
{ • Array of pointers is a collection of
addresses
int *pa[3];
int a=97, b=21, c=54;
pa[0]=&a;
pa[1]=&b;
pa[2]=&c;
for(int i=0; i<3; i++)
{
printf("%d\n", *(pa[i]));
}
return 0;
}
Array of Pointers
#include<stdio.h>

int main()
{
int a[]={1, 2, 3 ,4, 5};
Multiple indirection
int *pa[]={a, a+1, a+2};
printf("%p %p %d\n", pa, *pa, *(*pa));
return 0;
}
Arrays of Pointers to Strings
char *names[]={
"Ayon",
"Santu",
"Shampa",
"Sohan",
"Sunny"
}
• names[] is an array of pointers
• Contains the base address of respective names
Arrays of Pointers to Strings
Ayon\0 Santu\0 Shampa\0
1360
1108 2102
Sunny\0 Sohan\0
4706 5954

1108 1360 2102 4706 5954


8120 8124 8128 8132 8136
• Note the change in the memory
Arrays of Pointers to Strings
Arrays of Pointers to Strings
• Limitations
int main()
{
char *names[6];
for(int i=0; i<6; i++)
scanf("%s", names[i]);
return 0;
}
• The program will crash
• As no valid address is contained
Pointers and Arrays
• Pointer version is faster but sometimes difficult to understand
Function with Pointers
• The actual address can be obtained
• The value of the variables of the calling function can be changed
Swap Function

Pointer_swap_function.c
Function with Pointers
• The return type can be pointer
• See Pointer_ret_type.c for example after reading the Dynamic Allocation
section
Multiple Indirection

mp p ch
7092 … … 7540 … … 'A'
5166 7092 7540

Pointer_Multiple_Indirection.c
Dynamic Memory Allocation
void *malloc(size_t numbytes);
•Needs stdlib.h

void free (void *ptr);


•Frees allocated memory starting from address contained in the pointer ptr
Dynamic Memory Allocation

Pointer_Dynamic_MA1.c
Dynamic Memory Allocation

Pointer_Dynamic_MA2.c
Array of Pointers
• Char *p[10];

p[0]
Each one is a character
pointer
p[1]
p[2]
p[3]
p[4]
p[5]
p[6]
p[7]
p[8]
p[9]
Pointer_array_of_strings2.c
Hello 1600 Base
add
ptr[0] 1600 CSE 1460 Base
ptr[1] 1460 add
ptr[2] 1620 Bangla 1620 Base
ptr[3] 1280 add
Flag 1280 Base
add

Pointer_array_of_strings2.c
Hello 1600 Base
add
ptr[0] 1600 CSE 1460 Base
ptr[1] 1460 add
ptr[2] 1620 Bangla 1620 Base
ptr[3] 1280 add
Flag 1280 Base
add

Carefully check how to free


an array of pointers

Pointer_array_of_strings2.c
Void pointer
• A generic pointer
• Doesn’t have any data type associated with it
• Can represent any pointer type
• Can be used in either side of assignment operation without using cast operator
• Can not be dereferenced
• Dose not know how many bytes to read
Reference
• TEACH YOURSELF C by Herbert Schildt (3rd Edition)
– Chapter 6 (Full)
– Chapter 12 (12.7)
– Chapter A (A.1 -> Try to implement the functions on your own.) [N.B. Chapter
A means Appendix, you will find it after Chapter 12]
• https://www.tutorialspoint.com/cprogramming/c_return_pointer_from_fun
ctions.htm
• https://www.dyclassroom.com/c/c-function-returning-pointer
Thank You 

You might also like