3

I would like to know if there is possible to initialize all variables (within a LOOP) present in a Struct to 0 and back to 1.

Here is a demonstrating program:

#include <stdio.h>

#define LEDS_LENGTH 7

void inititate_to_zero(void);
void inititate_to_one(void);

struct pins
{
    unsigned char state : 1;
    unsigned char LED0  : 1;
    unsigned char LED1  : 1;
    unsigned char LED2  : 1;
    unsigned char LED3  : 1;
    unsigned char LED4  : 1;
    unsigned char LED5  : 1;
}pins;

int main(void)
{
    inititate_to_zero( );
    inititate_to_one( );
}

void inititate_to_zero(void)
{
    for(unsigned char i = 0; i < LEDS_LENGTH; i++)
    {
        /// set all variable in struct pins to 0;
        pins.VARIABLE[SOME_HOW] ^= ( 1 << 0 );
    }
}

void inititate_to_one(void)
{
    for (unsigned char i = 0; i < LEDS_LENGTH; i++)
    {
        /// set all variable in struct pins to 1;
        pins.VARIABLE[SOME_HOW] ^= ( 1 << 0 );
    }
}

EDIT:

I needed to replace the function inititate_to_one() to use a LOOP if it is possible:

#include <stdio.h>

#define LEDS_LENGTH 7

void inititate_to_one ( void );

struct pins
{
    volatile unsigned char state    : 1;
    unsigned char LED0              : 1;
    unsigned char LED1              : 1;
    unsigned char LED2              : 1;
    unsigned char LED3              : 1;
    unsigned char LED4              : 1;
    unsigned char LED5              : 1;
}pins{ 0 };


int main( void )
{
    inititate_to_one ( );
}

void inititate_to_one( void )
{
    state ^= ( 1 << 0 );
    LED0  ^= ( 1 << 0 );
    LED1  ^= ( 1 << 0 );
    LED2  ^= ( 1 << 0 );
    LED3  ^= ( 1 << 0 );
    LED4  ^= ( 1 << 0 );
    LED5  ^= ( 1 << 0 );
}
John Doe
  • 85
  • 9
  • 3
    Perhaps what you really want is an array? Or possibly single `unsigned char` used as a bit-field? – Some programmer dude Jan 24 '19 at 09:40
  • *Initialization* to 0 (or any zero-ish/null value) for a C struct is straightforward. *Setting* to 0 or 1 later, or initialization to 1, is different. So it really depends on what question your asking *precisely*. – 9769953 Jan 24 '19 at 09:40
  • how about making an array of LED[i] instead of led0 led1... – Spinkoo Jan 24 '19 at 09:41
  • 4
    You have `memset` available right? (e.g. `memset (&pins, 1, sizeof (struct pins));`) and just use `0` to zero each byte. – David C. Rankin Jan 24 '19 at 09:41
  • @Someprogrammerdude Your suggestion looks interesting. Could you please provide an example? – John Doe Jan 24 '19 at 09:42
  • `Perhaps what you really want is an array?` perhaps uCs does not have unlimited resources – 0___________ Jan 24 '19 at 09:43
  • @DavidC.Rankin I was thinking on that too, but I was not sure is better that what I was asking. – John Doe Jan 24 '19 at 09:43
  • have you tried [this](https://stackoverflow.com/a/2000646/7177029) ? – Kunal Mukherjee Jan 24 '19 at 09:44
  • 1
    @DavidC.Rankin this memset will not work. instead of 1 you need 0xff – 0___________ Jan 24 '19 at 09:44
  • PORTB on `atmega328` has `0` to `5` so my intention is to save space as much as possible. So I tough that probably `const unsigned char LEDS[] = { PB0, PB1, PB2, PB3, PB4, PB5 };` needs more space that a struct with bit-field. – John Doe Jan 24 '19 at 09:46
  • @P__J__ - Thank you -- good catch, yes `memset (&pins, 0xff, sizeof (struct pins));` – David C. Rankin Jan 24 '19 at 09:47
  • I added in the loop an example of what exactly I need to do. – John Doe Jan 24 '19 at 09:59
  • What do you mean by ".. back to `1`" - they were never `1` to go "back to". The initialisation to zero can be achieved in the declaration by `... } pins = {0} ;` – Clifford Jan 24 '19 at 10:09
  • @Clifford Thank you for your suggestion. You are all most there. Please check the EDIT part now. – John Doe Jan 24 '19 at 10:13
  • I recommend that you don't use bit-fields. Instead use simple unsigned integer, and bitwise operations to adjust individual bits. Changing all bits will be simple assignment. – user694733 Jan 24 '19 at 10:15
  • `LED5 ^= ( 1 << 0 );` only sets the bit to 1 if it is not already 1. It flips the bit which is not what the function name suggests. Why not simply `LED5 = 1`? The XOR is wrong, and the shift pointless. Moreover you have not answered by question - your question remains unclear. – Clifford Jan 24 '19 at 10:16
  • The main goal was [to replaces the array in my example](https://stackoverflow.com/questions/54331621/setting-up-interrupts-on-atmega328-in-pure-c/54331887?noredirect=1#comment95482353_54331887) with bit-fields. – John Doe Jan 24 '19 at 10:17
  • @Clifford I think (hope) that the EDIT part does explain it better. – John Doe Jan 24 '19 at 10:18
  • @JohnDoe : Note really, and your insistence that the answer use a loop is an unnecessary constraint. `memset()` will work as already advised. – Clifford Jan 24 '19 at 10:20

1 Answers1

7

having

struct pins
{
    volatile unsigned char state    : 1;
    unsigned char LED0              : 1;
    unsigned char LED1              : 1;
    unsigned char LED2              : 1;
    unsigned char LED3              : 1;
    unsigned char LED4              : 1;
    unsigned char LED5              : 1;
}pins;

to set all to 0 : memset(&pins, 0, sizeof(pins));

to set all to 1 : memset(&pins, -1, sizeof(pins));

and probably the memset will be optimize to just set one byte


To help John Doe :

#include <stdio.h>
#include <string.h>

struct pins
{
    volatile unsigned char state    : 1;
    unsigned char LED0              : 1;
    unsigned char LED1              : 1;
    unsigned char LED2              : 1;
    unsigned char LED3              : 1;
    unsigned char LED4              : 1;
    unsigned char LED5              : 1;
} pins;

void pr()
{
  printf("%u %u %u %u %u %u %u\n",
     pins.state, pins.LED0, pins.LED1, pins.LED2, pins.LED3, pins.LED4, pins.LED5);
}

int main()
{
  /* pins is already to 0 because static */
  memset(&pins, -1, sizeof(pins));
  pr();
  memset(&pins, 0, sizeof(pins));
  pr();
  memset(&pins, -1, sizeof(pins));
  pr();

  return 0;
}

Execution :

1 1 1 1 1 1 1
0 0 0 0 0 0 0
1 1 1 1 1 1 1
bruno
  • 32,421
  • 7
  • 25
  • 37
  • And that value 255, where does it come from? – Dominique Jan 24 '19 at 09:51
  • @Dominique 255 has all its bits to 1, 0xff in hexadecimal and 11111111 in binary – bruno Jan 24 '19 at 09:51
  • Not all bits. if a byte has `8` bit: then `0` means `0000 0000` and what i need for one is `0000 0001` for all variables. Think of this: `uint8_t led = 0:` this means `0000 0000` then if I do `led ^= ( 1 << 0 );` I get `0000 0001` and this is what I need. – John Doe Jan 24 '19 at 09:52
  • I need to set all to `0000 0000` and `0000 0001`. Because I use Bit-field, I have only on bit, so this BIT should be `0` and `1` – John Doe Jan 24 '19 at 09:53
  • @Dominique I edited to use -1 to be compatible with any size of byte up to an int (even that is stupid of course) – bruno Jan 24 '19 at 09:57
  • `and probably the memset will be optimize to just set one byte` I need only one BIT not the whole BYTE – John Doe Jan 24 '19 at 09:58
  • @JohnDoe you request to set state and all the LEDi to 0 or 1 no ? This what I do – bruno Jan 24 '19 at 09:59
  • When I use this: `memset(&pins, 0, sizeof(pins));` then the variables are `0000 0000` and when I use this: `memset(&pins, -1, sizeof(pins));` then tha variables becomes `1111 1111` am I right? If so, then is wrong. I need to be `0000 0000` and `0000 0001`. But I think that is not possible. – John Doe Jan 24 '19 at 10:02
  • @Dominique You are right. I do not need `255`. What I need is that `0` to become `1` and not `255`. – John Doe Jan 24 '19 at 10:03
  • @JohnDoe I edited my answer to put a full programm and execution – bruno Jan 24 '19 at 10:08
  • @JohnDoe: Each one of your fields is a single bit in length (and most likely shares storage with the other fields). Setting the entire structure to be all 1s is equivalent to your function. I'd usually use `~0` (i.e. NOT 0) instead of `-1` for clarity though. – Hasturkun Jan 24 '19 at 10:09
  • No, that is not what I need. I do not need `1 1 1 1 1 1 1` I need `0000 0001` Please read my EDITED Question. – John Doe Jan 24 '19 at 10:09
  • 2
    @JohnDoe : You have not understood this answer; by setting all _bytes_ occupied by the structure to all ones, the single bit-fields will implicitly become `1` because they are _packed_ into those _bytes_. You could just try it. Note that I's suggest `~0` rather then `-1`, but either will work. – Clifford Jan 24 '19 at 10:13
  • @Clifford Oh I did not understand that indeed . Sorry Guys. :D – John Doe Jan 24 '19 at 10:15