pointer arithmetic

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

    pointer arithmetic

    I'm having some trouble interpreting some legacy code...here's a single
    line of the kind of pointer arithmetic that baffles me. I need help
    both interpreting and understanding the reasoning behind it. Can
    someone help me?

    *(ioStruct.Frnt ScrPtrn + uj *(*ioStruct.Frn tScrPtrn_NumIte msY)+ui) =
    tempChar;

    can someone re-write this for me in terms I can understand? i.e., my
    first attempt was this, but it's incorrect:

    ioStruct.FrntSc rPtrn[ uj * ioStruct.FrntSc rPtrn_NumItemsY[ui] ] =
    tempChar;

    Also, is there a purpose for this form of pointer arithmetic? Is it
    faster?

    Many thanks,
    sharon

  • Carl Daniel [VC++ MVP]

    #2
    Re: pointer arithmetic

    dotnetchic wrote:
    I'm having some trouble interpreting some legacy code...here's a
    single line of the kind of pointer arithmetic that baffles me. I
    need help both interpreting and understanding the reasoning behind
    it. Can someone help me?
    >
    *(ioStruct.Frnt ScrPtrn + uj *(*ioStruct.Frn tScrPtrn_NumIte msY)+ui) =
    tempChar;
    >
    can someone re-write this for me in terms I can understand? i.e., my
    first attempt was this, but it's incorrect:
    >
    ioStruct.FrntSc rPtrn[ uj * ioStruct.FrntSc rPtrn_NumItemsY[ui] ] =
    tempChar;
    >
    Also, is there a purpose for this form of pointer arithmetic? Is it
    faster?
    This calculated an index into a 2-dimensional array of variable size:

    uj is the "x coordinate", ui is the "y coordinate",
    ioStruct.FrntSc rPtrn_NumItemsY is the width of the array in the "Y"
    dimension, and the array is stored in "column major order" (all points with
    the same Y coordinate value are contiguous in the array).

    The purpose is simple: C and C++ don't have any built-in concept of a
    variable-sized array, so there's no way the compiler can know the length of
    the rows in the array at compile time (and it's necessary to know the length
    of the major axis of a 2-D array to calculate the offset to an element in
    the array).

    HTH

    -cd


    Comment

    • Pavel A.

      #3
      Re: pointer arithmetic

      "dotnetchic " <dotnetchic@gma il.comwrote in message news:1157124179 .417392.293490@ m73g2000cwd.goo glegroups.com.. .
      I'm having some trouble interpreting some legacy code...here's a single
      line of the kind of pointer arithmetic that baffles me. I need help
      both interpreting and understanding the reasoning behind it. Can
      someone help me?
      >
      *(ioStruct.Frnt ScrPtrn + uj *(*ioStruct.Frn tScrPtrn_NumIte msY)+ui) =
      tempChar;
      >
      can someone re-write this for me in terms I can understand? i.e., my
      first attempt was this, but it's incorrect:
      >
      ioStruct.FrntSc rPtrn[ uj * ioStruct.FrntSc rPtrn_NumItemsY[ui] ] =
      tempChar;
      ioStruct.FrntSc rPtrn[ui+ uj * (*ioStruct.Frnt ScrPtrn_NumItem sY)] =tempChar;

      Also, is there a purpose for this form of pointer arithmetic? Is it
      faster?
      No, not faster. A decent compiler would create same code.
      But a pointer and array are actually different concepts; so it really
      depends whether the author sees it as array, or not.

      --PA


      Comment

      • Doug Harrison [MVP]

        #4
        Re: pointer arithmetic

        On 1 Sep 2006 08:22:59 -0700, "dotnetchic " <dotnetchic@gma il.comwrote:
        >I'm having some trouble interpreting some legacy code...here's a single
        >line of the kind of pointer arithmetic that baffles me. I need help
        >both interpreting and understanding the reasoning behind it. Can
        >someone help me?
        >
        >*(ioStruct.Frn tScrPtrn + uj *(*ioStruct.Frn tScrPtrn_NumIte msY)+ui) =
        >tempChar;
        >
        >can someone re-write this for me in terms I can understand? i.e., my
        >first attempt was this, but it's incorrect:
        >
        >ioStruct.FrntS crPtrn[ uj * ioStruct.FrntSc rPtrn_NumItemsY[ui] ] =
        >tempChar;
        >
        >Also, is there a purpose for this form of pointer arithmetic? Is it
        >faster?
        It looks like someone is simulating 2D array access with a pointer into a
        1D array. If I knew exactly what ui, uj, and NumItemsY represent, I could
        explain it specifically, but the general pattern for turning a[i][j] into a
        pointer expression is this:

        T* a1d = (T*) a;
        assert(a1d+i*Nu mCols+j == &a[i][j]);

        If ui is the row number, uj the column number, and NumItemsY the number of
        rows, then your expression represents column-major access (as in Fortran)
        vs. the normal row-major access of C++.

        --
        Doug Harrison
        Visual C++ MVP

        Comment

        • dotnetchic

          #5
          Re: pointer arithmetic

          Thanks to you all for the quick responses. I have posted the more
          complete snippet this time.

          for (uj = 0; uj < * ioStruct.FrntSc rPtrn_NumItemsX ; uj++)
          for (ui = 0; ui < * ioStruct.FrntSc rPtrn_NumItemsY ; ui++)
          {
          fread(&tempChar , sizeof(tempChar ), 1, fInput);
          *(ioStruct.Frnt ScrPtrn + uj
          *(*ioStruct.Frn tScrPtrn_NumIte msY)+ui) = tempChar;
          }

          Carl Daniel [VC++ MVP] wrote:
          The purpose is simple: C and C++ don't have any built-in concept of a
          variable-sized array, so there's no way the compiler can know the length of
          the rows in the array at compile time (and it's necessary to know the length
          of the major axis of a 2-D array to calculate the offset to an element in
          the array).
          I don't *believe* these are variable sized arrays, but I could be
          wrong. If so, how would overruns be handled (I'm guessing silently
          ignored and trashed data/data pointers)?

          Comment

          • Ben Voigt

            #6
            Re: pointer arithmetic

            "dotnetchic " <dotnetchic@gma il.comwrote in message
            news:1157132952 .279800.286710@ m79g2000cwm.goo glegroups.com.. .
            Thanks to you all for the quick responses. I have posted the more
            complete snippet this time.
            >
            for (uj = 0; uj < * ioStruct.FrntSc rPtrn_NumItemsX ; uj++)
            for (ui = 0; ui < * ioStruct.FrntSc rPtrn_NumItemsY ; ui++)
            {
            fread(&tempChar , sizeof(tempChar ), 1, fInput);
            *(ioStruct.Frnt ScrPtrn + uj
            *(*ioStruct.Frn tScrPtrn_NumIte msY)+ui) = tempChar;
            }
            That's about the lamest loop I've ever seen. Obviously written for
            employment security. It's equivalent to the slightly faster (calling T the
            element type of ioStruct.FrntSc rPtrn):

            const size_t colcount = *ioStruct.FrntS crPtrn_NumItems Y;
            size_t rowsleft = *ioStruct.FrntS crPtrn_NumItems X;
            T* p = ioStruct.FrntSc rPtrn;
            while (rowsleft-- 0)
            {
            size_t colsleft = colcount;
            while (colsleft-- 0)
            {
            fread(&tempChar , sizeof(tempChar ), 1, fInput);
            *(p++) = tempChar;
            }
            }

            But that still calls fread a bunch of times, so we'll speed that up with:

            when sizeof(T) == sizeof(tempChar ),

            const size_t colcount = *ioStruct.FrntS crPtrn_NumItems Y;
            const size_t rowcount = *ioStruct.FrntS crPtrn_NumItems X;
            fread(ioStruct. FrntScrPtrn, sizeof(*ioStruc t.FrntScrPtrn), colcount *
            rowcount, fInput);

            or, when sizeof(T) != sizeof(tempChar ), calling T1 the type of tempChar

            const size_t colcount = *ioStruct.FrntS crPtrn_NumItems Y;
            const size_t rowcount = *ioStruct.FrntS crPtrn_NumItems X;
            size_t elems = colcount * rowcount;
            T1 *tempBuffer = (T1*)alloca(ele ms * sizeof (T1)); // pick your favorite
            allocator
            fread(tempBuffe r, sizeofT1), elems, fInput);
            while (elems-- 0)
            ioStruct.FrntSc rPtrn[elems] = tempBuffer[elems]; // compiler should
            convert this to a pair of pointers...
            // deallocate tempBuffer here if not using alloca or garbage collection


            Comment

            Working...