0

I know that the title is not clear at all , but i use this code to tell what i want to ask assume the following simple code :

void example(int *a)
{
    for(i = 0 ; i < 20 ; i++)
    {
       printf(" %d number is %d \n " , i , a[i]);
    }
}
int main()
{
    int a[20] ; 
    // assume that the array is filled 
    example(a);
    return 0 ;
}

so my question is ,what is the 'addresing mode' that c language follow , if we write a[i] ? if we just follow the rules of pointer or syntax of pointer we must write this in this way *a[i] , since we need to show the value that *a point on it , and not the address ?

Cœur
  • 37,241
  • 25
  • 195
  • 267
hbak
  • 1,333
  • 3
  • 10
  • 22

4 Answers4

2

The simple rule is that arrays are not pointers. Array names are converted to pointer (in most cases) to its first element when they passed as arguments to a function.

haccks
  • 104,019
  • 25
  • 176
  • 264
  • 'in most cases': you've made me curious: at the moment I can't think of an example when it's not so. Could you please help me out? – Ingo Leonhardt Mar 19 '14 at 18:11
  • @IngoLeonhardt; `sizeof`. – haccks Mar 19 '14 at 18:16
  • 2
    Yepp, but to be pedantic, `sizeof` ist not a function at all – Ingo Leonhardt Mar 19 '14 at 18:17
  • 1
    He meant `sizeof(array)` will give you the full memory space occupied by the array, not the size of a pointer. `sizeof(some ordinary pointer)` will always give you 4 bytes for 32-bit architecture and 8 bytes for 64-bit architecture regardless of anything. – Havenard Mar 19 '14 at 18:23
  • @Havenard I'm quite aware of what `sizeof()` does. I have just been wondering if there is is really an exception if you call a (real) function. – Ingo Leonhardt Mar 19 '14 at 18:26
  • Yes. You can have a function like `void exemple(int foo[20])`. It will not accept pointers, only arrays of `int` with 20 elements. – Havenard Mar 19 '14 at 18:27
  • Yes but calling `sizeof(foo)` in `exemple()`, you will get pointer size, what shows that there still is a array to pointer conversion – Ingo Leonhardt Mar 19 '14 at 18:30
  • Are you sure? I don't think so. It is probably being passed by value. – Havenard Mar 19 '14 at 18:30
  • sizeof will return the size of a pointer when the arrays definition is not visible. If it is visible it will return the size of the entire array. array size scripts use this to determine how large an array is that was defined locally by dividing the size of the array by the size of one element of the array. – DAhrens Mar 19 '14 at 18:33
  • I just tested in Ideone and indeed `sizeof(foo)` is returning 4. But then I tried to pass a `foo[10]` as parameter to a function that is supposed to take `foo[20]` and it also worked without complaining, what is weird. I guess it depends on the compiler. – Havenard Mar 19 '14 at 18:36
  • @IngoLeonhardt; I never said `sizeof` is a function. My statement is *Array names are converted to pointer (in most cases)....*. I Did't said that `Array names are converted to pointer to its first element when passed to a function (in most cases)`. i think both statement are different. – haccks Mar 19 '14 at 18:39
  • @Havenard; There is no difference in `void example(int foo[20])`, `void example(int foo[])` and `void example(int *foo)`. You can omit first dimension of array when declaring it as a function parameter. – haccks Mar 19 '14 at 18:41
  • @Havenard `void example(int foo[20]);` and `void example(int *foo);` are equivalent. – ajay Mar 19 '14 at 18:42
  • I really didn't mean to criticize. But to be honest, as a non native speaker I've understood your post as ther may be cases, where there is a difference when you call a function and was wondering, if there ist some weird case I am not aware of. Thank you! – Ingo Leonhardt Mar 19 '14 at 18:44
  • @Havenard You cannot pass an array to a function. You only pass a pointer to the first element of the array. That's because arrays cannot be assigned in C even though they can be initialized. – ajay Mar 19 '14 at 18:44
  • @ajay In some compilers they are not. The compiler will enforce the type, meaning it should be an array of 20 elements otherwise you get an error. But I see that is probably not part of the standard. – Havenard Mar 19 '14 at 18:48
  • 1
    @Havenard; No this is the part of the standard. In C, there is no pass by reference. – haccks Mar 19 '14 at 18:50
  • @IngoLeonhardt; *I've understood your post as ther may be cases, where there is a difference when you call a function and was wondering, if there ist some weird case I am not aware of.* ??? – haccks Mar 19 '14 at 18:50
  • I meant that I was wondering if there are cases where an array name is **not** converted to a pointer when calling a **function**. Sorry for all the trouble I might have caused because my English is too poor. But the discussion has been quite interesting, anyway I hope – Ingo Leonhardt Mar 19 '14 at 18:55
0

No when using the []'s it automatically does this. Also it wouldn't make sense to dereference say array[1] and so on since the pointer points to the first index (0).

TerraOrbis
  • 91
  • 4
0

When you use brackets you are implicitly handling a specific element of the array, so you don't need to head it with * to set its value.

In int *a, a is a pointer. It means it holds a memory address of an int. This can be a lone int or the first element of an array of int. There is no way to know just by having the pointer.

There are several synthaxes you can use to work with this pointer.

By reading or writing to *a, you are handling the int variable that pointer is pointing to. It can also be done by reading or writing to a[0], both means exactly the same thing.

Assuming a points to a sequence of int variables, working with a[1] makes you handle the int stored right next to a[0]. The pointer type is internally used do determine how many bytes next the suceeding int should be in the memory. It will be sizeof(*a) bytes next, or sizeof(int).

Instead of a[1] you could also use *(a + 1). It means the same thing. Such arithmetic operations with pointers are possible, but notice that the compiler will automatically multiply 1 by sizeof(int) internally, so you don't need to be redundant in informing the variable type stored there.

Havenard
  • 27,022
  • 5
  • 36
  • 62
0

About the array subscript operator [], the C99 standard §6.5.2.1¶2 says -

A postfix expression followed by an expression in square brackets [] is a subscripted designation of an element of an array object. The definition of the subscript operator [] is that E1[E2] is identical to (*((E1)+(E2))). Because of the conversion rules that apply to the binary + operator, if E1 is an array object (equivalently, a pointer to the initial element of an array object) and E2 is an integer, E1[E2] designates the E2-th element of E1 (counting from zero).

So a[i] in the function example evaluates to *(a + i). You could write it either way. Please note that arrays and pointers are different types. Arrays are not first-class objects in C unlike integers, floats, structures etc. This means you can't pass array to or return an array from a function.

In the function main, a is an array type - its type is int[20], i.e., an array of 20 integers. When you pass a to the function example in the statement

example(a);

in main, then the array a evaluates to a pointer to its first element which is assigned to function parameter a which is of type int *. You can access the elements in the array a in main by either syntax - a[i] or *(a + i) - they are equivalent as described in the standard. However, remember that the there is a difference in the way the array elements are accessed when using the array itself (a[i] in main) and using a pointer to the first element in the array (a[i] in example). For more details, please look here - Difference between dereferencing pointer and accessing array elements

Community
  • 1
  • 1
ajay
  • 9,402
  • 8
  • 44
  • 71