Two dimensional array Question

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • mdh

    Two dimensional array Question

    I am still having a problem understanding K&RII on p 112. I have
    looked at the FAQs --which I am sure answer it in a way that I have
    missed, so here goes.
    A 2-dim array, (per K&R) is really a 1-dim array, each of whose
    elements is an array.
    Looking at the debugger I use, arr[2][13] is shown as an initial value
    of "2", but when expanded, there are 2 consecutive arrays of 13
    elements.
    So, may I ask this?
    Is there anything special that marks the end of the first 13 elements
    from the beginning of the 2nd 13 elements? In other words, it seems to
    me that this is nothing more than a 1-dim array, with the information
    about the structure of the array provided by the declaration?
    Hopefully this makes sense.

    The exercise associated with this, used the construct

    *p = arr[1 or 0 ] to point to either the "first" or "second" row of
    the array. Does the compiler "know" where to point to because it has
    been given this information by the declaration of "13" in arr[2][13].
    Hopefully this makes sense too!


    And lastly, K&R's description of "each of whose elements is an array"
    has never made sense to me. It may be that the answer to the above may
    clarify it.

    Thanks in advance.
  • Joe Wright

    #2
    Re: Two dimensional array Question

    mdh wrote:
    I am still having a problem understanding K&RII on p 112. I have
    looked at the FAQs --which I am sure answer it in a way that I have
    missed, so here goes.
    A 2-dim array, (per K&R) is really a 1-dim array, each of whose
    elements is an array.
    Looking at the debugger I use, arr[2][13] is shown as an initial value
    of "2", but when expanded, there are 2 consecutive arrays of 13
    elements.
    So, may I ask this?
    Is there anything special that marks the end of the first 13 elements
    from the beginning of the 2nd 13 elements? In other words, it seems to
    me that this is nothing more than a 1-dim array, with the information
    about the structure of the array provided by the declaration?
    Hopefully this makes sense.
    >
    Perfect sense. All above is correct. Given 'int arr[2][13];', arr is an
    array 2 of array 13 of int. 26 consecutive ints.
    The exercise associated with this, used the construct
    >
    *p = arr[1 or 0 ] to point to either the "first" or "second" row of
    the array. Does the compiler "know" where to point to because it has
    been given this information by the declaration of "13" in arr[2][13].
    Hopefully this makes sense too!
    >
    No. arr[0] is (the address of) an array 13 of int. The pointer 'p' must
    be declared to reflect this.

    int (*p)[13];

    Now p is a pointer to array 13 of int and..

    p = arr[0];

    ...makes sense.
    >
    And lastly, K&R's description of "each of whose elements is an array"
    has never made sense to me. It may be that the answer to the above may
    clarify it.
    >
    I hope so. You're really not too far off. Hang in there.
    Thanks in advance.
    --
    Joe Wright
    "Everything should be made as simple as possible, but not simpler."
    --- Albert Einstein ---

    Comment

    • Default User

      #3
      Re: Two dimensional array Question

      Joe Wright wrote:
      mdh wrote:
      Perfect sense. All above is correct. Given 'int arr[2][13];', arr is
      an array 2 of array 13 of int. 26 consecutive ints.
      >
      The exercise associated with this, used the construct

      *p = arr[1 or 0 ] to point to either the "first" or "second" row of
      the array. Does the compiler "know" where to point to because it has
      been given this information by the declaration of "13" in
      arr[2][13]. Hopefully this makes sense too!
      No. arr[0] is (the address of) an array 13 of int.
      No, it's not. It is an array 13 of int, not a pointer to one. arr is a
      pointer to array 13 of int.
      The pointer 'p'
      must be declared to reflect this.
      >
      int (*p)[13];
      >
      Now p is a pointer to array 13 of int and..
      >
      p = arr[0];
      >
      ..makes sense.
      Not to me.

      p = &arr[0];

      Would. Or what the OP had:

      int *p;
      p = arr[0];





      Brian

      Comment

      • Ben Bacarisse

        #4
        Re: Two dimensional array Question

        mdh <mdeh@comcast.n etwrites:

        <When discussing int a[2][13];>
        And lastly, K&R's description of "each of whose elements is an array"
        has never made sense to me. It may be that the answer to the above may
        clarify it.
        Another thought... Do you have a problem with:

        struct ints { int a,b,c,d,e,f,g,h ,i,j,k,l,m; };
        struct ints a[2];

        being an array, each of whose elements is a structure of 13 ints?
        What if we say:

        struct ints { int e[13]; };
        struct ints a[2];

        For many people the trouble is the way it is written. If it were
        something like: 'int[13] a[2];' they might find it easier to swallow
        but the array declarators group like this:

        int (a[2]) [13] ;

        (you can write that if you want!) so a is "an array of 2... arrays of
        13... ints. I think you are very close to "getting it".

        --
        Ben.

        Comment

        • pete

          #5
          Re: Two dimensional array Question

          Default User wrote:
          Joe Wright wrote:
          >
          >mdh wrote:
          >
          >Perfect sense. All above is correct. Given 'int arr[2][13];', arr is
          >an array 2 of array 13 of int. 26 consecutive ints.
          >>
          >>The exercise associated with this, used the construct
          >>>
          >>*p = arr[1 or 0 ] to point to either the "first" or "second" row of
          >>the array. Does the compiler "know" where to point to because it has
          >>been given this information by the declaration of "13" in
          >>arr[2][13]. Hopefully this makes sense too!
          >>>
          >No. arr[0] is (the address of) an array 13 of int.
          >
          No, it's not. It is an array 13 of int, not a pointer to one. arr is a
          pointer to array 13 of int.
          You just made the same mistake that you just corrected.

          arr isn't any more of a pointer than arr[0] is.
          arr isn't any less of an array than arr[0] is.

          (sizeof arr) equals (2 * 13 * sizeof(int)).

          --
          pete

          Comment

          • mdh

            #6
            Re: Two dimensional array Question

            Thanks to all who responded. It makes a *little* more sense now, but I
            think it will hopefully clear up with time and practice.

            Comment

            • Barry Schwarz

              #7
              Re: Two dimensional array Question

              On Thu, 8 May 2008 08:16:13 -0700 (PDT), mdh <mdeh@comcast.n etwrote:
              >I am still having a problem understanding K&RII on p 112. I have
              >looked at the FAQs --which I am sure answer it in a way that I have
              >missed, so here goes.
              >A 2-dim array, (per K&R) is really a 1-dim array, each of whose
              >elements is an array.
              The C99 standard uses the term "multidinension al array" so K&R is
              slightly out of date in this regard.
              >Looking at the debugger I use, arr[2][13] is shown as an initial value
              >of "2", but when expanded, there are 2 consecutive arrays of 13
              >elements.
              What do you mean by "2". Is it an array of char arrays and the first
              of such holds the string '2' '\0'?
              >So, may I ask this?
              >Is there anything special that marks the end of the first 13 elements
              >from the beginning of the 2nd 13 elements? In other words, it seems to
              No. It is prohibited. arr[1] must immediately follow arr[0] in
              memory.
              >me that this is nothing more than a 1-dim array, with the information
              >about the structure of the array provided by the declaration?
              >Hopefully this makes sense.
              It is true that the 26 "basic elements" of arr will appear in memory
              "linearly". This has prompted many debates about whether a pointer to
              arr[0][0] can be used with subscripts ranging from 0 to 25 to access
              all 26. What is not in dispute is that in a 1d array T x[N], x[0]
              evaluates to an element of type T. In your case, arr[0] evaluates to
              an array of T. To my mind, this is sufficient to say arr cannot be
              considered a 1d array.
              >
              >The exercise associated with this, used the construct
              >
              *p = arr[1 or 0 ] to point to either the "first" or "second" row of
              >the array. Does the compiler "know" where to point to because it has
              >been given this information by the declaration of "13" in arr[2][13].
              >Hopefully this makes sense too!
              Yes and yes.
              >
              >
              >And lastly, K&R's description of "each of whose elements is an array"
              >has never made sense to me. It may be that the answer to the above may
              >clarify it.
              arr[0] is an array 13 T. arr[1] is an array of 13 T. arr[2] does not
              exist. arr[i][j] is an object of type T as long as 0<=i<=1 and
              0<=j<=12. arr[i][j] is an element of arr[i] but not element of arr.
              arr[i] is an element of arr and it is an array.


              Remove del for email

              Comment

              • mdh

                #8
                Re: Two dimensional array Question

                On May 8, 8:54 pm, Barry Schwarz <schwa...@dqel. comwrote:
                >
                >
                The C99 standard uses the term "multidinension al array" so K&R is
                slightly out of date in this regard.
                >
                Looking at the debugger I use, arr[2][13] is shown as an initial value
                of "2", but when expanded, there are 2 consecutive arrays of 13
                elements.
                >
                What do you mean by "2".  Is it an array of char arrays and the first
                of such holds the string '2' '\0'?

                I am using Xcode...not that that probably makes any difference.
                Initially arr[2][13] is declared as a char array. In the debugger
                window, there is a column for value and the "initial" value of arr is
                "2". If one expands this, then one sees 2 arrays of 13 elements, and
                as you say below, these seem to be contiguous. I was trying to find a
                way of seeing what the address of each element is, but have been
                unable to do so....

                >
                It is true that the 26 "basic elements" of arr will appear in memory
                "linearly".  This has prompted many debates about whether a pointer to
                arr[0][0] can be used with subscripts ranging from 0 to 25 to access
                all 26.  What is not in dispute is that in a 1d array T x[N], x[0]
                evaluates to an element of type T.  In your case, arr[0] evaluates to
                an array of T.  To my mind, this is sufficient to say arr cannot be
                considered a 1d array.
                >

                thank you Barry.





                Comment

                • Default User

                  #9
                  Re: Two dimensional array Question

                  pete wrote:
                  Default User wrote:
                  Joe Wright wrote:
                  mdh wrote:
                  Perfect sense. All above is correct. Given 'int arr[2][13];', arr
                  is an array 2 of array 13 of int. 26 consecutive ints.
                  >
                  The exercise associated with this, used the construct

                  *p = arr[1 or 0 ] to point to either the "first" or "second"
                  row of the array. Does the compiler "know" where to point to
                  because it has been given this information by the declaration
                  of "13" in arr[2][13]. Hopefully this makes sense too!

                  No. arr[0] is (the address of) an array 13 of int.
                  No, it's not. It is an array 13 of int, not a pointer to one. arr
                  is a pointer to array 13 of int.
                  >
                  You just made the same mistake that you just corrected.
                  Yes, I did in a way. I was sloppy about context. It is correct that arr
                  is not a pointer, although it's converted to one in most contexts.

                  The code was correct, which it wasn't originally.


                  Thanks for clarifying my stab at i.





                  Brian

                  Comment

                  • mdh

                    #10
                    Re: Two dimensional array Question

                    >
                    >
                    The exercise associated with this, used the construct
                    >
                    *p = arr[1 or 0 ] to point to either the "first" or "second" row of
                    the array. Does the compiler "know" where to point to because it has
                    been given this information by the declaration of "13" in arr[2][13].
                    Hopefully this makes sense too!
                    >
                    Yes and yes.
                    >
                    I was in a hurry to get to work this am...so forgot to ask this.
                    In a multidimensiona l array, one can simply drop the second []? as in
                    *p=arr[i] and this is legal?
                    Thanks.

                    Comment

                    • pete

                      #11
                      Re: Two dimensional array Question

                      mdh wrote:
                      >>
                      >>The exercise associated with this, used the construct
                      >>*p = arr[1 or 0 ] to point to either the "first" or "second" row of
                      >>the array. Does the compiler "know" where to point to because it has
                      >>been given this information by the declaration of "13" in arr[2][13].
                      >>Hopefully this makes sense too!
                      >Yes and yes.
                      >>
                      I was in a hurry to get to work this am...so forgot to ask this.
                      In a multidimensiona l array, one can simply drop the second []? as in
                      *p=arr[i] and this is legal?
                      Thanks.
                      It's legal regardless of whether or not
                      you understand what you're writing.
                      But it's better if you realize that

                      *p = arr[i];

                      means the same thing as

                      *p = &arr[i][0];

                      because

                      &arr[i][0] means &*(*(arr + i) + 0)

                      which can be simplified to

                      (*(arr + i) + 0)
                      *(arr + i)
                      arr[i]

                      --
                      pete

                      Comment

                      • Ben Bacarisse

                        #12
                        Re: Two dimensional array Question

                        pete <pfiland@mindsp ring.comwrites:
                        mdh wrote:
                        >>>
                        >>>The exercise associated with this, used the construct
                        >>>*p = arr[1 or 0 ] to point to either the "first" or "second" row of
                        >>>the array. Does the compiler "know" where to point to because it has
                        >>>been given this information by the declaration of "13" in arr[2][13].
                        >>>Hopefully this makes sense too!
                        >>Yes and yes.
                        >>>
                        > I was in a hurry to get to work this am...so forgot to ask this.
                        >In a multidimensiona l array, one can simply drop the second []? as in
                        >*p=arr[i] and this is legal?
                        >Thanks.
                        >
                        It's legal regardless of whether or not
                        you understand what you're writing.
                        But it's better if you realize that
                        >
                        *p = arr[i];
                        >
                        means the same thing as
                        >
                        *p = &arr[i][0];
                        The trouble is this phrase "means the same as". Both right hand sides
                        are certainly closely related expressions, but they have different
                        types, different sizes (sizeof arr[i] != sizeof &arr[i][0]) and they
                        can't be used in the same places (you can, for example take the
                        address of one but not of the other).

                        Sometimes it helps to gloss over these differences and sometimes it
                        does not. I am not sure which is the case here.
                        because
                        >
                        &arr[i][0] means &*(*(arr + i) + 0)
                        >
                        which can be simplified to
                        >
                        (*(arr + i) + 0)
                        *(arr + i)
                        arr[i]
                        C is not good for equational reasoning. The OP might find this
                        helpful:

                        #include <stdio.h>

                        #define PSZ(exp) printf("sizeof " #exp " = %d\n", (int)sizeof exp)

                        int main(void)
                        {
                        int i = 0;
                        int arr[2][13] = {0};

                        PSZ(&arr[i][0]);
                        PSZ(&*(*(arr + i) + 0));
                        PSZ((*(arr + i) + 0));
                        PSZ(*(arr + i));
                        PSZ(arr[i]);

                        return 0;
                        }

                        --
                        Ben.

                        Comment

                        • pete

                          #13
                          Re: Two dimensional array Question

                          Ben Bacarisse wrote:
                          pete <pfiland@mindsp ring.comwrites:
                          >
                          >mdh wrote:
                          >>>>The exercise associated with this, used the construct
                          >>>>*p = arr[1 or 0 ] to point to either the "first" or "second" row of
                          >>>>the array. Does the compiler "know" where to point to because it has
                          >>>>been given this information by the declaration of "13" in arr[2][13].
                          >>>>Hopefully this makes sense too!
                          >>>Yes and yes.
                          >>>>
                          >> I was in a hurry to get to work this am...so forgot to ask this.
                          >>In a multidimensiona l array, one can simply drop the second []? as in
                          >>*p=arr[i] and this is legal?
                          >>Thanks.
                          >It's legal regardless of whether or not
                          >you understand what you're writing.
                          >But it's better if you realize that
                          >>
                          > *p = arr[i];
                          >>
                          >means the same thing as
                          >>
                          > *p = &arr[i][0];
                          >
                          The trouble is this phrase "means the same as". Both right hand sides
                          are certainly closely related expressions, but they have different
                          types, different sizes (sizeof arr[i] != sizeof &arr[i][0]) and they
                          can't be used in the same places (you can, for example take the
                          address of one but not of the other).
                          Think harder.

                          *p = arr[i];
                          means the same thing as
                          *p = (arr[i] + 0);

                          sizeof arr[i]
                          does not mean the same thing as
                          sizeof (arr[i] + 0)

                          My claim was about two expression statements.
                          You're talking about array type expressions
                          in a context which is irrelevant to this.

                          Consider new.c:
                          Do you think new.c is missing a cast somewhere?
                          Do you have a compiler that thinks
                          that new.c is missing a cast somewhere?
                          Do you know under what circumstances
                          cast operators are required in C?

                          /* BEGIN new.c */

                          int main(void)
                          {
                          int arr[2][13] = {0};
                          int **p1;
                          int **p2;

                          *p1 = arr[1];
                          *p2 = &arr[1][0];
                          return *p1 != *p2;
                          }

                          /* END new.c */


                          --
                          pete

                          Comment

                          • Joe Wright

                            #14
                            Re: Two dimensional array Question

                            Ben Bacarisse wrote:
                            pete <pfiland@mindsp ring.comwrites:
                            >
                            >mdh wrote:
                            >>>>The exercise associated with this, used the construct
                            >>>>*p = arr[1 or 0 ] to point to either the "first" or "second" row of
                            >>>>the array. Does the compiler "know" where to point to because it has
                            >>>>been given this information by the declaration of "13" in arr[2][13].
                            >>>>Hopefully this makes sense too!
                            >>>Yes and yes.
                            >>>>
                            >> I was in a hurry to get to work this am...so forgot to ask this.
                            >>In a multidimensiona l array, one can simply drop the second []? as in
                            >>*p=arr[i] and this is legal?
                            >>Thanks.
                            >It's legal regardless of whether or not
                            >you understand what you're writing.
                            >But it's better if you realize that
                            >>
                            > *p = arr[i];
                            >>
                            >means the same thing as
                            >>
                            > *p = &arr[i][0];
                            >
                            The trouble is this phrase "means the same as". Both right hand sides
                            are certainly closely related expressions, but they have different
                            types, different sizes (sizeof arr[i] != sizeof &arr[i][0]) and they
                            can't be used in the same places (you can, for example take the
                            address of one but not of the other).
                            >
                            Sometimes it helps to gloss over these differences and sometimes it
                            does not. I am not sure which is the case here.
                            >
                            >because
                            >>
                            > &arr[i][0] means &*(*(arr + i) + 0)
                            >>
                            >which can be simplified to
                            >>
                            > (*(arr + i) + 0)
                            > *(arr + i)
                            > arr[i]
                            >
                            C is not good for equational reasoning. The OP might find this
                            helpful:
                            >
                            #include <stdio.h>
                            >
                            #define PSZ(exp) printf("sizeof " #exp " = %d\n", (int)sizeof exp)
                            >
                            int main(void)
                            {
                            int i = 0;
                            int arr[2][13] = {0};
                            >
                            PSZ(&arr[i][0]);
                            PSZ(&*(*(arr + i) + 0));
                            PSZ((*(arr + i) + 0));
                            PSZ(*(arr + i));
                            PSZ(arr[i]);
                            >
                            return 0;
                            }
                            >
                            All true on the face of it but sizeof was not what was asked, it was
                            assignment. Given..

                            int *p;
                            p = arr[i];

                            Yes, arr[i] is an array 13 of int but expressing an array as above
                            yields the address of its first element, in this case int*.

                            p = &arr[i][0];

                            The address of the int yields the same int*.

                            --
                            Joe Wright
                            "Everything should be made as simple as possible, but not simpler."
                            --- Albert Einstein ---

                            Comment

                            • Ben Bacarisse

                              #15
                              Re: Two dimensional array Question

                              pete <pfiland@mindsp ring.comwrites:
                              Ben Bacarisse wrote:
                              >pete <pfiland@mindsp ring.comwrites:
                              <snip>
                              >>But it's better if you realize that
                              >>>
                              >> *p = arr[i];
                              >>>
                              >>means the same thing as
                              >>>
                              >> *p = &arr[i][0];
                              >>
                              >The trouble is this phrase "means the same as". Both right hand sides
                              >are certainly closely related expressions, but they have different
                              >types, different sizes (sizeof arr[i] != sizeof &arr[i][0]) and they
                              >can't be used in the same places (you can, for example take the
                              >address of one but not of the other).
                              >
                              Think harder.
                              OK, but you'll have to help me if you think I've missed something. I
                              really do think I get it.

                              I know you meant "in most expression contexts" and I did not say you
                              said anything wrong. All I was saying is that it sometimes helps to
                              know the ways in which they *don't* mean the same thing. Obviously
                              you disagree, and that is fine. Only the OP can say which is more
                              helpful in "getting it".
                              *p = arr[i];
                              means the same thing as
                              *p = (arr[i] + 0);
                              >
                              sizeof arr[i]
                              does not mean the same thing as
                              sizeof (arr[i] + 0)
                              Of course not, and that is one reason why I'd be loath to say that
                              arr[i] and &arr[i][0] mean the same thing.

                              sizeof &arr[i][0]

                              *does* mean the same thing as

                              sizeof (&arr[i][0] + 0)

                              (as do '*p = &arr[i][0];' and '*p = &arr[i][0] + 0;').

                              All this does is to highlight that we expect different things from two
                              expressions that "mean the same".

                              --
                              Ben.

                              Comment

                              Working...