C++ Arrays as Function Arguments

Passing an array as an argument to a function in C

When passing an array as a parameter, this

void arraytest(int a[])

means exactly the same as

void arraytest(int *a)

so you are modifying the values in main.

For historical reasons, arrays are not first class citizens and cannot be passed by value.

Which way is better to pass arrays as function arguments in C?

Which way is better to pass arrays as function arguments in C?

I am going for Door #4. The receiving function needs to know the size.

void myFunction(size_t array_element_count, int *param);

Alternatively code could use a terminating sentinel, but there are no special "I-am-not-an-int" values.

In terms of the below, they emit the same code. This is a style issue. As such, follow the group's style guide. For me I favor size_t array_element_count, int param[array_element_count] as most informative to code's intent.

void myFunction(size_t array_element_count, int *param);
void myFunction(size_t array_element_count, int param[array_element_count]);
void myFunction(size_t array_element_count, int param[]);

In terms of style, f(size, ptr) vs f(ptr, size), I recall reading on the next C rev promoting f(size, ptr). IAC, with more complex arrays and VLA support , the below is useful:

foo(size_t row, size_t col, matrix[row][col]);

Passing an array as a parameter in C

This function declaration

void func(int v[]){
v[0] = 1;
}

is adjusted by the compiler to the declaration

void func(int *v){
v[0] = 1;
}

From the C Standard (6.7.6.3 Function declarators (including prototypes))

7 A declaration of a parameter as ‘‘array of type’’ shall be
adjusted to ‘‘qualified pointer to type’’, where the type qualifiers
(if any) are those specified within the [ and ] of the array type
derivation.
If the keyword static also appears within the [ and ] of
the array type derivation, then for each call to the function, the
value of the corresponding actual argument shall provide access to the
first element of an array with at least as many elements as specified
by the size expression

On the other hand, in this call

func(v);

the array designator v is implicitly converted to a pointer to its first element.

The C Standard (6.3.2.1 Lvalues, arrays, and function designators)

3 Except when it is the operand of the sizeof operator or the unary &
operator, or is a string literal used to initialize an array, an
expression that has type ‘‘array of type’’ is converted to an
expression with type ‘‘pointer to type’’ that points to the initial
element of the array object and is not an lvalue. If the array object
has register storage class, the behavior is undefined.

That is the function call is equivalent to

func( &v[0] );

So in fact the first element of the array is passed to the function by reference through a pointer to it. Dereferencing the pointer by means of the subscript operator (the expression v[0] is equivalent to the expression *v)

v[0] = 1;

the referenced first element of the array is changed.

Passing an Array as Argument to Function in C

char request[] is not the same as char *request[MAXSTRING]. The former declares an array of characters (i.e. a string), the latter an array of pointers to char, i.e. an array of strings.

So declare it correctly in your function:

int findMatches (const char *filename, char *request[]) {

Next you will need a way to detect the end of the array of strings contained in request. Either pass a count to findMatches() or arrange for the last string to be NULL. If using a count you can redefine the function to accept a count:

void findMatches (const char *filename, char *request[], int n) {
for (int i = 0; i < n; i++) {
printf("%s \n", request[i]);
}
}

And call it like this:

findMatches("filename.txt", request, agrc-1);

Also, the use of MAXSTRING in char *request[MAXSTRING] seems confused. You seem to want an array of strings, but MAXSTRING seems to be a maximum length of a string. It's unlikely that you will have 1000 arguments to your program.

Is using array arguments in C considered bad practice?

If you write

void f(int a[4]);

that has exactly the same meaning to the compiler as if you wrote

void f(int *a);

This is why Linus has the opinion that he does. The [4] looks like it defines the expected size of the array, but it doesn't. Mismatches between what the code looks like it means and what it actually means are very bad when you're trying to maintain a large and complicated program.

(In general I advise people not to assume that Linus' opinions are correct. In this case I agree with him, but I wouldn't have put it so angrily.)

Since C99, there is a variation that does mean what it looks like it means:

void f(int a[static 4]);

That is, all callers of f are required to supply a pointer to an array of at least four ints; if they don't, the program has undefined behavior. This can help the optimizer, at least in principle (e.g. maybe it means the loop over a[i] inside f can be vectorized).

Your alternative construct

void f(int (*a)[4]);

gives the parameter a a different type ('pointer to array of 4 int' rather than 'pointer to int'). The array-notation equivalent of this type is

void f(int a[][4]);

Written that way, it should be immediately clear that that declaration is appropriate when the argument to f is a two-dimensional array whose inner size is 4, but not otherwise.

sizeof issues are another can of worms; my recommendation is to avoid needing to use sizeof on function arguments at almost any cost. Do not contort the parameter list of a function to make sizeof come out "right" inside the function; that makes it harder to call the function correctly, and you probably call the function a lot more times than you implement it.

Passing an array as function argument without defining a variable

You can make use of a compound literal. Something like

function((int []){3, -11, 0, 122});

Passing arrays as arguments in C

Replace int sum(int a, int size) to int sum(int *a, int size) or int sum(int a[], int size)

pointer to array as function argument in C

As a function parameter, int array[] is fully equivalent to int *array.

The purpose of [] there is to convey to the reader that the int * pointer that the function takes should probably point to an array rather than just a single int.

You can put qualifiers such as restrict or const inside the brackets to get the equivalents of int *restrict or int *const, and in C11, you can even do

int array[static MINIMUMS_SIZE] 

to convey the array param should have at least MINIMUM SIZE members.
(clang checks this, gcc doesn't (last time I checked)).

int foo(int array[static 1])

(also C11) should effectively be equivalent to

int foo(int *array) __attribute__((__nonnull__));
//== please help me check I don't pass a NULL pointer

You can even do:

int foo(int n_items, int array[n_items]);

and pray the compiler will help you check this (it probably won't).

In any case, the basic and oldest rule is that arrays in parameters simply translate to pointers.

Indexed array function argument in C

It's the array size, but it's ignored when it's in a function parameter declaration. A function parameter of the form int a[size] or int a[] is treated identically to int *a, because arrays decay to pointers when used as function arguments.

So it's essentially just a form of self-documentation. The caller is supposed to pass an array that contains size elements.

Note that this only applies to the first dimension in a multidimensional array parameter. If you have something like

void func(int width, int height, int a[height][width]) { ... }

The width part of the array declaration is used, but the height is ignored. a is a pointer to an array of int[width] rows; the width is needed when indexing the first dimension.



Related Topics



Leave a reply



Submit