Reputation: 37
I have a function foo
which processes the elements of an array whose size is user defined.
This function needs two parameters (not necessarily two separate arguments, or so do I think) - a pointer to the array and size of the array.
Are the three methods used below to the call the function valid?
int size; // Obtained from user
int arr[size];
foo(int (*arr)[size]); // Will size be available as a vairable inside foo ?
foo(int (*arr)[],size);
foo(int (*arr)[size],size); // Is the 2nd parameter redundant here ?
Upvotes: 2
Views: 1754
Reputation: 153468
3 approaches
Pass array and size. (in any order.) b
will convert to the type and address of its first element - this becomes a
. sizeof b/sizeof b[0]
will take on the value of 42 - useful to not repeat 42 all over the place. foo1
receives a pointer the the first element of the array and knows the array element count.
void foo1(int *a, size_t n);
size_t sz = 42;
int b[sz];
foo1(b, sizeof b/sizeof b[0]);
Pass a pointer to an fixed sized array. The address of a fixed sized array is passed to foo2()
. foo2()
can use (*d)[0]
to access the first array element and (*d)[41]
for the last element. foo2()
does not have to get receive the array element count, because the array element is known and fixed at 42.
void foo2(int (*d)[42]);
int e[42];
foo2(&e);
int f[13];
foo2(&f); // invalid
Pass the dimensions then a variable-length array. VLA is available in C99 and optionally in C11. Notice that foo3()
understands d2
in accessing arr[i][j]
, but does not know arr
outer dimension is d1
, even if /* d1 */
was replaced with d1
.
void foo3(size_t d1, size_t d2, char arr[/* d1 */][d2]) {
char x = 0;
for (size_t i=0; i<d1; i++) {
for (size_t j=0; j<d2; j++) {
arr[i][j] = ++x;
}
}
}
void foop(size_t d1, size_t d2, char arr[/* d1 */][d2]) {
printf("ptr size:%zu, sub-array size:%zu, element size:%zu |",
sizeof arr, sizeof arr[0], sizeof arr[0][0]);
for (size_t i=0; i<d1; i++) {
for (size_t j=0; j<d2; j++) {
printf(" %d", arr[i][j]);
}
}
printf("\n");
}
int foo2(int (*arr)[42]) {
printf("%zu\n", sizeof *arr);
return 0;
}
#define SZ(a) (sizeof(a)/sizeof((a)[0]))
int main() {
char a[2][3];
char b[4][5];
foo3(SZ(a),SZ(a[0]), a);
foop(SZ(a),SZ(a[0]), a);
foo3(SZ(b),SZ(b[0]), b);
foop(SZ(b),SZ(b[0]), b);
}
Sample output
ptr size:4, sub-array size:3, element size:1 | 1 2 3 4 5 6
ptr size:4, sub-array size:5, element size:1 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
If a fixed array is needed, the array sizes may be omitted, depending on how the data is passed.
For a variable sized array, the dimensions need to be passed in some fashion.
Arrays may also be passed as a field of a struct/union
- not shown.
Upvotes: 0
Reputation: 717
In C, the size is not part of the array "object". Therefore, idiomatic C code passes the size of an array along with the array itself:
foo(arr, size);
for function
void foo(int arr[], int size);
(in the case of an array of integers).
See for example the main
function:
int main(int argc, char *argv[]);
(Note the arguments are reversed here.)
Upvotes: 1