c++ passing 2d arrays to funcions - c++

I know my code isnt finished yet im not asking for it to be done. It's supposed to input food eaten by 3 monkeys over a week and other stuff. But I've hit a snag. It gives me an error(Error: no operator "<<" matches these operands) when i put the cin in the poundsEaten function. Am I not passing the array right is that why it isnt working? Thanks for any help
#include <iomanip>
#include <iostream>
using namespace std;
//Global Constants
const int NUM_MONKEYS = 3;
const int DAYS = 7;
//Prototypes
void poundsEaten(const double[][DAYS],int, int);
void averageEaten();
void least();
void most();
int main()
{
//const int NUM_MONKEYS = 3;
//const int DAYS = 7;
double foodEaten[NUM_MONKEYS][DAYS]; //Array with 3 rows, 7 columns
poundsEaten(foodEaten, NUM_MONKEYS, DAYS);
system("pause");
return 0;
}
void poundsEaten(const double array[][DAYS], int rows, int cols)
{
for(int index = 0; index < rows; index++)
{
for(int count = 0; count < DAYS; count++)
{
cout << "Pounds of food eaten on day " << (index + 1);
cout << " by monkey " << (count + 1);
cin >> array[index][count];
// Here is where i get the error
}
}
}

You've declared array as containing const doubles. They're constant, so you can't write to them as you are trying to do with cin >> array[index][count];. Just change the parameter declaration to:
double array[][DAYS]
Perhaps you should think about when and why you should declare a variable as const.
As an aside to avoid later confusion, it's worth mentioning here that there's no such thing as array type parameters. The above parameter is actually transformed to:
double (*array)[DAYS]
However, your code is written appropriately to work with this (you passed the number of rows to the function).

you declare:
const double array[][DAYS],
however, inside poundsEaten function, you are asking user to input information to fill in the array, which means the array is not const, therefore, error. Remove the const qualifier from the parameter such that the array can be changed by user input.
void poundsEaten(double array[][DAYS], int rows, int cols)
BTW: don't use array as variable name for an array, use some other names for good practice.
Meanwhile,cols is not used inside your poundsEaten function.

Related

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

Change the function signature

I'm new to C++ and for now there is one thing I would want to make clear. As I'm going through the tutorial,there is this program that stores user's input into an array and gives a sum of all numbers when the user exits the program:
//PROTOTYPE DECLARATION:
int readArray(int integerArray[], int maxNumElements);
int sumArray(int integerArray[], int numElements);
void displayArray(int integerArray[], int numElements);
int main(int nNumberofArgs, char* pszArgs[])
{
cout << "This program sums values entered\n";
cout << "Terminate the loop by entering a negative number" << endl;
//store the numbers from the user into a local array
int inputValues [128];
int numberOfValues = readArray(inputValues, 128);
//output the values and the sum of the values
displayArray(inputValues, numberOfValues);
cout << "The sum is " << sumArray(inputValues, numberOfValues) << endl;
return 0;
}
int readArray(int integerArray[], int maxNumElements)
{
int numberOfValues;
for(numberOfValues = 0; numberOfValues < maxNumElements; numberOfValues++)
{
//fetch another number
int integerValue;
cout << "Enter next number: ";
cin >> integerValue;
if (integerValue < 0)
{
break;
}
//otherwise store the number into the storage array
integerArray[numberOfValues] = integerValue;
}
//return the number of elements read
return numberOfValues;
}
//displayArray - display the members of an array:
void displayArray(int integerArray[], int numElements)
{
cout << "The value of the array is:" << endl;
for(int i = 0; i < numElements; i++)
{
cout << i << ":" << integerArray[i] << endl;
}
cout << endl;
}
//sumArray
int sumArray(int integerArray[], int numElements)
{
int accumulator = 0;
for(int i = 0; i < numElements; i++)
{
accumulator += integerArray[i];
}
return accumulator;
}
My questions are:
Is it neccessary to declare local variables in each function (e.g. int inputValues [128];)?
Would it be correct to store the input into the arguments that were declared in the function prototype? For example, can we just store everything into integerArray[] instead of creating a storage array integerValue ?
This may look obvious but I want to understand this to avoid making mistakes in the future.
inputValues is necessary if you want to pass an array to the function.
int inputValues [128];
int numberOfValues = readArray(inputValues, 128); //passing array to function
Either way you do it is fine. So what you have is not wrong.
As noted in the comments you could also pass inputValues by reference. Which you could declare the prototype of function like this.
int readArray(int (&integerArray)[128]);
Any changes you make to the array you passed by reference will be updated when the function returns to main because you are not operating on a copy of the array anymore.
Edit:
As #Kevin pointed out, you can use a template function to get the size of the array at compile time.
template<size_t N> int readArray(int (&integerArray)[N]);
There are a lot of understanding gaps in this question.
The function parameter lists will convert their input:
If the type is "array of T" or "array of unknown bound of T", it is replaced by the type "pointer to T"
Using the implicit array to pointer assignment:
Constructs a pointer to the first element of an array.
These two together hopefully help you to see that when you declare a function like: int readArray(int integerArray[], int maxNumElements), integerArray is really just a pointer to the first element of it's first argument. You call readArray(inputValues, 128) so the parameter integerArray is equivalent to &intputArray[0].
It is not necessary and you can use global variables instead but that is bad choice in terms security and visibility etc. This program can be done few different ways but I guess what you need to learn first is difference between local and global scope, pointer/array.
In the program, memory is allocated for
int inputValues[128]; //memory allocation
Then address of that location is passed here.
int numberOfValues = readArray(inputValues, 128);
It is much more efficient this way. But it will start make more sense once you get more experience with pointer and arrays.

VOID function passes array by reference, but when used, I get "No matching matching function for call to..."

I wrote the following code to fill a double array of length len (that has already been initialized) with random floating point numbers:
void FillRay(double (&array)[] , const unsigned int len, const double a , const double b)
{
for(unsigned int i = 0 ; i < len ; ++i )
{
array[i] = randFloat(a,b); // Fill array at i with random number
}
return;
}
However, when I use my FillRay function in main() (see end of main)...
#include <iostream>
#include <cstdlib>
#include <ctime>
#include <math.h>
using namespace std;
int main(){
double a;
double b;
cout << "Please enter lower bound (a): ";
cin >> a;
cout << endl;
cout << "Please enter upper bound (b): ";
cin >> b;
cout << endl;
//Calculate mean and variance
double mu = (b - a)/2;
double sigma = pow(b - a , 2)/12;
//Declare arrays (with langths)
unsigned int shorter = 1000;
unsigned int longer = 100000;
double shortArray[shorter];
double longArray[longer];
// Fill array of length 1K
FillRay(shortArray , shorter, a , b); // ***THIS IS MY PROBLEM AREA***
return 0;
}
... I get the error No matching function for call to 'FillRay'
Can someone please explain what I am doing wrong?? Thanks!
Change your function prototype to following:
void FillRay(double* array, const unsigned int len, const double a , const double b)
Also, it is a good practice to use size_t instead of int for array sizes.
void FillRay(double (&array)[] , const unsigned int len, const double a , const double b)
double (&array)[] is an attempt to take an array by reference without specifying the array's size. This is not possible. The fact that you also specify a len parameter is technically irrelevant. If you want to use standard C++ without any proprietary extensions, then you have three choices:
Completely change the program logic such that the array size is fixed at compile time.
Have the function take a double* and let the automatic conversion (informally called "decay") from array to pointer take place.
Use std::vector<double>.

To write a program to remove duplicates from an array

I am working on program that remove duplicates from an array I am using three functions here: one to take the input such as the size and the number, second function to remove duplicates and return the number without duplicates and the third function just a report show the size and the new number but I am having problem I don't know in what step I think in report or phillip erreur:
In function ‘int main()’: invalid conversion from ‘int*’ to ‘int’,initializing argument 1 of ‘void report(int, int)’
#include <iostream>
using namespace std;
const int size = 100;
void phillip(int[], int & );
/* Preconditions: Array of base type in declared and int varuable declared
postconditions: the array is filled with values supllied by the user at
the keybord. the user is assked how many values they want - this value is
given to the second argument.
*/
int remdubs(int[], int noel);
/* Preconditions: An array of basetype int that has noel values.
postconditions: The number of unique elemts in the array is returned. The function removes all dubplicates inside the array.
*/
void report(int s, int d);
int main()
{
int ruby[size];
int numele, numuniq;
phillip(ruby, numele);
numuniq = remdubs(ruby, numele);
report(ruby, numuniq);
return 0;
}
void phillip(int[], int& )
{
int s;
cout << "\nHow many values you want? ";
cin >> s;
cout << "\nPlease input 10 integers, hitting return after each one \n";
for (int i = 0; i < s; i++)
{
int num;
cin >> num;
}
}
int rembups(int sapphire[], int noel)
{
for (int i = 0; i < noel; i++)
{
for (int j = i + 1; j < noel; j++)
{
if (sapphire[i] == sapphire[j])
{
for (int k = j; k < noel; k++)
sapphire[k] = sapphire[k + 1];
noel--;
j--;
}
}
}
return noel;
}
void report(int s, int d)
{
cout << "\nYou entered " << s << "distinct numbers: " << d;
}
Can't explain it better than your error:
void report (int s, int d);
this function asks for two integer values, you're passing an array to it which, with decayed functionalities, will behave like an integer pointer
int ruby[size];
report (ruby, numuniq);
I'm unsure on the behavior of your program but you should rather do something like
report(ruby[0], numuniq);
that is: access the element of the array and feed it to the function
The error is in the function report, it asks for two integer and you are passing an array and an integer instead
and again i don't think you need 2 parameters in the function report one would solve your purpose
void report(int d)
{
cout << "\nYou entered <<d<<" distinct numbers";
}
that would solve your error but i don't think you would get your desired output
Few problems with the code:
Report function should be expecting an array of integers rather than single integer
Try using human readable variable or function names
remdubs was renamed to rempubs in function definition
phillip function definition didn't have params defined properly
You have const int size but do not use it
remdups has a bug somewhere. I will leave that out as I am trying to fix other issues here.
There are better ways of finding duplicates than remdups. Please look at some other solutions.
I have fixed your code and provided it here on ideone

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.