Thread: sending or recieving a[][]to a function

  1. #1
    Registered User
    Join Date
    Nov 2003
    Posts
    183

    Question sending or recieving a[][]to a function

    can u plz tell me how can I send (or recieve) a[][] to(from) a function .
    for example what is the changes that must be done in this program .
    Code:
    #include <iostream.h>
    int **b;
    int** change(int **);
    int main(){
    int a[3][2],i,j;
    for(i=0;i<3;i++)
      for(j=0;j<2;j++)
        cin>>a[i][j];
    b=change(a);
    for(i=0;i<3;++i){
      cout <<'\n';
      for(j=0;j<2;++j)
        cout <<b[i][j] <<' ' ;}
    return 0;}
    
    
    int** change(int **a){
    int i,j;
    for(i=0;i<3;i++)
      for(j=0;j<2;++j)
        if(i==j)
          a[i][j]=0;
    return (a);}
    tnx

  2. #2
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,661
    Code:
    #include <iostream.h>
    void change(int a[3][2]);
    int main(){
    int a[3][2],i,j;
    for(i=0;i<3;i++)
      for(j=0;j<2;j++)
        cin>>a[i][j];
    change(a);
    for(i=0;i<3;++i){
      cout <<'\n';
      for(j=0;j<2;++j)
        cout <<a[i][j] <<' ' ;}
    return 0;}
    
    void change(int a[3][2]){
    int i,j;
    for(i=0;i<3;i++)
      for(j=0;j<2;++j)
        if(i==j)
          a[i][j]=0;
    }
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  3. #3
    Registered User
    Join Date
    Dec 2003
    Posts
    92
    hello , can anybody say what was wrong in arian's code ? which line is wrong ? is it when the function returning ??
    can u point out the mistake in that code ?
    blue_gene

  4. #4
    Registered User
    Join Date
    Dec 2003
    Posts
    92
    but this code is working !!
    Code:
    #include <iostream>
    using namespace std;
    
    int* func(int* y);
    int main()
    {
    int m = 4;
    int* x =&m;
    int* p =  func(x);
    cout<<*p<<endl;
    }
    
    int* func(int* y)
    {
    *y = 3;
    return y;
    }
    blue_gene

  5. #5
    Registered User
    Join Date
    Mar 2002
    Posts
    1,595
    The relationship between pointers and arrays causes a fair amount of confusion for lots of us. The name of an array is considered to be a constant pointer to the first element of an array. You can use pointer math to navigate arrays instead of using the [] operator if you wish. You use pointers to declare arrays using dynamic memory. However there are important differences. One important difference is that you can assign one pointer to another using the assignment operator, but you can't assign one array to another using the assignment operator.

    In blue_genes code pointers are declared and used as an argument and as a return value for a function. The pointers never pretend to be anything but a pointer, however, so everything works.

    In arians code the variable a is declared as an array, filled element by element as an array, passed to change() as a pointer (to pointer), changed as an array, passed back to main() as a pointer(to pointer), and then attempts to assign a to b as a pointer (to pointer) only to have b handled like an array. The problem is that the name of an array can act like a pointer, but a pointer can't act like an entire array, unless it assigned memory using the new operator, in which case it's not really a pointer anymore but an array!

    Salems code makes it clear that variable a is going to be used as an array throughout. It takes advantage of the relationship between pointers and arrays in that changes made to a in change() are reflected in a back in main() in the second output loop.

    At least that's my explanation.

  6. #6
    Registered User
    Join Date
    Nov 2003
    Posts
    183
    tnx for ur explanation.
    but I still have some question :

    isnt possible that a function returns int ** ?

    and what can I do when I dont know "[3][2]"(I mean when I dont know the number of rows and columns of a 2 dimenention array at first), can I sent it to a function?
    some times we use malloc inside main for getting memory . in these programs how can we send the aray to a function ?
    for example in this program what must be instead of (?) , can 'a' be sent to function change ?

    Code:
    void change(?);
    int main(){
    int i,j,k,**a;
    cin >> i >> j;
    a=(int **)malloc(i);
    for(k=0;k<i;++k)
      *(a+k)=(int *)malloce(j);
    change (?);

  7. #7
    Registered User
    Join Date
    Nov 2001
    Posts
    1,348
    One solution is **.

    func(int **pInt, int nRow, int nCol)
    {}

    Kuphryn

  8. #8
    Registered User
    Join Date
    Mar 2002
    Posts
    1,595
    > isnt possible that a function returns int ** ?

    if the int ** is truly a pointer, then yes I can envision that. However, if int ** is a cover for a two dimensional array, then I have trouble envisioning that as a return value, although maybe others can give you an example.




  9. #9
    Registered User
    Join Date
    Nov 2001
    Posts
    1,348
    There are several solutions, but they require you knowing the size of the array.

    void func (int (*in)[nRow])
    {}

    void func (int (*in)[nRow][nCol])
    {}

    Kuphryn

  10. #10
    Registered User
    Join Date
    Nov 2003
    Posts
    183
    tnx alot for helping .

  11. #11
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,661
    > passed to change() as a pointer (to pointer),
    No - its a pointer to an array, not a pointer to a pointer.
    The "array is pointer to first element" rule is only applied once, not recursively.

    > unless it assigned memory using the new operator, in which case it's not really a pointer anymore but an array!
    Nope - its still a pointer
    The fact that you can do ptr[index] on a pointer doesn't make it an array.

    Because arrays are passed as a pointer to the first element of the array (in the case of 2D pointers, this in in fact a pointer to an array - namely one whole row of the 2D array), the called function is able to modify the contents of that array. So returning a pointer to it is seldom necessary.

    But anyway, for those who are interested, this is the lowdown
    Code:
    #include <iostream>
    using namespace std;
    
    // func takes pointer to a 2D array as a parameter
    // and returns a pointer to a 2D array
    // this is not the same as int **func( int a[2][3] );
    // remember, pointer to ARRAY, not pointer to POINTER
    int (*func( int a[2][3] ))[3] {
        for ( int r = 0 ; r < 2 ; r++ ) {
            for ( int c = 0 ; c < 3 ; c++ ) {
                a[r][c] = r * c;
            }
        }
        return a;
    }
    // but that sure is messy to write (or remember even)
    // oh yeah, parentheses matter - just try taking some out and see
    
    // a typedef makes it so much easier
    typedef int (*twodptr)[3];
    twodptr func2 ( twodptr a ) {
        for ( int r = 0 ; r < 2 ; r++ ) {
            for ( int c = 0 ; c < 3 ; c++ ) {
                a[r][c] = r * c;
            }
        }
        return a;
    }
    
    
    int main() {
        int a[2][3];    // a 2D array
        int (*b)[3];    // a pointer to a 2D array (this is not the same as int**)
                        // specifically a 2D array with [3] as the minor dimension
        twodptr c;      // another pointer, just like b
        int row,col;
    
        b = func( a );  // pass array to func, get a pointer to the array back
        c = func2( a );
    
        // show a,b,c are the same
        for ( row = 0 ; row < 2 ; row++ ) {
            for ( col = 0 ; col < 3 ; col++ ) {
                cout << a[row][col] << " "
                     << b[row][col] << " "
                     << c[row][col] << "   ";
            }
            cout << endl;
        }
    
        // you can even allocate a 2D array in one step - with the right pointer type
        // and pass it to the same function as before
        b = new int[2][3];  // the minor dimension MUST MATCH
        func( b );
        for ( row = 0 ; row < 2 ; row++ ) {
            for ( col = 0 ; col < 3 ; col++ ) {
                cout << b[row][col] << " ";
            }
            cout << endl;
        }
        delete [] b;
        return 0;
    }
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  12. #12
    Registered User
    Join Date
    Mar 2002
    Posts
    1,595
    Salem--thanks for the clarifications.

    int (*func( int a[2][3] ))[3]

    typedef int (*twodptr)[3];

    int (*b)[3]; // a pointer to a 2D array (this is not the same as int**)
    // specifically a 2D array with [3] as the minor dimension


    That's some of the funkier notation I've seen. Can't say as I understand it yet. In particular I can't get my brain to accept that the * before b can give b a "second dimension".

    Is this correct?

    int version1[][]-->2D array of int
    int *version2[]-->array of pointer to int
    int (*version3)[]-->pointer to array of int???
    int **version4-->pointer to pointer to int

    if version4 is assigned dynamic memory will it become the same functional entity as version1 and version3? Can version2 ever be the same as the others?

  13. #13
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,661
    > That's some of the funkier notation I've seen
    Yeah - you don't see it too often. typedef's hugely simplify the declarations.

    If you want really scary looking functions, create a non-trivial function returning a pointer to another non-trivial function.

    > Is this correct?
    Yes those are all correct.
    The parentheses change "array of pointer" into "pointer to array". A subtle change of wording results in very different interpretations of what the variable actually is.

    > if version4 is assigned dynamic memory will it become the same functional entity as version1 and version3?
    Not quite.
    version3 is the dynamic counterpart of version1, and both can be passed to the same function.
    This is the example I showed in my previous post with the b = new int[2][3];

    Likewise, version4 is the dynamic counterpart of version2, you could pass either of these to a func( int**a) or a func( int *a[] )

    But you can't mix and match them
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Getting an error with OpenGL: collect2: ld returned 1 exit status
    By Lorgon Jortle in forum C++ Programming
    Replies: 6
    Last Post: 05-08-2009, 08:18 PM
  2. dllimport function not allowed
    By steve1_rm in forum C++ Programming
    Replies: 5
    Last Post: 03-11-2008, 03:33 AM
  3. Game Pointer Trouble?
    By Drahcir in forum C Programming
    Replies: 8
    Last Post: 02-04-2006, 02:53 AM
  4. Dikumud
    By maxorator in forum C++ Programming
    Replies: 1
    Last Post: 10-01-2005, 06:39 AM
  5. c++ linking problem for x11
    By kron in forum Linux Programming
    Replies: 1
    Last Post: 11-19-2004, 10:18 AM