プロが教える店舗&オフィスのセキュリティ対策術

x_i = cos ((PI*(2*i-1))/( 2*N )) i =1,2,...,N   (見づらくてすみません)

という式を計算して、結果を出力したいのですが、コンパイルできません。
自分で書いてみたプログラムとエラーを書いておくので、どこを直せばいいか教えてください。

#include <stdio.h>
#include <math.h>

#define PI 3.1415926535

double x_i(int i, int N)
{
for (i = 1 ; i <= N ; i++) {
x_i(i, N) = cos ((PI*(2*i-1))/( 2*N ));

}
}

int main()
{
int i, N ;
printf("N= ");
scanf("%d", &N);
for (i = 1 ; i <= N ; i++) {

printf("x[%2d] = %f\n",i, x_i(i,N));

}

return 0 ;
}


C:\Users>gcc nnn.c
nnn.c: In function 'x_i':
nnn.c:9:16: error: lvalue required as left operand of assignment
x_i(i, N) = cos ((PI*(2*i-1))/( 2*N ));
^


初心者なのでできれば丁寧に教えていただけると助かります。
よろしくお願いします。
結果は、
C:\Users>a
N = 5
x[ 1] = 0.951057
x[ 2] = 0.587785
x[ 3] = 0.000000
x[ 4] = -0.587785
x[ 5] = -0.951057

という風にしたいです。

質問者からの補足コメント

  • 求めたい結果なんですが、Nは5と決まっているわけではなくて、20までで自分で、自由に決めれるようにしたいです。
    N = 8
    x[ 1] = 0.980785
    x[ 2] = 0.831470
    x[ 3] = 0.555570
    x[ 4] = 0.195090
    x[ 5] = -0.195090
    x[ 6] = -0.555570
    x[ 7] = -0.831470
    x[ 8] = -0.980785

    N = 3
    x[ 1] = 0.866025
    x[ 2] = 0.000000
    x[ 3] = -0.866025

    このように、N=
    に数字を入れると計算して出力できるようにしたいです。

    説明足らずですみません。

      補足日時:2018/12/04 10:00
  • 以前、同じ目的で以下のプログラムを作成しました。
    今回はこのプログラムを、関数を作成して同じように作動するようにするのが目的です。

    以下のプログラムで正常に動いたので、これを関数に変えればいいと思っていたのですが、うまくいかず質問させていただいてるという流れです。
    このプログラムも捕足になるか分かりませんが、書いておくので、このプログラムを関数を利用する形(私が最初に質問で書いていたプログラム)にすると、なぜうまくいかないのか、どうすればうまくいくのかなど、教えていただけるとありがたいです。よろしくお願いします。
    プログラムが入らないので、次の補足に入れます。

      補足日時:2018/12/04 11:24
  • 先ほどの補足に入らなかった分のプログラムです。

    #include <stdio.h>
    #include <math.h>
    #define PI 3.1415926535

    int main()
    {
    int i , N ;
    double x_i ;

    printf("i = ");
    scanf("%d", &N);

    for (i = 1 ; i <= N ; i++) {
    x_i = cos ((PI*(2*i-1))/( 2*N ));
    printf("x[%2d] = %f\n",i, x_i);
    }

    return 0 ;

    }

      補足日時:2018/12/04 11:26
  • 皆さんのご回答を参考にさせていただいて何とか正常に動くプログラムを作成することができました。
    特にrnakamraさん、Wr5さん、kmeeさんなどの回答を参考にしてプログラムを作らせてもらいました。

    皆さんご回答ありがとうございました。また、質問していたらご回答いただけると嬉しいです。
    一応成果としてプログラムと結果を書かせていただきます。

    入らないので、次のページに書きますね。

      補足日時:2018/12/05 09:48
  • #include <stdio.h>
    #include <math.h>

    #define PI 3.1415926535

    double x_i(int i, int N)
    {
    return cos ((PI*(2*i-1))/( 2*N ));
    }

    int main()
    {
    int i, N ;

    do{
    printf("N= ");
    scanf("%d", &N);
    }
    while((N < 0) || (N > 20));

    for (i = 1 ; i <= N ; i++) {
    printf("x[%2d] = %lf\n",i, x_i(i,N));
    }
    return 0 ;
    }

      補足日時:2018/12/05 09:49
  • 結果
    N= 5
    x[ 1] = 0.951057
    x[ 2] = 0.587785
    x[ 3] = 0.000000
    x[ 4] = -0.587785
    x[ 5] = -0.951057

    N= 3
    x[ 1] = 0.866025
    x[ 2] = 0.000000
    x[ 3] = -0.866025

    N= 7
    x[ 1] = 0.974928
    x[ 2] = 0.781831
    x[ 3] = 0.433884
    x[ 4] = 0.000000
    x[ 5] = -0.433884
    x[ 6] = -0.781831
    x[ 7] = -0.974928


    Nの値も整数なら自由に入れることができました。

      補足日時:2018/12/05 09:51

A 回答 (13件中1~10件)

>以下のプログラムで正常に動いたので、これを関数に変えればいいと思っていたのですが、うまくいかず質問させていただいてるという流れです。



・ループはコール側でやっているので関数内でやる必要はない。
・ループで結果を表示しているので配列は関係ない。
ということで…

>double x_i(int i, int N)
>{
> for (i = 1 ; i <= N ; i++) {
>  x_i(i, N) = cos ((PI*(2*i-1))/( 2*N ));
> }
>}

は、
double x_i(int i, int N)
{
 return cos ((PI*(2*i-1))/( 2*N ));
}
になるだけなんじゃないですかね?


>int i[20];   //配列の指定の大きさ
>int N[20];
で、関数の方は
>double x_i(int i, int N)
で、コールは
>printf("x[%2d] = %f\n",i, x_i(i,N));

コールする時の第1引数と第2引数は配列を渡していますが、関数の仮引数の方と一致しません。
ということで、コンパイルエラーでしょう。

>x_i(i, N) = cos ((PI*(2*i-1))/( 2*N ));

既に指摘していますし、他の方からも回答ありますが、関数コールに対して値の代入はできません。
ので、こちらもコンパイルエラーでしょう。


>Nは5と決まっているわけではなくて、20までで自分で、自由に決めれるようにしたいです。

>printf("i = ");
>scanf("%d", &N);

iなのかNなのか不明ですが…
規定の範囲の値が入力されるまでループするようにすればよいかと。

do {
 printf("i = ");
 scanf("%d", &N);
} while((N < 0) || (N > 20));
とか?
# scanf()でのエラー処理していませんが。(数字以外を入力すると無限ループに堕ちるとか)
    • good
    • 2

私が少しかき回しちゃいましたね。

すみませんでした。
    • good
    • 0

昔知り合いにこんなプログラムを書く人がいたなー。


質問者はC言語とBASICを混同していませんか?

関数の戻り値は"return"で、これがC言語の決まり。
また、関数名はその関数内で変数とはならない。

double x_i(int i, int N)
{
for (i = 1 ; i <= N ; i++) {
x_i(i, N) = cos ((PI*(2*i-1))/( 2*N ));

}
}

先ず、 x_i(int i, int N)関数内で x_i(i, N)を出していますね。これはC言語では再帰に使用します。つまり、x_i()関数をx_i()関数内で呼び出しているのです。今回の場合、x_i()に数値を入力しようとしていますが、こんなことはC言語ではできません。
BASICだとこの書き方はx_i()に戻り値を与えることになりますが、C言語では違います。
関数の戻り値は単にreturnに戻り値を渡せばOK。return a;とすればaの値がこの関数の値として呼び出した側の関数に渡されます。

それとこの関数内でforループを入れる必要はありませんね。main()関数でforループを回しているのでx_i()関数内でのforループは不要。ついでに言っておくとC言語では一つの関数に複数の戻り値を持たせることはできない。
複数の結果が必要な場合は引数をポインタで渡して、そのポインタから得られるアドレスに数値を代入することになります。


質問者が望むC言語の関数x_i()は
double x_i(int i, int N)
{
return cos ((PI*(2*i-1))/( 2*N ));
}

これで十分。
    • good
    • 2

>double x_i(int i, int N)


>{
> for (i = 1 ; i <= N ; i++) {
>  x_i(i, N) = cos ((PI*(2*i-1))/( 2*N ));
> }
> return 0 ;    //ここにreturnがなかった
>}

『関数の戻り値に代入しようとしている。』
という点を除けば、とりあえず戻り値返しているのでコンパイルエラーにはならずに済むでしょう。
ただし、cos()の結果は捨てて「常に0は正義なのだ!!!」としているので、
x[ 1] = 0
x[ 2] = 0
x[ 3] = 0
x[ 4] = 0
x[ 5] = 0
となりますが。

何度も書いていますが、計算結果を一時保存するわけではないのですから配列はまったく無関係です。
仮に一時保存するのであれば、「20までで自分で、自由に決めれるようにしたいです。」という条件から、動的確保することになるでしょう。
# 最大値の要素数20個の配列固定でもいいですけどね。(エラー処理あるから20個固定の方が楽でしょう)
    • good
    • 0

>ここも


>double x_i[ i, N]

それで…x_iというシンボルは
「配列」なんですかね?
「関数名」なんですかね?
    • good
    • 0
この回答へのお礼

x_i は関数名のつもりで作成していました。

お礼日時:2018/12/04 12:05

ここも



double x_i[ i, N]
    • good
    • 1

x_i[i, N] = cos ((PI*(2*i-1))/( 2*N ));

    • good
    • 0

ご参考まで。



https://www.sejuku.net/blog/24359

配列は[ ]でしたね。
    • good
    • 0
この回答へのお礼

ご回答ありがとうございます。
理解が悪くてすみません。配列の大きさの指定は読んだことがありました。
それで、変えてみたのですが、

#include <stdio.h>
#include <math.h>

#define PI 3.1415926535

int i[20];   //配列の指定の大きさ
int N[20];

double x_i(int i, int N)
{
for (i = 1 ; i <= N ; i++) {
x_i(i, N) = cos ((PI*(2*i-1))/( 2*N ));
}
return 0 ;
}

int main()
{
int i, N ;

printf("N= ");
scanf("%d", &N);

for (i = 1 ; i <= N ; i++) {
printf("x[%2d] = %f\n",i, x_i(i,N));
}
return 0 ;
}

で合ってますか?また何か違うところがあれば教えていただけると嬉しいです。

お礼日時:2018/12/04 11:30

x_i(i, N) = cos ((PI*(2*i-1))/( 2*N ));


で、左辺の 「 x_i(i,N) 」というのが、文法的には「関数の呼び出し」で、
「関数の呼び出し」というのは、その値を参照することはできても代入はできない値(rvalue)です。
その rvalue に代入しようとしている、というのがエラーの内容です。

lvalue required as left operand of assignment
代入の左辺にlvalueが必要だ


まずは、 x_i という関数がどんな仕様なのか、はっきりさせましょう。

x_i = cos ((PI*(2*i-1))/( 2*N )) i =1,2,...,N  
の iとNを指定して、そのときの x_iの値を求める関数、ということなら、この関数の中でループする必要は無いし、
存在しない「配列」なんて考える必要もありません。
    • good
    • 3

>double x_i(int i, int N)


>{
> for (i = 1 ; i <= N ; i++) {
>  x_i(i, N) = cos ((PI*(2*i-1))/( 2*N ));
> }
>}

関数の戻り値?にcos()の結果を代入したいんでしょうか?
でも、return文がないので戻り値ではないですね。

どこにも配列は出てきていませんが。
    • good
    • 1
この回答へのお礼

ご回答ありがとうございます。
直してみたんですが、wr5さんのおっしゃってるのは

#include <stdio.h>
#include <math.h>

#define PI 3.1415926535

int i[20];
int N[20];

double x_i(int i, int N)
{
for (i = 1 ; i <= N ; i++) {
x_i(i, N) = cos ((PI*(2*i-1))/( 2*N ));
}
return 0 ;    //ここにreturnがなかった
}

int main()
{
int i, N ;

printf("N= ");
scanf("%d", &N);

for (i = 1 ; i <= N ; i++) {
printf("x[%2d] = %f\n",i, x_i(i,N));
}
return 0 ;
}

で合ってますか?もし何か間違いがあれば教えていただきいです。

よろしくお願いします。

お礼日時:2018/12/04 11:33

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!