-
July 2nd, 2018, 12:15 AM
#1
[RESOLVED] pass 2-dim matrix by pointer
Code:
somma(double* m, int row, int col)
{
double tot=0;
for (int r=0; r<row; r++)
for (int c=0; c<col; c++)
tot+=*(m+r*col+c);
}
int R=3, C=7;
double mat[R][C]={ 1,2,3,4,5,6,7,8,9, .... };
cout << somma( (double*)mat, R, C);
I read several documents about 2-dim matrix and howto pass it by pointers.
I'm not able to understand because mat is different than double*. I undestand It's necessary casting operator because mat is seen as diferent, but why?!
I know mat represents address of first row but why this one what type represents?!
Can you suggest some documents where I can understand this pass by pointer please?
-
July 2nd, 2018, 01:44 AM
#2
Re: pass 2-dim matrix by pointer
Some remarks:
* somma() must have a return type, or void.
* R and C must be constants, otherwise they cannot be used for the definition of mat.
* The type of "mat" is "double(*)[7]"
* You need to pass the address of the first element, so either the cast as you did, or something like: "&mat[0][0]"
-
July 2nd, 2018, 02:40 AM
#3
Re: pass 2-dim matrix by pointer
Originally Posted by Marc G
Some remarks:
* somma() must have a return type, or void.
* R and C must be constants, otherwise they cannot be used for the definition of mat.
* The type of "mat" is "double(*)[7]"
* You need to pass the address of the first element, so either the cast as you did, or something like: "&mat[0][0]"
I quickly wrote this code to highlight the parameters pass but I will correct it immediately
Code:
double somma(double* m, const int row, const int col)
{
double tot=0;
for (int r=0; r<row; r++)
for (int c=0; c<col; c++)
tot+=*(m+r*col+c);
}
const int R=3, C=7;
double mat[R][C]={ 1,2,3,4,5,6,7,8,9, .... };
cout << somma( (double*)mat, R, C);
I'd like to see documentation which explains because, in this case, I have to specify casting (double*) for mat matrix in actual parameter.
-
July 2nd, 2018, 03:27 AM
#4
Re: pass 2-dim matrix by pointer
You don't actually need to pass the dimensions of the array to somma - although I know that many books, courses etc say this is how you do it. But there is another way which uses more advanced c++. Consider
Code:
template<typename T, size_t R, size_t C>
double somma(T(&m)[R][C])
{
double tot = 0;
for (size_t r = 0; r < R; ++r)
for (size_t c = 0; c < C; ++c)
tot += m[r][c];
return tot;
}
int main()
{
const size_t R = 3, C = 7;
const double mat[R][C] = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21};
cout << somma(mat);
}
Here when you call somma you just pass the array without also passing its dimensions. In somma R (which is a different variable from R in main() ) and C hold the dimensions of the passed array. In main, if you change the dimensions of mat then somma() will automatically obtain the correct dimensions.
All advice is offered in good faith only. All my code is tested (unless stated explicitly otherwise) with the latest version of Microsoft Visual Studio (using the supported features of the latest standard) and is offered as examples only - not as production quality. I cannot offer advice regarding any other c/c++ compiler/IDE or incompatibilities with VS. You are ultimately responsible for the effects of your programs and the integrity of the machines they run on. Anything I post, code snippets, advice, etc is licensed as Public Domain https://creativecommons.org/publicdomain/zero/1.0/ and can be used without reference or acknowledgement. Also note that I only provide advice and guidance via the forums - and not via private messages!
C++23 Compiler: Microsoft VS2022 (17.6.5)
-
July 2nd, 2018, 03:38 AM
#5
Re: pass 2-dim matrix by pointer
Originally Posted by zio_mangrovia
I quickly wrote this code to highlight the parameters pass but I will correct it immediately
Code:
double somma(double* m, const int row, const int col)
{
double tot=0;
for (int r=0; r<row; r++)
for (int c=0; c<col; c++)
tot+=*(m+r*col+c);
}
const int R=3, C=7;
double mat[R][C]={ 1,2,3,4,5,6,7,8,9, .... };
cout << somma( (double*)mat, R, C);
I'd like to see documentation which explains because, in this case, I have to specify casting (double*) for mat matrix in actual parameter.
You need the cast (double*) because although mat is defined with 2 dimensions, you are passing it as a 1 dimension to somma() which then calculates the correct memory location to use.
You can also code it like this
Code:
const size_t MaxRow = 3, MaxCol = 7;
using MyMat = double[MaxRow][MaxCol];
double somma(const MyMat m)
{
double tot = 0;
for (size_t r = 0; r < MaxRow; ++r)
for (size_t c = 0; c < MaxCol; ++c)
tot += m[r][c];
return tot;
}
int main()
{
const MyMat mat = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21};
cout << somma(mat);
}
with a defined type for the array. Passing a pointer to an array and also its dimensions is not really good C++ practice! The C++ 'good practice' way is as per post #4.
Last edited by 2kaud; July 2nd, 2018 at 04:52 AM.
All advice is offered in good faith only. All my code is tested (unless stated explicitly otherwise) with the latest version of Microsoft Visual Studio (using the supported features of the latest standard) and is offered as examples only - not as production quality. I cannot offer advice regarding any other c/c++ compiler/IDE or incompatibilities with VS. You are ultimately responsible for the effects of your programs and the integrity of the machines they run on. Anything I post, code snippets, advice, etc is licensed as Public Domain https://creativecommons.org/publicdomain/zero/1.0/ and can be used without reference or acknowledgement. Also note that I only provide advice and guidance via the forums - and not via private messages!
C++23 Compiler: Microsoft VS2022 (17.6.5)
-
July 2nd, 2018, 02:04 PM
#6
Re: pass 2-dim matrix by pointer
Originally Posted by 2kaud
You need the cast (double*) because although mat is defined with 2 dimensions, you are passing it as a 1 dimension to somma() which then calculates the correct memory location to use.
with a defined type for the array. Passing a pointer to an array and also its dimensions is not really good C++ practice!
This method is been applied from academic people for education purpose and I have to follow these way, but first of all I have to understand it.
I can understand It's not a good practise but I have no choice, in the future I'll develop my opinion which can I apply as I wish.
I'm not able to understand:
mat is defined with 2 dimensions, you are passing it as a 1 dimension to somma() which then calculates the correct memory location to use.
mat is ok, it has 2 dimensions, but why you are saying I'm passing a 1 dimension array?!?! Where and how can I understand these concepts?
-
July 3rd, 2018, 01:12 AM
#7
Re: pass 2-dim matrix by pointer
Originally Posted by zio_mangrovia
mat is ok, it has 2 dimensions, but why you are saying I'm passing a 1 dimension array?!?! Where and how can I understand these concepts?
Pointers and arrays are related. An array can be thought of as a pointer. But an array also has dimensions. If the dimensional structure of an array is lost the array is said to decay to a pointer. It happens for example if you cast the array to a pointer. This pointer can still be used as a 1D array though and be accessed using [].
So to use a 2D array as a 2D array the compiler must be supplied enough information to uphold the 2D structure. If not the [][] notation can no longer be used and one must manage the array's dimensions in some other fashion.
Code:
double somma(double m[3][5]) {} // [][] can be used to access m, m is expected to be 3 x 5
//
somma(mat);
Code:
double somma(double m[][5], const int row) // [][] can be used to access m, m is expected to be row x 5
//
somma(mat, 3);
Code:
double somma(double m[][], const int row, const int col) {} // compiler error
Code:
double somma(double* m, const int row, const int col) {} // [][] cannot be used to access m (but [] can), m is expected to be row x col
//
somma((double*)mat, 3, 5); // mat decays to a pointer, dimensional structure is lost
somma(&mat[0][0], 3, 5); // mat decays to a pointer, dimensional structure is lost
Last edited by wolle; July 3rd, 2018 at 02:23 AM.
-
July 3rd, 2018, 02:50 AM
#8
Re: pass 2-dim matrix by pointer
Your words explained me several things and now I can just understand.
Originally Posted by wolle
Code:
double somma(double* m, const int row, const int col) {} // [][] cannot be used to access m (but [] can), m is expected to be row x col
//
somma((double*)mat, 3, 5); // mat decays to a pointer, dimensional structure is lost
somma(&mat[0][0], 3, 5); // mat decays to a pointer, dimensional structure is lost
I also could write somma((double*)mat[0], 3, 5) ? because mat[0] represents address of first line of array and casting operator helps me to convert it for pointer m, right?
-
July 4th, 2018, 12:36 AM
#9
Re: pass 2-dim matrix by pointer
Originally Posted by zio_mangrovia
I also could write somma((double*)mat[0], 3, 5) ? because mat[0] represents address of first line of array and casting operator helps me to convert it for pointer m, right?
That sounds right and my compiler (VS 2017) accepts it so I guess it's okey. Your suggestion is a mix of my suggestions ((double*)mat and &mat[0][0]) and I most likely would use one of those two since I feel they're more straightforward.
Note that array elements are contiguously laid out in memory so you could implement somma like this,
Code:
double somma(double* m, const int row, const int col) {
double tot = 0.0;
for (double* p = m; p < m + row*col; tot += *p++);
return tot;
}
That's typical C code but arrays belong to the C part of C++ so why not.
Last edited by wolle; July 4th, 2018 at 01:56 AM.
-
July 5th, 2018, 12:04 AM
#10
Re: pass 2-dim matrix by pointer
Originally Posted by wolle
That sounds right and my compiler (VS 2017) accepts it so I guess it's okey. Your suggestion is a mix of my suggestions ((double*)mat and &mat[0][0]) and I most likely would use one of those two since I feel they're more straightforward.
Note that array elements are contiguously laid out in memory so you could implement somma like this,
Code:
double somma(double* m, const int row, const int col) {
double tot = 0.0;
for (double* p = m; p < m + row*col; tot += *p++);
return tot;
}
That's typical C code but arrays belong to the C part of C++ so why not.
thanks for your wonderful explanation
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|