Pointers and Pointer-Based Strings

You might also like

Download as pptx, pdf, or txt
Download as pptx, pdf, or txt
You are on page 1of 21

KIG2007 : Computer Programming

Pointers and Pointer-Based Strings


Semester 2, Session 2022/2023
Pointers
• Pointers are extremely powerful because they allows you to access
addresses and manipulate their contents. But they are also
extremely complex to handle.
• A pointer variable contains the memory address of a variable that
contains a specific value. A computer memory location has an
address and holds a content. Typically, each address location holds
8-bit (i.e., 1-byte) of data.
• Unlike normal variable which stores a value (such as an int, a
double, a char), a pointer stores a memory address.
Memory address and variable
Computer Programmers

Address Content Name Type Value


90000000 00
90000001 00 int
sum 000000FF (25510)
90000002 00 (4 bytes)
90000003 FF
90000004 FF short
age FFFF (-110)
90000005 FF (2 bytes)
90000006 1F
90000007 FF
90000008 FF
90000009 FF double 1FFFFFFFFFFFFFFF
average (4.45015E-30810)
9000000A FF (8 bytes)
9000000B FF
9000000C FF
9000000D FF
9000000E 90
9000000F 00 int*
ptrSum 90000000
90000010 00 (4 bytes)
90000011 00

* All numbers in hexadecimal


Pointer declaration
• The syntax of declaring a pointer is to place a * in front of the name
type *ptr; or
type* ptr; or
type * ptr;
• The * in the declaration statement is not an operator, but indicates
that the name followed is a pointer variable.
• Each variable being declared as a pointer must be preceded by an
asterisk (*).

Example: int *p1, *p2, i;


p1 and p2 are int pointers. i is an int.
• Pointers can be declared to point to objects of any data type.
Pointer initialization
• A pointer can be initialized by assigning it a valid address. This is
normally done via the address operator (&).
• The address operator (&) operates on a variable, and returns the
address of the variable. For example, if number is an int variable,
&number returns the address of the variable number.
• You can use the address operator to get the address of a variable,
and assign the address to a pointer variable.
Note: The address operator (&) can only be used on the RHS.

Example: Graphical pNumber number


int number = 88; representation: 88
int * pNumber;
pNumber = &number; Memory:
pNumber number
int * pAnother = &number; location location
5000 6000 6000 88
Null pointer
• You can initialize a pointer to 0 or NULL, i.e., it points to nothing. It is
called a null pointer.
• NULL is defined in several standard library headers to represent the
value 0.
• Pointers are often set to 0 to signal that they are not currently valid.
• A pointer needs to be initialized a pointer by assigning it a valid
address. Initialize a pointer to null during declaration is a good
software engineering practice.
Indirection operator (*)
• The unary * operator – commonly referred to as the indirection
operator or dereferencing operator – returns the value stored in the
address kept in the pointer variable.
• For example, if pNumber is an int pointer, *pNumber returns the
int value "pointed to" by pNumber
• The indirection operator (*) can be used in both the RHS (temp =
*pNumber) and the LHS (*pNumber = 99) of an assignment
statement.
• Take note that the symbol * has different meaning in a declaration
statement and in an expression.
• When it is used in a declaration (e.g., int * pNumber), it
denotes that the name followed is a pointer variable.
• Whereas when it is used in a expression (e.g., *pNumber =
99;), it refers to the value pointed to by the pointer variable.
& and * operators
• The usage of the * and & operators with pointers/references can be
confusing. Generally,
• &x evaluates to the address of x in memory.
• *(&x) takes the address of x and dereferences it – it retrieves
the value at that location in memory. *(&x) thus evaluates to the
same thing as x.
• * and & are inverses of each other – will “cancel one another out”
when applied consecutively in either order

Example:
int *ptr = &x;
int *ptr declares the pointer variable ptr to an integer value,
which we are initializing to the address of x (&x).
& and * operators (Example)
#include <iostream>
using namespace std;

int main() {
int a = 7; // initialize a with 7
int* aPtr = &a; // initialize aPtr with the address of int variable a

cout << "The address of a is " << &a


<< "\nThe value of aPtr is " << aPtr;
cout << "\n\nThe value of a is " << a
<< "\nThe value of *aPtr is " << *aPtr << endl;
cout << "\n\nShowing that * and & are inverses of "
<< "each other.\n&*aPtr = " << &*aPtr Output:
<< "\n*&aPtr = " << *&aPtr << endl; The address of a is 0012F580
} The value of aPtr is 0012F580

The value of a is 7
The value of *aPtr is 7

Showing that * and & are inverses of each other.


&*aPtr = 0012F580
*&aPtr = 0012F580
Pass-by-reference with pointers
• Three ways to pass arguments to a function
• Pass-by-value
• Pass-by-reference with reference arguments
• Pass-by-reference with pointer arguments
• Pointers, like references, can be used to modify one or more
variables in the caller or to pass pointers to large data objects to
avoid the overhead of passing the objects by value.
• You can use pointers and the indirection operator (*) to accomplish
pass-by-reference.
• When calling a function with an argument that should be modified,
the address of the argument is passed.
Pass-by-reference with pointers
(Example – 1/2)
#include <iostream>
using namespace std;

int cubeByValue(int); // function prototype (value pass)


void cubeByReference(int*); // function prototype (pointer pass)
Prototype indicates parameter
int main() { is a pointer to an int
int number = 5;

cout << "Pass-by-value: "<<endl;


cout << "The original value of number is " << number << endl;
cout << "Value returned by cubeByValue: "<< cubeByValue(number);
cout << "\nThe new value of number is " << number << endl;

cout << "\nPass-by-reference with pointer arguments: " <<endl;


cout << "The original value of number is " << number;
cubeByReference(&number); // pass number address to cubeByReference
cout << "\nThe new value of number is " << number << endl;
} Apply address operator & to pass address of
number to cubeByReference
Pass-by-reference with pointers
(Example – 2/2)
// calculate and return cube of integer argument
int cubeByValue(int n) {
return n * n * n; // cube local variable n and return result
}

// calculate cube of *nPtr; modifies variable number in main


void cubeByReference(int* nPtr) { cubeByReference receives
*nPtr = *nPtr * *nPtr * *nPtr; // cube *nPtr address of an int variable, i.e.,
} a pointer to an int

Output:
Pass-by-value:
The original value of number is 5
Value returned by cubeByValue: 125
The new value of number is 5

Pass-by-reference with pointer arguments:


The original value of number is 5
The new value of number is 125
const pointers
• There are two places the const keyword can be placed within a
pointer variable declaration.
1. the pointer itself
const int *ptr;
• declares a changeable pointer to a constant integer. The integer
value cannot be changed through this pointer, but the pointer
may be changed to point to a different constant integer.

2. the value it points to


int * const ptr;
• declares a constant pointer to changeable integer data. The
integer value can be changed through this pointer, but the
pointer may not be changed to point to a different constant
integer.
const pointers (Example)
int x, y;

const int *xPtr = &x;


*xPtr = 100; // error: cannot modify a const object
xPtr = &y; // allowed: xPtr is not const

int * const ptr = &x;


*ptr = 7; // allowed: *ptr is not const
ptr = &y; // error: ptr is const; cannot assign to it a new address

x = 5;
const int *const ptr = &x;
*ptr = 7; // error: *ptr is const; cannot assign new value
ptr = &y; // error: ptr is const; cannot assign new address
sizeof operators
• The unary operator sizeof determines the size of an array (or of
any other data type, variable or constant) in bytes during program
compilation.
• Size of fundamental data types:
Type Byte Type Byte Type Byte
char 1 long 4 double 8
int 4 long long 8 long double 12
short 2 float 4 bool 1

• Size of array:
• sizeof(arrayName) returns the total bytes of the array
• sizeof(arrayName[0]) returns the bytes of first element

Note: To determine the number of elements in an array numbers, use


sizeof(numbers) / sizeof(numbers[0])
sizeof operators (Example)
#include <iostream>
using namespace std; type returned by the sizeof operator

size_t getSize(double*); // function prototype


returns total number of
int main() { bytes in the array
double numbers[20]; // 20 doubles; occupies 160 bytes on our system

cout << "The number of bytes in the array is " << sizeof(numbers);

cout << "\nThe number of bytes returned by getSize is "


<< getSize(numbers) << endl;
} returns the number of bytes used
to store array address
// return size of ptr
size_t getSize(double* ptr) { Output:
The number of bytes in the array is 160
return sizeof(ptr);
The number of bytes returned by getSize is
} 4
Pointer-based strings
• A pointer-based string is an array of characters ending with a null
character ('\0').
• A string is accessed via a pointer to its first character.
• The sizeof a string literal is the length of the string including the
terminating null character.
• A string literal may be used as an initializer in the declaration of
either
• character array
char color[] = "blue";
- creates a five-element array color containing the characters 'b', 'l', 'u', 'e'
and '\0'.
• variable of type char *
const char *colorPtr = "blue";
- creates pointer variable colorPtr that points to the letter b in the string
"blue" (which ends in '\0')
Reading string into char arrays
Example 1:
cin >> word;
Reads characters until whitespace or EOF

Example 2:
cin >> setw(20) >> word;
Reads only up to 19 characters (space reserved for '\0')

Example 3:
cin.getline(array, size, delimiter);
The function stops reading characters when
1. the delimiter character is encountered (by default '\n' ),
2. when the end-of-file indicator is entered or
3. when the number of characters read so far is one less than the
length specified in the second argument.
Functions in <cstring> header
Function Explanations
size_t strlen (const char * cstr) Return the length of cstr, excluding
terminating null character '\0'.
// Copying
char * strcpy (char * dest, const Copy src into dest, return dest
char * src)

char * strncpy (char * dest, Copy at most n characters from src into
const char * src, size_t n) dest, return dest

// Comparison
int strcmp (const char * cstr1, Compare cstr1 and cstr2. Return 0 if
const char * cstr2)
cstr1 is equal to cstr2, less than zero
(usually -1) if cstr1 is less than cstr2,
more than zero (usually 1) if cstr1 is more
than cstr2.
int strncmp (const char * cstr1, Compare up to n characters.
const char * cstr2, size_t n)
// Concatenation Append src to dest, return src.
char * strcat (char * dest, const
char * src)
Functions in <cstring> header (Example –
1/2)
#include <iostream>
#include <cstring>
using namespace std;

int main() {
char s1[20] = "Happy ";
char *s2 = "New Year ";
char s3[40] = "";

// Return the length of s1, s2 and s3


cout << "The length of " << s1 << " is " << strlen(s1) << endl;
cout << "The length of " << s2 << " is " << strlen(s2) << endl;
cout << "The length of " << s3 << " is " << strlen(s3) << endl;

// Concatenating strings
strcat(s1, s2); // Append s2 to s1
cout << "\nAfter strcat(s1, s2): \ns1 = " << s1 << "\ns2 = " << s2;
strncat(s3, s1, 8); // Append first 8 characters of s1 to s3
cout << "\n\nAfter strncat(s3, s1, 8): \ns1 = " << s1 << "\ns3 = " <<
s3;
Functions in <cstring> header (Example –
2/2)
// Comparing strings
cout << "\n\nstrcmp(s1, s3) = " << strcmp(s1, s3);
cout << "\nstrncmp(s1, s3, 6) = " << strncmp(s1, s3, 6);

// Copying strings
Compare up to 6 characters of s1 and s3
cout << "\n\nBefore copying:\ns1 = " << s1 << "\ns3 = " << s3;
strcpy(s1, s3); // copy contents of s3 into s1
cout << "\nAfter copying: \ns1 = " << s1 << "\ns3 = " << s3;

cout << endl; Output: Output (cont’d):


The length of Happy is 6 strcmp(s1, s3) = 1
} The length of New Year is 9 strncmp(s1, s3, 6) = 0
The length of is 0
Before copying:
After strcat(s1, s2): s1 = Happy New Year
s1 = Happy New Year s3 = Happy Ne
s2 = New Year After copying:
s1 = Happy Ne
After strcat(s3, s1, 8): s3 = Happy Ne
s1 = Happy New Year
s3 = Happy Ne

You might also like