0% found this document useful (0 votes)
47 views65 pages

Pointers: ICT1002 - P F W 10

1. Pointers are variables that store memory addresses. They allow indirect access to other variables. 2. The & operator returns the address of its operand. The * operator dereferences a pointer and returns the value at the addressed memory location. 3. Arrays and pointers are closely related - array names evaluate to the address of the first element, and pointers can be used to navigate arrays using pointer arithmetic or subscript notation. 4. Pointer arithmetic increments or decrements a pointer by the size of the type it points to. Adding an integer to a pointer moves the pointer that number of elements forward or backward in an array.

Uploaded by

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

Pointers: ICT1002 - P F W 10

1. Pointers are variables that store memory addresses. They allow indirect access to other variables. 2. The & operator returns the address of its operand. The * operator dereferences a pointer and returns the value at the addressed memory location. 3. Arrays and pointers are closely related - array names evaluate to the address of the first element, and pointers can be used to navigate arrays using pointer arithmetic or subscript notation. 4. Pointer arithmetic increments or decrements a pointer by the size of the type it points to. Adding an integer to a pointer moves the pointer that number of elements forward or backward in an array.

Uploaded by

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

POINTERS

DR FRANK GUAN
ICT1002 – PROGRAMMING FUNDAMENTALS
WEEK 10
SELF-ASSESSMENT FOR WEEK 9

2
Agenda
1. Pointers
2. Arrays and pointers
3. User-defined data types
4. Call-by-reference

3
RECOMMENDED READING
Paul Deitel and Harvey
Deitel, C: How to
Program, 8th Edition,
Prentice Hall, 2016

– Chapter 7: C Pointers

– Chapter 10: C Structures,


Unions, Bit Manipulation
and Enumerations

4
POINTERS
POINTER VARIABLES
Pointers are variables whose values are
memory addresses.

int
ptr
POINTER VARIABLE
DEFINITION
* indicates
int *ptr; that the
variable being
defined is a
int pointer:
ptr
“ptr is a
pointer to an
int”
POINTER VARIABLES
count
count directly references a variable
int count = 7; 7 that contains the value 7

A variable directly contains a


specific value
POINTER VARIABLES
count
count directly references a variable
int count = 7; 7 that contain the value 7

countPtr
countPtr indirectly references a
int *countPtr = &count; 0xF200 7 variable that contains the value 7
Memory 
location: 
0xF200

A pointer contains an address of a


variable that contains a specific
value
POINTER VARIABLE DEFINITION

int *ptr1, *ptr2;

Note: The asterisk (*) does not distribute to all


variable names in a declaration.

Each pointer must be declared with the *


prefixed to the name.
POINTER OPERATORS

#include <stdio.h> The &


int main() {
int y = 5;
int *yPtr;
operator
yPtr = &y;
printf("Address of y: %d\n", &y);
returns the
printf("Value of yPtr: %d\n", yPtr);
printf("Address of yPtr: %d\n", &yPtr);
printf("Value to which yPtr points: %d\n",
address of its
*yPtr);

}
return 0; operand.
POINTER OPERATORS

Assign the #include <stdio.h>

address of y int main() {
int y = 5;
int *yPtr;

to yPtr yPtr = &y;
printf("Address of y: %d\n", &y);
printf("Value of yPtr: %d\n", yPtr);
printf("Address of yPtr: %d\n", &yPtr);
printf("Value to which yPtr points: %d\n",
*yPtr);

return 0;
}
POINTER OPERATORS

#include <stdio.h>

int main() {
int y = 5;
int *yPtr;

yPtr = &y;
printf("Address of y: %d\n", &y);
printf("Value of yPtr: %d\n", yPtr);
printf("Address of yPtr: %d\n", &yPtr);
printf("Value to which yPtr points: %d\n",
*yPtr);

return 0;
}
The de‐referencing operator
returns the value of the object to
which its operand points.
POINTER OPERATORS

Dereferencing a pointer that has not been


properly initialised or that has not been
assigned to point to a specific location in
memory is an error.

This could cause a fatal run time


error, or it could accidentally modify
important data and allow the program to run
to completion with incorrect results.
int y = 5; y 5 2044

int *yPtr; yPtr 3064

*yPtr Error

Dereferencing a pointer that has not been properly initialised.


EXERCISE
What are the values of a and b after
each line of the following program?

int a = 5, b = 2;
int *p = &a, *q = &b;

*p *= 2;
*q  = *p – 1;
p  = &b;
b  = *p + 3;

16
POINTERS & ARRAYS
POINTERS & ARRAYS
Pointers and arrays are intimately related
in C.

– An array name can be thought of as a


constant pointer to the start of the
array.

– Array subscripts can be applied to


pointers.

– Pointer arithmetic can be used to


navigate arrays.

18
POINTERS & ARRAYS
The name of the array evaluates to the address of
the first element of the array.
int main() {

char charArray[5];

printf("charArray: \t%p\n", charArray);
printf("&chararray[0]: \t%p\n", &charArray[0]);
printf("&charArray: \t%p\n", &charArray);

return 0;
}

charArray:      003CFC34
Output &charArray[0]:  003CFC34
&charArray:     003CFC34
array VS &array: https://www.geeksforgeeks.org/whats-difference-between-array-and-array-for-int-array5/ 19
POINTERS & ARRAYS
Subscripting and pointer arithmetic can be used
interchangeably.
int main() {

char b[] = {'a', 'b', 'c', 'd', 'e' };
char *bPtr = b;

printf("*(bPtr + 3): \t%c\n", *(bPtr + 3));
printf("*(b + 3): \t%c\n", *(b + 3));
printf("bPtr[3]: \t%c\n", bPtr[3]);

return 0;
} *(bPtr + 3): d
Output *(b + 3): d
bPtr[3]: d

20
POINTERS & ARRAYS
The fourth element of b can be referenced
using any of the following statements:

3 is the offset to the pointer indicates which


*(bPtr + 3)  element of the array should be referenced

The array itself can be treated as a pointer to the


*(b+3) first element of the array.

bPtr[3] pointers can be subscripted exactly as arrays can.

21
EXERCISE
What are the contents of the array a
and the position of the pointer p after
each line of the following program?

int a[] = { 1, ‐1, 4, 5, 4, ‐3 };
int *p = a + 5;

*p = ‐(*p);
p ‐= 2;
*p = *p + 1;
*(p + 1) = *p * 2;

22
POINTER EXPRESSIONS & ARITHMETIC
POINTER EXPRESSIONS & ARITHMETIC
In general, pointers are valid
operands in
– assignment expressions
– arithmetic expressions
– comparison expressions

However, not all the operators


normally used in these
expressions are valid in
conjunction with pointer variables.

24
POINTER ASSIGNMENT
A pointer can be assigned to another pointer
if they have the same type.
3000 3434

n 5 3000 ptr
4000

3000 anotherPtr

anotherPtr will point to


whatever memory location that
ptr is pointing to

25
POINTER EXPRESSIONS & ARITHMETIC
3000 3004 3008 3012 3016
v v[0] v[1] v[2] v[3] v[4]

3000 What is the


result of
vPtr vPtr += 2;

int v[5] = {0};


int *vPtr = v;
vPtr = &v[ 0 ];
26
POINTER EXPRESSIONS & ARITHMETIC
3000 3004 3008 3012 3016
v v[0] v[1] v[2] v[3] v[4]

3002
3000 What is the
result of
vPtr vPtr += 2;

int v[5] = {0}; In conventional arithmetic, 3000+2 =


int *vPtr = v; 3002. However, this is not the case 
vPtr = &v[ 0 ]; with pointer arithmetic.

27
POINTER EXPRESSIONS & ARITHMETIC
3000 3004 3008 3012 3016
v v[0] v[1] v[2] v[3] v[4]

vPtr += 2; 3008

vPtr
3008 = 3000 + 2*sizeof(int)

When an integer is added or subtracted from a pointer, the pointer is


incremented or decremented by that integer times the size of the
object to which the pointer refers.

28
POINTER EXPRESSIONS & ARITHMETIC
3000 3004 3008 3012 3016
v v[0] v[1] v[2] v[3] v[4]

if vPtr has been incremented 3016


to 3016, the statement vPtr
vPtr ‐=4;
would set vPtr to 3000.

29
POINTER EXPRESSIONS & ARITHMETIC
3000 3004 3008 3012 3016
v v[0] v[1] v[2] v[3] v[4]

3004
If vPtr has been reset
vPtr to 3000, the statement
vPtr++;
would set vPtr to 3004.

30
CONFUSED NOW?
– Easier way to remember: DID

– D: Declaration
– int *ptr;

– I: Initialization (assignment)
– int variable = 10;
– ptr = &variable;

– D: Dereference
– *ptr = 20;

31
EXERCISE
– DID for the following statements

*abc = 100;

float *xyz;

ptr = &va;

int *a = &vb;

32
POINTERS TO POINTERS
POINTERS TO POINTERS
ptrToPtr ptr n
int n = 5;
Address Address
int *ptr = &n;
int **ptrToPtr = &ptr;
of ptr of n 5

(int *): pointer to an integer


(int *)*: pointer to a pointer which points to
an integer
Many uses in C:
– Arrays of pointers
– Arrays of strings
POINTERS TO POINTERS
#include <stdio.h>

int main() {

int n = 5;
int *ptr = &n;
int **ptrToPtr = &ptr;

printf("&n = %d\n", &n);
printf("ptr = %d\n", ptr);
printf("&ptr = %d\n", &ptr);
printf("ptrToPtr = %d\n", ptrToPtr);

/* illustrating the dereferencing operator * */

Output
printf("*ptr = %d\n", *ptr);
printf("*ptrToPtr = %d\n", *ptrToPtr);
printf("ptr = %d\n", ptr);
printf("**ptrToPtr = %d\n", **ptrToPtr);
return 0;

}
POINTERS TO POINTERS
EXAMPLE
What does swapPointer do?
How is it different from swapValue?

void swapPointer(int **a, int **b) {
int *temp = *a;
*a = *b;
*b = temp;
}

void swapValue(int *a, int *b) {
int temp = *a;
*a = *b;
*b = temp;
}
POINTERS TO POINTERS
EXAMPLE – WHAT IS THE OUTPUT OF THIS PROGRAM?
int main() {

int a = 5;
int b = 6;
int *ptrA = &a;
int *ptrB = &b;

printf("At the start:\n");
printf("a = %d, b = %d\n", a, b);
printf("ptrA = %p, ptrB = %p\n\n", ptrA, ptrB);

/* test swapPointer() */
ptrA = &a;
ptrB = &b;
swapPointer(&ptrA, &ptrB);
printf("After swapPointer():\n");
printf("a = %d, b = %d\n", a, b);
printf("ptrA = %p, ptrB = %p\n\n", ptrA, ptrB);

/* test swapValue() */
ptrA = &a;
ptrB = &b;
swapValue(ptrA, ptrB);
printf("After swapValue():\n");
printf("a = %d, b = %d\n", a, b);
printf("ptrA = %p, ptrB = %p\n\n", ptrA, ptrB);

return 0;

}
ARRAYS OF POINTERS
Arrays may contain pointers.
char * suit[ 4 ] = { "Hearts", "Diamonds", "Clubs", "Spades" };
each element “an array of
is of type
“pointer to 4 elements”
char”

*illustration from Deitel & Deitel 38


ARRAYS OF POINTERS - EXAMPLE
#include <stdio.h>

int main() {
char *suit[4] = { "Hearts", "Diamonds", "Clubs", "Spades" };
char *face[13] = {
"Ace", "2", "3", "4", "5", "6", "7", "8", "9", "10",
"Jack", "Queen", "King"
};

for (int i = 0; i < 4; i++) {


char *card_suit = suit[i];
for (int j = 0; j < 13; j++) {
printf("%s of %s\n", face[j], card_suit);
}
}

return 0;
}

39
VOID POINTERS

All pointers can be


int x; assigned to a
void *xPtr = &x; pointer to void.
printf("xPtr: %p\n", xPtr);

float f;
void *fPtr = &f; A pointer to void
printf("fPtr: %p\n", fPtr);
can point to a
variable of any
type.

40
VOID POINTERS
float f = 123.45;
The compiler says:
/* incorrect */
void_pointers.c
void *fPtr = &f;
void_pointers.c(16): error C2100:
printf("*fPtr: %f\n", *fPtr);
illegal indirection
/* correct */
float *fPtr2 = (float *)fPtr;
printf("*fPtr2: %0.2f\n", *fPtr2);

A pointer to void cannot be dereferenced.


Void pointers should always be cast before
dereferencing. 41
USER-DEFINED DATA TYPES
STRUCTURES
Suppose you want to Name Sachin Kumar
represent this Roll 101
information about a Age 16
student. Class ICT1002

43
STRUCTURES
C allows structured collections of
information to be defined using the
struct keyword.

struct <name> {
member 1
member 2
:
member n
};
44
STRUCTURES - EXAMPLE
struct student {
char name[20];
int roll;
int age;
char class[12];
} student_x, student_y;

struct student student_z;

The code above declares three variables of type


struct student, called student_x, student_y, and
student_z
45
STRUCTURES – EXAMPLE
/*
* struct example from Sharma Output
*/
#include <stdio.h> Name : Sachin Kumar
struct student { Roll : 101
char name[20]; Age  : 16
int roll; Class: ICT1002
int age;
char class[12];
};

int main() {

/* initialise a variable of type student */
struct student stud1 = { "Sachin Kumar", 101, 16, "ICT1002" };
Structures /* display contents of stud1 */
can be printf("\n Name : %s", stud1.name);
printf("\n Roll : %d", stud1.roll); Use the dot
initialised
printf("\n Age  : %d", stud1.age); operator to refer
similar to printf("\n Class: %s", stud1.class);
to members of a
arrays.
return 0; structure.
} 46
USER-DEFINED DATA TYPES - TYPEDEF

typedef <type> <new_type>
User-defined data types can be declared using typedef:
<type> can be a basic data type or struct
<new_type> is the user-defined data type

47
USER-DEFINED DATA TYPES - TYPEDEF

typedef float salary;
salary wages_of_month;

In this example wages_of_month is of type


salary which is a float by itself.
This enhances the readability of the
program.
48
USER-DEFINED DATA TYPES - TYPEDEF

struct student {
char name[20];
int roll;
int age;
char class[12];
};

typedef struct student Student;

/* initialise a variable of type Student */
Student stud1 = { "Sachin Kumar", 101, 16, "ICT1002" };

49
USER-DEFINED DATA TYPES - TYPEDEF

typedef struct {
char name[20];
int roll;
int age;
char class[12];
} Student;

/* initialise a variable of type student */
Student stud1 = { "Sachin Kumar", 101, 16, "ICT1002" };

50
USER-DEFINED DATA VALUES
Many programmers use #define to
give symbolic names to numeric codes.
#define EPERM        1  /* Operation not permitted */
#define ENOENT       2  /* No such file or directory */
#define ESRCH        3  /* No such process */
...
#define EDOM        33  /* Math argument out of domain */
#define ERANGE      34  /* Math result not representable */
<errno.h> (gcc)

double r = sqrt(n);
if (errno == EDOM)
    printf("%f does not have a square root.\n", n);

51
CALL-BY-REFERENCE
CALLING FUNCTIONS BY VALUE
Recall call-by-value:
– A copy of the argument’s value is made
and passed to the called function.
– Changes to the copy do not affect the
original variable’s value in the caller.
– By default, all calls in C are by value.

53
CALLING FUNCTIONS BY REFERENCE
In call-by-reference:
– The caller allows the called function to
modify the original value.
– Call-by-reference can be simulated
using a pointer in C.

54
FUNCTIONS – CALL-BY- Simulating call-
REFERENCE by-reference
#include <stdio.h>

/* cube a number in‐place */
void cubeByReference(int *); When calling a
int main() { function with
int number = 5; arguments that
cubeByReference(&number);
printf("number = %d\n", number); should be modified,
return 0; the addresses 
}
for the 
void cubeByReference(int *ptr) {
arguments are
*ptr = (*ptr) * (*ptr) * (*ptr);

}
passed.

Output
55
PASSING ARRAYS TO FUNCTIONS

The square brackets tell


the compiler that the
function expects an array.

void modifyArray(int b[], int size)

The size of the array is not


required between the array
brackets [].

56
PASSING ARRAYS TO FUNCTIONS
Suppose we have this array:
int a[5] = { 0, 1, 2, 3, 4 };

To pass an array argument to a function, specify the


name of the array without any brackets:
modifyArray(a, 5);

This function call passes array a and its size to function


modifyArray.

57
/* the first argument of this function is an array of integers */
void modifyArray(int [], int);

int main() {

int a[5] = {0, 1, 2, 3, 4};
modifyArray(a, 5);
PASSING
ARRAYS TO
return 0;

FUNCTIONS
}

/* double every element of an array */
void modifyArray(int b[], int size) {

int j;
for (j = 0; j < size; j++)
b[j] *= 2;

This function doubles the value of each element


in the array. Will the contents of array a in
main change after this function returns?
58
C automatically passes
arrays to functions by
reference.

The called function can


modify the element values in
the callers’ original arrays.

59
int main() {

int a[5] = {0, 1, 2, 3, 4};
Output: printArray(a, 5);
[Array] = 0 1 2 3 4 modifyArray(a, 5);
printArray(a, 5);
[Array] = 0 2 4 6 8
return 0;

void printArray(int b[], int size) {

This function int j;


prints the printf("[Array] = ");
contents of for (j = 0; j < size; j++)
printf("%d ", b[j]);
the array printf("\n");

60
Many times, you do not want
a function to change the
contents of the original array,
so what do you do in this
case?

61
Use const to
prevent modification of
values in an array in a
functions.

62
void tryToModifyArray(const int b[], int size) {
When an array
int j; parameter is
for (j = 0; j < size; j++)
b[j] *= 2; preceded by the
} const qualifier,
the array elements
Compiler Output
become constant in
const_array.c
the function body,
const_array.c(28): error C2166: l‐value specifies const object
and any attempt to
modify an element
of the array in the
function body
results in a
compile-time error.
63
PASSING STRUCTURES TO FUNCTIONS
/*
* struct example with functions
*/
#include <stdio.h>

void print_student(Student *s);

int main() {

/* initialise a variable of type Student */
Structures Student stud1 = { "Sachin Kumar", 101, 16, "ICT1002" };
can be
/* display contents of stud1 */
passed by print_student(&stud1);
reference.
return 0;
}
Use the arrow
void print_student(Student *s) { operator to de-
reference a
printf("\n Name : %s", s‐>name);
printf("\n Roll : %d", s‐>roll); pointer to a
printf("\n Age  : %d", s‐>age); structure.
printf("\n Class: %s", s‐>class);

} 64
END-OF-WEEK 10 CHECKLIST

Pointer declarations Arrays & pointers

Address operator Arrays of pointers

Pointer dereferencing Call by reference

Pointer assignment Passing arrays to functions

Void pointers Using const

Pointers to pointers User-defined data types


Pointer arithmetic Dot and arrow operators

Self-assessment (for practice only):


Socrative: https://b.socrative.com/login/student
Room: ICT1002
65

You might also like