question regarding pointers

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Wajih-ur-Rehman

    question regarding pointers

    The question is about C++ (since its the C family, i posted it on this
    newsgroup)

    Lets say i declare an array
    int a[] = {1,2,3,4};
    int *p = a; //This is allowed because "a" returns the address of the first
    element

    The question is actually about 2D arrays. As far as I know, when a 2D array
    is declared in C++, in the memory it is actually stored as a 1D array. and
    the name of the array is pointing to the first element ie. a[0][0] i.e

    int a[2][2] = { {1,2},{3,4} };

    Now the question is that why cant i do this
    int *p = a; //Compiler gives error. Whats wrong with this????? a is not an
    int ** right?

    However following are correct
    int *p = &a[0];
    int *p = &a[0][0];

    Why doesnt int* p = a; work? (if you cout<<a<<&a[0]<<&a[0][0]; it gives the
    same address)

    Thanx in advance


  • Mattias Sjögren

    #2
    Re: question regarding pointers

    >The question is about C++ (since its the C family, i posted it on this[color=blue]
    >newsgroup)[/color]

    I suggest you repost in microsoft.publi c.dotnet.langua ges.vc



    Mattias

    --
    Mattias Sjögren [MVP] mattias @ mvps.org

    Please reply only to the newsgroup.

    Comment

    • 100

      #3
      Re: question regarding pointers

      Hi Wajih-ur-Rehman,

      "> The question is actually about 2D arrays. As far as I know, when a 2D
      array[color=blue]
      > is declared in C++, in the memory it is actually stored as a 1D array. and
      > the name of the array is pointing to the first element ie. a[0][0] i.e
      >
      > int a[2][2] = { {1,2},{3,4} };
      >
      > Now the question is that why cant i do this
      > int *p = a; //Compiler gives error. Whats wrong with this????? a is not an
      > int ** right?[/color]

      No it is not.
      Actually multidimensiona l arrays are treated differently when they has been
      defined statically. They are array of arrays of arrays......
      But it is not int** because no pointers are saved so it is not int **.

      So when you do a[0] it returns one-dimensional array for the first row,
      which can be cast to int *
      [color=blue]
      > However following are correct
      > int *p = &a[0];[/color]
      This will fail (check it). a[0] is onedimensional array and it is already
      pointer to the first element.
      So what a[0] returns is address (number, constant) you cannot get the
      address of a number. You can get address only of *l-values* (varaibles)
      the correct is:
      int *p = a[0];

      Unlike a[0], which is not a *l-value* a[0][0] is a normal *l-value* and you
      can get its address. So the following succeed.[color=blue]
      > int *p = &a[0][0];[/color]
      This is ok. a[0][0] returns a *l-value* of the first element and &a[0][0]
      returns its address
      [color=blue]
      >
      > Why doesnt int* p = a; work? (if you cout<<a<<&a[0]<<&a[0][0]; it gives[/color]
      the[color=blue]
      > same address)[/color]

      It shouldn't work. you cannot get &a[0]. However VC++ compiles it and just
      change the type of the returning address. now it is of type int (*)[2] which
      means pointer that points to array of 2 int values.
      I don't know if it is by C/C++ spec and frankly I don't believe it.
      Sometimes designers of the compilers simplify the grammer in order to make
      it simple and the compiler faster. This simplifications lead to some really
      rear erronous constructs to go thru and compiler may not report error at all
      or may report not correct error.

      So I believe:
      int **b = &a[0] ;
      should be reported as the error "'&' requires l-value";

      Indexing operator [] works differently for multidimensiona l arrays when they
      are declared statically and dynamically:
      int a[2][2]
      or
      int **a;

      And here comes the confusion for the compiler:
      This definitely doesn work:

      int a = 10
      int **b = &(&a);
      ....
      compiler says correctly: *& requires l-value*

      So if cout <<&a[0]; goes thru that means a[0] is l-value;
      Then the following has to work as well:
      int a[2][2] = {...}
      int b[2] = {...}
      a[0] = b;

      MS VC compiler reports error: '=' : left operand must be l-value

      so a[0] *is not* a l-value;

      Can you see the inconsistency here.

      I believe you will get different results with different compiler.

      HTH
      B\rgds
      100



      Comment

      • 100

        #4
        Re: question regarding pointers

        Hi Wajih-ur-Rehman,

        "> The question is actually about 2D arrays. As far as I know, when a 2D
        array[color=blue]
        > is declared in C++, in the memory it is actually stored as a 1D array. and
        > the name of the array is pointing to the first element ie. a[0][0] i.e
        >
        > int a[2][2] = { {1,2},{3,4} };
        >
        > Now the question is that why cant i do this
        > int *p = a; //Compiler gives error. Whats wrong with this????? a is not an
        > int ** right?[/color]

        No it is not.
        Actually multidimensiona l arrays are treated differently when they has been
        defined statically. They are array of arrays of arrays......
        But it is not int** because no pointers are saved so it is not int **.

        So when you do a[0] it returns one-dimensional array for the first row,
        which can be cast to int *
        [color=blue]
        > However following are correct
        > int *p = &a[0];[/color]
        This will fail (check it). a[0] is onedimensional array and it is already
        pointer to the first element.
        So what a[0] returns is address (number, constant) you cannot get the
        address of a number. You can get address only of *l-values* (varaibles)
        the correct is:
        int *p = a[0];

        Unlike a[0], which is not a *l-value* a[0][0] is a normal *l-value* and you
        can get its address. So the following succeed.[color=blue]
        > int *p = &a[0][0];[/color]
        This is ok. a[0][0] returns a *l-value* of the first element and &a[0][0]
        returns its address
        [color=blue]
        >
        > Why doesnt int* p = a; work? (if you cout<<a<<&a[0]<<&a[0][0]; it gives[/color]
        the[color=blue]
        > same address)[/color]

        It shouldn't work. you cannot get &a[0]. However VC++ compiles it and just
        change the type of the returning address. now it is of type int (*)[2] which
        means pointer that points to array of 2 int values.
        I don't know if it is by C/C++ spec and frankly I don't believe it.
        Sometimes designers of the compilers simplify the grammer in order to make
        it simple and the compiler faster. This simplifications lead to some really
        rear erronous constructs to go thru and compiler may not report error at all
        or may report not correct error.

        So I believe:
        int **b = &a[0] ;
        should be reported as the error "'&' requires l-value";

        Indexing operator [] works differently for multidimensiona l arrays when they
        are declared statically and dynamically:
        int a[2][2]
        or
        int **a;

        And here comes the confusion for the compiler:
        This definitely doesn work:

        int a = 10
        int **b = &(&a);
        ....
        compiler says correctly: *& requires l-value*

        So if cout <<&a[0]; goes thru that means a[0] is l-value;
        Then the following has to work as well:
        int a[2][2] = {...}
        int b[2] = {...}
        a[0] = b;

        MS VC compiler reports error: '=' : left operand must be l-value

        so a[0] *is not* a l-value;

        Can you see the inconsistency here.

        I believe you will get different results with different compiler.

        HTH
        B\rgds
        100



        Comment

        • 100

          #5
          Re: question regarding pointers

          Hi Wajih-ur-Rehman,

          "> The question is actually about 2D arrays. As far as I know, when a 2D
          array[color=blue]
          > is declared in C++, in the memory it is actually stored as a 1D array. and
          > the name of the array is pointing to the first element ie. a[0][0] i.e
          >
          > int a[2][2] = { {1,2},{3,4} };
          >
          > Now the question is that why cant i do this
          > int *p = a; //Compiler gives error. Whats wrong with this????? a is not an
          > int ** right?[/color]

          No it is not.
          Actually multidimensiona l arrays are treated differently when they has been
          defined statically. They are array of arrays of arrays......
          But it is not int** because no pointers are saved so it is not int **.

          So when you do a[0] it returns one-dimensional array for the first row,
          which can be cast to int *
          [color=blue]
          > However following are correct
          > int *p = &a[0];[/color]
          This will fail (check it). a[0] is onedimensional array and it is already
          pointer to the first element.
          So what a[0] returns is address (number, constant) you cannot get the
          address of a number. You can get address only of *l-values* (varaibles)
          the correct is:
          int *p = a[0];

          Unlike a[0], which is not a *l-value* a[0][0] is a normal *l-value* and you
          can get its address. So the following succeed.[color=blue]
          > int *p = &a[0][0];[/color]
          This is ok. a[0][0] returns a *l-value* of the first element and &a[0][0]
          returns its address
          [color=blue]
          >
          > Why doesnt int* p = a; work? (if you cout<<a<<&a[0]<<&a[0][0]; it gives[/color]
          the[color=blue]
          > same address)[/color]

          It shouldn't work. you cannot get &a[0]. However VC++ compiles it and just
          change the type of the returning address. now it is of type int (*)[2] which
          means pointer that points to array of 2 int values.
          I don't know if it is by C/C++ spec and frankly I don't believe it.
          Sometimes designers of the compilers simplify the grammer in order to make
          it simple and the compiler faster. This simplifications lead to some really
          rear erronous constructs to go thru and compiler may not report error at all
          or may report not correct error.

          So I believe:
          int **b = &a[0] ;
          should be reported as the error "'&' requires l-value";

          Indexing operator [] works differently for multidimensiona l arrays when they
          are declared statically and dynamically:
          int a[2][2]
          or
          int **a;

          And here comes the confusion for the compiler:
          This definitely doesn work:

          int a = 10
          int **b = &(&a);
          ....
          compiler says correctly: *& requires l-value*

          So if cout <<&a[0]; goes thru that means a[0] is l-value;
          Then the following has to work as well:
          int a[2][2] = {...}
          int b[2] = {...}
          a[0] = b;

          MS VC compiler reports error: '=' : left operand must be l-value

          so a[0] *is not* a l-value;

          Can you see the inconsistency here.

          I believe you will get different results with different compiler.

          HTH
          B\rgds
          100


          Comment

          • 100

            #6
            Re: question regarding pointers

            Hi Wajih-ur-Rehman,

            "> The question is actually about 2D arrays. As far as I know, when a 2D
            array[color=blue]
            > is declared in C++, in the memory it is actually stored as a 1D array. and
            > the name of the array is pointing to the first element ie. a[0][0] i.e
            >
            > int a[2][2] = { {1,2},{3,4} };
            >
            > Now the question is that why cant i do this
            > int *p = a; //Compiler gives error. Whats wrong with this????? a is not an
            > int ** right?[/color]

            No it is not.
            Actually multidimensiona l arrays are treated differently when they has been
            defined statically. They are array of arrays of arrays......
            But it is not int** because no pointers are saved so it is not int **.

            So when you do a[0] it returns one-dimensional array for the first row,
            which can be cast to int *
            [color=blue]
            > However following are correct
            > int *p = &a[0];[/color]
            This will fail (check it). a[0] is onedimensional array and it is already
            pointer to the first element.
            So what a[0] returns is address (number, constant) you cannot get the
            address of a number. You can get address only of *l-values* (varaibles)
            the correct is:
            int *p = a[0];

            Unlike a[0], which is not a *l-value* a[0][0] is a normal *l-value* and you
            can get its address. So the following succeed.[color=blue]
            > int *p = &a[0][0];[/color]
            This is ok. a[0][0] returns a *l-value* of the first element and &a[0][0]
            returns its address
            [color=blue]
            >
            > Why doesnt int* p = a; work? (if you cout<<a<<&a[0]<<&a[0][0]; it gives[/color]
            the[color=blue]
            > same address)[/color]

            It shouldn't work. you cannot get &a[0]. However VC++ compiles it and just
            change the type of the returning address. now it is of type int (*)[2] which
            means pointer that points to array of 2 int values.
            I don't know if it is by C/C++ spec and frankly I don't believe it.
            Sometimes designers of the compilers simplify the grammer in order to make
            it simple and the compiler faster. This simplifications lead to some really
            rear erronous constructs to go thru and compiler may not report error at all
            or may report not correct error.

            So I believe:
            int **b = &a[0] ;
            should be reported as the error "'&' requires l-value";

            Indexing operator [] works differently for multidimensiona l arrays when they
            are declared statically and dynamically:
            int a[2][2]
            or
            int **a;

            And here comes the confusion for the compiler:
            This definitely doesn work:

            int a = 10
            int **b = &(&a);
            ....
            compiler says correctly: *& requires l-value*

            So if cout <<&a[0]; goes thru that means a[0] is l-value;
            Then the following has to work as well:
            int a[2][2] = {...}
            int b[2] = {...}
            a[0] = b;

            MS VC compiler reports error: '=' : left operand must be l-value

            so a[0] *is not* a l-value;

            Can you see the inconsistency here.

            I believe you will get different results with different compiler.

            HTH
            B\rgds
            100


            Comment

            Working...