Hi Juergen,
Jürgen Hochwald wrote:
Maybe this is a simple question, but I don't know how to solve.
Background: A weather station connected to the serial port sends data
packets. This data packets are containing variables fom one byte up to 4
byted in mixed order. Now I want to define a structure to overlay it with
UNION over the receive buffer for easily access to the single values in the
data packet.
The problem is, that I cannot defind a variable, which only reserves one
byte of memory. A simple 'char' or 'char[1]' eats 4 bytes and all following
variables are not matching.
How can I define a variable, which uses exactly one byte ?
Here is a small text app:
------------------------------------------
#include <stdio.h>
#include <stdlib.h>
struct data {
int i;
char c;
int j;
};
union ovr {
struct data d;
char c[16];
};
int main(void) {
union ovr d;
int l;
for (l=0;l<16;l++)
d.c[l]=l;
printf("size=%d\n",sizeof(d));
printf("i=%X\n",d.d.i);
printf("c=%X\n",d.d.c);
printf("j=%X\n",d.d.j);
}
--------------------------------
and the output:
size=16
i=3020100
c=4
j=B0A0908
To overlay the data packet correct, j must be 8070605.
There are several issues here:
- If you want to access something bytewise, use unsigned char
- The size of a char/signed char/unsigned char _always_ is one
byte
- A byte is not necessarily eight bit but at least so much.
Check the symbolic constant CHAR_BIT from <limits.h> to find
out the exact ratio
If you have a C99 compiler with the integer types in <stdint.h>,
then you can use the type uint8_t. 8 Bits often are referred to
as "octet"
- sizeof(int)>=sizeof(unsigned char), so your assumptions about
a certain ratio may be wrong
- In a structure, there may be padding bytes between the members
if there are alignment requirements. If sizeof(int) > 1 and
ints have to be sizeof(int)-aligned (that is, their address
can be divided by sizeof(int) without remainder), then there
are probably sizeof(int)-1 padding bytes between the c and j
members of your structure.
As an aside: If you have larger structures then it makes sense
to put the variables with the largest type first and then go
down in size -- this often leads to smaller structures.
- The bytes of types with size >1 are not necessarily ordered as
you assume. Thus,
unsigned int i=1;
unsigned char lowestbyte=((unsigned char *)&i)[0];
may yield lowestbyte==1 or lowestbyte==0.
So, check the necessary size, use
union ovr {
struct data d;
unsigned char c[sizeof(struct data)];
};
or do not use a union at all but access the structure representation
directly, find out the byte order (or: rather use shifting and masking
instead of access by unsigned char for portable code), and so on.
BTW: The offsetof macro yields the offset in bytes of a member of
a structure with respect to the start of the structure.
The comp.lang.c FAQ addresses several of these issues in detail.
It has been posted here on November 1 and can also be found at
http://www.eskimo.com/~scs/C-faq/top.html
The ASCII version is up to date, unlike the HTML version.
HTH
Michael
--
E-Mail: Mine is an /at/ gmx /dot/ de address.