6
#include<stdio.h>
void printd(char []);
int main(void){
       char a[100];
       a[0]='a';a[1]='b';a[2]='c';a[4]='d';
       printd(a);
       return 0;
}
void printd(char a[]){
        a++;
        printf("%c",*a);
        a++;
        printf("%c",*a);
}

Explanation: I was expecting that it would result in lvalue error. But it is working with out any error and giving bc as output. Why is this incrementing array "a" is not an error?

Jens
  • 69,818
  • 15
  • 125
  • 179
Subhiksh
  • 301
  • 2
  • 13

5 Answers5

5

If an array is passed to a function it decays to a pointer to the array's first element.

Due to this inside printd() the pointer a can be incremented and decremented, to point to different elements of the array a as defined in main().

Please note that when declaring/defining a function's parameter list for any type T the expression T[] is equivaltent to T*.

In question's specific case

void printd(char a[]);

is the same as

void printd(char * a);

The code below shows equivalent behaviour as the OP's code, with pa behaving like a in side printd():

#include <stdio.h>

int main(void)
{
   char a[100];
   a[0]='a';a[1]='b';a[2]='c';a[4]='d';

   {
     char * pa = a;

     pa++;
     printf("%c", *pa);
     pa++;
     printf("%c", *pa);
   }

   return 0;
`}
alk
  • 69,737
  • 10
  • 105
  • 255
3

In C language array declaration in function parameter list and array declaration outside of function parameter list mean completely different things, even though they look similar (or the same) on the surface.

When you use array declaration in function parameter list (as is the case with void printd(char a[]) in your code), you are not declaring an array. The top-level [] syntax in function parameter list is just an alternative form of pointer declaration. This means that your a parameter is actually declared as char *a. It is not an array at all, it is an ordinary pointer. There's nothing unusual in being able to increment such a, and this is why you are not getting any "lvalue errors" from it.

Meanwhile, your a in main is a true array.

AnT stands with Russia
  • 312,472
  • 42
  • 525
  • 765
  • And _that_ is the actual correct explanation for the seemingly strange behaviour. You can't declare function parameters that are arrays. You can only use declarations that _look like_ array declarations. – gnasher729 Jul 19 '15 at 09:13
0

Why is this incrementing array "a" is not an error?

In C arrays are passed as a pointer to any function. Thats why you get no error.

The function calls in main() pass the name of the array, a, as an argument because the name of an array in an expression evaluates to a pointer to the array. In other words, the expression, a, is a pointer to (the first element of) the array, a[]. Its type is, therefore, char *, and a called function uses this pointer (passed as an argument) to indirectly access the elements of the array.

Now as you receive the address of the first element of a, a++ means ahead the array's initial address by 1. That's why the first printf prints b, the second element of array a.

mazhar islam
  • 5,561
  • 3
  • 20
  • 41
  • Still nitpicking: One does not pass the "name" of a variable, but the variable itself. So this "*pass the name of the array*" should read "*pass the array*". – alk Jul 18 '15 at 07:08
  • Also not "*the name of an array ... evaluates*", but the array itself. – alk Jul 18 '15 at 07:10
  • _name_ of the array is a metaphor which explained in the next line describing actually it means `char *`. – mazhar islam Jul 18 '15 at 07:13
0

a also works as a pointer. It is a pointer to the first element of the array. The a++ increments that pointer. That is, after a++ the a[0] or *a now gives you what a[1] gave you prior to the increment, that is 'b'.

Note that you do not increment the value of a[0] from 'a' to 'b'. Check that if you use different values in your array, like 'a, 'd', 'h', 'x'.

Christian Fries
  • 16,175
  • 10
  • 56
  • 67
  • @Ticktick, If you want to increment the value of a[0], you should do something like (*a)++ - not too elegant in this case, but used nonetheless. – piffy Jul 18 '15 at 06:42
  • "*a++ increments the pointer to the array.*" This is not correct. `a` in `printd()` initially is a pointer to the 1st element of `a` as defined in `main()`. A pointer to an array is something different. – alk Jul 18 '15 at 06:48
0

An array is passed to a function as a pointer, which can be incremented.

So, in your example, it is not possible to increment a within the main() function, since a is an array and cannot be incremented.

However, not withstanding the syntax, the a within the printd() function is a pointer, so can be incremented. Incrementing a inside printd() does not affect the array a inside main() - although they have the same names, they are different entities within different scopes.

Peter
  • 35,646
  • 4
  • 32
  • 74