stepper_m
stepper_m

Reputation: 63

C array with structs - cannot change variable

Can anybody explain why

all_leds[0].pattern = 3;

and

all_leds[1].pattern = 4;

do nothing ?

#include <stdio.h>

int main(void)
{
    struct Led
    {
      int pin;
      int pattern;
    };

    struct Led led_1 = {1, 1};
    struct Led led_2 = {2, 2};

    printf("%d\n", led_1.pattern);  // prints 1
    printf("%d\n", led_2.pattern);  // prints 2

    struct Led all_leds[2];
    all_leds[0] = led_1;
    all_leds[1] = led_2;

    printf("%d\n", led_1.pattern);  // prints 1
    printf("%d\n", led_2.pattern);  // prints 2

    all_leds[0].pattern = 3;
    all_leds[1].pattern = 4;

    printf("%d\n", led_1.pattern);    // prints 1 ????
    printf("%d\n", led_2.pattern);    // prints 2 ????

    return 0;
}

Upvotes: 1

Views: 59

Answers (4)

Vlad from Moscow
Vlad from Moscow

Reputation: 310940

In these statements

printf("%d\n", led_1.pattern);    // prints 1 ????
printf("%d\n", led_2.pattern);    // prints 2 ????

you are ouputing data members of structures led_1 and led_2. However in these statements

all_leds[0].pattern = 3;
all_leds[1].pattern = 4;

You changed elements of array all_leds. The array and object led_1 and Led_2 are different objects and occupy different areas of memory. So changing one object does not influence on other object.

Maybe you mean the following

printf("%d\n", all_leds[0].pattern);    // prints 1 ????
printf("%d\n", all_leds[1].pattern);    // prints 2 ????

Or you could define an array of pointers to structures. For example

struct Led *all_leds[2];
*all_leds[0] = &led_1;
*all_leds[1] = &led_2;

In this case after statements

all_leds[0]->pattern = 3;
all_leds[1]->pattern = 4;

and

printf("%d\n", led_1.pattern);    // prints 1 ????
printf("%d\n", led_2.pattern);    // prints 2 ????

you would get the expected result.

Upvotes: 0

stepper_m
stepper_m

Reputation: 63

Ok, i figured out this one and it works as expected:

#include <stdio.h>

int main(void)
{
    struct Led
    {
      int pin;
      int pattern;
    };

    struct Led led_1 = {1, 1};
    struct Led led_2 = {2, 2};
    printf("%d\n", led_1.pattern);
    printf("%d\n", led_2.pattern);

    struct Led * all_leds[2];
    all_leds[0] = &led_1;
    all_leds[1] = &led_2;

    printf("%d\n", led_1.pattern);
    printf("%d\n", led_2.pattern);

    all_leds[0] -> pattern = 3;
    all_leds[1] -> pattern = 4;
    printf("%d\n", led_1.pattern);
    printf("%d\n", led_2.pattern);

    return 0;
}

Upvotes: 0

jwde
jwde

Reputation: 650

You are copying the values of led_1 and led_2 into your struct array. If you want them to be the same objects you should make your array an array of pointers to structs then you can update them by reference.

#include <stdio.h>

int main(void)
{
    struct Led
    {
      int pin;
      int pattern;
    };

    struct Led led_1 = {1, 1};
    struct Led led_2 = {2, 2};

    printf("%d\n", led_1.pattern);  // prints 1
    printf("%d\n", led_2.pattern);  // prints 2

    struct Led *all_leds[2];
    all_leds[0] = &led_1;
    all_leds[1] = &led_2;

    printf("%d\n", led_1.pattern);  // prints 1
    printf("%d\n", led_2.pattern);  // prints 2

    all_leds[0]->pattern = 3;
    all_leds[1]->pattern = 4;

    printf("%d\n", led_1.pattern);   
    printf("%d\n", led_2.pattern);    

    return 0;
}

Upvotes: 1

cdhowie
cdhowie

Reputation: 168988

Led is a value type (as are all types in C; it has no reference types like C++ has) so when you say all_leds[0] = led_1; you are copying the struct value in led_1 into the first element of all_leds. After this line, all_leds[0] and led_1 remain separate values with no connection to each other. Modifying one will not modify the other.

Instead, you can fill all_leds with pointers to the Led values.

struct Led * all_leds[2] = { &led_1, &led_2 };
// ...
all_leds[0]->pattern = 3;
all_leds[1]->pattern = 4;

Upvotes: 2

Related Questions