How to implement multiple pointers in C++ to a pointer array - c++

I've been working on a class project program using pointers and arrays with pointer offset notation (I think).
Below is the diagram used for the project
Prompt for project
*The shaded boxes represent pointers. The unshaded boxes represent a dynamically allocated two dimensional int array. Your program cannot create named identifiers for any of the unnamed items. The number of rows and the number of columns will be user input. The ellipses in the diagram represent that the sizes of the rows and columns are variable. The vertical array is an array of pointers. Each of the vertical array elements points to a one dimensional array of integers.
In your program only refer to the integer array through the pointers represented by s, t, u, and v. When passing to functions you must always pass these pointers. You cannot dereference actual parameters in a function call. Nor can you dereference pointers and assign them to variables just in order to work with them.*
#include <iostream>
using namespace std;
void fillArray(int **pArray, int rows, int columns)
{
for(int row = 0; row < rows; row++)
{
*(pArray + row) = new int;
cout << "Enter " << " row " << row + 1<< endl;
for(int col = 0; col < columns; col++)
{
cin >> *(*(pArray + row) + col);
}
}
}
void printArray(int **pArray, int rows, int columns)
{
for(int row = 0; row < rows; row++)
{
cout << "Row " << row + 1 << endl;
for(int col = 0; col < columns; col++)
{
int num = *(*(pArray + row) + col);
cout << num << " ";
}
cout << endl;
}
}
void reverseArray(int **pArray, int rows, int columns)
{
for(int row = 0; row < rows; row++)
{
cout << "Reversed Row " << row + 1 << endl;
for(int col = columns - 1; col >= 0; col--)
{
int num = *(*(pArray + row) + col);
cout << num << " ";
}
cout << endl;
}
}
int main()
{
int rows;
int columns;
cout << ("Input number of rows: ");
cin >> rows;
cout << ("Input number of columns: ");
cin >> columns;
int **pArray; //Initialize array
int ****s; //Initialize pointers s, t, u, v
**s = pArray;
int ****t;
*t = *s;
int ****u;
**u = pArray;
int ****v;
*v = *u;
pArray = new int*[rows]; //create pointer to rows. 1st level of indirection
*pArray = new int[columns]; //create pointer to columns. 2nd level of indirection
fillArray(pArray, rows, columns);
printArray(pArray, rows, columns);
reverseArray(pArray, rows, columns);
//Loop to terminate program
while (true)
{
cout << "\nEnter letter \'q\' to terminate program\n";
char c;
cin >> c;
if(c == 'q')
break;
}
}
Sorry for the poor code formatting. I couldn't understand how to copy and paste in code block.
So my question is, how do I implement the diagram with my program. I started with the basics of creating the array using pointer offset and labeling it with it's own name.
I believe I have to change all of my references to work with the pointer variables 's, t, u, v.' Any help is appreciated.

In an effort to be at least somewhat helpful, note that the question is not crystal-clear on whether the arrays are fixed or variant You're given two sizes; a column count (the width) and a row count (the height). Also note that this statement:
"In your program only refer to the integer array..."
is nonsense. there are 'cols' integer arrays, not one.
int rows, cols; // acquire rows and cols from wherever.
// create the row vector that will hold the column pointers.
// this constitutes the first grey box above the main array.
int **rowsp = new int*[rows];
// for each slot we just allocated, set the value an allocation
// of 'int' values. the list will be `cols` wide
for (int i=0;i<rows;)
rowsp[i++] = new int[cols];
// thats both white boxes and the first grey box. rowsp points
// to the allocated pointer array holding 'rows' pointers, each
// pointing to an int array hold 'cols' ints.
// now we make the two pointers that point at rowsp
int ***p1 = &rowsp;
int ***p2 = p1;
// and finally, setup s,t,u,v
int ****s = &p1;
int ****t = s;
int ****u = &p2;
int ****v = u;
Terrific, but reading the context of your question, this isn't right at all. According to the question, you have only four pointers to work with: {s,t,u,v} The must be declared of a type appropriate to allow us to build all the way to the end int arrays. Looking at the above (which is throw-way code at this point) we know we need four levels of indirection. So this time, we start with s,t,u, and v, working our way down.
int ****s = new int***; // p1 in the prior code
int ****t = s; // points to the same p1
int ****u = new int***; // p2 in the prior code
int ****v = u; // points to the same p2
Now we need to get our p1 and p2 pointing to a common pointer as well. This pointer will be the rowsp pointer in out code from above (which means when we're done s,t,u, and v all should have a path to it eventually)
*s = new int**; // s-->p1-->rowsp, t-->p1-->rows
*u = *s; // u-->p2-->rowsp, v-->p2-->rowsp
Now we need to allocate the actual rows vector, which will contain pointers to ints:
**s = new int*[rows]; // the integer pointer array.
And finally, populate this array with 'cols'-length int-arrays.
for (int i=0;i<cols;++i)
{
*(**s+i) = new int[ cols ]();
for (int j=0;j<cols;++j)
*(*(**s+i)+j) = i+j; // <== beautiful dereference chain =P
}
If we did this right, the following should all point to the same thing:
cout << "**s = " << **s << endl;
cout << "**t = " << **t << endl;
cout << "**u = " << **u << endl;
cout << "**v = " << **v << endl;
I leave moving this madness to functions on your own dime. The entire code base from above appears below in one contiguous listing. You can also see it live on ideone.com:
#include <iostream>
using namespace std;
int main()
{
static const int rows = 8; // yours would come from user input
static const int cols = 9;
int ****s = new int***; // s --> p1
int ****t = s; // t --> p1
int ****u = new int***; // u --> p2
int ****v = u; // v --> p2
*s = new int**; // s-->p1-->rowsp, t-->p1-->rows
*u = *s; // u-->p2-->rowsp, v-->p2-->rowsp
**s = new int*[rows]; // s --> p1 --> rowsp --> int*[rows]
for (int i=0;i<rows;++i)
{
*(**s+i) = new int[ cols ];
for (int j=0;j<cols;++j)
*(*(**s+i)+j) = (i+j) % cols; // <== beautiful dereference chain =P
}
cout << "**s = " << **s << endl;
cout << "**t = " << **t << endl;
cout << "**u = " << **u << endl;
cout << "**v = " << **v << endl << endl;;
cout << "======= S =======" << endl;
for (int i=0;i<rows;++i)
{
for (int j=0;j<cols;++j)
cout << *(*(**s+i)+j) << ' ';
cout << endl;
}
cout << endl;
cout << "======= T =======" << endl;
for (int i=0;i<rows;++i)
{
for (int j=0;j<cols;++j)
cout << *(*(**t+i)+j) << ' ';
cout << endl;
}
cout << endl;
cout << "======= U =======" << endl;
for (int i=0;i<rows;++i)
{
for (int j=0;j<cols;++j)
cout << *(*(**u+i)+j) << ' ';
cout << endl;
}
cout << endl;
cout << "======= V =======" << endl;
for (int i=0;i<rows;++i)
{
for (int j=0;j<cols;++j)
cout << *(*(**v+i)+j) << ' ';
cout << endl;
}
cout << endl;
// delete rows.
for (int i=0;i<rows;++i)
delete [] *(**s+i);
// delete row pointer array
delete [] **s;
// delete rowsp pointer
delete *s;
// and finally, delete s and u (or t and v)
delete s;
delete u;
return 0;
}
Output (pointers will vary)
**s = 0x100103b60
**t = 0x100103b60
**u = 0x100103b60
**v = 0x100103b60
======= S =======
0 1 2 3 4 5 6 7 8
1 2 3 4 5 6 7 8 0
2 3 4 5 6 7 8 0 1
3 4 5 6 7 8 0 1 2
4 5 6 7 8 0 1 2 3
5 6 7 8 0 1 2 3 4
6 7 8 0 1 2 3 4 5
7 8 0 1 2 3 4 5 6
======= T =======
0 1 2 3 4 5 6 7 8
1 2 3 4 5 6 7 8 0
2 3 4 5 6 7 8 0 1
3 4 5 6 7 8 0 1 2
4 5 6 7 8 0 1 2 3
5 6 7 8 0 1 2 3 4
6 7 8 0 1 2 3 4 5
7 8 0 1 2 3 4 5 6
======= U =======
0 1 2 3 4 5 6 7 8
1 2 3 4 5 6 7 8 0
2 3 4 5 6 7 8 0 1
3 4 5 6 7 8 0 1 2
4 5 6 7 8 0 1 2 3
5 6 7 8 0 1 2 3 4
6 7 8 0 1 2 3 4 5
7 8 0 1 2 3 4 5 6
======= V =======
0 1 2 3 4 5 6 7 8
1 2 3 4 5 6 7 8 0
2 3 4 5 6 7 8 0 1
3 4 5 6 7 8 0 1 2
4 5 6 7 8 0 1 2 3
5 6 7 8 0 1 2 3 4
6 7 8 0 1 2 3 4 5
7 8 0 1 2 3 4 5 6

Related

Write a C++ program which will print (half pyramid) pattern of natural numbers

The task:
Write a C++ program which will print (half pyramid) pattern of natural numbers.
1
2 3
4 5 6
7 8 9 10
11 12 13 14 15
I have tried using this code, but its not giving the output:
#include <iostream>
using namespace std;
int main()
{
int rows, i, j;
cout << "Enter number of rows: ";
cin >> rows;
for(i = 1; i <= rows; i++)
{
for(j = 1; j <= i; j++)
{
cout << j << " ";
}
cout << "\n";
}
return 0;
}
OUTPUT:
Enter number of rows: 5
1
1 2
1 2 3
1 2 3 4
1 2 3 4 5
j in your inner loop is the 1 based index of the element in the current row (1,2,3 etc.).
Instead of printing it, you should print a counter that is increased over all the iterations.
Something like:
#include <iostream>
int main()
{
int rows, i, j;
std::cout << "Enter number of rows: ";
std::cin >> rows;
int n = 1;
for (i = 1; i <= rows; i++)
{
for (j = 1; j <= i; j++)
{
std::cout << n << " ";
n++; // for next iteration
}
std::cout << "\n";
}
return 0;
}
Output example:
Enter number of rows: 5
1
2 3
4 5 6
7 8 9 10
11 12 13 14 15
A side note: better to avoid using namespace std - see here Why is "using namespace std;" considered bad practice?.

Align output in c++

int n, o = 2;
cout << "n="; cin >> n;
for(int i = 1; i <= n; i++) {
for(int j = n; j >= i; j--) {
cout << o << " ";
o += 2;
}
cout << endl;
}
My code outputs (when n is 4)
2 4 6 8
10 12 14
16 18
20
How would I align it to output this?
2 4 6 8
10 12 14
16 18
20
I am trying to align the output to the right in such a way that the numbers are aligned one below another (for example the 4 is aligned to the space between the 10 and 12 and I want to align it to 10). Thanks.
The header <iomanip> provides many input/output manipulators you can play with, one beeing std::setw, which sets the width parameter of the stream for the next item.
Changing the line in the posted snippet that outputs the numbers into
std::cout << std::setw(3) << o;
The output becames
2 4 6 8
10 12 14
16 18
20
Now, to produce the desired output, we can notice that the first number of each row can either be printed with an increasing "width" (3 the first row, 6 the second and so on) or after a loop that prints the right amount of spaces (0 the first row, 3 the second and so on).
just edited the inner loop of your code and this is the edited code:
#include <iostream>
using namespace std;
int main() {
int n, o = 2;
cout << "n="; cin >> n;
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= n; j++) {
if (j >= i) {
cout << o << "\t";
o += 2;
}
else
{
cout << "\t";
}
}
cout << endl;
}
}
and this is some example output:
n=4
2 4 6 8
10 12 14
16 18
20
what I did is to make the inner loop, loops from 1 till n like the outer loop and only check if the current column is greater than or equal to the current row, if so, then I print the number and increment it, if not then I just cout a space or a tab to be more specific

C++ - Building Addition Tables

I am having some troubles with this problem presented from my lab. My goal is to produce an addition table that looks something like this -
(From range(1-5)) :
+ 1 2 3 4 5
1 2 3 4 5 6
2 3 4 5 6 7
3 4 5 6 7 8
4 5 6 7 8 9
5 6 7 8 9 10
Mine is looking like this, however :
+ 1 2 3 4 5
2 3 4 5 6
3 4 5 6 7
4 5 6 7 8
5 6 7 8 9
My code looks like this :
if (choice == ADD) {
cout << "+";
for (int i = 0; i < max; i++) {
cout << "\t";
for (int j = min; j <= max; j++) {
cout << i + j << "\t";
}
}
}
(For reference, int max = maximum number in range, int min = minimum number in range, and choice is the decision for user to do either an addition or multiplication table). How can I change my code to fit the proper format? I can't seem to figure it out. Any hints/help would be greatly appreciated :)
#include <iostream>
using namespace std;
int main(){
int max = 5;
int min = 1;
if (true){
cout << "+\t";//print out the initial +
for(int i = min; i <= max; i++) cout << i << "\t";//print out the entire first row
cout << "\n"; //start the next row
//here is the main loop where you do most of the logic
for(int i = min; i <= max; i++){
cout << i << "\t"; //this prints out the first column of numbers
for(int j = min; j <=max; j++){
cout << j+i << "\t"; //this line fills in the body of your table
}
cout << "\n";//creates the space between each row
}
}
}
This code builds the table as explained:
for (int i = 0; i <= max; i++) {
if (i == 0)
cout << '+';
else
cout << i;
cout << '\t';
for (int j = min; j <= max; j++) {
cout << i + j << '\t';
}
cout << '\n';
}
Tip: when you want to print only a character, it is more efficient to use single quotes like '+' or '\t'. Double quotes are more expensive because they represent a const char*.

vectors in range based for loop

I was testing vector to vector initialization, I used range based for loop it gives different output.
with respect to Normal for loop.
vector<int> intVector;
for(int i = 0; i < 10; i++) {
intVector.push_back(i + 1);
cout << intVector[i] << endl;
}
cout << "anotherVector" << endl;
vector<int> anotherVector(intVector);
for(auto i : anotherVector)
cout << anotherVector[i] << endl;
//for(unsigned int i = 0; i < anotherVector.size(); i++) {
// cout << anotherVector[i] << endl;
//}
this range based for loop gives the output - Linux ubuntu
Output
STLTest Cunstructor Called.
1
2
3
4
5
6
7
8
9
10
anotherVector
2
3
4
5
6
7
8
9
10
81
2.
vector<int> intVector;
for(int i = 0; i < 10; i++) {
intVector.push_back(i + 1);
cout << intVector[i] << endl;
}
cout << "anotherVector" << endl;
vector<int> anotherVector(intVector);
//for(auto i : anotherVector)
// cout << anotherVector[i] << endl;
for(unsigned int i = 0; i < anotherVector.size(); i++) {
cout << anotherVector[i] << endl;
}
This gives different output.
output
STLTest Cunstructor Called.
1
2
3
4
5
6
7
8
9
10
anotherVector
1
2
3
4
5
6
7
8
9
10
why both for loop acting differently?
for(auto i : anotherVector)
cout << anotherVector[i] << endl;
This code doesn't do what you think it does. The range-based for loop iterates over values, not over indices. In other words, the loop variable (i) is assigned all ements of the vector in turn.
To replicate the functionality of your first loop, you need this:
for (auto i : anotherVector)
cout << i << endl;
What your original code was doing was take an element of the vector, and use it to index into the vector again. That's why the numbers were off by one (since the vector held number n + 1 at position n). Then, the final output (81 in your case) was effectively random and the result of Undefined Behaviour—you were reaching past the end of the vector.

Wrong output while printing a multidimensional array

i have some trouble while printing this pseudo-multidimensional array , with elements that are set already.
And the point of it is to swap the first and third row and 2nd and 4th column, but the output looks weird...
#include <iostream>
using namespace std;
int main()
{
int arr[12]= {
1,2,3,4,5,6,7,8,6,4,5,3
};
cout << "Before change: "<<endl;
for (int row=0;row<3;row++){
for (int col=0;col<4;col++){
cout << arr[row*col]<<" ";
}
cout <<endl;
}
cout << "After the row change: "<<endl;
for (int row=2;row>=0;row--){
for(int col=0;col<4;col++){
cout<<arr[row*col]<<" ";
}
cout<<endl;
}
cout << "After the column change: "<<endl;
int temp;
for(int row=0;row<3;row++){
temp=arr[row*1];
arr[row*1]=arr[row*3];
arr[row*3]=temp;
for (int col=0;col<4;col++){
cout<<arr[row*col]<<" ";
}
cout<<endl;
}
Instead of having an output like this:
1 2 3 4
5 6 7 8
6 4 5 3
6 4 5 3
5 6 7 8
1 2 3 4
6 3 5 4
5 8 7 6
1 4 3 2
i get this :
1 1 1 1
1 2 3 4
1 3 5 7
1 3 5 7
1 2 3 4
1 1 1 1
1 1 1 1
1 4 3 2
1 7 5 3
You wrong how to calculate the element inside the array arr[row*col] will be always 0 for the first row ( row = 0). So you have to do something like this:
#include <iostream>
using namespace std;
int main()
{
int arr[12] = {
1, 2, 3, 4, 5, 6, 7, 8, 6, 4, 5, 3
};
**int dimCol = 4;**
cout << "Before change: " << endl;
for (int row = 0; row < 3; row++){
for (int col = 0; col < 4; col++){
cout << arr[**(row*dimCol) + col**] << " ";
}
cout << endl;
}
cout << "After the row change: " << endl;
for (int row = 2; row >= 0; row--){
for (int col = 0; col < 4; col++){
cout << arr[**(row*dimCol) + col**] << " ";
}
cout << endl;
}
cout << "After the column change: " << endl;
int temp;
for (int row = 0; row < 3; row++){
temp = arr[row * 1];
arr[row * 1] = arr[row * 3];
arr[row * 3] = temp;
for (int col = 0; col < 4; col++){
cout << arr[**(row*dimCol) + col**] << " ";
}
cout << endl;
}
}
The formule will be: array[row*numberOfColumn + Column]
You got a wrong argument definition:
Instead of
array[row*col]
write this
array[row*4 + col]
So the formula is:
array[row*total_col + col]
The loop you are using multiplies each time your variable with Zero that's why you are getting 1 at the beginning of every line as your first element is 1, and arr[0] is 1.
*and your line 1 is
1 1 1 1*
because value of outer loop is zero and any value of variable of inner loop multiplied will result in 0.
the reason you are not getting correct output is your logic to print all element is not correct.
go for
array[row*4 + col]