Home > Net >  Function Template that will add all elements of any 2-D integer array in C
Function Template that will add all elements of any 2-D integer array in C

Time:11-16

I have been tasked with creating a function template that will add all elements of any 2-dimensional integer array as part of an exercise for a programming theory language course.

I have tried several methods and keep getting compiler errors that I don't understand.

1)

template<typename T>
T addArraysOne(T rows, T cols, T arr[][cols])
{
    T output;
    for(int i = 0; i < rows; i  )
    {
        for(int j = 0; j < cols; j  )
        {
            output  = arr[i][j];
        }
    }
    return output;
}

This one errors as the parameter for the number of columns is "not a constant".

2)

int addArraysTwo(int rows, int cols, int** arr)
{
    int output;
    for(int i = 0; i < rows; i  )
    {
        for(int j = 0; j < cols; j  )
        {
            output  = *arr[i*rows j];
        }
    }
    return output;
}

This one errors when I try and call it with addArraysTwo(5, 5, arr); because it "does not match the function call", when "arr" is a 2 dimensional int array. I haven't found any problems particularly similar to this online. Any suggestions on how to modify these so that I do not piss off the compiler would be much appreciated. Thanks!

CodePudding user response:

You can use the following program that uses template nontype parameters.

Version 1: For integer arrays


#include <iostream>
//a function template that takes a 2D int array by reference
template< std::size_t N, std::size_t M>
int calculateSum(const int (&arr)[N][M])
{
    int sum = 0;
    //iterate through rows and colums of the passed 2D int array
    for(std::size_t row = 0; row < N;   row)
    {
        for(std::size_t col = 0 ; col < M;   col)
        {
            sum = arr[row][col];
        }
    }
    return sum;
}
int main()
{
    int arr[2][3] = {{1,2,3},{3,4,5}};
    std::cout<<"Sum is: "<<calculateSum(arr)<<std::endl;

    return 0;
}

Version 2: For array of arbitrary type


#include <iostream>
//a function template that takes a 2D array(with elements of type T) by reference
template< typename T, std::size_t N, std::size_t M>
T calculateSum(const T (&arr)[N][M])
{
    T sum{0};
    //iterate through rows and colums of the passed 2D T array
    for(std::size_t row = 0; row < N;   row)
    {
        for(std::size_t col = 0 ; col < M;   col)
        {
            sum = arr[row][col];
        }
    }
    return sum;
}
int main()
{
    double arr[2][3] = {{1.4,2,3},{3.6,4,5.45}};
    std::cout<<"Sum is: "<<calculateSum(arr)<<std::endl;

    return 0;
}

CodePudding user response:

Your first method, variable-lengthed-array only supported by c99 (and not adopted by c I believe?). otherwise, the length of the array must be known at compile time. And at least with c 17 and below, any parameter of array type is adjusted to the corresponding pointer type by the compiler, so it is no difference between int f(int a[5]) and int f(int a[]) and int f(int* a)。But for 2d arrays, the size of the second dimension must be known at compile time. int f(int a[][2]) (which is equavalent to int f(int(*a)[2])) is OK, but int f(int a[][]) is not.

Your second method, 2d arrays are not implicitly convertable to pointer of pointers, but pointer to 1d arrays:

int arr[2][3];
int **p = arr; // Error
int(*p)[3] = arr; // OK

so one of the solutions is just:

template<typename T>
T addArraysOne(T rows, T cols, T* arr)
{
    T output = 0; // NOTE: initialize to 0
    for(int i = 0; i < rows; i  )
    {
        for(int j = 0; j < cols; j  )
        {
            output  = arr[i*cols j]; // NOTE: not i*rows j
        }
    }
    return output;
}

and called it with:

int arr[2][3];
addArraysOne(2, 3, &arr[0][0]);
  • Related