CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 10 of 10
  1. #1
    Join Date
    May 2018
    Posts
    158

    [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?

  2. #2
    Join Date
    Nov 2003
    Location
    Belgium
    Posts
    8,150

    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]"
    Marc Gregoire - NuonSoft (http://www.nuonsoft.com)
    My Blog
    Wallpaper Cycler 3.5.0.97

    Author of Professional C++, 4th Edition by Wiley/Wrox (includes C++17 features)
    ISBN: 978-1-119-42130-6
    [ http://www.facebook.com/professionalcpp ]

  3. #3
    Join Date
    May 2018
    Posts
    158

    Re: pass 2-dim matrix by pointer

    Quote Originally Posted by Marc G View Post
    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.

  4. #4
    2kaud's Avatar
    2kaud is offline Super Moderator Power Poster
    Join Date
    Dec 2012
    Location
    England
    Posts
    7,822

    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)

  5. #5
    2kaud's Avatar
    2kaud is offline Super Moderator Power Poster
    Join Date
    Dec 2012
    Location
    England
    Posts
    7,822

    Re: pass 2-dim matrix by pointer

    Quote Originally Posted by zio_mangrovia View Post
    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)

  6. #6
    Join Date
    May 2018
    Posts
    158

    Re: pass 2-dim matrix by pointer

    Quote Originally Posted by 2kaud View Post
    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?

  7. #7
    Join Date
    Feb 2017
    Posts
    677

    Re: pass 2-dim matrix by pointer

    Quote Originally Posted by zio_mangrovia View Post
    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.

  8. #8
    Join Date
    May 2018
    Posts
    158

    Re: pass 2-dim matrix by pointer

    Your words explained me several things and now I can just understand.

    Quote Originally Posted by wolle View Post
    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?

  9. #9
    Join Date
    Feb 2017
    Posts
    677

    Re: pass 2-dim matrix by pointer

    Quote Originally Posted by zio_mangrovia View Post
    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.

  10. #10
    Join Date
    May 2018
    Posts
    158

    Re: pass 2-dim matrix by pointer

    Quote Originally Posted by wolle View Post
    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
  •  





Click Here to Expand Forum to Full Width

Featured