How to print out 2d arrays with function in C++? - c++

I am trying to make a function that prints out two dimensional arrays.
I did one that prints out 1d arrays.
#include <iostream>
using namespace std;
void printArray (int theArray[],int sizeOfArray);
int main ()
{
int array1[3] = {1,3,7};
int array2[5] = {123,5,23,2,324};
printArray(array1, 3);
printArray(array2, 5);
}
void printArray (int theArray[],int sizeOfArray){
for (int x=0; x<sizeOfArray; x++) {
cout<<theArray[x] <<" ";
}
cout<<endl;
}
I wrote these codes for printing out 2d arrays but I failed.
#include <iostream>
using namespace std;
void printArray (int theArray[][],int sizeOfRow, int sizeOfCol);
int main ()
{
int array[2][3] = {{1,3,7},{5,3,2}};
printArray(array, 2,3);
}
void printArray (int theArray[][],int sizeOfRow, int sizeOfCol){
for (int x=0; x<sizeOfRow; x++)
for (int y=0; y<sizeOfCol; y++) {
cout<<theArray[x][y] <<" ";
}
cout<<endl;
}
My compiler says array has incomplete element type 'int[]'.
What are the right codes for printing out 2d arrays?

Since array size has to be known during compile time, you can use templates to provide flexibility to the function.
template< typename T, size_t N, size_t M >
void printArray( T(&theArray)[N][M] ) {
for ( int x = 0; x < N; x ++ ) {
for ( int y = 0; y < M; y++ ) {
cout << theArray[x][y] << " ";
}
}
}
printArray( array );
this is much nicer since there is no need to pass the dimension of array anywhere, also work for 3D, 4D array by adding extra parameter to the template.

For a multi-dimensional array you need to declare the size of the array in your function declaration.
So your method needs to look like:
void printArray (int theArray[][3],int sizeOfRow, int sizeOfCol)
Then it should compile and work.

A tip for printing out two dimensional arrays -- it is easier to use the variables r and c (i.e. for row and columns) to visualize how the array is being printed out.
As noted above, the column size is REQUIRED by the language when passing 2d arrays.
The function header should look as follows:
void printArray (int theArray[][3],int sizeOfRow, int sizeOfCol)

Related

Can we pass an array to any function in C++?

I have passed an array of size 10 to a funtion to sort the array reversely, but it's going wrong after rightly sorting first five elements of the array.
I want to sort the array 'std' reversely here,
# include <iostream>
using namespace std;
int reverse(int a[]); //funtion prototype
int main()
{
int std[10] = {0,1,2,3,4,5,6,7,8,9};
reverse(std);
}
int reverse(int a[]) //funtion defination
{
int index = 0;
for (int i = 9; i >= 0; i--)
{
a[index] = a[i]; //swaping values of the array
cout << a[index] << " ";
index++;
}
}
There's basically three things wrong with your code.
You aren't swapping anything
You have to swap the first half of the array with the second half, not swap the whole array. If you do that then everything gets swapped twice, so that nothing changes
You should print the reversed array after you have finished the reverse, not while you are doing the reverse.
Here's some code that fixes all these problems
# include <iostream>
# include <utility>
void reverse(int a[]);
int main()
{
int std[10] = {0,1,2,3,4,5,6,7,8,9};
reverse(std);
// print the array after reversing it
for (int i = 0; i < 10; ++i)
std::cout << std[i] << ' ';
std::cout << '\n';
}
void reverse(int a[])
{
for (int i = 0; i < 5; ++i) // swap the first half of the array with the second half
{
std::swap(a[i], a[9 - i]); // real swap
}
}
Yes you can.
I usually don't use "C" style arrays anymore (they can still be useful, but the don't behave like objects). When passing "C" style arrays to functions you kind of always have to manuall pass the size of the array as well (or make assumptions). Those can lead to bugs. (not to mention pointer decay)
Here is an example :
#include <array>
#include <iostream>
// using namespace std; NO unlearn trhis
template<std::size_t N>
void reverse(std::array<int, N>& values)
{
int index = 0;
// you only should run until the middle of the array (size/2)
// or you start swapping back values.
for (int i = values.size() / 2; i >= 0; i--, index++)
{
// for swapping objects/values C++ has std::swap
// using functions like this shows WHAT you are doing by giving it a name
std::swap(values[index], values[i]);
}
}
int main()
{
std::array<int,10> values{ 0,1,2,3,4,5,6,7,8,9 };
reverse(values);
for (const int value : values)
{
std::cout << value << " ";
}
return 0;
}

How to use the same multidimensional array in many functions?

I'm a beginner at C++ and to be honest, I've got no idea how to solve one task.
I have to create a matrix using a two dimensional array. It's size should be dependent on user's input (it should be like...int matrix[m][n], where m and n are the numbers entered by user). Then I'm supposed to fill it with random numbers from 0 to 100 and print it. Well, I can manage it.
The problem starts when I have to create a function finding the highest number from this array's row. The only parameter of this function can be the number of row entered by user (eg. int function(int i)).
The question is-how can I use the same array in multiple functions? Is there any way to do this, considering the fact that I'm a newbie?
Or maybe the task is formed incorrectly?
Sorry for the long post and thanks in advance
PS Someone asked for code, so here it is:
#include <iostream>
#include <cstdlib>
using namespace std;
int function1(int i)
{
//this is one of the functions I'm supposed to create-I described it earlier
}
int main()
{
int m,n;
cout<<"Matrix's size will be m rows and n columns. Please write m and n"<<endl;
cin>>m>>n;
int A[m][n];
int a,b;
for (a=0;a<m;a++)
{
for (b=0;b<n;b++)
{
A[a][b]=rand()%(100+1);
cout<<A[a][b]<<" ";
}
cout<<"\n";
}
}
EDIT: I'd like to thank you all for help guys. I asked my teacher about that and he finally responded. If you're curious, he told us (I hadn't heard it) to define an array like int[100][100] or higher and not allow user to input any higher numbers ;) That's not an optimal solution but surely a practical one. Thank you again!
The correct way to do this in C++ is to use a std::vector or std::array.
If you cannot do this because of artificial requirements, then there is simply no way you can declare a 2D array in C++ based on user input.
cin >> m >> n;
...
int array [m][n]; // not possible
int** wannabe; // not an array
int array [m * n]; // not possible
What you can do is a "mangled" 2D array:
int* mangled = new int[m * n];
Example of use:
class int_matrix
{
private:
int* mangled;
size_t rows;
size_t cols;
public:
int_matrix(size_t row, size_t col)
:rows(row),
cols(col)
{
mangled = new int[row * col];
}
int highest_in_row (size_t row)
{
...
}
};
Please note that this code requires that you follow the rule of three.
In C you would just have elegantly solved this by writing int array[m][n], but you are using C++ so you can't do that.
You can wrap your function into a class. In that class, you can have your array as member variable.
class A {
int **matrix;
public:
A(int rows, int columns) {
matrix = new int*[rows];
for(int i = 0; i < rows; ++i)
matrix[i] = new int[columns];
}
int function(int i); //you can use your matrix in this function
}
If you can't use classes, you can use global variables.
In a file.cpp
int **matrix;
int function(int i) {
//Do Something
}
//With rows the number of rows and columns the number of columns
//You can take these as parameters
int main() {
matrix = new int*[rows];
for(int i = 0; i < rows; ++i)
matrix[i] = new int[columns];
function(42);
}
If you declare a matrix like int int A[m][n]; where m and n aren't const, you can't pass it to a function. There are two ways to fix it:
1) Declare matrix with const size like int A[10][10];. In this case function which finds max will look like this:
int max_in_row(int matr[10][10], int row) {
int max = 0;
for (int col = 0; col < 10; ++col)
if (matr[row][col] > max)
max = matr[row][col];
return max;
}
and you can find max simple as int max = max_in_row(A, <row you want>);
2) (If you don't know size) Declare matrix as array of arrays:
int **A = new int*[n];
for (int i = 0; i < n; ++i)
A[i] = new int[m];
// fill A like you did
Then the function will look like
int max_in_row(int **matr, int row, int m) {
int max = 0;
for (int col = 0; col < m; ++col)
if (matr[row][col] > max)
max = matr[row][col];
return max;
}
and you can find max by int max = max_in_row(A, <row you want>, m);
The following is not standard C++ because it will only work if the compiler supports Variable Length Arrays. VLA were introduced in C99 and made optional in C11 but were never introduced in C++ standard - but some compilers support it even in C++ mode.
The hack will be to store the matrix address as a global void * and cast it to the proper pointer to VLA inside the function. This hack is required because at the moment of the global declaration you cannot know the number of columns of the matrix.
#include <iostream>
#include <cstdlib>
void *Matrix;
int Columns;
using namespace std;
int function1(int i)
{
typedef int MAT[Columns]; // BEWARE!!! VLA is not standard C++
MAT *mat = static_cast<MAT *>(Matrix);
int mx = mat[i][0];
for(int j=0; j<Columns; j++) {
cout << " " << mat[i][j];
if (mat[i][j] > mx) mx = mat[i][j];
}
std::cout << endl;
return mx;
}
int main()
{
int m,n;
cout<<"Matrix's size will be m rows and n columns. Please write m and n"<<endl;
cin>>m>>n;
int A[m][n]; // BEWARE!!! VLA is not standard C++
int a,b;
for (a=0;a<m;a++)
{
for (b=0;b<n;b++)
{
A[a][b]=rand()%(100+1); // Note that I now use a and b here !
cout<<A[a][b]<<" ";
}
cout<<"\n";
}
Matrix = static_cast<void *>(A);
Columns = n;
cout << "Enter row number to process: ";
cin >> a;
b = function1(a);
cout << "Max of row " << a << " is " << b << endl;
return 0;
}
Not really C++-ish, but at least it compiles and give expected results with clang version 3.4.1

Inputing the Size of a 2-dimentional Array

In my code I input the sizes of both dimensions and then declare a two-dimensional array. My question is, how do I use that array as a function parameter? I know that I need to write the number of columns in the function specification but how do I pass the number of columns?
void gameDisplay(gameCell p[][int &col],int a,int b) {
for(int i=0;i<a;i++) {
for(int j=0;j<b;j++) {
if(p[i][j].getStat()==closed)cout<<"C ";
if(p[i][j].getStat()==secure)cout<<"S ";
if(p[i][j].getBomb()==true&&p[i][j].getStat()==open)cout<<"% ";
if(p[i][j].getBomb()==false&&p[i][j].getStat()==open) {
if(p[i][j].getNum()==0)cout<<"0 ";
else cout<<p[i][j].getNum()<<" ";
}
cout<<endl;
}
}
}
int main() {
int row,col,m;
cout<<"Rows: ";cin>>row;cout<<"Columns: ";cin>>col;
m=row*col;
gameCell p[row][col];
gameConstruct(p[][col],m);
gameDisplay(p[][col],row,col);
}
I tried this way but it doesn't work.
Thank you.
In C++, you cannot have variable length arrays. That is, you can't take an input integer and use it as the size of an array, like so:
std::cin >> x;
int array[x];
(This will work in gcc but it is a non-portable extension)
But of course, it is possible to do something similar. The language feature that allows you to have dynamically sized arrays is dynamic allocation with new[]. You can do this:
std::cin >> x;
int* array = new int[x];
But note, array here is not an array type. It is a pointer type. If you want to dynamically allocate a two dimensional array, you have to do something like so:
std::cin >> x >> y;
int** array = new int*[x]; // First allocate an array of pointers
for (int i = 0; i < x; i++) {
array[i] = new int[y]; // Allocate each row of the 2D array
}
But again, this is still not an array type. It is now an int**, or a "pointer to pointer to int". If you want to pass this to a function, you will need the argument of the function to be int**. For example:
void func(int**);
func(array);
That will be fine. However, you almost always need to know the dimensions of the array inside the function. How can you do that? Just pass them as extra arguments!
void func(int**, int, int);
func(array, x, y);
This is of course one way to do it, but it's certainly not the idiomatic C++ way to do it. It has problems with safety, because its very easy to forget to delete everything. You have to manually manage the memory allocation. You will have to do this to avoid a memory leak:
for (int i = 0; i < x; i++) {
delete[] array[i];
}
delete[] array;
So forget everything I just told you. Make use of the standard library containers. You can easily use std::vector and have no concern for passing the dimensions:
void func(std::vector<std::vector<int>>);
std::cin >> x >> y;
std::vector<std::vector<int>> vec(x, std::vector<int>(y));
func(vec);
If you do end up dealing with array types instead of dynamically allocating your arrays, then you can get the dimensions of your array by defining a template function that takes a reference to an array:
template <int N, int M>
void func(int (&array)[N][M]);
The function will be instantiated for all different sizes of array that are passed to it. The template parameters (dimensions of the array) must be known at compile time.
I made a little program:
#include <iostream>
using namespace std;
void fun(int tab[][6], int first)
{}
int main(int argc, char *argv[])
{
int tab[5][6];
fun(tab, 5);
return 0;
}
In function definition you must put size of second index. Number of column is passed as argument.
I'm guessing from Problems with 'int' that you have followed the advices of the validated question and that you are using std::vector
Here is a function that returns the number of columns of an "array" (and 0 if there is a problem).
int num_column(const std::vector<std::vector<int> > & data){
if(data.size() == 0){
std::cout << "There is no row" << std::endl;
return 0;
}
int first_col_size = data[0].size();
for(auto row : data) {
if(row.size() != first_col_size){
std::cout << "All the columns don't have the same size" << std::endl;
return 0;
}
}
return first_col_size;
}
If you're using C-style arrays, you might want to make a reference in the parameter:
int (&array)[2][2]; // reference to 2-dimensional array
is this what you're looking for?
int* generate2DArray(int rowSize, int colSize)
{
int* array2D = new int[rowSize, colSize];
return array2D;
}
example . . .
#include <iostream>
#include <stdio.h>
int* generate2DArray(int rowSize, int colSize);
int random(int min, int max);
int main()
{
using namespace std;
int row, col;
cout << "Enter row, then colums:";
cin >> row >> col;
//fill array and display
int *ptr = generate2DArray(row, col);
for(int i=0; i<row; ++i)
for(int j=0; j<col; ++j)
{
ptr[i,j] = random(-50,50);
printf("[%i][%i]: %i\n", i, j, ptr[i,j]);
}
return 0;
}
int* generate2DArray(int rowSize, int colSize)
{
int* array2D = new int[rowSize, colSize];
return array2D;
}
int random(int min, int max)
{
return (rand() % (max+1)) + min;
}
instead of accessing p[i][j] you should access p[i*b + j] - this is actually what the compiler do for you since int[a][b] is flattened in the memory to an array in size of a*b
Also, you can change the prototype of the function to "void gameDisplay(gameCell p[],int a,int b)"
The fixed code:
void gameDisplay(gameCell p[],int a, int b) {
for(int i=0;i<a;i++) {
for(int j=0;j<b;j++) {
if(p[i*a +j].getStat()==closed)cout<<"C ";
if(p[i*a +j].getStat()==secure)cout<<"S ";
if(p[i*a +j].getBomb()==true&&p[i][j].getStat()==open)cout<<"% ";
if(p[i*a +j].getBomb()==false&&p[i][j].getStat()==open) {
if(p[i*a +j].getNum()==0)cout<<"0 ";
else cout<<p[i*a +j].getNum()<<" ";
}
cout<<endl;
}
}
}
int main() {
int row,col,m;
cout<<"Rows: ";cin>>row;cout<<"Columns: ";cin>>col;
m=row*col;
gameCell p[row][col];
gameConstruct(p[][col],m);
gameDisplay(p[],row,col);
}

How to pass two dimensions array to a function and how to call it

I've tried many time to pass the array to a function then do some calculation such as getting the total of the columns, the problem is I don't know how to call the result form the function, usually I get errors.
this is just one code I'm trying to solve it from yesterday :
#include <iostream>
using namespace std;
//prototype
int get_total(int whatever[][2], int row);
int main ()
{
const int row=2;
const int col=3;
int marks[row][col];
// this is prompt the user to input the values
for (int i=0; i<row;i++)
{
for (int p=0; p<col; p++)
{
cin >> marks[i][p];
}
cout << endl;
}
// this is just display what the user input as a table
for (int x=0; x< row ; x++)
{
for (int y=0; y<col ; y++)
{
cout << marks[x][y] << " ";
}
cout << endl;
}
int sum;
// this is the most important thing I want to know,
// how to call the function :(
sum=get_total(marks,row);
return 0;
}
// to get the total of each columns
const int row=3;
// not sure if the declaration is correct or not :(
int get_total(int whatever[][2], int row)
{
for (int i=0; i < 2; i++)
{
for (int p=0; p < 3; p++)
int total=0;
//this line is completly wrong, How can I calculate the total of columns?
total+=get_total[2][p];
}
// do we write return total ?
// I'm not sure because we need the total for each column
return total;
}
sorry for the mess, and I appreciate any help to explain passing the multidimensions arry to a function as parameter and how to call the function>
Arrays decay to pointers when calling functions.
You can do 2 things:
Pass the number of lines and columns as arguments to the function.
Use std::vector instead. I suggest you take a look at it, it'll do the trick and you'll learn something new and very useful.
Also, your function should do this:
int get_total(int** whatever)
{
//total is 0 at the beginning
int total=0;
for (int i=0; i < 2; i++)
{
for (int p=0; p < 3; p++)
//go through each element and add it to the total
total+=whatever[i][p];
}
return total;
}
This will return the total for the whole matrix, I'm assuming that's what you mean by getting the total of the columns
int marks[row][col]
This means that marks has type int[2][3].
int get_total(int whatever[][2], int row);
You've however declared get_total to accept an int(*)[2]. int[2][3] can decay to int(*)[3] but that is not compatible with int(*)[2], hence why you can't pass marks to get_total. You can instead declare get_total to accept an int(*)[3]:
int get_total(int whatever[][3], int row);
// equivalent to:
int get_total(int (*whatever)[3], int row);
If you instead decide to declare get_total to accept an int** or an int*, then you can't legally pass marks to it in the former case, and you can't legally iterate over the whole multidimensional array in the latter. Consider not using arrays, it's simpler this way.

How do I pass multi-dimensional arrays of unknown size into a function using pointers in c++?

Like the question says, I am trying to pass multi-dimensional arrays into a function to print it to a file for an engineering project. The format for which the data is inputted CANNOT be changed, so please don't suggest I just input it as a different datatype.
This particular function anticipates a two-dimensional array (although I have others with three dimensions after this one), where nothing is known about the size of the array until run-time. I know I must use pointers to point to each row of the array separately, but I have NO idea what the syntax is for passing it to the function. In the following code, the array in question is 'block'. The main function is just a little testing example I made to try to make it work:
#include<fstream>
using namespace std;
void of_write_blocks(string filename, string block_type[], int **block,
int grid[][3], string grade_type[], int grade[][3], int n_blocks, int m[])
{
ofstream file_out(filename.c_str(),ios::app);
file_out<<"\nblocks\n(\n";
for(int i=0;i<n_blocks;++i) {
file_out<<" "<<block_type[i]<<" ( ";
for(int j=0;j<m[i];++j)
file_out<<block[i][j]<<" ";
file_out<<") ( ";
file_out<<grid[i][0]<<' '<<grid[i][1]<<' '<<grid[i][2]<<" ) ";
file_out<<grade_type[i]<<" ( ";
file_out<<grade[i][0]<<' '<<grade[i][1]<<' '<<grade[i][2]<<" )\n";
}
file_out<<");\n";
}
//testing example:
int main()
{
int block[6][9];
for(int i=0; i<6;++i)
for(int j=0; i<9;++j)
block[i][j] = i*j;
int grid[6][3];
for(int i=0; i<6;++i)
for(int j=0; i<3;++j)
block[i][j] = i*j;
int grade[6][3];
for(int i=0; i<6;++i)
for(int j=0; i<3;++j)
block[i][j] = i*j;
string grade_type[6] = {"simpleGrading"};
string block_type[6] = {"hex"};
int m[6] = {8};
int n_blocks = 6;
of_write_blocks("name",block_type,block,grid,grade_type,grade,n_blocks,m);
}
any help is appreciated!
You can't. Multidimensional arrays are syntactic sugar, and are compiled directly into the code that does manipulations on the array, which is a single memory block. The dimensions are not passed into the function as parameters or anything like that as part of the array, as things are done in e.g. Java or C#.
If you need the dimensions of the array in your function, you'll need to just accept a pointer to the first element of the array, and the dimensions, and do the multiplies and adds to get the right index yourself.
Alternately, use something like a std::vector<std::vector<block>>, which pass the dimensions as part of the object, rather than a built in array.
If you have Boost installed, check out Boost Multi-Array.
For clarity I removed all the irrelevant code from your example.
#include <iostream>
#include <fstream>
using namespace std;
void of_write_blocks(int **block, int bh, int bw){
for(int i = 0; i < bh; ++i)
for(int j = 0; j < bw; ++j)
cout << block[i][j] << " ";
cout << endl;
}
int main(){
int bh, bw;
cin >> bh >> bw;
int** block;
block = new int*[bh];
for(int k = 0; k < bh; k++)
block[k] = new int[bw];
// initialize the array
for(int i = 0; i < bh; i++)
for(int j = 0; j < bw; j++)
block[i][j] = (i*bw) + j;
of_write_blocks( block, bh, bw);
}
In the main we are creating a 2D array and initializing it. Then we pass it to of_write_block, which prints the array. Is that what you wanted to do?
Why can't use a reference of array. See below example:
char c[10];
int i[10][20];
double d[10][20][30];
Write a wrapper function like this:
template<typename T, int SIZE>
void Array (T (&a)[SIZE])
{}
template<typename T, int SIZE1, int SIZE2>
void Array (T (&a)[SIZE1][SIZE2])
{}
template<typename T, int SIZE1, int SIZE2, int SIZE3>
void Array (T (&a)[SIZE1][SIZE2][SIZE3])
{}
This is just an example to demonstrate the syntax which will elegantly receive the array without any copying and also avoids confusing pointers. Also, if you are aware that you are going to use only for int then simply remove the typename and explicitly mention int. i.e.
template<int SIZE>
void Array (int (&a)[SIZE]); // explicitly mention int