I want an array to have two different values, based on a condition. I can initialize the array inside the condition with the values i want.
if (myCondition == 0)
{
byte my_message[8] = {0x00, 0xAB, 0xEE, 0xFF, 0x00, 0x01, 0x0A, 0x0B};
}
else if (myCondition == 1)
{
byte my_message[8] = {0x11, 0xA1, 0xBC, 0x71, 0x00, 0x02, 0x94, 0x10};
}
The problem with the previous approach is that the array has local scope, and it cannot be "seen" by the code beneath.
If I try to declare the array outside the condition with:
byte my_message[8];
then, inside the condition, I cannot use the previous way of initializing the whole array all at once.
There is no pattern in the data so I can use a for
loop- inside the condition- in order to give value to each element of the array easily.
Is there a way of giving values to the array, besides the cumbersome:
if (myCondition == 0)
{
my_message[0] = {0x00};
my_message[1] = {0xAB};
my_message[2] = {0xEE};
....
}
CodePudding user response:
In C you can use standard function memcpy
and compound literals the following way
byte my_message[8];
if (myCondition == 0)
{
memcpy( my_message, ( byte [] ){0x00, 0xAB, 0xEE, 0xFF, 0x00, 0x01, 0x0A, 0x0B}, 8 * sizeof( byte ));
}
else if (myCondition == 1)
{
memcpy( my_message, ( byte[] ){0x11, 0xA1, 0xBC, 0x71, 0x00, 0x02, 0x94, 0x10}, 8 * sizeof( byte ) );
}
In C it is better to use std::array
instead of a raw array. For example
std::array<byte, 8> my_message;
if (myCondition == 0)
{
my_message = {0x00, 0xAB, 0xEE, 0xFF, 0x00, 0x01, 0x0A, 0x0B};
}
else if (myCondition == 1)
{
my_message = {0x11, 0xA1, 0xBC, 0x71, 0x00, 0x02, 0x94, 0x10};
}
Or if to use a raw array then if the compiler supports C 20 then you can use the range based for loop the following way
byte my_message[8];
if (myCondition == 0)
{
for ( auto *p = my_message; auto item : {0x00, 0xAB, 0xEE, 0xFF, 0x00, 0x01, 0x0A, 0x0B} )
{
*p = item;
}
}
else if (myCondition == 1)
{
for ( auto *p = my_message; auto item : {0x11, 0xA1, 0xBC, 0x71, 0x00, 0x02, 0x94, 0x10} )
{
*p = item;
}
}
Otherwise if the compiler does not support C 20 then this declaration
auto *p = my_message;
must be moved outside the range based for loop.
CodePudding user response:
If my_message
isn't changed, you could use a pointer instead of an array.
const byte my_messages[2][8] = {
{ 0x00, 0xAB, 0xEE, 0xFF, 0x00, 0x01, 0x0A, 0x0B },
{ 0x11, 0xA1, 0xBC, 0x71, 0x00, 0x02, 0x94, 0x10 },
};
const byte *my_message = my_messages[ myCondition ];
If you need to be able to change my_array
, I'd use the following:
const byte my_messages[2][8] = {
{ 0x00, 0xAB, 0xEE, 0xFF, 0x00, 0x01, 0x0A, 0x0B },
{ 0x11, 0xA1, 0xBC, 0x71, 0x00, 0x02, 0x94, 0x10 },
};
byte my_message[8];
memcpy( my_message, my_messages[ myCondition ], sizeof( my_message ) );
You could memcpy from an anonymous array, but it's overly complicated and involves code repetition:
byte my_message[8];
if ( myCondition ) {
memcpy( my_message, ( byte[] ){ 0x11, 0xA1, 0xBC, 0x71, 0x00, 0x02, 0x94, 0x10 }, sizeof( my_message) );
} else {
memcpy( my_message, ( byte[] ){ 0x00, 0xAB, 0xEE, 0xFF, 0x00, 0x01, 0x0A, 0x0B }, sizeof( my_message) );
}
CodePudding user response:
- You can wrap the message into the struct and use assign operator with compound literal.
- You can use compound literal
memcpy
typedef unsigned char byte;
typedef struct
{
byte my_message[8];
}message_t;
int foo(int myCondition)
{
message_t my_message;
if (myCondition == 0)
{
my_message = (message_t){0x00, 0xAB, 0xEE, 0xFF, 0x00, 0x01, 0x0A, 0x0B};
}
else if (myCondition == 1)
{
my_message = (message_t){0x11, 0xA1, 0xBC, 0x71, 0x00, 0x02, 0x94, 0x10};
}
return 0;
}
int bar(int myCondition)
{
byte my_message[8];
if (myCondition == 0)
{
memcpy(my_message, (byte[]){0x00, 0xAB, 0xEE, 0xFF, 0x00, 0x01, 0x0A, 0x0B}, sizeof(my_message));
}
else if (myCondition == 1)
{
memcpy(my_message, (byte[]){0x11, 0xA1, 0xBC, 0x71, 0x00, 0x02, 0x94, 0x10}, sizeof(my_message));
}
return 0;
}
or you can myCondition
as index:
int zoo(int myCondition)
{
byte my_message[8];
memcpy(my_message,
(byte[][8]){{0x00, 0xAB, 0xEE, 0xFF, 0x00, 0x01, 0x0A, 0x0B},
{0x11, 0xA1, 0xBC, 0x71, 0x00, 0x02, 0x94, 0x10}}[myCondition],
sizeof(my_message));
return 0;
}
memcpy
way looks the most efficient: