Sheet1 - Solution - Pointers, Functions and Arrays
Sheet1 - Solution - Pointers, Functions and Arrays
Cairo University
Faculty of Engineering
Computer Engineering Department
Programming Techniques
Sheet #1 - Solution Commented [E1]:
[Sheet Topics]:
CMP1020/CMPN103 1/10
Programming Techniques Sheet #1 - Solution
int A[10] = {1, 10, 20, 30, 40, 50, 60, 70, 80, 90};
int *B;
int *C;
B = &A[2]; Commented [E2]: B = &A[2];
C = A+6; B becomes the name of the array portion that starts at the
A[2] to the last element, so, B[0] is the same as A[2].
Commented [E3]: C = A+6;
Assume that the array "A" is stored at address 100 and the size of the int is 4 bytes. C becomes the name of the array portion that starts at the
A[6] to the last element, so, C[0] is the same as A[0].
Complete the following table:
Commented [E4]:
Note that in general addresses are numbers.
Item Value Item Value When we wrote it in labs as 0x90 for example, that was also a
number but in Hexadecimal number system (not decimal).
A 100 B 108
&A[0] 100 C 124 Although addresses are after all numbers, the data type of
addresses must contain (*) after the data type of the
*A 1 C-B 4 variable stored in this address, like: int * or char *, …etc.
A[0] 1 B[0] 20 Commented [E5]:
*&A[0] 1 C[2] 80 B = &A[2];
So,
&*A 100 *(B+1) 30 B equals: 100 + 2 * size of elements (4 bytes here) = 108
A[0]+7 8 *B+1 21
Commented [E6]: C - B
A+2 108 *(&C[1]+1) 80 C – B = (124 - 108) / the size of the elem. (4 bytes here) = 4
which means:
*(A+7) 70 *&C[1]+1 71 Pointer1 – Pointer2 = Number of elements (not number of
&A[2] 108 *A**B**C 1200 bytes)
&A[6] 124 Commented [E7]: *&A[0]
*& Cancelled each other.
Commented [E8]: A + 2
(A + 2) is 108 Not 102.
because when you add:
Pointer + Number
in the code, the result will be:
Pointer + Number * No. Of Bytes of the Element Type (4
here)
So, the Number you add to the Pointer in the code is not the
number of bytes but number of elements.
Commented [E9]: *(&C[1]+1)
&C[1] is the address of element A[7]
(&C[1] + 1) is the address of element A[8]
*(&C[1]+1) is A[8]
Commented [E10]: *(A+7)
*(A+7) is the same as A[7]
Commented [E11]: &A[2]
&A[2] is the same as (A+2)
Commented [E12]: *A**B**C
The asterisk (*):
When it comes immediately before a pointer means
dereference operator (to reach the value that the pointer
points to) and when it comes between 2 numbers means
multiplication.
*A**B**C is the same as (*A)*(*B)*(*C)
CMP1020/CMPN103 2/10
Programming Techniques Sheet #1 - Solution
b. [Alias Variables]
Problem:
A = P; // Compilation error. yes A is a pointer to int like P
// but A is a constant pointer ➔ can’t change its value (the
address it points to).
b.
int* f)(
{
int x=90;
int *p=&x;
return p;
}
CMP1020/CMPN103 3/10
Programming Techniques Sheet #1 - Solution
Commented [E17]:
Constants can be initialized once then never modified.
Note: Initialization of const. variable must be in the same line
of declaration.
Commented [E18]: int * const p = &x;
c. [Const. Pointer and Pointer to Const.] Here, p is a const. pointer
(the const. immediately before the pointer name).
1) int x = 10, y = 20; It means the pointer itself is const. (cannot point to another
2) const int z=30; location other than the initial location it pointed to).
3) int * q;
4) int * const p = &x; Cannot say: p = something; → Error
5) const int * r;
However, the const. pointer can change the value stored in
the location it’s already pointing to.
6) p = &y; ➔ can't change a const. pointer
7) r = &y; Can say: *p = y; → Correct
8) *p = 7; Note#1: constant pointers like any normal constant
9) *r = 9; ➔ r is a pointer to const. (can't change the pointee) variable must be initialized in the same line of declaration.
10) *q = 40; ➔ error (q is not initialized, “Bad Pointer”)
int * const p; → Error
p = &x;
11) z=50; ➔ can't change a const. variable
12) q = &z; ➔ q can't point to a const. var. because it can change it Note#2: automatic array’s pointer int A[10]; is a constant
pointer that’s why we cannot make A = something;
13) r = &z;
14) p = &z; ➔ can't change a const. pointer Commented [E19]: const int * r;
Here, r is a pointer to constant
(“const” anywhere before (*) → can be after or before “int”)
15) const int * const S = &y; const int * r; OR int const * r;
16) *S = 10; ➔ can't change the pointee of a pointer to const.
It means that the value it’s pointing to cannot be changed
17) S = &z; ➔ can't change a const. pointer using this pointer (maybe changed by other pointers but not
18) cout << S << “ ” << *S; by a pointer to const).
*S = something; → Error
S = something; → Error
CMP1020/CMPN103 4/10
Programming Techniques Sheet #1 - Solution
5. Write function “Abs” that takes a float number and change it to its absolute value. If the number
is positive, it returns false indicating that it did not need to perform the absolute operation.
Otherwise, it changes the number to its absolute value and returns true.
Should we pass this number by value, reference or pointer? Why?
Write a main function that tests your function.
#include <iostream>
using namespace std;
bool Abs(float & x) // pass by ref.
{
if (x >= 0)
return false; // return will exit the func.
x = -x;
return true;
}
int main()
{
float a = 5.3;
bool b = Abs(a); // the function changes “a” itself if negative
if (!b) // (!b) means (not b)→ if b equals false, enter
cout << “Non-Negative!” << endl;
else
cout << “New Value = ”<< a << endl;
}
6. Write function “CountLessGreaterEq” that takes an array of integers and a value then outputs
3 counts: the count of elements less than the value, greater than the value and equal to the
value. Write a main function that tests your function.
Solution Notes:
The array should be allocated and filled in the “main” and be passed
to function ready to operate on it. The “main” function here will delete
this allocated array after last use of it.
CMP1020/CMPN103 5/10
Programming Techniques Sheet #1 - Solution
#include<iostream>
using namespace std;
int CountLessGreaterEq(int * A, int asize, int val, int & L, int *pG)
{
// The three output counts (we used here 3 different ways of output)
int E = 0;// E for Equal elements count-> 1- return statement
L = 0; // L for Less elements count -> 2- passed by reference (alias)
*pG = 0; // *pG for Greater elements count -> 3- passed by pointer
int main()
{
// 1- allocate and read input array
int arr[5];
cout << "Enter Array Elements: " << endl;
for (int i = 0; i < 5; i++)
cin >> arr[i];
// 2- read the input value
int val;
cout << "Enter Value: " << endl;
cin >> val;
// 3- define output variables and call the func.
int ls, gr, eq;
eq = CountLessGreaterEq(arr, 5, val, ls, &gr);
// 4- print the output variables
cout << "less=" << ls << ", greater=" << gr << ", equal=" << eq << endl;
return 0;
}
7. Write function “ReplaceAll” that takes an array and two values, “oldV” and “newV”, and
replaces each occurrence of “oldV” in the array with value “newV” and returns the count of the
replaced elements. Write a main function that tests your function.
Solution Notes:
The array elements changed inside the function will also be changed in
the original array of the main because elements are passed by pointer
(the array name) → do NOT need to pass the array pointer by ref to Commented [E25]: Note:
change the elements. In the labs if you pass variables by reference without a need,
you will be penalized.
The array pointer here does not need to be passed by ref because we
will not make it point to another location (to NULL or a newly allocated
memory) inside the function.
CMP1020/CMPN103 6/10
Programming Techniques Sheet #1 - Solution
8. Write function “IsEven” that takes an array of positive integers and outputs a boolean array of
the same size of the input array. Each element of the output array contains true if the
corresponding element of the input array is even, otherwise, false. Write a main function that
tests your function.
#include <iostream>
using namespace std;
9. Write a function “SwapArr” that swaps two dynamically allocated integer arrays but without [Note#2]:
actually copying array elements from one place to another. We allocated B dynamically (with new) inside the function
because it’s the output array of the function, so one of the
jobs of the function is to allocate the array inside it.
Solution:
[Note#3]:
void SwapArr(int* &P, int* &R) The main deallocated B after last use of it (doesn’t need it
anymore).
{ int *T = P;
P = R; // (this line is why P is sent by ref.) In labs/exams/project if you forget any needed
R = T; // (this line is why R is sent by ref.) deallocation, you will be penalized.
} Commented [E29]: Only swap the array pointers while
passing them by ref.
10. Write a function “AlternateSplit” that takes an array “A” of size n and splits it into two arrays “B”
and “C”. Your function should
a. Create two dynamic arrays “B” and “C”.
b. Copy elements from array “A” to “B” and “C” alternatively (one to “B” then one to “C”
and so on).
c. Free the array “A” and make “A” points to NULL.
Write a main function that tests the function.
Solution:
void AlterSplit(int *&A, int size, int *&B, int &n, int *&C, int &m)
{
m = size/2; // the smaller size (of array C)
Commented [E30]:
n = size - m; Better to replace these 2 lines with:
// Dynamic Allocation (that's why B and C are sent by ref.) B = (n > 0)? new int[n] : NULL;
B = new int[n]; C = (m > 0)? new int[m] : NULL;
C = new int[m]; To allocate only when the no. of elements > 0.
// Filling Arrays The question mark (?) and th Colon ( : ) are with the “ternary
operator” → Search about it (self-study).
CMP1020/CMPN103 7/10
Programming Techniques Sheet #1 - Solution
// [TODO] Print B’s Elements (if B is not NULL) and same for C
// [TODO] Deallocate B (if not NULL) and same for C Commented [E33]:
} Note that:
A is allocated in main and deallocated in func. (as required).
B and C are allocated in func. and deallocated in main.
Another Solution (More Difficult):
If it is not required in the question to deallocate A in the
function, it is more logical to deallocate it inside the main
void AlternateSplit(int* &A,int* &B,int* &C,int n) but since it’s required, make it inside.
{
int i,j;
//Dynamically allocate memory for B & C
B=new int[(n+1)/2]; // n+1 to account for odd values for n.
C=new int[n/2];
11. Write function “CountOccurrences” that takes a sorted array, “Input”, and counts the number Commented [E34]:
of occurrence of each element in the array. It outputs two arrays: Solution:
In the slides of: “Introduction to Algorithms”
a. “Unique” array that contains the unique elements of the input array, lecture.
b. “Freq” array that contains the number of occurrence of each element in the input array.
Write a main function that tests your function. (Assume that the input array is entered sorted!)
CMP1020/CMPN103 8/10
Programming Techniques Sheet #1 - Solution
12. Write the following functions to deal with character arrays: Commented [E35]:
a. Function “GetCopy” that takes a word and returns a new copy of this word. [Char Variable]: ---------
b. Function “GetFullname” that takes the first name and the second name of a person and char c = ‘s’; // single quotes with characters
returns his full name.
[Char Array]: ---------
c. Function “PrintSorted” that takes 2 words and print them sorted ascendingly
alphabetically. If the 2 words are the same, the function should print it once. char word [] = “sheet”; // double quotes with char arrays or
Assume that the function is case sensitive, so “sheet” is different from “Sheet” and in strings
this case the function should print them “Sheet” then “sheet” (the default ASCII sorting). The above statement will allocate 6 characters: 5 for the word
d. A main function that tests the above 3 functions. Do not forget any needed and 1 for null character (null terminator) ‘\0’ (not related to
deallocation. NULL pointer we studied before).
// 3- append sname to fullname Read the difference between the 2 versions here (self-study):
strcat_s(fullname, fullsize, sname); http://www.cplusplus.com/forum/beginner/118771/
return fullname; The safe version takes the 2nd argument (the max size of the
} destination array).
CMP1020/CMPN103 9/10
Programming Techniques Sheet #1 - Solution
int main()
{
// --- Function # 1 -----------------------------
// 1- allocate first automatically (max 25) and read it form the user
char first[25]; Commented [E43]: char first[25];
cout << "Enter first: "; The maximum size of the actual characters is 24 not 25 (the
last one is left for the null terminator).
cin >> first;
Commented [E44]: cin >> first;
[Note #1]:
// 2- call copy function to copy first name in fcopy Don’t need a loop to read/write each character of char array
char * fcopy; // to receive the output of the function (unlike arrays of other types).
fcopy = GetCopy(first); // is there a problem with simply making: fcopy = first; ? cin >> first; → reads chars then add null terminator auto.
cout << first; → prints characters till it finds null terminator
// 3- display the copy [Note #2]:
cout << "The copy: " << fcopy << endl; The entered name here may be less than 24 which is fine
because cin with char array adds the null terminator after
the actual chars it read from the user.
// 4- change fcopy and display first
cout << "Change the copy (choose no. chars <= no. chars of the old copy): "; [Note #3]:
cin >> first; reads the characters that the user enter before
cin>> fcopy; the white space (it takes one word).
cout << "First: " << first << endl;
If you want to read the whole line that may contain more than
one word (contain white spaces), you can use getline;
// 5- deallocate the copy
delete [] fcopy; cin.getline(first, 24);
CMP1020/CMPN103 10/10