I am trying to modify the contents of a 2D array in C++ using a function. I haven't been able to find information on how to pass a 2D array to a function by reference and then manipulate individual cells.
The problem I am trying to solve has the following format. I have made a simple program for brevity.
#include<cstdlib>
#include<iostream>
using namespace std;
void func(int& mat) {
int k,l;
for(k=0;k<=2;k++) {
for(l=0;l<=2;l++) {
mat[k][l]=1; //This is incorrect because mat is just a reference, but
// this is the kind of operation I want.
}
}
return;
}
int main() {
int A[3][3];
int i, j;
char jnk;
for(i=0;i<=2;i++) {
for(j=0;j<=2;j++) {
A[i][j]=0;
}
}
func(A);
cout << A[0][0];
return 0;
}
So the value of A[0][0] should change from 0 to 1. What is the correct way to do this? Many thanks in advance...
Arrays are not passed by value, so you can simply use
void func(int mat[][3])
and, if you modify the values of mat
inside func
you are actually modifying it in main
.
You can use that approach if you know a priori the size of your matrix, otherwise consider working with pointers:
#include <iostream>
void f(int **m, int r, int c) {
m[0][0]=1;
}
int main () {
int **m;
int r=10,c=10;
int i;
m = (int**)malloc(r*sizeof(int*));
for (i=0; i<r;i++)
m[i] = (int*)malloc(c*sizeof(int));
f(m,r,c);
printf("%d\n",m[0][0]);
for(i=0;i<r;i++)
free(m[i]);
free(m);
return 0;
}
C++ allows you to encapsulate code structures like this into an object, for example an array has the std::vector
and std::array
object.
I personally roll my own matrix containers. This way you don't have to worry about the details of how they are passed.
A basic example of a matrix implemenation could be:
template<typename T>
class matrix
{
public: //TYPEDEFS
typedef T value_type;
private:
typedef std::vector<value_type> vect_type;
public:
typedef typename vect_type::iterator iterator;
typedef typename vect_type::const_iterator const_iterator;
private: //DATAMEMBERS
vect_type values;
size_t x_sz, y_sz;/not const for assingment reasons
public: //MEMBER FUNCTIONS
matrix(const matrix&) =default;
matrix(matrix&&) =default;
matrix& operator=(const matrix&)=default;
matrix& operator=(matrix&&) =default;
matrix(size_t x_sz_=0u, size_t y_sz_=0u, value_type t=value_type())
: values(x_sz_*y_sz_, t)
, x_sz(x_sz_)
, y_sz(y_sz_)
{ }
//return symbol const body
size_t x_size() const { return x_sz; }
size_t y_size() const { return y_sz; }
iterator begin() { return values.begin(); }
iterator end() { return values.end(); }
const_iterator begin() const { return values.cbegin(); }
const_iterator end() const { return values.cend(); }
const_iterator cbegin() const { return values.cbegin(); }
const_iterator cend() const { return values.cend(); }
value_type& at(size_t x, size_t y)
{
return values.at(y*x_sz+x);
}
const value_type& at(size_t x, size_t y) const
{
return values.at(y*x_sz+x);
}
}; //class matrix
Then you simply do the following:
void func(const mat& m)....
:::
matrix<int> mat(3,3);
//this isn't necessary as the ctor take a default value,
// however it show you how you might iterate through the values.
for(size_t y=0; y!=mat.y_size(); ++y)
for(size_t x=0; x!=mat.x_size(); ++x)
mat.at(x, y)=0;
func(mat); //as param
can you check on this:
#include <cstdio>
#include <cstdlib>
void printArrays(int* array[], int len1, int len2) {
for (int i=0; i<len1; i++) {
for (int j=0; j<len2; j++) {
printf("%d ", array[i][j]);
}
printf("\n");
}
}
void modify(int* array[], int len1, int len2) {
for (int i=0; i<len1; i++) {
for (int j=0; j<len2; j++) {
array[i][j]*=(i+j);
}
}
}
int main() {
int arr1[3] = {4, 5, 5};
int arr2[3] = {6, 1, 5};
int arr3[3] = {7, 5, 1};
int *array[3] = {arr1, arr2, arr3};
printArrays(array, 3, 3);
printf("After modify:\n");
modify(array, 3, 3);
printArrays(array, 3, 3);
return 0;
}
Here's the conventional way. You can use either version of function "f":
#include <cstdlib>
const size_t cols = 10; // You can hardcode this below if you want
// Can only be called if you know "cols" at compile-time
void f(int pArray[][cols], size_t rows)
{
for(size_t i = 0; i < rows; ++i)
{
for(size_t j = 0; j < cols; ++j)
{
pArray[i][j] = 1;
}
}
}
// Use this if you don't know "cols" at compile-time (good for any arbitrary 2D array)
void f(int *pArray, size_t rows, size_t cols)
{
for(size_t i = 0; i < rows; ++i)
{
const size_t RowOffset = (i * cols);
for(size_t j = 0; j < cols; ++j)
{
pArray[RowOffset + j] = 1;
}
}
}
int main()
{
int array[][cols]= {{ 5, 10, 15, 20, 25, 30, 35, 40, 45, 50 },
{ 55, 60, 65, 70, 75, 80, 85, 90, 95, 100 },
{ 105, 110, 115, 120, 125, 130, 135, 140, 145, 150 },
{ 155, 160, 165, 170, 175, 180, 185, 190, 195, 200 },
{ 205, 210, 220, 225, 230, 235, 240, 245, 250, 255}};
const size_t rows = sizeof(array) / sizeof(array[0]); // 5 in this example but you can hardcode it if you want
f(array, rows);
f(array[0], rows, cols);
return 0;
}