part of c programming
sometimes it would be useful to assign array content literally by listing the contents. something like this is possible in most scripting languages:
a = [1, 2, 3, 4]
but c is limited and the following shows some possible options and alternatives.
example:
int a[] = {1, 2, 3};
can only be used once where a variable is defined
can only be used for stack arrays, not for heap arrays (allocated by malloc, etc)
can be passed to and accessed in sub-functions
can not be accessed after the declaring function has returned unless declared as a static variable
type names like int[4][2] come with restrictions on the types that variables and function parameters using the type can have. at least the last dimension has to be provided in types, for example int arr[][2]. pointers can be used for more flexibility
#include could be used to keep large definitions in a separate file and include the definitions where needed
this method can also be used to define nested arrays:
int a[3][2] = {{1, 2}, {3, 4}, {5, 6}};
more information:
struct int_array3 { int data[3]; } struct int_array3 x = {.data = {1, 2, 3}}
int* int_array4(int a, int b, int c, int d) { int* x = malloc(4 * sizeof(int)); if (!x) return 0; x[0] = a; x[1] = b; x[2] = c; x[3] = d; return x; }
int* e = int_array4(2, 3, 4, 5);
memory allocation can fail, therefore the question of how to handle this failure arises.
this interface is similar to malloc, which also just returns a null pointer on failure.
no further error checking code is needed, nor relevant, with this option. this option does not compose well because it exits the using process, which tends to be particularly undesirable when the code is used as part of a library.
example, inside the array creating function:
if (!x) exit(1);
needs a temporary variable and a local goto label
int* x = int_array4(1, 2, 3, 4); if (!x) goto exit;
#define array_set4(x, a, b, c, d) x[0] = a; x[1] = b; x[2] = c; x[3] = d;
int* x = malloc(4 * sizeof(int)); if (!x) exit(1); array_set4(x, 2, 3, 4, 5);