chapter 4
TRANSCRIPT
POINTERS, STRINGS and STRUCTURES
CHAPTER 4
POINTERs A pointer variable contains an address of
another variable. Pointers can point to any variable types such
as integer, character, float etc., as long as it has same type with the variable to point.
Pointer Declaration A simple pointer declaration looks like this:
int *ptr; /*ptr is a pointer to an integer*/• Multiple pointer require using a * before each variable definition
int *myPtr1, *myPtr2; double *xPtr, *yPtr;.
•Pointers can be declared to point to objects ofany data type.
Pointer operators The unary operator & gives the “address of a
variable”
& (address operator)For example:
int y = 5;int *yPtr; yPtr = &y; /* assign the address of y to yPtr */ // yPtr “points to” y
| Graphical representation of a pointer pointing to an integer variable in memory.
Representation of y and yPtr in memory.
* (indirection/dereferencing operator)
Returns a synonym/alias of what its operand points to *yptr returns y (because yptr points to y) * can be used for assignment Returns alias to an object
*yptr = 5; /* changes y to 5 */ Dereferenced pointer (operand of *) must be an lvalue
(no constants)
Declaration of Pointers
After we declare a pointer variableint *ip;
The expressionip = &i;
sets what ip points to, while the expression*ip = 5;
sets the value of the location pointed to by ip
Cont’d…
Declaration of Pointers If we declare a pointer variable and include and
initializer: int *ip3 = &i;
we’re setting the initial value for ip3, which is where ip3 will point. The initial value is a pointer.
The * in the above declaration is not the contents-of-operator, but it is the indicator that ip3 is a pointer.
Cont’d…
Declaration of Pointers If you have a pointer declaration containing an
initialization, break it up to a simple declaration and a conventional assignment, like this:
int *aptr, a;aptr = &a;
Do not write like this:int *aptr, a;*aptr = &a; /* WRONG! */
Cont’d…
Declaration of Pointers When a pointer is declared, it does not point anywhere. You
must set it to point somewhere before you use it. So,int *ip;*ip = 100; /* WRONG! */
The correct use is:int *ip;int x;ip = &x;*ip = 100;
Cont’d…
Consider the effect of the following code:
int x = 10, y =5;int *ip;
ip = &x;y = *ip;x = ip;*ip = 3;
int x = 10, y = 5;
int *ip;ip = &x;
y = *ip;
x = ip;
*ip = 3;
x y100 200
ip10 5
x y100 200
ip1000
10 5 100
x y100 200
ip1000
10010 10
x y100 200
ip1000
100100 10
x y100 200
ip1000
100103
#include <iostream>using namespace std;
int main(){int x, *xptr;x=10; xptr=&x;cout<< "\nThe address of x is : "<<&x
<<"\nThe value of xptr is : "<<xptr;cout<<"\n\nThe value of x is : "<<x
<<"\nThe value of *xptr is : "<<*xptr;cout<<"\n\nShowing that * and & are inverses of each other :\n"
<<"&*xptr = "<<&*xptr<<"\n*&xptr = "<<*&xptr<<endl;
return 0;}
output
Calling functions by reference In this chapter, we’ll look at the call-by-
reference with pointer arguments Pointers can be used to modify one /more
variables in the caller or to pass pointer to large data.
When calling a function with arguments that should be modified, the address of the arguments are passed, by using the operator (&) to the name of the variable to pass.
#include <iostream>using namespace std;
void cubebyRef(int *);void cubebyValue(int);int main(){int num=5, num2=5;cout<<"CubebyRef: \n The original value of number : "<<num;cubebyRef(&num);cout<<"\nThe new value of number : "<<num;cout<<"\n\nCubebyValue: \n The original value of number 2 : "<<num2;cubebyValue(num2);cout<<"\n The new value of number 2: "<<num2;cout<<endl<<endl;return 0;}
void cubebyRef(int *x){ *x *= *x;}
void cubebyValue(int x){ x*=x;}
Passing pointer to a function 4 ways to do so :
i. a nonconstant pointer to nonconstant dataii. a constant pointer to non constant dataiii. a nonconstant pointer to constant dataiv. a constant pointer to constant data
• a nonconstant pointer to nonconstant data- the data can be modified through the dereferenced
pointer, and pointer can point to other data
#include <iostream>using namespace std;
void Uppercase (char *);int main(){char string [] = "thank you. your change is rm20.22";cout<<"\nThe string before conversion: "<<string;Uppercase(string);cout<<"\n\nThe string after conversion: "<<string<<endl;return 0;}
void Uppercase(char *strP){
while (*strP !='\0'){ *strP=toupper(*strP);
++strP ; //move strP to the next character}
}
• a nonconstant pointer to constant data-Pointer that can be modified to point to any data, but the data which it points cannot be modified thru that pointer. - e.g of function header definition :
void printChars(const char sPtr*) - read the declaration right to left : sptr is a pointer to a char constant
#include <iostream>using namespace std;
void print (const int * ,int);int main(){int x[3]={45,12,2};cout<<"\nThe value is: ";print(x,3);cout<<endl;return 0;}
void print (const int *xPtr ,int s){ for(s=0;s<3;s++)
{ cout<<*xPtr<<' '; ++xPtr ; //move strP to the next value
} }
Value of data point to by xPtr cannot be changed
a constant pointer to non constant data A pointer that always points to the same memory
location, and the data at that location can be modified thru the pointer. #include <iostream>using namespace std;
int main(){int x,y;
int * const ptr =&x;
*ptr=10;ptr=&y ; // ERROR!return 0;}
a constant pointer to a constant data a pointer always point to the same memory location
and the data at that memory cannot be modified using the pointer.
Pointer expression & pointer arithmetic
A limited set of arithmetic expressions may be performed o pointers Pointer maybe incremented(++) or decremented(--) Integer may be added (+=,+) to a pointer, subtract
from a pointer Any arithmetic operations for pointers are based on
the size of the data type being used by the machine – pointer arithmetic is machine dependent.
Pointers ArithmeticExample: int v[5];
int *vp;vp = v; /* array name refer to 1st
element, v[0] */
Cont’d…
v[0] v[1] v[2] v[3] v[4]
3000 3004 3008 3012 3016location
vp
This machine has 4-byte integers
Pointers ArithmeticIf an integer is stored in 4-bytes of memoryvp += 2; (3000 + 2*4) = 3008
size of memory
v[0] v[1] v[2] v[3] v[4]
3000 3004 3008 3012 3016
location
vp vp now points to v[2]
* Use sizeof() to determine the size of memory
int v[5]={10,12,4,6,8};int *vp;vp = &v[4];cout<<*vp;
vp--; cout<<"\n"<<*vp<<endl; vp -= 2; cout<<"\n"<<*vp<<endl;
Output : 8612
Relationship Between Pointers and Arrays
Arrays and pointers closely related Array name like a constant pointer Pointers can do array subscripting operations
Define an array b[ 5 ] and a pointer bPtr To set them equal to one another use:
bPtr = b; The array name (b) is actually the address of first
element of the array b[ 5 ]bPtr = &b[ 0 ]
Explicitly assigns bPtr to address of first element of b
Element b[ 3 ] Can be accessed by *( bPtr + 3 )
Where 3 is called the offset. Called pointer/offset notation
Can be accessed by bptr[ 3 ] Called pointer/subscript notation bPtr[ 3 ] same as b[ 3 ]
Can be accessed by performing pointer arithmetic on the array itself*( b + 3 )
Relationship Between Pointers and Arrays
Pointer and Arrays
e.g: int a[10];you can refer to a[0], a[1], a[2], etc..orto a[i] where i is an int.
If you declare a pointer variable ip and sets it to point to the beginning of the array:
int *ip = &a[0];
you can refer to *ip,*(ip+1),*(ip+2), etc…or to *(ip+i) where i is an int.
Cont’d…
const int size=3;int main(){ int s[size]={5,10,15}; int *sPtr,i; sPtr=s;
for(i=0;i<size;i++){
cout<<"*s["<<i<<"] = "<<*(s+i)<<"\t*sPtr["<<i<<"] = "<<*(sPtr+i)<<endl;
}cout<<endl;return 0;}
int main(){ char string[10]="good luck"; char *str;
str=string; for(;*str!='\0';str++)
{cout<<*str;
}
cout<<endl; return 0;}
Array of Pointers We can have arrays of pointers since pointers are
variables.e.g:char *text[3] = {“teh”, “susu”, gula”};
‘t’ ‘e’ ‘h’ ‘\0’
‘s’ ‘u’ ‘s’ ‘u’
‘g’ ‘u’ ‘l’ ‘a’
text[0]
text[1]
text[2]
‘\0’
‘\0’
Example :
char *s[size]={"siti", "ali", "bade"}; int i;
for(i=0;i<size;i++){
cout<<*(s+i);}
Strings A string is a series of characters treated as a single unit
(array of characters, ending with null (‘\0’)) A string may include letters, digits and symbols String literals/ string constant are written in “ “, such as
“Abdullah Azzam,”, “99 21 Jump Street”, “AG100” Example of declaration : char state[] = “kelantan”; or char *statePtr=“Johor”;
char name1[30], name2[30];cout<<“name1 : ”;cin.getline(name1,30); cout<<“name2 : ”cin>>name2;cout<<“/n”<<name1<<endl<<name2;
String manipulation: <cstring>Function Description
strcpy(string1,string2) Copies string2 to string1.
strcnpy(string1,string2,size n) Copies at most n characters of string2 to string1
strcat(string1,string2) Appends string2 to string1
strncat(string1,string2, size n) Appends at most n character of string2 to string1
strcmp(string1,string2) Compares string1 with string2. return zero if string1 equal to string2, <0 and >0
strncmp(string1,string2, size ) Compares up to n character of string1 with string2. return zero if string1 equal to string2
strtok(string1,string2) Breaks string1 into tokens- delimited by characters in string2
strlen(string1) Determine length of string1
#include <iostream>#include<cstring>using namespace std;
int main(){char s1[]={"kedah darul aman"}; char s2[17],s3[11] ,s4[20]="negeri "; cout <<"The string in s1 is : "<<s1<<endl
<<"The string in s2 is : "<<strcpy(s2,s1)<<endl <<"The string in s3 is : "; strncpy(s3,s1,11); s3[11]='\0'; cout<<s3;
cout<<endl;cout<<"strcat(s4,s3) = "<<strcat(s4,s3);return 0;}
char *s1= "Selamat Menyambut Bulan Ramadhan" ; char *s2="Selamat Menyambut Bulan Puasa";
cout<<"s1 = "<<s1<<endl <<"s2 = "<<s2<<endl; if (strcmp(s1,s2)==0)
cout<<"s1 and s2 have the same string"; else cout<<"s1 and s2 are different";
cout<<endl;
int main(){char s1[]="Ahlan ya Ramadhan" ; char *token; cout<<"The length of \""<<s1<<"\" is : "<<strlen(s1)<<endl; //cout<<"s1 = "<<s1<<endl; cout<<"Setelah di token kan: "<<endl<<endl; token=strtok(s1," "); while(token!=NULL) {
cout<<token<<endl; token=strtok(NULL," ");
}cout<<endl;return 0;}
Structures
Structures Collections of related variables (aggregates) under
one name - Can contain variables of different data types
- Commonly used to define records to be stored in files For example, we might want to group three strings (name,
address, and phone number) into one structure Sometimes we want to use the entire structure (i.e., for
moving to secondary storage) Sometimes we want to use just a single member of the
structure
Structure Definitions Structures are user defined data types
This means that we have to tell C++ the makeup of our structure
We must provide a structure definition
Structure Definition Format• The structure definition follows the format:
struct tag {member definitions};– The tag is the name of our new data type
(equivalent to int or float)– In member definitions we define each of the
individual variables that make up the structure
struct employeeRecord{ char name[30]; int empNo; float payRate;};
Structure Declarations The definition does not allocate any memory
Member definitions are not variable declarations, they just tell C what the structure contains
We must declare a variable of our structure just like we would an int or float
The keyword struct must be included whenever a structure data type is referred to
struct employeeRecord{ char name[30]; int empNo; float payRate;};
struct employeeRecord fullTime;
Definitions/Declaration We can define and declare structures in the same
statementstruct tag {member definitions} variable names; The names are the identifiers of the variables of the
data type named tag The tag is optional in this case, but if we leave it off we
can not declare more variables of this type at a later point
Definition/Declaration ExamplesWith the tag:
struct employeeRecord{ char name[30]; int empNo; float payRate;} fullTime, partTime;
Without the tag:
struct{ char name[30]; int empNo; float payRate;} fulltime, partTime;
Structure Initializations Can initialize at the declaration stage Values must be listen in the exact order of
the corresponding members
struct employeeRecord{ char name[30]; int empNo; float payRate;}struct employeeRecord fullTime={“Abdullah”, 444, 12.63};
fulltime.name =“Abadi”;Fulltime.empNo= 101;
Accessing Structures We usually want access to the individual members of the
structure We use the variable name, member name, and member
operator to access these The member name is the variable that is part of the structure The member operator is a dot operator(.) or an arrow
operator( -> )structureVariable.memberNamestructureVariable-> memberName
e.g fulltime.name
#define NAME_CHRS 30struct employeeRecord{ char name[NAME_CHRS]; int empNo; float payRate;};
int main(void){struct employeeRecord fullTime = {"Abdullah",001,150.00};
cout<<"Employee’s name: "<< fullTime.name<<endl ;cout<<"Employee number: "<<fullTime.empNo<<endl ;cout<<"Change pay rate from ";cout<<setiosflags(ios::showpoint|ios::fixed) <<setprecision(2) <<fullTime.payRate << " to " ;cin>> fullTime.payRate;cout<<"Confirm new pay rate : "<<setprecision(2)<<fullTime.payRate<<endl;
Example/* declaring and initializing a structure and a pointer to a structure */
struct date
{int day,month;
int year};
Picasso = {25, 10, 1881;},*pointer;
pointer = &Picasso;Direct Access Arrow Notation(pointer) Pointer NotationPicasso.day pointer --> day (*pointer).dayPicasso.month pointer --> month (*pointer).monthPicasso.year pointer --> year (*pointer).year
struct temp { int num; char ch; }; int main() {
struct temp var;struct temp *ptr;ptr = &var;ptr->num = 611;ptr->ch= 'S';cout<<"\n Num : "<<ptr->num;cout<<"\n Ch : "<<ptr->ch;(*ptr).ch='K';(*ptr).num=105;cout<<"\n Num : "<<(*ptr).num <<"\n Ch : "<<var.ch<<endl;
return 0;}
Passing and Returning Structures
Passing - Call by value and call by reference By value – pass the copy of structure member or
the whole structure, to defined function. This technique won’t change the original structure
By reference - pass the address of structure to defined function. This technique will change the original structure.
Passing call by value - examplestruct{ int idNum;
double payRate;double hours;
} emp;
//e.g: Passing individual member(s) of the structure – func. calldisplay(emp.idNum);calcPay(emp.payRate, emp.hours);
//e.g :Passing the complete emp structure to calcNet()calcNet(emp);
Passing call by reference - example// func prototypedouble calcNet(struct Employee *pt);
struct{ int idNum;
double payRate;double hours;
} emp;
//Passing the address of the structure- function callcalcNet(&emp);//Received as pointer – function headerdouble calcNet(struct Employee *pt){ // function body}
struct vegetable{ char name[30];float price;};
void main(){struct vegetable veg1, veg2;struct vegetable addname();void list_funct(vegetable);veg1= addname();veg2= addname();cout<<“\n Vegetable for sale\n”;list_funct(veg1);list_funct(veg2);}
continue
//this function returns a structurestruct vegetable addname( ){struct vegetable vege; cout<<“\n Vegetable name : ”;cin>>vege.name;cout<<“Price (per 100gm) : ”;cin>>vege.price; return(vege);}void list_funct (vegetable list){ cout<<“\n Vegetable name : ”<< list.name;cout<<“\n Vegetable price : RM ”<< list.price;}
Arrays of Structures You can have arrays of structures, just like any other data type
struct tag variableName [numberOfElements] ;• You can also initialize an array of structures
struct studentRecord { char name[25]; int m1; float x;};struct studentRecord students[4] = { {“Zaid Akhtar”, 5, 12.63}, {“C.K Tan”, 0, 9.50}, {“ G.Gobala”, 3, 10.83}, {“Cik Lela Manja”, 5, 15.25}};
Array of Structures Example#define NUM_OF_EMPLOYEES 2#define NAME_CHRS 30
void main(void){ struct employeeRecord { char name[NAME_CHRS]; int dependents; float payRate;}; struct employeeRecord employees [NUM_OF_EMPLOYEES]; for (int i = 0; i < NUM_OF_EMPLOYEES; i++) { cout<<"Enter the employee name: "; cin.getline(employees[i].name,NAME_CHRS);
cout<<"Enter the number of dependents ";cin>>employees[i].dependents ;cout<<"Enter pay rate: ";
cin>>employees[i].payRate; }
for (i = 0; i < NUM_OF_EMPLOYEES; i++) {cout<<"Employee # "<<i<<"\n\tName: "<<employees[i].name <<"\n\tNumber of dependents : "<<employees[i].dependents <<"\n\tPay Rate: $ "
<<setiosflags(ios::showpoint|ios::fixed) <<setprecision(2)
<<employees[i].payRate; }}
Structures within structures
Structures can be declared within another structures, or nested.
Save times for program requires similar structure or overlapping information.
First, you need to declare the struct that you to pu/ nested to another struct. Then, during the declaration of another struct, call the first struct that you have declared.
Declaration examplestruct date{ int day; int month, year;};struct record{ char title[30]; char writer[30]; struct date date1;} book;
book
date1
day
month
year
to acces values in date1 structure, 2 dot(.) symbol is needed
Refer to the previous slide:
cout<<"Book Title : ";cin.getline(book.title,30);cout<<"Date (ddmmyy) : ";cin>>book.date1.day ;cin>>book.date1.month;cin>>book.date1.year);cout<<"Book List : \n\n";cout<<"Title : “<< book.title<<endl;cout<<"Date purchased : “<< book.date1.day
<<“ “<< book.date1.month<<“ “<< book.date1.year;
struct country{ char name[30] ;int areacode;};struct position{ struct country north;struct country south;};
struct position t = {{"USA", 102}, {"Australia", 227}};void main(){cout<<"\n COUNTRY UP NORTH\n";cout<<"Name : "<< t.north.name;cout<<"\nArea code : "<< t.north.areacode;cout<<"\n\n COUNTRY DOWN SOUTH\n";cout<<"Name : "<< t.south.name;cout<<"\nArea code : "<< t.south.areacode<<endl;}
Another example