1

I am recently studying pointers and arrays. Suppose I initialize an array like

 int a[4]={6,2,3,4};

Now after reading a lot ,I understand that

1) a and &a will point to same location.But they aren't pointing to the same type.

2) a points to the first element of the array which is an integer value so the type of a is int*.

3) &a points to an entire array(i.e an integer array of size 4) therefore the type is int (*)[].

Now what I actually don't get is how to use these type??

For Example: CODE 1:

#include<stdio.h>
void foo(int (*arr)[4],int n)
{
    int i;
    for(i=0;i<n;i++)
        printf("%d ",*(*arr+i));
    printf("\n");
}
int main()
{
    int arr[4]={6,2,3,4};
    foo(&arr,4);
    return 0;
}

CODE 2:

#include<stdio.h>
void foo(int *arr,int n)
{
    int i;
    for(i=0;i<n;i++)
        printf("%d ",*(arr+i));
    printf("\n");
}
int main()
{
    int arr[4]={6,2,3,4};
    foo(&arr,4);
    return 0;
}

In code 2 we are passing &arr so its type should be of int (*)[],then how come we are getting the correct output even though we are having a type int *.

I really don't understand what is the meaning of type and how to use it?

Kindly explain with some examples.

SanQA
  • 233
  • 3
  • 9
  • 3
    type of `&a` is `int (*)[4]`, not `int (*)[]` – M.M Nov 03 '17 at 05:50
  • I bet your compiler will give you a warning with Code 2, something about incompatible pointer types... – yano Nov 03 '17 at 05:51
  • 1
    You might want to see this question (I posted) and the answer on it https://stackoverflow.com/questions/43851470/cast-t-to-t . Although your question has more than it. Since it tries to convert the pointer without a cast. Your compiler would at the least warn. – Ajay Brahmakshatriya Nov 03 '17 at 05:52
  • 1
    Code 2 is illegal code, your compiler permits it in the default mode because otherwise people whose programs rely on this sort of illegal code would get annoyed. IMO it is a good idea to configure the compiler to report errors – M.M Nov 03 '17 at 05:54
  • I am surprised code 2 gives that output. Suspect undefined behavior but need someone to reference backup – SwiftMango Nov 03 '17 at 06:00
  • 1
    @texasbruce it "works" because in most implementations, dereference of a `int (*)[]` is a `NOP`. – Ajay Brahmakshatriya Nov 03 '17 at 06:02
  • Case 2 `foo (&arr, 4);` -> `foo (arr, 4);` – David C. Rankin Nov 03 '17 at 06:07

2 Answers2

1

Code 2 is not valid C, because a conversion between an array pointer and a pointer to int is not a valid pointer conversion - they are not compatible types. If it works, it is because of some non-standard extension of your compiler, or possibly you just "got lucky".

Please note that the best way to pass an array to a function in modern C is this:

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

As part of a function parameter list, arr will get adjusted to a pointer to the first element of the array, type int*.

The pedantically correct version would also replace int n and int i with size_t, which is the most proper type to use when describing the size of an object.

Lundin
  • 195,001
  • 40
  • 254
  • 396
  • What's the upside of using this over the usual `void foo(int arr[], int n)`? – a3f Nov 03 '17 at 08:09
  • @a3f The advantage is that good compilers or static analysers may spot a type inconsistency when you try to pass anything but an array of size `n` to the function. In fact if you would have used array pointers like in the first example, you would be guaranteed by the standard to always get a compiler message if passing an array of wrong size. You also get self-documenting code - it is obvious to anyone viewing the function that the purpose of `n` is to express the array size. – Lundin Nov 03 '17 at 09:40
0

The best way to pass arrays in to functions is a pointer and the number of elements.

Note you can pass arr in to the function as arr or &arr[0]; both resolve to the same address.

#include<stdio.h>
void foo(int *arr,int n)
{
    int i;
    for(i=0;i<n;i++)
        printf("%d ",arr[i]);
    printf("\n");
}
int main()
{
    int arr[4]={6,2,3,4};
    foo(arr,4);
    return 0;
}

Also, it's better to index the array, rather than addition and dereference. e.g. *(arr+i) becomes arr[i].

NeRa
  • 101
  • 5