Array Initialisation in C using Typedefs - c

Getting an odd error trying to initialise an array in C - anyone know why this might happen?
I have a global variable:
static my_type foo[6];
And in an included header file, I have:
typedef uint32_t my_type[5];
I then in a function in the same file as the global variable try to do:
foo = {{1, 2, 3, 4, 5}, {1, 2, 3, 4, 6}, {1, 2, 3, 4, 7}, {1, 2, 3, 4, 8}, {1, 2, 3, 4, 9}, {1, 2, 3, 4, 10}};
The compiler (GCC4) gives the error 'expected expression before '{' token'.
Anyone know what's gone wrong and how to fix it?
Cheers!

That's not initialization, that's assignment. Initialization has to be a single statement:
static my_type foo[6] = {{1, 2, 3, 4, 5},
{1, 2, 3, 4, 6},
{1, 2, 3, 4, 7},
{1, 2, 3, 4, 8},
{1, 2, 3, 4, 9},
{1, 2, 3, 4, 10}};
You cannot assign to a whole array in C89 with this syntax. What you can do is memcpy from a const:
void initialize_foo()
{
static const my_type init[6] =
{{1, 2, 3, 4, 5},
{1, 2, 3, 4, 6},
{1, 2, 3, 4, 7},
{1, 2, 3, 4, 8},
{1, 2, 3, 4, 9},
{1, 2, 3, 4, 10}};
assert(sizeof(foo) == sizeof(init));
memcpy(foo, init, sizeof(foo));
}

If you are under C99:
ISO C99 supports compound literals. A compound literal looks like a
cast containing an initializer. Its value is an object of the type
specified in the cast, containing the elements specified in the
initializer; it is an lvalue. As an extension, GCC supports compound
literals in C89 mode and in C++.
But foo must be a pointer
#include <stdio.h>
#include <stdint.h>
typedef uint32_t my_type[5];
int main(void)
{
int i, j;
my_type *foo;
foo = ((my_type[]) {
{1, 2, 3, 4, 5},
{1, 2, 3, 4, 6},
{1, 2, 3, 4, 7},
{1, 2, 3, 4, 8},
{1, 2, 3, 4, 9},
{1, 2, 3, 4, 10}
});
for (i = 0; i < 6; i++) {
for (j = 0; j < 5; j++) {
printf("%d ", foo[i][j]);
}
printf("\n");
}
return 0;
}

Related

size of two dimension array

int main()
{
int a[3][4] = {
{0, 1, 2, 3} , // initializers for 0 row
{4, 5, 6, 7} , // initializers for 1 row
{8, 9, 10, 11} // initializers for 2 row
};
int b[3][4] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11};
printf("size of *a = %ld\n", sizeof(*a));
printf("size of *b = %ld\n", sizeof(*b));
//these prints out 16.
//why is this 16?
Hello, I am learning c in school and I have a question.
why is the size of a(and b) 16?? How does it work?

Determine the type of an array which stores the pointer to other arrays of different dimensions

I have many constant 2D arrays of all possible permutation of integer in [0,LEN) for many LEN:
static const char permu2[][2] = {{0, 1}, {1, 0}};
static const char permu3[][3] = {{0, 1, 2}, {0, 2, 1}, {1, 0, 2},
{1, 2, 0}, {2, 0, 1}, {2, 1, 0}};
static const char permu4[][4] = {
{0, 1, 2, 3}, {0, 1, 3, 2}, {0, 2, 1, 3}, {0, 2, 3, 1}, {0, 3, 1, 2},
{0, 3, 2, 1}, {1, 0, 2, 3}, {1, 0, 3, 2}, {1, 2, 0, 3}, {1, 2, 3, 0},
{1, 3, 0, 2}, {1, 3, 2, 0}, {2, 0, 1, 3}, {2, 0, 3, 1}, {2, 1, 0, 3},
{2, 1, 3, 0}, {2, 3, 0, 1}, {2, 3, 1, 0}, {3, 0, 1, 2}, {3, 0, 2, 1},
{3, 1, 0, 2}, {3, 1, 2, 0}, {3, 2, 0, 1}, {3, 2, 1, 0}};
static const char permu5[][5] = {{0, 1, 2, 3, 4}, {0, 1, 2, 4, 3}, {0, 1, 3, 2, 4}, /*... */}
// and many more as you can imagine...
And I'd like to store the pointers to those arrays in another array:
static const char *permu[] = {0, 0, permu2, permu3, permu4,
permu5, permu6, permu7, permu8};
static const int fac_seq[] = {1, 1, 2, 6, 24, 120,
720, 5040, 40320, 362880, 3628800, 39916800};
So that for a given LEN=n, I can access those constants in this way:
const int n = 8;
for ( size_t i = 0; i < fac_seq[n]; i++ ) {
for ( size_t j = 0; j < n; j++ ) {
printf( "%2d", *( permu[n] + n*i + j ) );
}
putchar( '\n' );
}
Although this will compile and work correctly, the compiler (gcc) complains like:
30.c:1966:47: warning: initialization from incompatible pointer type [-Wincompatible-pointer-types]
static const char *permu[] = {0, 0, permu2, permu3, permu4,
^~~~~~
30.c:1966:47: note: (near initialization for ‘permu[2]’)
30.c:1966:55: warning: initialization from incompatible pointer type [-Wincompatible-pointer-types]
static const char *permu[] = {0, 0, permu2, permu3, permu4,
^~~~~~
30.c:1966:55: note: (near initialization for ‘permu[3]’)
What should be the right type for the permu array? I tried const char **permu[] and still got the same warnings.
You could try
static const void *permu[] = { };
You would then have to cast it when accessed.
Alternatively you can make each array one-dimensional and work out the indexing yourself.
The correct declaration is
static const char (*permu[9])[] = {0, 0, permu2, permu3, permu4,
permu5, permu6, permu7, permu8};
permu is an array of 9 pointers to arrays of unknown numbers of const chars. Writing the 9 is optional; it can be inferred from the initializer. You could instead make it an array of pointers to void, as in the other answer, but it's best to preserve as much information as possible. You use it like this:
const int n = 4;
const char (*perms)[n] = permu[n];
for (size_t i = 0; i < fac_seq[n]; i++) {
for (size_t j = 0; j < n; j++) {
printf("%2d", perms[i][j]);
}
putchar('\n');
}
Note that I perform a cast with the assignment to perms. I take a pointer to an array of unknown size and convert it to a pointer where the array size is actually n. This is what allows the double [] syntax later: the type const char[n] has a defined size (sizeof(char)*n), so we know how far we need to skip for perms[i].
Godbolt

Create array of arrays with varying sizes

I'm working on an Arduino project which requires an array of arrays, each with varying sizes. Here are the arrays:
int seg0[6] = {10, 3, 4, 5, 12, 11};
int seg1[2] = {3, 4};
int seg2[5] = {10, 11, 2, 4, 5};
int seg3[5] = {10, 11, 2, 12, 5};
int seg4[4] = {3, 11, 2, 12};
int seg5[5] = {10, 3, 2, 12, 5};
int seg6[6] = {10, 3, 2, 4, 5, 12};
int seg7[3] = {10, 11, 12};
int seg8[7] = {10, 11, 12, 5, 4, 3, 2};
int seg9[6] = {10, 3, 11, 2, 12, 5};
I'd like to have them all in one big array, so that I can enter a number, eg. 8, and then it would give me the array with the index number which was specified (array[0] would give seg0, array[8] would give seg8, etc).
Anyone have any tips?
Thanks
I guess you are asking about dimension array
int seg0[6] = {10, 3, 4, 5, 12, 11};
int seg1[2] = {3, 4};
int seg2[5] = {10, 11, 2, 4, 5};
int seg3[5] = {10, 11, 2, 12, 5};
int seg4[4] = {3, 11, 2, 12};
int seg5[5] = {10, 3, 2, 12, 5};
int seg6[6] = {10, 3, 2, 4, 5, 12};
int seg7[3] = {10, 11, 12};
int seg8[7] = {10, 11, 12, 5, 4, 3, 2};
int seg9[6] = {10, 3, 11, 2, 12, 5};
// Keep all of seg in a dimension array
int* dimention_array[10] = {seg0, seg1, seg2, seg3, seg4, seg5, seg6, seg7, seg8, seg9};
// Print first element of |seg0|
printf("%d", dimention_array[0][0]);

Random numbers from one array to another

I am programming for an embedded board to light up 4 LED's (out of 8).
I want to randomise the ones that are lit, and repeat this process.
Basically, by copying the values from an array of set numbers (the LED bit values), making them random, and inserting them into another array. The second array needs unique values (ie the same 4 LED's, but in a unique random pattern). I need to replicate this x number of times, hence the main while loop.
Currently, I get repeated numbers in the second array. I believe this is because the nested for loops are not breaking properly. I have tried break, making the for loop counters (i/j) maximum value (this causes an infinite loop), and even goto.
So far to no avail. Any corrections or advice on a better way to solve this appreciated!
int main() {
srand(time(NULL)); //Set seed random number
int ledORIGINAL[4] = { 2,4,6,8 }; //Array of defined numbers to use
int led[4] = { 0,0,0,0 }; //Empty array (set to 0's)
int rIndex=0, ledIndex=0, loop=0; //Index variables
bool originalNum = false; //Boolean flag to find original number
while (loop < 2) { //Set how many random arrays you need
while (ledIndex < 4) { //Repeat util all 4 array slots filled
rIndex = rand() % 4; //Get a random index number
if (led[ledIndex] == 0) { //If the array slot is empty
for (int i = 0; i < 4; i++) { //Nested for loops to check number is not already in array
for(int j=0; j<4; j++){
if (led[i] != ledORIGINAL[j]) {
originalNum = true;
}
else {
originalNum = false; //Boolean flag set to false, no need to search further
//i= 4; //Set i to 4 to break outer loop
//j = 4; //Set j to 4 to break inner loop
break;
//goto PLACE;
}
}
}
//PLACE:
if (originalNum) {
led[ledIndex] = ledORIGINAL[rIndex];
ledIndex++;
}
}
}
for (int i = 0; i < 4; i++) {
std::cout << led[i];
led[i] = 0;
}
ledIndex = 0;
loop++;
}
}
strongly suggest replacing the posted code with:
struct fourLeds = { int led[4] };
const struct fourLeds ledTable[] =
{
{8, 7, 6, 5},
{8, 7, 6, 4},
{8, 7, 6, 3},
{8, 7, 6, 2},
{8, 7, 6, 1},
{8, 6, 5, 4},
{8, 6, 5, 3},
{8, 6, 5, 2},
{8, 6, 5, 1},
{8, 6, 4, 3},
{8, 6, 4, 2},
{8, 6, 4, 1},
{8, 6, 3, 2},
{8, 6, 3, 1},
{8, 6, 2, 1},
{8, 5, 4, 3},
{8, 5, 4, 2},
{8, 5, 4, 1],
{8, 4, 3, 2},
{8, 4, 3, 1},
{8, 3, 2, 1},
{7, 6, 5, 4},
{7, 6, 5, 3},
{7, 6, 5, 2},
{7, 6, 5, 1},
....
{7, 5, 4, 3},
{7, 5, 4, 2},
{7, 5, 4, 1},
....
{7, 5, 2, 1},
{7, 4, 3, 2},
{7. 4, 3, 1},
{7, 4, 2, 1},
{7, 3, 2, 1},
{6, 5. 4, 3},
{6, 5, 4, 2},
{6, 5, 4, 1},
{6, 4, 3, 2},
{6, 4, 3, 1},
{6, 3, 2, 1},
{5, 4, 3, 2},
{5, 4, 3, 1},
{5, 4, 2, 1},
{5, 3, 2, 1},
{4, 3, 2, 1},
};
int selection = rand() %( sizeof(ledTable) / sizeof(ledTable[0]) );
then output `ledTable[ selection ]`

C pointers with Structs and 2D Arrays

I am confused on how these C pointers work.
Here is what I am trying to do:
Create a struct that has a row, column, and grid (2d array of predefined size).
typedef struct
{
int row;
int column;
int (*matrix)[GRID_SIZE];
} parameters;
Now I create one
int grid[GRID_SIZE][GRID_SIZE] = {
{6, 5, 3, 1, 2, 8, 7, 9, 4},
{1, 7, 4, 3, 5, 9, 6, 8, 2},
{9, 2, 8, 4, 6, 7, 5, 3, 1},
{2, 8, 6, 5, 1, 4, 3, 7, 9},
{3, 9, 1, 7, 8, 2, 4, 5, 6},
{5, 4, 7, 6, 9, 3, 2, 1, 8},
{8, 6, 5, 2, 3, 1, 9, 4, 7},
{4, 1, 2, 9, 7, 5, 8, 6, 3},
{7, 3, 9, 8, 4, 6, 1, 2, 5}};
parameters *data = (parameters *) malloc(sizeof(parameters));
data->row = 1;
data->column = 2;
data->matrix = grid; // is this right?
int** test = data->matrix; //this is wrong.
My goal is to pass in that struct as data when creating a new thread. I am really clueless on how the pointer system works when creating the 2D array in the struct and then using it later. Any help is appreciated.
Edit... here is my new code.. looks like its working! :)
parameters *data = malloc(sizeof(parameters)); //make sure to free thread after
data->row = 1;
data->column = 2;
data->matrix = grid;
int (*test)[GRID_SIZE] = data->matrix;
printf("first value, %d\n", test[0][0]);
Something like this should work.
Define your struct like this:
typedef struct
{
int row;
int column;
int matrix[GRID_SIZE][GRID_SIZE];
} parameters;
Copy the matrix like this:
memcpy( data->matrix, grid, sizeof(grid) );

Resources