2

The foo function below finds the first occurrence of the given number and returns it's index. If the number wasn't found it returns the size of the array(n):

‪int foo(int arr[10], int num, int n)‬
{
‫;‪   int *p‬‬
‪   for (p=arr;(*p!=num) && (p<arr+n);++p);‬‬
   ‫;‪return p-arr‬‬
}

My question is: is the parameter int arr[10] the same as writing int * arr or int arr[] for that matter? because when i pass an int array of size 100 i can iterate through it and i'm not capped to only 10 elements.

Tom
  • 9,275
  • 25
  • 89
  • 147
  • There's a lot of valuable information [in this](http://stackoverflow.com/questions/4810664/how-do-i-use-arrays-in-c). Many of the points are just as valid for C. – chris Jan 31 '13 at 12:02
  • http://c-faq.com/aryptr/aryptrparam.html – hmjd Jan 31 '13 at 12:02
  • `foo()` return type is `int` whereas you are returning `int *` – manav m-n Jan 31 '13 at 12:08
  • @Manav pointer subtraction of the same array returns a number – Tom Jan 31 '13 at 12:40
  • `int arr[10]` is the same as `int arr[]` here; `int *arr` is different, in that the former are arrays (aproximately a _fixed_ pointer to its start), while the later is a plain pointer (can be changed at will). – vonbrand Feb 01 '13 at 01:32

5 Answers5

2

My question is: is the parameter int arr[10] the same as writing int *arr or int arr[] for that matter?

Yes, as long as it's part of the declaration of a function argument list and the array is one-dimensional.

  • Why would the number of dimensions matter, as long as a _true_ multi-dimensional array is passed, with all memory cells allocated adjacently? – Lundin Jan 31 '13 at 12:15
  • 4
    @Lundin, because then the other dimensions would be reflected in the type and the compiler would be able to do the index calculations correctly. – Jens Gustedt Jan 31 '13 at 12:23
  • @JensGustedt What do you mean "index calculation"? Are you saying that I would get a compiler error if I tried to pass a plain pointer to a function expecting an array pointer to a multi-dim. array? – Lundin Jan 31 '13 at 12:26
  • @Lundin No, pointer arithmetic. `int arr[2][]` is not the same as `int arr[3][]` when calculating `*arr + 1`. –  Jan 31 '13 at 13:13
  • 1
    @Lundin, index calculations means that inside the function something like `arr[i][j]` would just compute the element of the 2D array that everybody expects it to be. No opaque handcrafted index calculations but a compiler that knows what it is doing. That is what multi-dimensional arrays are made for. – Jens Gustedt Jan 31 '13 at 13:27
  • @H2CO3 That's an odd special case, but fair enough, I see your point. (Though only the inner-most dimension is allowed to be unspecified, so your examples would have been `int arr[][2]` and `arr[][3]`. parameter. Your logic for the arithmetic is right, but you forget that *arr is a a 1d-array, which in turn decays into a pointer when used in pointer arithmetic - it would be the same as if arr was a plain pointer. So you probably meant 'arr+1'.) – Lundin Jan 31 '13 at 13:53
  • @JensGustedt As in compile-time address calculation even when arr[i][j] is accessed inside a function? Wouldn't the compiler have to treat a 2D array parameter as (int*)[n] though, since the inner-most dimension can be anything? – Lundin Jan 31 '13 at 13:59
  • @Lundin Yes, right, so then `int arr[][2]` etc. I was specifically referring to multidimensional arrays in the example, though - I did mean `*arr`. –  Jan 31 '13 at 14:02
  • Yes, compile time calculations if the dimensions are constants and run time calculations if they are dynamic, and thus arr is a (pointer to) VLA. Sure the innermost dimension can be anything, but for index calculations it isn't needed, fortunately. – Jens Gustedt Jan 31 '13 at 14:04
  • @H2CO3 Given `func (int arr[][2])`, `*arr+1` will evaluate to a 4 byte increment, while `arr+1` will evaluate to a 8 byte increment. – Lundin Jan 31 '13 at 14:15
2

Yes, int arr[10], int arr[], and int *arr in a function argument list all mean exactly the same thing.

In C99 you have a new option: int arr[static 10]. This means you must pass to the function an address pointing to at least 10 elements (under penalty of Undefined Behaviour).

pmg
  • 106,608
  • 13
  • 126
  • 198
1

Why would you expect your code to be "capped"? What would happen?

C doesn't have "safe" array indexing, it will just index where you tell it. It's up to you to not step out of bounds.

In my opinion, it's always best to pass the size explicitly, as you've done since that makes the function more general, and avoids confusion about array/pointer issues.

unwind
  • 391,730
  • 64
  • 469
  • 606
0

You can iterate, but over a region of your memory you should not the clean way to do it is,

int foo(int *arr, int num, int n)‬
{
    int i;
 ‪   for (i=0;arr[i]!=num && i<n; i++);‬‬
    ‫;‪return i‬‬
}

Besides, since you do p=arr and then use p, it really does not matter the way you define arr

jpmuc
  • 1,092
  • 14
  • 30
0

if you do *arr , you are basically passing a pointer to the first element of the array.

Since the behavior of pointers can be used as a complement of the use of array, there is no problem at all.

when you do something like arr[1], the pointer arr to the first element automatically gets incremented by one and points to the address of the second element in the array.

Aakash Anuj
  • 3,773
  • 7
  • 35
  • 47