12 Pointers
12 Pointers
Pointers
Swaroop Joshi
2023
Down the memory lane…
A box for an int
76
Down the memory lane… Address: 2008
Name: marks
76
Down the memory lane… Address: 2008
Name: marks
76
Down the memory lane… Address: 2008
Name: marks
76
Down the memory lane… Address: 2008
Name: marks
printf(“%p\n\n”, &marks);
A box for an int
76
Down the memory lane… Address: 2008
Name: marks
printf(“%p\n\n”, &marks);
76
Down the memory lane… Address: 2008
Name: marks
printf(“%p\n\n”, &marks);
76
Down the memory lane… Address: 2008
Name: marks
printf(“%p\n\n”, &marks);
> ./a.out
76
0x16b85b354
A box for an int
76
Down the memory lane… Address: 2008
Name: marks
printf(“%p\n\n”, &marks);
> ./a.out
76 This value can be different on different machines;
0x16b85b354 Can also be different the next time you run it on the same machine!
A box for an int
76
Down the memory lane… Address: 2008
Name: marks
printf(“%p\n\n”, &marks);
> ./a.out
76
0x16b85b354
Detour: hexadecimal numbers
✤ You have also heard of the binary number system with two numerals: 0, 1
✤ In general, you can represent the same number in an n-ary number system
with numerals 0, …, n-1
Dec. Hex.
✤ We are familiar with the decimal number system
0 0
✤ It uses the Hindu-Arabic numerals 0, 1, …, 9 1 1
9 9
✤ You have also heard of the binary number system with two numerals: 0, 1
10 a
✤ In general, you can represent the same number in an n-ary number system 11 b
with numerals 0, …, n-1 15 f
✤ Hexadecimal number system uses 16 symbols: 0,…, 9, a,…,f 16 10
17 11
✤ It’s just another form of representing numbers that is used to show
31 1f
memory addresses in C
32 20
Back to the memory
lane…
Relevant portion of memory (‘data area’) allotted to main
76
lane… 0x16f25b354
int marks = 76;
printf("%d\n", marks);
printf("%p\n", &marks);
Relevant portion of memory (‘data area’) allotted to main
76
lane… 0x16f25b354
int marks = 76;
printf("%d\n", marks);
printf("%p\n", &marks); Computer nds an address within the
memory where it can keep a box big enough
to store the speci ed type and notes down
its name, type, and address
fi
fi
Relevant portion of memory (‘data area’) allotted to main
76
lane… 0x16f25b354
int marks = 76;
printf("%d\n", marks);
printf("%p\n", &marks);
76
0x16d12b354
Relevant portion of memory (‘data area’) allotted to main
76
lane… 0x16f25b354
int marks = 76;
printf("%d\n", marks);
printf("%p\n", &marks);
76
0x16d12b354
Relevant portion of memory (‘data area’) allotted to main
76
lane… 0x16f25b354
ans: char
76
0x16d12b354
Relevant portion of memory (‘data area’) allotted to main
76
lane… 0x16f25b354
ans: char
76
0x16d12b354
y
0x16d12b350
Relevant portion of memory (‘data area’) allotted to main
76
lane… 0x16f25b354
ans: char
76
0x16d12b354
y
0x16d12b350
Relevant portion of memory (‘data area’) allotted to main
76
lane… 0x16f25b354
ans: char
76
lane… 0x16f25b354
ans: char
76
lane… Note, no matter what the variable type is,
0x16f25b354
ans: char
76
lane… 0x16f25b354
ans: char
76
lane… 0x16f25b354
ans: char
76
lane… 0x16f25b354
ans: char
marks: int
76
ans: char
0x16f25b354
int marks = 76; y
printf("%d\n", marks);
printf("%p\n", &marks); 0x16d12b350
area: double
76 314.159265
0x16f25b354
0x16f25b344
Data area of main
marks: int
76
ans: char
0x16f25b354
int marks = 76; y
printf("%d\n", marks);
printf("%p\n", &marks); 0x16d12b350
int *marks_ptr = &marks;
printf("%d\n", *marks_ptr);
area: double
76 314.159265
0x16f25b354
0x16f25b344
Data area of main
marks: int
76
ans: char
0x16f25b354
int marks = 76; y
printf("%d\n", marks);
printf("%p\n", &marks); 0x16d12b350
int *marks_ptr = &marks;
printf("%d\n", *marks_ptr);
area: double
76 314.159265
0x16f25b354
0x16f25b344
marks_ptr: int*
0x16f25b354
0x16f663368
Data area of main
area: double
76 314.159265
0x16f25b354
0x16f25b344
marks_ptr: int*
0x16f25b354
0x16f663368
Data area of main
marks: int
76
ans: char
0x16f25b354
int marks = 76; y
printf("%d\n", marks);
printf("%p\n", &marks); 0x16d12b350
int *marks_ptr = &marks;
printf("%d\n", *marks_ptr);
area: double
0x16f25b354
0x16f663368
Data area of main
marks: int
76
ans: char
0x16f25b354
int marks = 76; y
printf("%d\n", marks); This creates a special relation
printf("%p\n", &marks); 0x16d12b350
between the two:
int *marks_ptr = &marks; marks_ptr “points to” marks
printf("%d\n", *marks_ptr);
area: double
76 314.159265
0x16f25b354
0x16f25b344
marks_ptr: int*
0x16f25b354
0x16f663368
Data area of main
marks: int
76
ans: char
0x16f25b354
int marks = 76; y
printf("%d\n", marks);
printf("%p\n", &marks); 0x16d12b350
int *marks_ptr = &marks; * * is a pointer dereference operator;
printf("%d\n", *marks_ptr);
* Gets the “value at the address” it is applied to
area: double
76 314.159265
0x16f25b354
0x16f25b344
marks_ptr: int*
0x16f25b354
0x16f663368
Data area of main
marks: int
76
ans: char
0x16f25b354
int marks = 76; y
printf("%d\n", marks);
printf("%p\n", &marks); 0x16d12b350
int *marks_ptr = &marks;
printf("%d\n", *marks_ptr);
area: double
76 314.159265
0x16f25b354
0x16f25b344
76 marks_ptr: int*
0x16f25b354
0x16f663368
Data area of main
marks: int
76
ans: char
0x16f25b354
int marks = 76; y
printf("%d\n", marks);
printf("%p\n", &marks); 0x16d12b350
int *marks_ptr = &marks;
printf("%d\n", *marks_ptr);
76 314.159265
0x16f25b354
0x16f25b344
76 marks_ptr: int*
0x16f25b354
0x16f663368
Data area of main
marks: int
76
ans: char
0x16f25b354
int marks = 76; y
printf("%d\n", marks);
printf("%p\n", &marks); 0x16d12b350
int *marks_ptr = &marks;
printf("%d\n", *marks_ptr);
76 314.159265
0x16f25b354
You can print/use its value, i.e., address 0x16f25b344
of marks, without the *
76 marks_ptr: int*
And its address using the &
0x16f25b354
0x16f663368
Data area of main
marks: int
76
ans: char
0x16f25b354
int marks = 76; y
printf("%d\n", marks);
printf("%p\n", &marks); 0x16d12b350
int *marks_ptr = &marks;
printf("%d\n", *marks_ptr);
76 314.159265
0x16f25b354
0x16f25b344
76 marks_ptr: int*
0x16f25b354
0x16f25b354
0x16f663368
0x16f663368
Data area of main
marks: int
76
ans: char
0x16f25b354
int marks = 76; y
printf("%d\n", marks);
printf("%p\n", &marks); 0x16d12b350
int *marks_ptr = &marks;
printf("%d\n", *marks_ptr);
76 314.159265
0x16f25b354
0x16f25b344
76 marks_ptr: int*
Ok, again, pretty cool,
0x16f25b354
0x16f25b354 but what’s the real point
0x16f663368 of pointers?
0x16f663368
Data area of main
marks: int
76
ans: char
0x16f25b354
int marks = 76; y
printf("%d\n", marks);
printf("%p\n", &marks); 0x16d12b350
int *marks_ptr = &marks;
printf("%d\n", *marks_ptr);
76 314.159265
0x16f25b354
0x16f25b344
76 marks_ptr: int*
0x16f25b354
0x16f25b354
0x16f663368
0x16f663368
Data area of update_rank
update_rank(my_rank, -1);
printf("Rank: %d\n”, my_rank);
return 0;
}
Data area of update_rank
update_rank(my_rank, -1);
printf("Rank: %d\n”, my_rank);
return 0;
}
Data area of update_rank
update_rank(my_rank, -1); 7
printf("Rank: %d\n”, my_rank);
0x16b743358
return 0;
}
Data area of update_rank
7 -1
0x16f7d732c 0x16f7d7328
update_rank(my_rank, -1); 7
printf("Rank: %d\n”, my_rank);
0x16b743358
return 0;
}
Data area of update_rank
67 -1
0x16f7d732c 0x16f7d7328
update_rank(my_rank, -1); 7
printf("Rank: %d\n”, my_rank);
0x16b743358
return 0;
}
Data area of update_rank
update_rank(my_rank, -1); 7
printf("Rank: %d\n”, my_rank);
0x16b743358
return 0;
}
void update_rank(int rank, int change)
{
rank += change; Data area of main
}
int main() {
int my_rank = 7; my_rank: int
update_rank(my_rank, -1); 7
printf("Rank: %d\n”, my_rank);
0x16b743358
return 0;
}
void update_rank(int rank, int change)
{
rank += change; Data area of main
}
int main() {
int my_rank = 7; my_rank: int
update_rank(my_rank, -1); 7
printf("Rank: %d\n”, my_rank);
0x16b743358
return 0;
}
Rank: 7
int main() {
int my_rank = 7;
update_rank_p(&my_rank, -1);
printf("Rank: %d\n”, my_rank);
return 0;
}
void update_rank_p(int *ptr, int change)
{
*ptr = *ptr + change;
}
int main() {
int my_rank = 7;
update_rank_p(&my_rank, -1);
printf("Rank: %d\n”, my_rank);
return 0;
}
void update_rank_p(int *ptr, int change)
{
*ptr = *ptr + change;
}
What is the output of
int main() { this program?
int my_rank = 7;
update_rank_p(&my_rank, -1);
printf("Rank: %d\n”, my_rank);
return 0;
}
void update_rank_p(int *ptr, int change)
{
*ptr = *ptr + change;
}
Data area of main
int main() {
int my_rank = 7;
my_rank: int
update_rank_p(&my_rank, -1);
printf("Rank: %d\n”, my_rank); 7
0x16b743358
return 0;
}
void update_rank_p(int *ptr, int change)
{
*ptr = *ptr + change; When update_rank_p is called, two new
} variables, ptr and change, are created in its
Data area of main
data area and new copies of values of
int main() { expressions &my_rank and -1 are placed in
int my_rank = 7;
them my_rank: int
update_rank_p(&my_rank, -1);
printf("Rank: %d\n”, my_rank); 7
0x16b743358
return 0;
}
Data area of update_rank_p
ptr: int*
change: int
0x16b743358
-1
0x16b0e7328
void update_rank_p(int *ptr, int change)
0x16f7d7328
{
*ptr = *ptr + change;
}
Data area of main
int main() {
int my_rank = 7;
my_rank: int
update_rank_p(&my_rank, -1);
printf("Rank: %d\n”, my_rank); 7
0x16b743358
return 0;
}
Data area of update_rank_p
ptr: int*
change: int
0x16b743358
-1
0x16b0e7328
void update_rank_p(int *ptr, int change)
0x16f7d7328
{
*ptr = *ptr + change;
}
Data area of main
int main() {
int my_rank = 7;
my_rank: int
update_rank_p(&my_rank, -1);
printf("Rank: %d\n”, my_rank); 7
0x16b743358
return 0;
}
Data area of update_rank_p
ptr: int*
change: int
0x16b743358
-1
0x16b0e7328
void update_rank_p(int *ptr, int change)
0x16f7d7328
{
*ptr = *ptr + change;
}
Data area of main
int main() {
int my_rank
Value = 7; pointed to by ptr is
of the variable my_rank: int
replaced by (the value of the variable
update_rank_p(&my_rank, -1);
pointed to by %d\n”,
printf("Rank: ptr + value of change)
my_rank); 7
0x16b743358
return 0;
}
Data area of update_rank_p
ptr: int*
change: int
0x16b743358
-1
0x16b0e7328
void update_rank_p(int *ptr, int change)
0x16f7d7328
{
*ptr = *ptr + change;
}
Data area of main
int main() {
int my_rank = 7;
my_rank: int
update_rank_p(&my_rank, -1);
printf("Rank: %d\n”, my_rank); 67
0x16b743358
return 0;
}
Data area of update_rank_p
int main() {
int my_rank = 7;
my_rank: int
update_rank_p(&my_rank, -1);
printf("Rank: %d\n”, my_rank); 67
0x16b743358
return 0;
}
void update_rank_p(int *ptr, int change)
{
*ptr = *ptr + change;
}
Data area of main
int main() {
int my_rank = 7;
my_rank: int
update_rank_p(&my_rank, -1);
printf("Rank: %d\n”, my_rank); 67
0x16b743358
return 0;
}
void update_rank_p(int *ptr, int change)
{
*ptr = *ptr + change;
}
Data area of main
int main() {
int my_rank = 7;
my_rank: int
update_rank_p(&my_rank, -1);
printf("Rank: %d\n”, my_rank); 67
0x16b743358
return 0; But the change persists since it
}
has modi ed the variable in
the calling function
fi
void update_rank_p(int *ptr, int change)
{
*ptr = *ptr + change;
}
Data area of main
int main() {
int my_rank = 7;
my_rank: int
update_rank_p(&my_rank, -1);
printf("Rank: %d\n”, my_rank); 67
0x16b743358
return 0;
}
Rank: 6
void update_rank_p(int *ptr, int change)
{
*ptr = *ptr + change;
}
Data area of main
int main() {
int my_rank = 7;
my_rank: int
update_rank_p(&my_rank, -1);
printf("Rank: %d\n”, my_rank); 67
Point of using pointers 1: 0x16b743358
return 0;
} Pointers allow you to modify
Rank: 6 variables outside their scope
More use of pointers
✤ I get super annoyed when I can’t get ₹ 100 notes easily – ATMs only seem to give ₹ 500
ones!
✤ Write a function that receives an integer input that is a multiple of 100 and outputs the
number of ₹ 500 notes, ₹ 200 notes, and ₹ 100 notes it should dispense. (Always
maximise the higher denomination notes.)
✤ E.g.: Input = 800 → Output = 1x₹ 500, 1x₹ 200, 1x₹ 100
More use of pointers
✤ I get super annoyed when I can’t get ₹ 100 notes easily – ATMs only seem to give ₹ 500
ones! How can you ever return three things
from a function?
✤ Suppose you are hired by a bank to update their ATM program.
✤ Write a function that receives an integer input that is a multiple of 100 and outputs the
number of ₹ 500 notes, ₹ 200 notes, and ₹ 100 notes it should dispense. (Always
maximise the higher denomination notes.)
✤ E.g.: Input = 800 → Output = 1x₹ 500, 1x₹ 200, 1x₹ 100
More use of pointers
✤ I get super annoyed when I can’t get ₹ 100 notes easily – ATMs only seem to give ₹ 500
ones!
✤ Write a function that receives an integer input that is a multiple of 100 and outputs the
number of ₹ 500 notes, ₹ 200 notes, and ₹ 100 notes it should dispense. (Always
maximise the higher denomination notes.)
You cannot!
✤ E.g.: Input = 900 → Output = 1x₹ 500, 2x₹ 200 But you can pass three pointers to a
function and ask it to put the relevant
✤ E.g.: Input = 800 → Output = 1x₹ 500, 1x₹ 200, 1x₹ 100 values in them!
More use of pointers
✤ I get super annoyed when I can’t get ₹ 100 notes easily – ATMs only seem to give ₹ 500
ones!
✤ Write a function that receives an integer input that is a multiple of 100 and outputs the
number of ₹ 500 notes, ₹ 200 notes, and ₹ 100 notes it should dispense. (Always
maximise the higher denomination notes.)
✤ E.g.: Input = 800 → Output = 1x₹ 500, 1x₹ 200, 1x₹ 100
void atm_dispensing(int total,
int *p500,
int *p200,
int *p100)
{
}
void atm_dispensing(int total,
int *p500,
int *p200,
int *p100)
{
}
int main()
{
int amount = 800;
int notes500, notes200, notes100;
return 0;
}
void atm_dispensing(int total,
int *p500,
int *p200,
int *p100)
{
*p500 = total / 500;
total = total % 500;
*p200 = total / 200;
total = total % 200;
*p100 = total / 100;
}
int main()
{
int amount = 800;
int notes500, notes200, notes100;
return 0;
}
void atm_dispensing(int total,
int *p500,
int *p200,
int *p100)
{
*p500 = total / 500;
total = total % 500;
*p200 = total / 200; Data area of main
total = total % 200;
*p100 = total / 100; amount: int
}
int main() 800
{
some_addr
int amount = 800;
int notes500, notes200, notes100;
return 0;
}
void atm_dispensing(int total,
int *p500,
int *p200,
int *p100)
{
*p500 = total / 500;
total = total % 500;
*p200 = total / 200; Data area of main
total = total % 200;
*p100 = total / 100; amount: int
}
int main() 800
{
some_addr
int amount = 800;
int notes500, notes200, notes100;
We don’t really
atm_dispensing(amount, ¬es500, ¬es200, care what the
¬es100);
exact address is!
printf("Dispense %d as %dx500 + %dx200 + %dx100\n",
amount, notes500, notes200, notes100);
return 0;
}
void atm_dispensing(int total,
int *p500,
int *p200,
int *p100)
{
*p500 = total / 500;
total = total % 500;
*p200 = total / 200; Data area of main
total = total % 200;
*p100 = total / 100; amount: int notes500: int
}
int main() 800 ?
{
some_addr some_addr
int amount = 800;
int notes500, notes200, notes100;
return 0;
}
void atm_dispensing(int total,
int *p500,
int *p200,
int *p100)
{
*p500 = total / 500;
total = total % 500;
*p200 = total / 200; Data area of main
total = total % 200;
*p100 = total / 100; amount: int notes500: int
}
int main() 800 ?
{
some_addr some_addr
int amount = 800;
int notes500, notes200, notes100;
return 0;
}
void atm_dispensing(int total,
int *p500,
int *p200,
int *p100)
{
*p500 = total / 500;
total = total % 500;
*p200 = total / 200; Data area of main
total = total % 200;
*p100 = total / 100; amount: int notes500: int notes200: int notes100: int
}
int main() 800 ? ? ?
{
some_addr some_addr some_addr some_addr
int amount = 800;
int notes500, notes200, notes100;
return 0;
}
void atm_dispensing(int total,
int *p500,
int *p200,
int *p100)
{
*p500 = total / 500;
total = total % 500;
*p200 = total / 200; Data area of main
total = total % 200;
*p100 = total / 100; amount: int notes500: int notes200: int notes100: int
}
int main() 800 ? ? ?
{
some_addr some_addr some_addr some_addr
int amount = 800;
int notes500, notes200, notes100;
return 0;
The function call creates three
}
pointer relations
void atm_dispensing(int total, Data area of atm_dispensing
int *p500,
int *p200, total: int p500: int* p200: int* p100: int*
int *p100)
{ 800
*p500 = total / 500;
total = total % 500;
*p200 = total / 200; Data area of main
total = total % 200;
*p100 = total / 100; amount: int notes500: int notes200: int notes100: int
}
int main() 800 ? ? ?
{
some_addr some_addr some_addr some_addr
int amount = 800;
int notes500, notes200, notes100;
return 0;
}
void atm_dispensing(int total, Data area of atm_dispensing
int *p500,
int *p200, total: int p500: int* p200: int* p100: int*
int *p100)
{ 800
*p500 = total / 500;
total = total % 500;
*p200 = total / 200; Data area of main
total = total % 200;
*p100 = total / 100; amount: int notes500: int notes200: int notes100: int
}
int main() 800 1? ? ?
{
some_addr some_addr some_addr some_addr
int amount = 800;
int notes500, notes200, notes100;
return 0;
}
void atm_dispensing(int total, Data area of atm_dispensing
int *p500,
int *p200, total: int p500: int* p200: int* p100: int*
int *p100)
{ 300
800
*p500 = total / 500;
total = total % 500;
*p200 = total / 200; Data area of main
total = total % 200;
*p100 = total / 100; amount: int notes500: int notes200: int notes100: int
}
int main() 800 1? ? ?
{
some_addr some_addr some_addr some_addr
int amount = 800;
int notes500, notes200, notes100;
return 0;
}
void atm_dispensing(int total, Data area of atm_dispensing
int *p500,
int *p200, total: int p500: int* p200: int* p100: int*
int *p100)
{ 300
800
*p500 = total / 500;
total = total % 500;
*p200 = total / 200; Data area of main
total = total % 200;
*p100 = total / 100; amount: int notes500: int notes200: int notes100: int
}
int main() 800 1? 1? ?
{
some_addr some_addr some_addr some_addr
int amount = 800;
int notes500, notes200, notes100;
return 0;
}
void atm_dispensing(int total, Data area of atm_dispensing
int *p500,
int *p200, total: int p500: int* p200: int* p100: int*
int *p100)
{ 100
300
800
*p500 = total / 500;
total = total % 500;
*p200 = total / 200; Data area of main
total = total % 200;
*p100 = total / 100; amount: int notes500: int notes200: int notes100: int
}
int main() 800 1? 1? ?
{
some_addr some_addr some_addr some_addr
int amount = 800;
int notes500, notes200, notes100;
return 0;
}
void atm_dispensing(int total, Data area of atm_dispensing
int *p500,
int *p200, total: int p500: int* p200: int* p100: int*
int *p100)
{ 100
300
800
*p500 = total / 500;
total = total % 500;
*p200 = total / 200; Data area of main
total = total % 200;
*p100 = total / 100; amount: int notes500: int notes200: int notes100: int
}
int main() 800 1? 1? 1?
{
some_addr some_addr some_addr some_addr
int amount = 800;
int notes500, notes200, notes100;
return 0;
}
void atm_dispensing(int total,
int *p500,
int *p200,
int *p100)
{
*p500 = total / 500;
total = total % 500;
*p200 = total / 200; Data area of main
total = total % 200;
*p100 = total / 100; amount: int notes500: int notes200: int notes100: int
}
int main() 800 1? 1? 1?
{
some_addr some_addr some_addr some_addr
int amount = 800;
int notes500, notes200, notes100;
return 0;
}
void atm_dispensing(int total,
int *p500,
int *p200,
int *p100)
{
*p500 = total / 500;
total = total % 500;
*p200 = total / 200; Data area of main
total = total % 200;
*p100 = total / 100; amount: int notes500: int notes200: int notes100: int
}
int main() 800 1? 1? 1?
{
some_addr some_addr some_addr some_addr
int amount = 800;
int notes500, notes200, notes100;
return 0;
}
Dispense 800 as 1x500 + 1x200 + 1x100
void atm_dispensing(int total,
int *p500,
int *p200,
int *p100)
{
*p500 = total / 500;
total = total % 500;
*p200 = total / 200; Data area of main
total = total % 200;
*p100 = total / 100; amount: int notes500: int notes200: int notes100: int
}
int main() 800 1? 1? 1?
{
some_addr some_addr some_addr some_addr
int amount = 800;
int notes500, notes200, notes100;
Input params - as
above;
Compute multiple Stored in the output
void Output params-
values params
pointers to actual
arguments
Types of functions seen so far
Input params - as
above;
Compute multiple Stored in the output
void Output params-
values params
pointers to actual
arguments
Your turn
✤ Suppose you are hired by a recruiting rm. They often receive a list of CGPAs from colleges
and have to determine how many interviews to hold based on some cutoff.
✤ Write a function that, given a list of real numbers representing student CGPAs, outputs the
number of students whose CGPA is
✤ Above 9
✤ Below 6
fi
BITS Pilani
K K Birla Goa Campus
Pointers
Swaroop Joshi
2023
Size matters!
char
int
double
A variable of a type takes specific space to store
A variable of a type takes specific space to store
typedef struct
{
char author[20];
char text[140];
char timestamp[40];
int num_rt;
int num_quote_rt;
int num_likes;
} tweet_t;
A variable of a type takes specific space to store
typedef struct char response = 'n';
{ int num = 42;
char author[20]; double discount = .1;
char text[140]; tweet_t t1 = {"@bitsgoa", "End of 2022-23"};
char timestamp[40];
int num_rt;
int num_quote_rt;
int num_likes;
} tweet_t;
A variable of a type takes specific space to store
The trailing elements of a struct, if
left unspeci ed, are automatically
typedef struct char response = 'n'; set to 0 - if numeric; “”- if strings
{ int num = 42;
char author[20]; double discount = .1;
char text[140]; tweet_t t1 = {"@bitsgoa", "End of 2022-23"};
char timestamp[40];
int num_rt;
int num_quote_rt;
int num_likes;
} tweet_t;
fi
A variable of a type takes specific space to store
typedef struct char response = 'n';
{ int num = 42;
char author[20]; double discount = .1;
char text[140]; tweet_t t1 = {"@bitsgoa", "End of 2022-23"};
char timestamp[40];
int num_rt;
int num_quote_rt; printf("A char takes %d bytes\n", (int) sizeof response);
int num_likes;
} tweet_t;
A variable of a type takes specific space to store
typedef struct char response = 'n';
{ int num = 42;
char author[20]; double discount = .1;
char text[140]; tweet_t t1 = {"@bitsgoa", "End of 2022-23"};
char timestamp[40];
int num_rt;
int num_quote_rt; printf("A char takes %d bytes\n", (int) sizeof response);
int num_likes;
} tweet_t;
sizeof is an operator that computes the
number of bytes the variable or the type it
is applied to takes in memory
A variable of a type takes specific space to store
typedef struct char response = 'n';
{ int num = 42;
char author[20]; double discount = .1;
char text[140]; tweet_t t1 = {"@bitsgoa", "End of 2022-23"};
char timestamp[40];
int num_rt;
int num_quote_rt; printf("A char takes %d bytes\n", (int) sizeof response);
int num_likes; A char takes 1 bytes
} tweet_t;
A variable of a type takes specific space to store
typedef struct char response = 'n';
{ int num = 42;
char author[20]; double discount = .1;
char text[140]; tweet_t t1 = {"@bitsgoa", "End of 2022-23"};
char timestamp[40];
int num_rt;
int num_quote_rt; printf("A char takes %d bytes\n", (int) sizeof response);
int num_likes; A char takes 1 bytes
} tweet_t;
return 0;
}
Data area of more_liked_tweet
tweet_t more_liked_tweet(tweet_t tw1,
tweet_t tw2)
{
tweet_t ans = (tw1.num_likes
> tw2.num_likes)
? tw1
: tw2;
return ans;
}
int main()
{
tweet_t t1 = {
“@bitsgoa”,
"End of 2022-23"}; Data area of main
tweet_t t2 = { t1: tweet_t
"@bitsgoa",
"Not for the first years!”, “@bitsgoa”,
“2023-05-19", 20, 30, 40};
“End of…”
tweet_t popular = more_liked_tweet(t1, t2);
printf("Tweet '%s' has more likes\n”,
popular.text);
return 0;
}
Data area of more_liked_tweet
tweet_t more_liked_tweet(tweet_t tw1,
tweet_t tw2)
{
tweet_t ans = (tw1.num_likes
> tw2.num_likes)
? tw1
: tw2;
return ans;
}
int main()
{
tweet_t t1 = {
“@bitsgoa”,
"End of 2022-23"}; Data area of main
tweet_t t2 = { t1: tweet_t
"@bitsgoa", 212 bytes
"Not for the first years!”, “@bitsgoa”,
“2023-05-19", 20, 30, 40};
“End of…”
tweet_t popular = more_liked_tweet(t1, t2);
printf("Tweet '%s' has more likes\n”,
popular.text);
return 0;
}
Data area of more_liked_tweet
tweet_t more_liked_tweet(tweet_t tw1,
tweet_t tw2)
{
tweet_t ans = (tw1.num_likes
> tw2.num_likes)
? tw1
: tw2;
return ans;
}
int main()
{
tweet_t t1 = {
“@bitsgoa”,
"End of 2022-23"}; 212Data
bytes
area of main
tweet_t t2 = { t1: tweet_t t2: tweet_t
"@bitsgoa",
"Not for the first years!”, “@bitsgoa”, “@bitsgoa”,
“2023-05-19", 20, 30, 40};
“End of…” “Not for…”
tweet_t popular = more_liked_tweet(t1, t2);
printf("Tweet '%s' has more likes\n”,
popular.text);
return 0;
}
Data area of more_liked_tweet
tweet_t more_liked_tweet(tweet_t tw1,
tweet_t tw2)
{
tweet_t ans = (tw1.num_likes
> tw2.num_likes)
? tw1
: tw2;
return ans;
}
int main()
{
tweet_t t1 = {
“@bitsgoa”,
"End of 2022-23"}; Data area of main
tweet_t t2 = { t1: tweet_t t2: tweet_t
"@bitsgoa",
"Not for the first years!”, “@bitsgoa”, “@bitsgoa”,
“2023-05-19", 20, 30, 40};
“End of…” “Not for…”
tweet_t popular = more_liked_tweet(t1, t2);
printf("Tweet '%s' has more likes\n”,
popular.text);
return 0;
}
Data area of more_liked_tweet
tweet_t more_liked_tweet(tweet_t tw1,
tweet_t tw2) tw1: tweet_t
{
tweet_t ans = (tw1.num_likes “@bitsgoa”,
> tw2.num_likes) “End of…”
? tw1
: tw2;
return ans;
}
int main()
{
tweet_t t1 = {
“@bitsgoa”,
"End of 2022-23"}; Data area of main
tweet_t t2 = { t1: tweet_t t2: tweet_t
"@bitsgoa",
"Not for the first years!”, “@bitsgoa”, “@bitsgoa”,
“2023-05-19", 20, 30, 40};
“End of…” “Not for…”
tweet_t popular = more_liked_tweet(t1, t2);
printf("Tweet '%s' has more likes\n”,
popular.text);
return 0;
}
Data area of more_liked_tweet
tweet_t more_liked_tweet(tweet_t tw1,
tweet_t tw2) tw1: tweet_t
{
tweet_t ans = (tw1.num_likes “@bitsgoa”,
> tw2.num_likes) “End of…”
? tw1
: tw2;
return ans; The entire value of t1
} is copied to tw1;
int main() So 212 bytes
{
tweet_t t1 = {
“@bitsgoa”,
"End of 2022-23"}; Data area of main
tweet_t t2 = { t1: tweet_t t2: tweet_t
"@bitsgoa",
"Not for the first years!”, “@bitsgoa”, “@bitsgoa”,
“2023-05-19", 20, 30, 40};
“End of…” “Not for…”
tweet_t popular = more_liked_tweet(t1, t2);
printf("Tweet '%s' has more likes\n”,
popular.text);
return 0;
}
Data area of more_liked_tweet
tweet_t more_liked_tweet(tweet_t tw1,
tweet_t tw2) tw1: tweet_t tw2: tweet_t
{
tweet_t ans = (tw1.num_likes “@bitsgoa”, “@bitsgoa”,
> tw2.num_likes) “End of…” “Not for…”
? tw1
: tw2;
return ans;
} Again 212 bytes
int main()
{
tweet_t t1 = {
“@bitsgoa”,
"End of 2022-23"}; Data area of main
tweet_t t2 = { t1: tweet_t t2: tweet_t
"@bitsgoa",
"Not for the first years!”, “@bitsgoa”, “@bitsgoa”,
“2023-05-19", 20, 30, 40};
“End of…” “Not for…”
tweet_t popular = more_liked_tweet(t1, t2);
printf("Tweet '%s' has more likes\n”,
popular.text);
return 0;
}
Data area of more_liked_tweet
tweet_t more_liked_tweet(tweet_t tw1,
tweet_t tw2) tw1: tweet_t tw2: tweet_t
{ Also 212 bytes
tweet_t ans = (tw1.num_likes “@bitsgoa”, “@bitsgoa”,
> tw2.num_likes) “End of…” “Not for…”
? tw1
: tw2; ans: tweet_t
return ans;
} “@bitsgoa”,
int main() “Not for…”
{
tweet_t t1 = {
“@bitsgoa”,
"End of 2022-23"}; Data area of main
tweet_t t2 = { t1: tweet_t t2: tweet_t
"@bitsgoa",
"Not for the first years!”, “@bitsgoa”, “@bitsgoa”,
“2023-05-19", 20, 30, 40};
“End of…” “Not for…”
tweet_t popular = more_liked_tweet(t1, t2);
printf("Tweet '%s' has more likes\n”,
popular.text);
return 0;
}
Data area of more_liked_tweet
tweet_t more_liked_tweet(tweet_t tw1,
tweet_t tw2) tw1: tweet_t tw2: tweet_t
{
tweet_t ans = (tw1.num_likes “@bitsgoa”, “@bitsgoa”,
> tw2.num_likes) “End of…” “Not for…”
? tw1
: tw2; ans: tweet_t
return ans;
} “@bitsgoa”,
int main() “Not for…”
{
tweet_t t1 = {
“@bitsgoa”,
"End of 2022-23"}; Data area of main
tweet_t t2 = { t1: tweet_t t2: tweet_t
"@bitsgoa",
"Not for the first years!”, “@bitsgoa”, “@bitsgoa”,
“2023-05-19", 20, 30, 40};
“End of…” “Not for…”
tweet_t popular = more_liked_tweet(t1, t2); popular: tweet_t
printf("Tweet '%s' has more likes\n”,
popular.text); “@bitsgoa”,
return 0;
“Not for…”
}
tweet_t more_liked_tweet(tweet_t tw1,
tweet_t tw2)
{
tweet_t ans = (tw1.num_likes
> tw2.num_likes)
? tw1
: tw2;
return ans;
}
int main()
{
tweet_t t1 = {
“@bitsgoa”,
"End of 2022-23"}; Data area of main
tweet_t t2 = { t1: tweet_t t2: tweet_t
"@bitsgoa",
"Not for the first years!”, “@bitsgoa”, “@bitsgoa”,
“2023-05-19", 20, 30, 40};
“End of…” “Not for…”
tweet_t popular = more_liked_tweet(t1, t2); popular: tweet_t
printf("Tweet '%s' has more likes\n”,
popular.text); The whole thing is copied “@bitsgoa”,
back here, so again, 212 bytes “Not for…”
return 0;
}
tweet_t more_liked_tweet(tweet_t tw1,
tweet_t tw2)
{
tweet_t ans = (tw1.num_likes
> tw2.num_likes)
? tw1
: tw2;
return ans;
}
int main()
{
tweet_t t1 = {
“@bitsgoa”,
"End of 2022-23"}; Data area of main
tweet_t t2 = { t1: tweet_t t2: tweet_t
"@bitsgoa",
"Not for the first years!”, “@bitsgoa”, “@bitsgoa”,
“2023-05-19", 20, 30, 40};
“End of…” “Not for…”
tweet_t popular = more_liked_tweet(t1, t2); popular: tweet_t
printf("Tweet '%s' has more likes\n”,
popular.text); “@bitsgoa”,
return 0;
“Not for…”
}
tweet_t more_liked_tweet(tweet_t tw1,
tweet_t tw2)
{
tweet_t ans = (tw1.num_likes
> tw2.num_likes)
? tw1
: tw2;
return ans;
}
int main()
{
tweet_t t1 = { Can we do better using pointers?
“@bitsgoa”,
"End of 2022-23"}; Data area of main
tweet_t t2 = { t1: tweet_t t2: tweet_t
"@bitsgoa",
"Not for the first years!”, “@bitsgoa”, “@bitsgoa”,
“2023-05-19", 20, 30, 40};
“End of…” “Not for…”
tweet_t popular = more_liked_tweet(t1, t2); popular: tweet_t
printf("Tweet '%s' has more likes\n”,
popular.text); “@bitsgoa”,
return 0;
“Not for…”
}
Data area of more_liked_tweet_p
tweet_t more_liked_tweet_p(tweet_t *t1_p,
tweet_t *t2_p)
{
tweet_t ans = ((*t1_p).num_likes
> (*t2_p).num_likes)
? (*t1_p)
: (*t2_p);
return ans;
}
int main()
{
tweet_t t1 = { … }; Data area of main
tweet_t t2 = { … };
tweet_t popular_p
= more_liked_tweet_p(&t1, &t2);
printf("Tweet '%s' has more likes\n”,
popular_p.text);
return 0;
}
Data area of more_liked_tweet_p
tweet_t more_liked_tweet_p(tweet_t *t1_p,
tweet_t *t2_p)
{
tweet_t ans = ((*t1_p).num_likes
> (*t2_p).num_likes)
? (*t1_p)
: (*t2_p);
return ans;
}
int main()
{
tweet_t t1 = { … }; Data area of main
tweet_t t2 = { … }; t1: tweet_t
return 0;
}
Data area of more_liked_tweet_p
tweet_t more_liked_tweet_p(tweet_t *t1_p,
tweet_t *t2_p)
{
tweet_t ans = ((*t1_p).num_likes
> (*t2_p).num_likes)
? (*t1_p)
: (*t2_p);
return ans;
}
int main()
{
tweet_t t1 = { … }; Data area of main
tweet_t t2 = { … }; t1: tweet_t
212 bytes
tweet_t popular_p “@bitsgoa”,
= more_liked_tweet_p(&t1, &t2);
printf("Tweet '%s' has more likes\n”, “End of…”
popular_p.text);
return 0;
}
Data area of more_liked_tweet_p
tweet_t more_liked_tweet_p(tweet_t *t1_p,
tweet_t *t2_p)
{
tweet_t ans = ((*t1_p).num_likes
> (*t2_p).num_likes)
? (*t1_p)
: (*t2_p);
return ans;
}
int main()
{
tweet_t t1 = { … }; 212Data
bytes
area of main
tweet_t t2 = { … }; t1: tweet_t t2: tweet_t
return 0;
}
Data area of more_liked_tweet_p
tweet_t more_liked_tweet_p(tweet_t *t1_p,
tweet_t *t2_p)
{
tweet_t ans = ((*t1_p).num_likes
> (*t2_p).num_likes)
? (*t1_p)
: (*t2_p);
return ans;
}
int main()
{
tweet_t t1 = { … }; Data area of main
tweet_t t2 = { … }; t1: tweet_t t2: tweet_t
return 0;
}
Data area of more_liked_tweet_p
tweet_t more_liked_tweet_p(tweet_t *t1_p,
tweet_t *t2_p) t1_p: tweet_t*
{
tweet_t ans = ((*t1_p).num_likes
> (*t2_p).num_likes)
? (*t1_p)
: (*t2_p);
return ans;
}
int main()
{
tweet_t t1 = { … }; Data area of main
tweet_t t2 = { … }; t1: tweet_t t2: tweet_t
return 0;
}
Data area of more_liked_tweet_p
tweet_t more_liked_tweet_p(tweet_t *t1_p,
tweet_t *t2_p) t1_p: tweet_t*
{
tweet_t ans = ((*t1_p).num_likes
> (*t2_p).num_likes)
? (*t1_p)
: (*t2_p);
return ans;
8 bytes
}
int main()
{
tweet_t t1 = { … }; Data area of main
tweet_t t2 = { … }; t1: tweet_t t2: tweet_t
return 0;
}
Data area of more_liked_tweet_p
tweet_t more_liked_tweet_p(tweet_t *t1_p,
tweet_t *t2_p) t1_p: tweet_t* t2_p: tweet_t*
{
tweet_t ans = ((*t1_p).num_likes
> (*t2_p).num_likes)
? (*t1_p)
: (*t2_p);
return ans; 8 bytes
}
int main()
{
tweet_t t1 = { … }; Data area of main
tweet_t t2 = { … }; t1: tweet_t t2: tweet_t
return 0;
}
Data area of more_liked_tweet_p
tweet_t more_liked_tweet_p(tweet_t *t1_p,
tweet_t *t2_p) t1_p: tweet_t* t2_p: tweet_t*
{
tweet_t ans = ((*t1_p).num_likes
> (*t2_p).num_likes)
? (*t1_p)
: (*t2_p);
return ans;
}
int main()
{
tweet_t t1 = { … }; Data area of main
tweet_t t2 = { … }; t1: tweet_t t2: tweet_t
return 0;
}
Data area of more_liked_tweet_p
tweet_t more_liked_tweet_p(tweet_t *t1_p,
tweet_t *t2_p) t1_p: tweet_t* t2_p: tweet_t*
{
tweet_t ans = ((*t1_p).num_likes
> (*t2_p).num_likes)
? (*t1_p)
: (*t2_p); ans: tweet_t
return ans;
} “@bitsgoa”,
“Not for…”
int main()
{ Copied
tweet_t t1 = { … }; Data area of main from here
tweet_t t2 = { … }; t1: tweet_t t2: tweet_t
return 0;
}
Data area of more_liked_tweet_p
tweet_t more_liked_tweet_p(tweet_t *t1_p,
tweet_t *t2_p) t1_p: tweet_t* t2_p: tweet_t*
{
tweet_t ans = ((*t1_p).num_likes
> (*t2_p).num_likes)
? (*t1_p)
: (*t2_p); ans: tweet_t
return ans;
} “@bitsgoa”,
“Not for…”
int main()
{
tweet_t t1 = { … }; Data area of main
tweet_t t2 = { … }; t1: tweet_t t2: tweet_t
return 0;
}
tweet_t more_liked_tweet_p(tweet_t *t1_p,
tweet_t *t2_p)
{
tweet_t ans = ((*t1_p).num_likes
> (*t2_p).num_likes)
? (*t1_p)
: (*t2_p);
return ans;
}
int main()
{
tweet_t t1 = { … }; Data area of main
tweet_t t2 = { … }; t1: tweet_t t2: tweet_t
return 0; “@bitsgoa”,
} 212 bytes
“Not for…”
tweet_t more_liked_tweet_p(tweet_t *t1_p,
tweet_t *t2_p)
{
tweet_t ans = ((*t1_p).num_likes
> (*t2_p).num_likes)
? (*t1_p)
: (*t2_p);
return ans;
}
int main()
{
tweet_t t1 = { … }; Data area of main
tweet_t t2 = { … }; t1: tweet_t t2: tweet_t
return 0; “@bitsgoa”,
}
“Not for…”
tweet_t more_liked_tweet_p(tweet_t *t1_p,
tweet_t *t2_p)
{
tweet_t ans = ((*t1_p).num_likes
> (*t2_p).num_likes)
? (*t1_p)
: (*t2_p);
return ans;
}
return 0; “@bitsgoa”,
}
“Not for…”
fi
tweet_t more_liked_tweet_p(tweet_t *t1_p,
tweet_t *t2_p)
{
tweet_t ans = ((*t1_p).num_likes
> (*t2_p).num_likes)
? (*t1_p)
: (*t2_p);
return ans;
}
return 0; “@bitsgoa”,
}
“Not for…”
fi
tweet_t more_liked_tweet_p(tweet_t *t1_p,
tweet_t *t2_p)
{
tweet_t ans = ((*t1_p).num_likes
> (*t2_p).num_likes)
? (*t1_p)
: (*t2_p);
return ans;
}
return 0; “@bitsgoa”,
} Yes, but be patient! :-)
“Not for…”
fi
The arrow operator
✤ Is equivalent to
✤ (*ptr_name).member_name
✤ Is equivalent to
✤ (*ptr_name).member_name
Pointers
Swaroop Joshi
2023
Pointer arithmetic
Data area of main
marks: int
Recall 76
ans: char
0x16f25b354
int marks = 76; y
printf("%d\n", marks);
printf("%p\n\n", &marks); 0x16d12b350
marks: int
Recall 76
ans: char
0x16f25b354
int marks = 76; y
printf("%d\n", marks);
printf("%p\n\n", &marks); 0x16d12b350
marks: int
Recall 76
ans: char
0x16f25b354
int marks = 76; y
printf("%d\n", marks);
printf("%p\n\n", &marks); Remember: these addresses are only 0x16d12b350
for representation purpose; actual
char ans = 'y';
printf("%c\n", ans); addresses can be different when you
printf("%p\n\n", &ans); run it on your machine
area: double
double area = M_PI * 10 * 10;
printf("%lf\n", area); 314.159265
printf("%p\n\n", &area);
0x16f25b344
76
0x16d12b354
y
0x16d12b350
314.159265
0x16d12b344
Under the hood
Data area of main
int main()
{
int nums[] = {10, 20, 30, 40, 50, 60};
print_array(nums, 6);
return 0;
}
Passing arrays to functions
int main()
{
int nums[] = {10, 20, 30, 40, 50, 60};
print_array(nums, 6);
return 0;
}
Passing arrays to functions
int main()
{
int nums[] = {10, 20, 30, 40, 50, 60};
print_array(nums, 6);
int main()
{
int nums[] = {10, 20, 30, 40, 50, 60};
print_array(nums, 6);
printf("\n");
}
Write a function that computes and displays
the cumulative sum of an array of integers
void print_array(int *nums, int length) Assume this function is available
{
for (int i = 0; i < length; ++i)
printf("%d ", nums[i]);
printf("\n");
} Does this code do the job?
print_array(nums, length);
}
Write a function that computes and displays
the cumulative sum of an array of integers
void print_array(int *nums, int length) Assume this function is available
{
for (int i = 0; i < length; ++i)
printf("%d ", nums[i]);
printf("\n");
}
printf("\n");
}
print_array(nums, length);
}
Write a function that computes and displays
the cumulative sum of an array of integers
void print_array(int *nums, int length) Assume this function is available
{
for (int i = 0; i < length; ++i)
printf("%d ", nums[i]); We know that pointers allow us to
manipulate variables outside their scope.
printf("\n");
}
Such side effects make it dif cult to reason
about programs, so be careful when writing
void print_cumulative_sum(int *nums, int length)
{ such code!
for (int i = 1; i < length; ++i)
nums[i] += nums[i - 1];
print_array(nums, length);
}
fi
Pointers summary
CSF111
Computer Programming
Pointers
(Supplementary)
Pointers Examples
Write a function that, given a list of real numbers representing student CGPAs, outputs the
number of students whose CGPA is
✤ Above 9
✤ Between 7.5 inclusive and 9 exclusive
✤ Between 6 inclusive and 7.5 exclusive
✤ Below 6
Pointers Examples
Write a function that, given a list of real numbers representing student CGPAs, outputs the
number of students whose CGPA is
✤ Above 9
✤ Between 7.5 inclusive and 9 exclusive
✤ Between 6 inclusive and 7.5 exclusive
✤ Below 6
Pointers Examples
Write a function that, given a list of real numbers representing student CGPAs, outputs the
number of students whose CGPA is
✤ Above 9
✤ Between 7.5 inclusive and 9 exclusive
✤ Between 6 inclusive and 7.5 exclusive
✤ Below 6
Pointers Examples
Swap two integer variables
✤ Passing by value
✤ Passing by address
Pointers Examples
Swap two integer variables
✤ Passing by value
✤ Passing by address
Output
Both works fine, however, the second one is more optimized (in terms of memory usage)!!
Revisiting Pointers
What will be the output of the code segment?
Revisiting Pointers
What will be the output of the code segment?
Revisiting Pointers
What will be the output of the code segment?
Revisiting Pointers
What will be the output of the code segment?
Revisiting Pointers
What will be the output of the code segment?
Revisiting Pointers
What will be the output of the code segment?
Revisiting Pointers
What will be the output of the code segment?
Revisiting Pointers
What will be the output of the code segment?
Revisiting Pointers
Pointers in expressions
• *p1 = *p1 + 2;
• x = *p1 / *p2 + 5;
Revisiting Pointers
Pointer arithmetic
• If p1 and p2 are both pointers to the same array, then p2–p1 gives what?
Revisiting Pointers
Pointer arithmetic
• If p1 and p2 are both pointers to the same array, then p2–p1 gives what?
• p1 = p1 + p2;
• p1 = p2 / 5;
• p1 = p1 – p2 * 10;
Revisiting Pointers
Pointer arithmetic
Scale Factor
Revisiting Pointers
Pointer arithmetic
Scale Factor
• Increasing a pointer by 1 does not necessarily increase the pointer by 1 byte, rather it depends on the size of the
data type to which the pointer points.
Revisiting Pointers
Pointer arithmetic
Scale Factor
struct class {
int roll;
char name[20];
float marks;
};
Member operator “.” has higher precedence than the dereferencing operator “*”
(++ptr) –> roll will increment the pointer (to the next structure in an array) and
access roll in the next structure.
Revisiting Pointers (and structures)
What will be the output of the code segment?
Revisiting Pointers
Practice Problems
1. Extend the complex number program to include functions for addition, subtraction, multiplication, and
division
2. Define a structure for representing a point in two-dimensional Cartesian coordinate system. Using this
structure for a point, do the following.
(a) Write a function to return the distance between two given points
(b) Write a function to return the middle point of the line segment joining two given points
(c) Write a function to compute the area of a triangle formed by three given points