Passing a struct member to a function question!

Go To Last Post
16 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Is it possible to pass a struct member as the variable to another function...kinda of like this

typedef char  byte; // 1byte
typedef unsigned short  word; // 2bytes
char buffer[8];
struct button
{
	uint16_t left;
	uint16_t top;
	uint8_t pressed;
	word text_color;
	word back_color;
	word press_color;
}One, Two, Three, Four, Five;

//what i am wondering if can be done somehow!!!

sprintf(buffer,"something");
Draw_Button(x);

void Draw_Button(x)
{
    FillRoundRect(x.left,x.top,x.left+164,x.top+42);
		SetColor1(x.text_color);
		tft_print(buffer,(x.left+30),(x.top+14));
}

Or do i have to do something like this


Draw_Button(One.left,One.top,One.pressed,One.Text_Color,One.back_color,One.press_color);

void Draw_Button(uint16_t left,uint16_t top,uint8_t press,word tcolor,word bcolor,word pcolor)
{
    FillRoundRect(left,top,left+164,top+42);
		SetColor1(tcolor);
		tft_print(buffer,(left+30),(top+14));
}
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

You can use a pointer:

void Draw_Button(struct button *x)
{
    FillRoundRect(x->left,x->top,x->left+164,x->top+42);
    ...
}

If you are determined to use the dot notation:

void Draw_Button(struct button *y)
{
    struct button x = *y;    //copy argument's contents to a local struct
    FillRoundRect(x.left,x.top,x.left+164,x.top+42);
    ...
}

Your other function is obviously ok, but pretty long-winded.
Using a pointer seems more intuitive to me.

David.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

david.prentice wrote:
You can use a pointer:

void Draw_Button(struct button *x)
{
    FillRoundRect(x->left,x->top,x->left+164,x->top+42);
    ...
}

If you are determined to use the dot notation:

void Draw_Button(struct button *y)
{
    struct button x = *y;    //copy argument's contents to a local struct
    FillRoundRect(x.left,x.top,x.left+164,x.top+42);
    ...
}

Your other function is obviously ok, but pretty long-winded.
Using a pointer seems more intuitive to me.

David.

Perfect that what i was looking for something easy instead of having to type in 10 variables!!!!

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Okay so i just tried that and i get this error!

Error	1	2622 : passing 'struct button' to parameter of incompatible type 'struct button *'; take the address with &	

not sure what it means
this is what i did to get this error


Draw_Button(One);

void Draw_Button(struct button *z)

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Figured it out i need to do the following

Draw_Button(&One);

void Draw_Button(struct button *z)

thanks for the quick and easy answer

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

One more quick question for struct use....i am trying to initialize my struct with values and getting an error but not quite sure how to fix

Error	1	expected expression before '{' token
Error	2	 968 : expected expression	
   One = {610,28,0,0x0000,0xFFFF,0x360E};//should this not be the same as whats below....this is were the compiler points me to
	One.left = 610;
	One.top = 28;
	One.pressed = 0;
	One.text_color = 0x0000;
	One.back_color = 0xFFFF;
	One.press_color = 0x360E;
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

You can't say One = {...}
You can only do it in a declaration e.g.

struct button One = { ... };

You should find all the semantics in your C textbook.

If your textbook weighs more than 25kg, buy a K&R. It is worth every penny. And it is very well written that it is a nice slim volume.

David.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

david.prentice wrote:
You can't say One = {...}
You can only do it in a declaration e.g.

struct button One = { ... };

You should find all the semantics in your C textbook.

If your textbook weighs more than 25kg, buy a K&R. It is worth every penny. And it is very well written that it is a nice slim volume.

David.

I tried

struct button Menu = {610,28,0,0x0000,0xFFFF,0x360E};

and recieved

Error	1	expected expression before '{' token	

the book i have atm is embedded C programing and the atmel avr by banett cox and o'cull its a pretty good book and has the same info as you posted but i am still recieving that error!

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

weird i did cleaned the project and now it works fine...Thanks

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Note that C99 has a nice extension (assuming you use -std=c99 or -std=gnu99) in that you can used named initialisers. Thus:

typedef struct
{
   uint16_t left;
   uint16_t top;
   uint8_t pressed;
   word text_color;
   word back_color;
   word press_color;
} button_t;

button_t One = {
 .text_color = 0xFFFF,
 .press_color = 0x360E,
 .left = 610
};

You don't have to give all the fields and you don't have to list them in order.

Another feature you might find useful given that you were going to call them "One", "Two", "Three".. would be to make an array of struct and you can even use designated initialisers on that:

button_t Buttons[5] = {
 [2].pressed = 0,
 [4].back_color = 0x0000
etc.
};

If you want more "traditional" initialisation use:

button_t Buttons[5] = {
 {610,28,0,0x0000,0xFFFF,0x360E},
 {400,40,0,0xFFFF,0x0000,0xABCD},
 {610,28,0,0x0000,0xFFFF,0x360E},
 {610,28,0,0x0000,0xFFFF,0x360E},
 {610,28,0,0x0000,0xFFFF,0x360E}
};

To use the array elements with your function should be as simple as:

Draw_Button(&Buttons[2]);

BTW you may have noticed I typedef'd the struct type. This means that the interface to your drawing routine can be:

void Draw_Button(button_t *but) {
  but->pressed = 1;
}

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

You have always been able to initialise a structure in its declaration/definition.

Can you do a subsequent assignment statement ? Especially with partial members.

Likewise, you have always been able to copy a complete structure with a simple assignment. Otherwise, you have to assign each member individually.

Untested. I suppose that I should try your assignment statements for myself.

David.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

This:

#include 

typedef unsigned short word;

typedef struct
{
	uint16_t left;
	uint16_t top;
	uint8_t pressed;
	word text_color;
	word back_color;
	word press_color;
} button_t;

button_t One = {
	.text_color = 0xFFFF,
	.press_color = 0x360E,
	.left = 610
};

int main(){
	while(1){
	}
}

leads to this:

	.type	One, @object
	.size	One, 11
One:
	.word	610
	.zero	3
	.word	-1
	.zero	2
	.word	13838

(-1 = 0xFFFF, 13838 = 0x360E)

And this:

button_t Buttons[5] = {
	[2].pressed = 37,
	[4].back_color = 12345
};

leads to this:

Buttons:
	.zero	22
	.zero	4
	.byte	37
	.zero	6
	.zero	11
	.zero	7
	.word	12345
	.zero	2

Interesting that it conglomerates the first two Buttons[0]/[1] into ".zero 22" but not the 6/11/7 in the middle which is the end of one, the whole of the next and the start of the one that follows.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Sureley this is an initialisation:

button_t One = {
   .text_color = 0xFFFF,
   .press_color = 0x360E,
   .left = 610
};

But this would be an assignment statement to an existing global struct:

int main(){
   One = { .pressed = 37, .text_color = 0x1234 }; 
   while(1){
   }
} 

Obviously this would work:

int main(){
   One.pressed = 37;
   One.text_color = 0x1234; 
   while(1){
   }
} 

I have not got avr-gcc 'open' at the moment. I should really try it for myself.

David.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Yes, I'm talking about compile time initialisation in the variable definition. I don't know of any run time mechanism to "block initialise" structs apart from individual member assignments (or a memset/memcpy of some/all of the whole thing I suppose?).

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

You can use compound literals:

One = (button_t){ .pressed = 42 };

Stefan Ernst

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Oh yeah, never knew that was possible:

#include 

typedef unsigned short word;

typedef struct
{
	uint16_t left;
	uint16_t top;
	uint8_t pressed;
	word text_color;
	word back_color;
	word press_color;
} button_t;

button_t Buttons[5] = {
	[2].pressed = 37,
	[4].back_color = 12345
};

int main(){
	Buttons[3] = (button_t){ .pressed = 42, .text_color=23232 }; 
	while(1){
	}
}

the runtime bit generates:

//==> 	Buttons[3] = (button_t){ .pressed = 42, .text_color=23232 }; 
	ldi r24,lo8(11)
	ldi r30,lo8(Buttons+33)
	ldi r31,hi8(Buttons+33)
	movw r26,r30
	0:
	st X+,__zero_reg__
	dec r24
	brne 0b
	ldi r24,lo8(42)
	sts Buttons+37,r24
	ldi r24,lo8(-64)
	ldi r25,lo8(90)
	sts Buttons+38+1,r25
	sts Buttons+38,r24

Oh and:

int main(){
	Buttons[3] = (button_t){ 610,28,0,0x0000,0xFFFF,0x360E }; 
	while(1){
	}
}

leads to:

	.section	.rodata
.LC0:
	.word	610
	.word	28
	.byte	0
	.word	0
	.word	-1
	.word	13838

...

//==> 	Buttons[3] = (button_t){ 610,28,0,0x0000,0xFFFF,0x360E }; 
	ldi r24,lo8(11)
	ldi r30,lo8(.LC0)
	ldi r31,hi8(.LC0)
	ldi r26,lo8(Buttons+33)
	ldi r27,hi8(Buttons+33)
	0:
	ld r0,Z+
	st X+,r0
	dec r24
	brne 0b