1

I have found myself unable to explain why the following piece of code works. Needless to say, I am quite new to C++...

#include <cstdio>

void foo(char* p)
{
    p[0] = 'y';
}

int main()
{
    char a[1];
    a[0] = 'x';
    printf("a[0] = %c\n", a[0]);
    foo(a);
    printf("a[0] = %c\n", a[0]);
    return 0;
}

This program outputs

a[0] = x
a[0] = y

What intrigues me us that I am not passing a pointer, but an array, to foo. So how can foo change the value of the array a? Does this apply only to arrays of char?

The answer to Difference between char and char[1], confirms my observation, but it does not go into detail about why this is the case.

Thanks!

Community
  • 1
  • 1
user1083059
  • 160
  • 1
  • 6
  • 1
    Because when you're passing pointer you're passing the address of the object so you can change it's value; This is the case with your fragment e.g. you are not passing the value but the address to the object in this case char[]; – v01d Feb 20 '12 at 10:05
  • 2
    Grab a good C beginner book and read. You can't learn languages from the Internet through tutorials. Or if you can, it takes quite a while longer than learning it through books. – Aamir Feb 20 '12 at 10:12
  • @Aamir +1 You are write. Using tutorials you can solve problems sometime but you cant learn new technologies.... – Amit Feb 20 '12 at 10:17
  • Remember when passing arrays in like this you also need to pass in the size of the array otherwise all sorts of "fun" can happen – Firedragon Feb 20 '12 at 11:04

7 Answers7

5

When you're passing an array to a function it decays to a pointer to the first element.

The following are completely equivalent:

void foo(char* p);
void foo(char p[]);
void foo(char p[42]); /* Or any other number. */ 

Does this apply only to arrays of char?

It applies to any array. I recommend the aryptr section of the C FAQ.

cnicutar
  • 178,505
  • 25
  • 365
  • 392
5

In C, arrays, in most contexts (*), decay into a pointer to their first element.

In your case, the array a decays into a pointer to a[0].

The array int arr[12][23], when used just by its identifier, decays to a pointer to its first element, namely arr[0], which is of type int (*)[23] (pointer to array of 23 ints).

(*) Arrays do not decay when used as the argument to the sizeof operator, or when used as argument to the & operator or when used as initializer (a string literal) for a character array.

pmg
  • 106,608
  • 13
  • 126
  • 198
  • For completeness I'd mention that the "decay" is formally speaking *lvalue-to-rvalue conversion*, or "*the process of getting a value out of a variable*". C has this weird decision that "there are no values of array type, only objects", and when you try to take a value of an array, you end up with a pointer. And C is strictly call-by-value, so you can't pass an array itself to the function, only a pointer to the first element (like `int*`), or a pointer to the whole array (like `int(*)[10]`). – Kos Feb 20 '12 at 11:23
  • Hence an array itself cannot be a function parameter. A question arises why an array-like syntax can be used to specify the parameter type- and this eludes me completely. :-) – Kos Feb 20 '12 at 11:25
1

When You say

char a[5];

the compiler allocates 5 sequential blocks of memory, and the address of the first block is assigned to a. So by definition name of the array (a in our case) is just a pointer to a memory location.

Now when we say a[0], compiler manipulates it as *(a+0*sizeof(array datatype i.e. char, int etc.)), symbolically a[i] is represented as *(a+i*sizeof(array datatype i.e. char, int etc.))

As far as function parameter passing is concerned When we pass an array to a function basically it is just the address of the first element which is passed. For more details regarding this plz follow this link or read the @cnicutar's answer (as he has already posted a correct answer there is no point repeating that again)...

Amit
  • 13,134
  • 17
  • 77
  • 148
1

You can try this to convince yourself how this works.

int a[8], *p;
p = a;
printf("%p, %p, %p\n", a, &a[0], p);
foo
  • 387
  • 2
  • 9
0

An array is nothing more than a pointer (to the first element), at least for argument passing sake.

Michel Keijzers
  • 15,025
  • 28
  • 93
  • 119
0

The three prototypes here are equivalent:

void foo(char *p);
void foo(char p[]);
void foo(char p[42]);

C says a declaration of parameter of type array of T is adjusted to a declaration of type pointer to T.

ouah
  • 142,963
  • 15
  • 272
  • 331
0

Array name points to the address of the first element of the array. Please refer: Is an array name a pointer?

Community
  • 1
  • 1
omggs
  • 1,163
  • 1
  • 11
  • 23