0
#include <stdio.h>

void test(int *arr, int n)
{
    for(int i = 0; i < n; ++i)
        printf("%d ", *(arr + i));
    printf("\n");
}

int main(void) {

    int a[10] = { 1,2,3,4,5,6,7,8,9,10};

    test(a,10);

    return 0;
}

this gives the correct answer which is "1 2 3 4 5 6 7 8 9 10" but when I change first argument's type in test function to *arr[] it gives

1 3 5 7 9 0 0 965108401 262144 404875544 

looks like i += 2 happens in for loop.

The changed code is below

#include <stdio.h>

void test(int *arr[], int n)
{
    for(int i = 0; i < n; ++i)
        printf("%d ", *(arr + i));
    printf("\n");
}

int main(void) {

    int a[10] = { 1,2,3,4,5,6,7,8,9,10};

    test(a,10);

    return 0;
}

What *arr[] actually is?

barbsan
  • 3,418
  • 11
  • 21
  • 28
  • 4
    What you've make of compiler warnings ? Compile with `-Wall -Wextra -Werror` and read error message. – Achal May 21 '19 at 03:41
  • 2
    Does https://cdecl.org/ help you? Do you really mean `int *arr` and `int *arr[]` or do you mean `int *arr` and `int arr[]`? – Werner Henze May 21 '19 at 06:41
  • `int *arr` - is a *pointer to array* (its first element), equivalent to `int arr[const]` as parameter, see: [C11 Standard - 6.3.2.1 Other Operands - Lvalues, arrays, and function designators(p3)](http://port70.net/~nsz/c/c11/n1570.html#6.3.2.1p3). Where as `int *arr[]` is a *array-of-pointers* to `int` (currently an incomplete type). The declaration would need to be `int *arr[5];` which you would then pass as `int **arr`. If you had `int (*arr)[5];` then you would have a *pointer-to-array* of `int` [5]. – David C. Rankin May 21 '19 at 08:21

2 Answers2

0

In main, a is declared to be an int array of size 10. When you pass it to a function, it nicely decays to a pointer to its first element, so declaring it as int *arr in the function if fine.

On the other hand, int *arr[] declares an (uncomplete) array of pointers to int. It will be processed in a function as an int ** what it is not, thus invoking Undefined Behaviour. In your implementation, a pointer seems to have twice the size of an int, that explains why it looks like the function was taking every second item. But because of the UB you cannot even rely on that

What to remember: correct indirection level may not be easy for C beginners but it is essential to correctly write C code. Use a decent/recent compiler and pay attention to warnings.

Serge Ballesta
  • 143,923
  • 11
  • 122
  • 252
0

An asterisk is a pointer to a type.

Thus, int[] * is a pointer to an array of ints. That is, you have a pointer to an array type/variable.

On the other hand, the int * is a pointer to an int. There is a common behaviour in redirecting between int[] and int *, but it is not the same (e.g. one of the first google search results https://www.quora.com/What-is-the-difference-between-pointer-and-array)

Setting aside that difference of int * and int[], the *arr[] is a pointer to an array. Because you can use the pointer mechanics/arithmetics to access arrays using pointers, you can think the *arr[] as a two dimensional array. That is, the equivalent of *arr[] with only pointers is int**.

Xxxo
  • 1,784
  • 1
  • 15
  • 24