1

以下に C プログラムがあり、関数funcには 2 つのforループがあります。最初のforループでは、配列変数をインクリメントする際に「左辺値が必要です」というエラーは発生しませんが、2 番目のループでa配列変数をインクリメントする際に、コンパイラは「左辺値が必要です」というエラーを返します。なんで?cfor

#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
    }
}
4

2 に答える 2

4

関数でcは、配列です。配列の名前は定数です。増やしたり減らしたりすることはできません。

一般的な神話に反して、配列とポインターには違いがあります。

また、関数プロトタイプでの使用は[]、ポインターを実際に識別するため、物事を混乱させます。次のようにしても同じ結果が得られます。

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++);
}
于 2013-08-22T05:28:47.880 に答える
2

配列は左辺値ではありません。配列の名前は、配列の最初の要素へのポインター定数です。配列の名前が指すアドレスを変更することはできません。次のコード フラグメント:

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

を試すと*c++、何cを指すかを変更しようとしています。cは変数ではなくポインター定数であるため、コンパイラ エラーが発生します。

ただし、配列を関数に渡すと、配列はポインターに "減衰" し、配列へのポインターは値で渡されます。この関数は、元のポインタと同じ値を持つ新しいポインタ、つまり配列の最初の要素である同じ場所を指す新しいポインタを受け取ります。これは定数ではないため、その新しいポインターを変更して別の場所を指すことができます。したがって*a++、コンパイラ エラーは発生しません。

于 2013-08-22T05:38:39.430 に答える