简体   繁体   中英

Array as a parameter without a length

I have a couple of questions about this code (I don't know what it does, it's from an exam). What does it mean when the array is passed like this: nums[] ? And what does nums + 1 mean? If nums is an array, what does it mean to add 1 to it?

int f(int nums[], int n){
  if(n > 1) {
    if(nums[0] < nums[1]) {
      return 1 + f(nums + 1, n - 1);
    }
    else {
      return f(nums + 1, n - 1);
    }
  }
  else return 0; 
}

In C arrays cannot be passed by value to a function.

If you write something like

int a[4] = {1, 2, 3, 4};
// ....
int result = f(a, 4);
//             ^ The array "decays" to a pointer

What the function receives as parameters (passed by value) are a pointer to the first element of the array a and the size of the array (hopefully the correct one).

In the declaration of such a function, some use (and recommend) the notation showed in the question as a "documentation" of the fact that we want to pass an array, but it may be misleading, if the coder forgets that said parameter is just a pointer.

Given the use (purely accademic, it makes no sense to implement that algorithm as a recursive function), I'd find more descriptive the * :

int f(const int *nums, size_t n) {
  //  ^^^^^     ^  
}

And what does nums + 1 mean?

The result of num + 1 is a pointer which points to the element immediately after the one pointed by num .

The recursive calls just traverse the array, one element at the time (note that the "size" is decreased accordingly), counting the times that two subsequent element are in increasing order. Would you be able to rewrite that function, without the recursive calls, using a loop?

int nums[] is an array of int s. The [] denote that it's an array. The int denotes that the array contains int s.

num + 1 points to the second position in the array, so the call basically calls the same function but passing the whole array minus the first element.

Maybe looking at the function from the side of the function prototype you will see more sense of this:

       int f(int[], int n);

Here f() is declared to return an int and use two arguments: the first is an address of an array of int , the second is an int .

Since inside f() you may want to know how many int 's are in the vector, it is common to the second argument to be number of elements in the array. Just as an example. Any similarity with the pair

        int argc, char** argv

is because it is the same thing: the system builds a list of the arguments passed on the command line and constructs the argv array. And passes argc as the number of arguments in the array.

C does pointer arithmetic, in a sense that if x points to an int (x+1) points to the x plus the sizeof() an int . This is fantastic in order to abstract things like memory, registers and hardware.

In this way, when you call f() again passing 1 + the original argument you are just calling f() and passing the array beginning at the next position.

Back to your example, consider f() just

int f(int nums[], int n)
{
    printf("First int is %d\n", nums[0]);
    return 0;
}

where f() just writes down the first int of the block, and the code

int f(int[], int n);

int main(int arg, char** argv)
{
    const int one[4] = { 1,2,3,4 };
    const int other[2] = { 3,4 };
    f(one, 4);
    f(other, 2);
    f(other + 1, 3'000);
    return 0;
};

it shows

First int is 1
First int is 3
First int is 4

And you see that in the 3rd call f() gets the array other starting at 4 , the second element.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM