I would like to define a custom structure that contains two dynamically allocatable integer arrays a
and b
. In order to allocate memory for the arrays and initialise arrays with values I have written a "constructor" function initp
. My approach is presented below.
A custom structure called pair
:
typedef struct {
...
int l; // length of compositions
int k; // no. of elements in compositions
int *a; // composition 1
int *b; // composition 2
} pair;
A function to initialise custom structure:
int initp(..., int l, int k, int a[], int b[], pair *f) {
...
f->l = l;
f->k = k;
// allocate composition arrays
f->a = (int *) calloc(l, sizeof(int));
f->b = (int *) calloc(l, sizeof(int));
// initialise composition arrays
for (int i = 0; i < k; i++) {
f->a[i] = a[i];
f->b[i] = b[i];
}
}
A function call in the main program:
// initialise pairs
pair f1, f2;
initp(..., 10, 2, (int[]){3, 4}, (int[]){7, 6}, &f1);
initp(..., 10, 1, (int[]){4}, (int[]){9}, &f2);
I'm on a mission to write an "elegant" code. Therefore, the questions I have are:
a
and b
passed to the initp
? This is the parameter k
. In the above examples it is 2 and 1.(int[])
in the function call?Is it possible to avoid specifying the no. of elements in arrays
a
andb
passed to theinitp
?
No.
Alternative: Create a macro INITP(l, a, b, f)
with macro magic determines the a
, b
are truly arrays, their array element counts, insure their counts are equal and then calls initp()
.
I am not fan of this approach, but it is do-able - with limitations.
Note: for size information, consider size_t
vs. int
.
Is it possible to avoid "explicit" casting with (int[]) in the function call?
With (int[]){3, 4}
, (int[])
is not a cast. It is simply the form of a compound literal and is required to form one.
if you have general comments and criticism on improving the quality of the code.
For working code, consider Code review for a deeper review.
I'd assign each array in turn - usually as fast or faster than interlacing.
memcpy(f->a, a, sizeof f->a[0] * k);
memcpy(f->b, b, sizeof f->b[0] * k);
Handle allocation failures.
Create a initp()
companion like void uninitp(pair *f)
.
Improve allocation for clarity, review and maintenance.
// f->a = (int *) calloc(l, sizeof(int));
f->a = calloc(l, sizeof f->a[0]);
const
, restrict
considerations.
Hmmm, this is getting to be too full a review for here, so will end now.