Iterating Through Variable Names

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • digital.pardoe@gmail.com

    Iterating Through Variable Names

    Hi,

    I have had a little programming experience with C but not enough to
    accomplish what I am trying to do. Nor have I been able to find any
    references on the internet regarding what I am trying to do.

    Basically, I have a structure, which I am unable to change, inside
    this structure are fields of an integer type that have the names: F0,
    F1, F2, F3, F4, F5.

    All I want to be able to to is iterate through them is something along
    the lines of this pseudocode;

    for(N, N == 5, N++) {
    STRUCTURE.F{N} = SOME_VAL;
    }

    I think I may need to utilize an array or hash but I'm really not
    sure.

    Basically I want to append N to the variable name. Is this possible,
    is there some other way of doing it?

    Thanks,
    Alex
  • Antoninus Twink

    #2
    Re: Iterating Through Variable Names

    On 4 Jun 2008 at 11:34, digital.pardoe@ gmail.com wrote:
    Basically, I have a structure, which I am unable to change, inside
    this structure are fields of an integer type that have the names: F0,
    F1, F2, F3, F4, F5.
    >
    All I want to be able to to is iterate through them is something along
    the lines of this pseudocode;
    >
    for(N, N == 5, N++) {
    STRUCTURE.F{N} = SOME_VAL;
    }
    If F0,...,F5 are successive fields in the struct, then it's very likely
    that you can do something like

    int *ip = &structure.F 0;
    for(i=0; i<=5; i++, ip++)
    /* do stuff */

    Otherwise, you could use offsetof to build a table of the offsets of the
    different fields, and then do something very much like indirect
    addressing.

    Comment

    • Richard Tobin

      #3
      Re: Iterating Through Variable Names

      In article <ab8d48a9-4413-4509-94be-2dfddeeda983@e5 3g2000hsa.googl egroups.com>,
      <digital.pardoe @gmail.comwrote :
      >Basically, I have a structure, which I am unable to change, inside
      >this structure are fields of an integer type that have the names: F0,
      >F1, F2, F3, F4, F5.
      >
      >All I want to be able to to is iterate through them is something along
      >the lines of this pseudocode;
      >
      >for(N, N == 5, N++) {
      STRUCTURE.F{N} = SOME_VAL;
      >}
      You can build an array containing the offsets of the fields,
      and then do a little pointer arithmetic:

      #include <stdio.h>
      #include <stddef.h>

      struct foo {
      int f0, f1, f2, f3, f4, f5;
      };

      size_t foo_f_offset[6] = {
      offsetof(struct foo, f0),
      offsetof(struct foo, f1),
      offsetof(struct foo, f2),
      offsetof(struct foo, f3),
      offsetof(struct foo, f4),
      offsetof(struct foo, f5)
      };

      int main(void)
      {
      int i;
      struct foo myfoo;

      for(i=0; i<=5; i++)
      *(int *)((char *)&myfoo + foo_f_offset[i]) = i*i;

      printf("myfoo.f 4 = %d\n", myfoo.f4);

      return 0;
      }

      -- Richard
      --
      In the selection of the two characters immediately succeeding the numeral 9,
      consideration shall be given to their replacement by the graphics 10 and 11 to
      facilitate the adoption of the code in the sterling monetary area. (X3.4-1963)

      Comment

      • David Resnick

        #4
        Re: Iterating Through Variable Names

        On Jun 4, 7:56 am, Antoninus Twink <nos...@nospam. invalidwrote:
        On 4 Jun 2008 at 11:34, digital.par...@ gmail.com wrote:
        >
        Basically, I have a structure, which I am unable to change, inside
        this structure are fields of an integer type that have the names: F0,
        F1, F2, F3, F4, F5.
        >
        All I want to be able to to is iterate through them is something along
        the lines of this pseudocode;
        >
        for(N, N == 5, N++) {
        STRUCTURE.F{N} = SOME_VAL;
        }
        >
        If F0,...,F5 are successive fields in the struct, then it's very likely
        that you can do something like
        >
        int *ip = &structure.F 0;
        for(i=0; i<=5; i++, ip++)
        /* do stuff */
        This is not very good code IMHO. Not written with an eye to being
        maintainable, hopefully wouldn't pass a code review. Forgetting the
        padding issue (seems unlikely to me that padding will between ints, I
        assume you mean that by your "likely" comment, though an assert could
        be added to test this), lying to the compiler means that it won't
        notice changes in the struct. This code will continue to compile just
        fine as long as something named F0 remains if you, for example
        eliminate F5
        insert something between F2 and F3
        reorder the fields, putting F0 last
        etc

        Resulting in some irritating memory overwrites or uninitialized memory
        that could be a bit of a pain to debug. Yeah, maybe nobody will ever
        reorder or otherwise munge this struct, but too many such assumptions
        that nobody will ever do a variety of unlikely things means one will
        happen somewhere anyway...
        >
        Otherwise, you could use offsetof to build a table of the offsets of the
        different fields, and then do something very much like indirect
        addressing.
        Seems a more maintainable choice to me assuming it needs doing at
        all. I assume that the OP actually has a good reason for this, as
        opposed to the simpler and very clear:
        STRUCTURE.F0 = SOME_VAL;
        STRUCTURE.F1 = SOME_VAL;
        ....
        STRUCTURE.F5 = SOME_VAL;

        -David

        Comment

        • digital.pardoe@gmail.com

          #5
          Re: Iterating Through Variable Names

          On Jun 4, 12:56 pm, Antoninus Twink <nos...@nospam. invalidwrote:
          On  4 Jun 2008 at 11:34, digital.par...@ gmail.com wrote:
          >
          Basically, I have a structure, which I am unable to change, inside
          this structure are fields of an integer type that have the names: F0,
          F1, F2, F3, F4, F5.
          >
          All I want to be able to to is iterate through them is something along
          the lines of this pseudocode;
          >
          for(N, N == 5, N++) {
              STRUCTURE.F{N} = SOME_VAL;
          }
          >
          If F0,...,F5 are successive fields in the struct, then it's very likely
          that you can do something like
          >
          int *ip = &structure.F 0;
          for(i=0; i<=5; i++, ip++)
            /* do stuff */
          >
          Otherwise, you could use offsetof to build a table of the offsets of the
          different fields, and then do something very much like indirect
          addressing.
          Hi,

          Thanks for your help.

          Alex.

          Comment

          • digital.pardoe@gmail.com

            #6
            Re: Iterating Through Variable Names

            Hi,

            Right, basically I think I've been really stupid in not reading the
            documentation (what there is of it) properly and probably wasted your
            time (although your code has gone into my code library because I can
            see myself using it somewhere).

            I think I need a better explanation of the problem as I am now
            struggling to understand it myself.

            I am actually programming a PIC chip using C, P16F627 to be precise
            and I have plenty of information and have successfully programmed it
            in assembly but I want to make my programming a little easier and I am
            trying to program it in C, the documentation for C however is
            virtually non existent and I had to work out some things by 'reverse
            engineering' the assembly into C.

            I think, what I originally stated as a struct is actually a bit field.
            I will explain how it works however and allow you to make up your
            mind.

            PORTB <- what I originally thought was a structure, allows me to use
            the output pins of the chip of which there are 6. In assembly the
            assignments to turn the outputs on and off in sequence are as follows;

            PORTB B'00000001'
            PORTB B'00000010'
            PORTB B'00000100'
            PORTB B'00001000'
            PORTB B'00010000'
            PORTB B'00100000'

            I can do this in C by performing the following;

            PORTB = 1
            PORTB = 2
            PORTB = 4
            PORTB = 8
            PORTB = 16
            PORTB = 32

            If I assign products of this then I can get multiple outputs to turn
            on;

            PORTB = 63 // Turns all outputs on.

            I mechanism is also provided to access and set each individual output;

            PORTB.F0 = 1 // Turn output 1 on.
            PORTB.F0 = 1 // Turn output 1 off.
            PORTB.F1 = 1 // Turn output 2 on.
            PORTB.F1 = 1 // Turn output 2 off.

            This means that I can use;

            PORTB.F0 = ~PORTB.F0

            To toggle the output on or off.

            Essentially what I am trying to do as part of my first very basic
            program is turn the outputs on in sequence, then off in sequence. I
            can do this;

            void main() {
            while(1) {
            PORTB.F0 = ~PORTB.F0;
            Delay_ms(100);
            PORTB.F1 = ~PORTB.F1;
            Delay_ms(100);
            PORTB.F2 = ~PORTB.F2;
            Delay_ms(100);
            PORTB.F3 = ~PORTB.F3;
            Delay_ms(100);
            PORTB.F4 = ~PORTB.F4;
            Delay_ms(100);
            PORTB.F5 = ~PORTB.F5;
            Delay_ms(100);
            }
            }

            I suppose it's a re-factoring issue more than anything but I can see a
            lot of code repetition above that I would prefer to shorten as per my
            original post.

            Obviously, the number of output pins doesn't change and I would prefer
            to use the PORTB.Fx method rather than work out all the maths to have
            to use the PORTB = x method of setting to outputs.

            Hope I haven't annoyed people to much with my initial stupidity. If
            people think it would be more appropriate I will move this topic to a
            PIC mailing list.

            Thanks & apologies,
            Alex

            Comment

            • Bartc

              #7
              Re: Iterating Through Variable Names


              <digital.pardoe @gmail.comwrote in message
              news:803a91a4-b26a-4684-8ef4-e3831566a2f0@y3 8g2000hsy.googl egroups.com...
              I am actually programming a PIC chip using C, P16F627 to be precise
              I think, what I originally stated as a struct is actually a bit field.
              I will explain how it works however and allow you to make up your
              mind.
              >
              PORTB = 63 // Turns all outputs on.
              Essentially what I am trying to do as part of my first very basic
              program is turn the outputs on in sequence, then off in sequence. I
              can do this;
              >
              void main() {
              while(1) {
              PORTB.F0 = ~PORTB.F0;
              Delay_ms(100);
              PORTB.F1 = ~PORTB.F1;
              Delay_ms(100);
              PORTB.F2 = ~PORTB.F2;
              Delay_ms(100);
              PORTB.F3 = ~PORTB.F3;
              Delay_ms(100);
              PORTB.F4 = ~PORTB.F4;
              Delay_ms(100);
              PORTB.F5 = ~PORTB.F5;
              Delay_ms(100);
              }
              }
              >
              I suppose it's a re-factoring issue more than anything but I can see a
              lot of code repetition above that I would prefer to shorten as per my
              original post.
              >
              Obviously, the number of output pins doesn't change and I would prefer
              to use the PORTB.Fx method rather than work out all the maths to have
              to use the PORTB = x method of setting to outputs.
              There's little maths involved. To turn on the first bit write 1. To turn on
              the next bit, write 3:

              bits=1;
              for (i=0; i<6; ++i) {
              PORTB = bits;
              bits = (bits<<1) |1;
              delay...
              }

              bits=63;
              for (i=0; i<6; ++i) {
              PORTB = bits;
              bits = (bits<<1); /* propagate 0 into lower bits */
              delay...
              }

              I haven't tested this but I think it's on the right lines. If you really
              want to use F0 to F5, you can write a couple of functions getbit(n) and
              setbit(n,x), each of which uses a switch statement to access F0 to F5, and
              use those instead, if you don't like bit-fiddling.

              --
              Bartc



              Comment

              • digital.pardoe@gmail.com

                #8
                Re: Iterating Through Variable Names

                On Jun 4, 3:23 pm, "Bartc" <b...@freeuk.co mwrote:
                <digital.par... @gmail.comwrote in message
                >
                news:803a91a4-b26a-4684-8ef4-e3831566a2f0@y3 8g2000hsy.googl egroups.com...
                >
                >
                >
                I am actually programming a PIC chip using C, P16F627 to be precise
                I think, what I originally stated as a struct is actually a bit field.
                I will explain how it works however and allow you to make up your
                mind.
                >
                PORTB = 63 // Turns all outputs on.
                Essentially what I am trying to do as part of my first very basic
                program is turn the outputs on in sequence, then off in sequence. I
                can do this;
                >
                void main() {
                 while(1) {
                   PORTB.F0 = ~PORTB.F0;
                   Delay_ms(100);
                   PORTB.F1 = ~PORTB.F1;
                   Delay_ms(100);
                   PORTB.F2 = ~PORTB.F2;
                   Delay_ms(100);
                   PORTB.F3 = ~PORTB.F3;
                   Delay_ms(100);
                   PORTB.F4 = ~PORTB.F4;
                   Delay_ms(100);
                   PORTB.F5 = ~PORTB.F5;
                   Delay_ms(100);
                 }
                }
                >
                I suppose it's a re-factoring issue more than anything but I can see a
                lot of code repetition above that I would prefer to shorten as per my
                original post.
                >
                Obviously, the number of output pins doesn't change and I would prefer
                to use the PORTB.Fx method rather than work out all the maths to have
                to use the PORTB = x method of setting to outputs.
                >
                There's little maths involved. To turn on the first bit write 1. To turn on
                the next bit, write 3:
                >
                bits=1;
                for (i=0; i<6; ++i) {
                 PORTB = bits;
                 bits = (bits<<1) |1;
                 delay...
                 }
                >
                bits=63;
                for (i=0; i<6; ++i) {
                 PORTB = bits;
                 bits = (bits<<1); /* propagate 0 into lower bits */
                 delay...
                 }
                >
                I haven't tested this but I think it's on the right lines. If you really
                want to use F0 to F5, you can write a couple of functions getbit(n) and
                setbit(n,x), each of which uses a switch statement to access F0 to F5, and
                use those instead, if you don't like bit-fiddling.
                >
                --
                Bartc
                The code works perfectly, just reading through my C book to better
                understand what it does then I'll see if I can write some code that
                produces another sequence.

                Thanks,
                Alex.

                Comment

                Working...