Duggs
Duggs

Reputation: 179

Can someone explain the error?

I have a C program below and in function func there are two for loops. In the first for loop, while incrementing the array variable a there is no 'lvalue required' error but while incrementing array variable c in the second for loop, the compiler gives an 'lvalue required' error. Why?

#include<stdio.h>
#include<string.h>
void func(char a[],int n);

int main(int argc,char **argv){

    char * s="Happy ,People\n\n";
    func(s,strlen(s));

    return 0;
}

void func(char a[],int n){
    for(int i=0;i<n;i++){
        printf("%c",*a++);      //This works fine — no lvalue error here
    }

    char c[]="Happy ,People\n\n";
    for(int i=0;i<n;i++){
        printf("%c",*c++); // there is error coming here lvalue Required
    }
}

Upvotes: 1

Views: 92

Answers (2)

verbose
verbose

Reputation: 7917

An array is not an lvalue. The name of the array is a pointer constant to the first element of the array. You cannot modify the address to which the array's name points. In following code fragment:

char c[]="Happy ,People\n\n";
for(int i=0;i<n;i++){
printf("%c",*c++); // there is error coming here lvalue Required

When you try *c++, you are attempting to modify what c points to. Since c is a pointer constant, not a variable, you will get the compiler error.

However, when you pass an array to a function, the array "decays" to a pointer, and the pointer to the array is passed by value. The function receives a new pointer with the same value as the original pointer--i.e., a new pointer that points to the same place, which is the first element of the array. Since it's not a constant, that new pointer can be modified to point somewhere else. So *a++ does not cause a compiler error.

Upvotes: 2

Jonathan Leffler
Jonathan Leffler

Reputation: 753815

In the function, c is an array. The name of an array is a constant. You can't increment it or decrement it.

Contrary to popular myth, there are differences between arrays and pointers.

And the use of [] in function prototypes confuses things because they really identify pointers. You'd get the same result with:

void func(char *a, int n)
{
    for (int i = 0; i < n; i++)
        printf("%c",*a++);
    char c[] = "Happy, People\n\n";
    for (int i = 0; i < n; i++)
        printf("%c",*c++);
}

Upvotes: 4

Related Questions