-1

How do I create a function that fills the original array sent to the function, rather than the one that is exclusively in the function? In my code so far I do it manually, but I would like to create a function that stores values and sorts the array. I'm not sure how to apply this to the original array rather than the one that is defined in the function parameters.

#include <iostream>
#include <ctime>
#include <cstdlib>
#include <string>

using namespace std;

class Functions
{
private:
    int input{};
    int numRows{};
    int numColumns{};
    int holder{};

public:
    void rndArrayMaxNumber (int x, int y)
    {
        int tempArray [x][y]{};
        srand(time(0));

        for (int j=0;j<x;j++)
        {
            for (int i=0;i<y;i++)
            {
                tempArray[j][i]= (rand()%99)+1;
            }
        }

        for (int j=0;j<x;j++)
        {
            for (int i=0;i<x-1;i++)
            {
                for (int k=0;k<y-1;k++)
                {
                    if (tempArray[i][k] < tempArray[i][k+1])
                    {
                        holder=tempArray[i][k];
                        tempArray[i][k]=tempArray[i][k+1];
                        tempArray[i][k+1]=holder;
                    }
                }

            }
        }

        for (int j=0;j<y;j++)
        {
            for (int i=0;i<y-1;i++)
            {
                for (int k=0;k<x-1;k++)
                {
                    if (tempArray[k][i] < tempArray[k+1][i])
                    {
                        holder=tempArray[k][i];
                        tempArray[k][i]=tempArray[k+1][i];
                        tempArray[k+1][i]=holder;
                    }
                }

            }
        }

        for (int i=0;i<y;i++)
        {
            for (int k=0;k<x;k++)
            {
                cout << tempArray[i][k] << "\t";
            }
            cout << endl;
        }
        cout << endl << "The greatest number is " << tempArray[0][0];
    }

    void arrayChoice ()
    {
        cout << "Enter the number of rows: ";
        cin >> numRows;
        cout << "Enter the number of columns: ";
        cin >> numColumns;
        cout << endl;
    }

    void menu ()
    {
        while (input!=7)
        {
            cout << "1. 2D array random numbers and show highest number" << endl;
            cout << "2. Exit" << endl << endl;
            cout << "Enter the number of the menu option you want to proceed with: ";
            cin >> input;
            cout << endl;
            switch (input)
            {
                case 1:
                    arrayChoice();
                    rndArrayMaxNumber(numRows, numColumns);
                    cout << endl << endl;
                    break;
            }
        }
    }
};

int main()
{
    Functions program;
    program.menu();
    return 0;
}
JeJo
  • 30,635
  • 6
  • 49
  • 88
Shezshade
  • 31
  • 1
  • 1
  • 2

2 Answers2

0

There are a few of ways to approach this problem.

you could use the begin() and end() functions defined in the header. These return the first and one past the last pointer in the array.This allows you to do something like this

void arr(int *b, int *e)
{
        /*code that reads/changes array i.e b[1] = 1 b[3] = 2 etc.*/
}
int main() {
        int a[10]; 
        arr(begin(a), end(a)); 
}

Another way is the pass the the pointer to the first element in the array along with the size of the array

void arr(int *b, size_t sz)
{
        /*code that reads/changes array */
}
int main() {     
        int a[10]; 
        arr(a, 10); 
}

You could also pass the array via a reference or pointer to the function like so

void array_function(T (*pointer_to_array)[n])

where T represents the type and n represents the size of the array. So passing an array of type int of size 10 would be like the following:

int a[10];

array_function(&a);

and from there you could access the elements in the array within the function body by using the deference and subscript operator:

*pointer_to_array[element] changes made to the variable in the function are reflected in the array a

You could also pass the array via a reference:

void array_function(T (&reference_to_array)[n])

an array is passed to the function in a similar way but without the address of operator &

int a[10];

array_function(a);

the array and its elements could be accessed in the function body using the parameter name and the subscript operator:

reference_to_array[element]

so any changes made to reference_to_array are also reflected in a

The Enigma
  • 137
  • 2
  • 6
0

Arrays cannot be reliably dynamically sized because the C++ Standard requires that the size of all arrays be known when the program is compiled. Some compilers allow dynamically-sized arrays as an extension, but as all things non-standard, support cannot be counted upon. It's best that Variable Length Arrays be avoided if for no other reason than portability. And there are a lot of other reasons (discussion here).

The next bit of nasty is that when passing an array, all dimensions except the first must be known at compile time. This makes it impossible to pass a dynamically sized 2D array should the compiler allow them to be created.

OK. So what do you do instead? The common solution is

std::vector<std::vector<int>> array_2d(x, std::vector<int>(y));

You then pass around array_2d by reference to minimize copying

void rndArrayMaxNumber (std::vector<std::vector<int>> & array_2d)

There is no need to pass x and y. vector knows how big it is.

This is simple and pretty much self maintaining. It is probably all that you need. You likely would not be asking this question or reading this answer if you're writing high performance code.

That said, it has some performance drawbacks as while a single vector is guaranteed to be a contiguous block of memory, a vector of vectors is not. This dooms the program to chasing pointers around in memory and prone to poor caching behaviour. Every time the program has to leave the CPU and high speed cache to grab stuff out of RAM (or god forbid, a swap file) you're leaving an environment running in many gigahertz for one running in hundreds of megahertz or worse.

More on how nasty that can get here: https://blog.codinghorror.com/the-infinite-space-between-words/

Plus every allocation has costs as well. One big allocation can cost much less than 1 vector of size x and x vectors of size y.

Because of this I recommend a simple matrix class based around a single vector.

#include <iostream>
#include <vector>


// template because if you are going to write this, why restrict yourself to just int?
template<class TYPE>
class Matrix
{
private:
    // good to know how big you are
    size_t rows, columns;
    // and the vector containing the data 
    std::vector<TYPE> matrix;
public:
    Matrix(size_t numrows, size_t numcols) :
            rows(numrows), // remember the size
            columns(numcols), 
            matrix(rows * columns) // and allocate storage
    {
    }

    // does the same thing as the other constructor, except it sets a default value
    Matrix(size_t numrows, size_t numcols, TYPE init) :
            rows(numrows), columns(numcols), matrix(rows * columns, init)
    {
    }

    // gets the value at row, column and allows it to be modified        
    TYPE & operator()(size_t row, size_t column)
    {
        // check bounds here if you want
        // note the indexing math mapping 2 dimensions into 1
        return matrix[row * columns + column];
    }

    // gets a copy of the the value at row, column
    TYPE operator()(size_t row, size_t column) const
    {
        return matrix[row * columns + column];
    }

    // obvious what the next two methods do
    size_t getRows() const
    {
        return rows;
    }
    size_t getColumns() const
    {
        return columns;
    }

};

// handy dandy output helper.
friend std::ostream & operator<<(std::ostream & out, const Matrix & in)
{
    for (int i = 0; i < in.getRows(); i++)
    {
        for (int j = 0; j < in.getColumns(); j++)
        {
            out << in(i, j) << ' ';
        }
        out << '\n';
    }

    return out;
}

Note that this answer does not bring new into the equation at all.

If you want to go the route, you have to do much, much more work. How do I declare a 2d array in C++ using new? will get you started down that path, but again, you are better off wrapping a single array as is done here: How do I create a subscript operator for a Matrix class?

Pay special attention to the unimplemented copy constructor and assignment operator. This is the magic sauce to making a good matrix class around a dynamic array, and for reasons I can only ascribe to sadism they are left out of that example. Read What is The Rule of Three? for information on why they are needed. Worth reading the Rule of Three link even if you use a vector because you cannot write non-trivial C++ without a firm grip on the Rule of Three (and its friends Five and Zero).

Documentation on std::vector

user4581301
  • 33,082
  • 7
  • 33
  • 54