ページ 1 / 1
この関数の意味は?
Posted: 2010年1月14日(木) 20:22
by jay
龍神録プログラミングの館で分からないことがあったので質問させて頂きます
反魂蝶八分咲きをつくろうの章で
for(j=0;j<2;j++){
for(i=0;i<num;i++){
int plmn=(j ? -1 : 1);
という部分がありますが、
これはint型で宣言した文字列plmnにどのような値を代入することになるのですか?
(j ? -1 : 1)この部分はどのような意味を持つのですか?

Re:この関数の意味は?
Posted: 2010年1月14日(木) 20:26
by Dixq (管理人)
条件演算子(三項演算子?)と言います。
http://www2.ee.knct.ac.jp/el/E3/E305/jy ... zansi.html
この辺参考になるかと。
if文使ってかかないといけない部分がすっきり書けていいのですが、
プログラムが読みにくくなるといって嫌う人もいます。
大勢で共有するプログラムはなるべく避ける傾向にあるかもしれませんね。
Re:この関数の意味は?
Posted: 2010年1月14日(木) 20:41
by たかぎ
> プログラムが読みにくくなるといって嫌う人もいます。
> 大勢で共有するプログラムはなるべく避ける傾向にあるかもしれませんね。
知らない人、使いこなせない人が多いからでしょうね。
あるべき論としては、"プログラマを信じる"ことを是とする「Cの精神」からすれば、信じるに値しないプログラマは、Cなんか使わず、能力に見合った分相応の言語や職業を選ぶべきなのですが、現実はなかなか難しいようです。
知らなかったことはしかたがありませんが、一度説明されれば分るはずですけどね。
もしかすると、末端のプログラマの問題ではなく、適切に指導できないベテランの能力の問題なのかもしれません。
Re:この関数の意味は?
Posted: 2010年1月14日(木) 21:00
by ft
横からすみません。私も龍神録プログラミングの条件演算子でつっかかっていたので教えてください。
これはcshot.cpp内の一部を丸ごとコピーしたものなんですが、
これを条件演算子を一切使わずにプログラムを書くとしたらどうなるのでしょうか?
分かる方がいましたら教えてください。
#include "../include/GV.h"
int cshot0num[2] ={2,4};
int cshot0pos_x[4]={-10, 10,-30, 30};
int cshot0pos_y[4]={-30,-30,-10,-10};
#define OPTION_X 25
#define OPTION_Y 35
int option0num[2] ={2,4};
double option0ang[4] = {-PI/2,-PI/2,-PI/2-PI/4,-PI/2+PI/4};//オプションの発射角度(49)
//自機ショットの登録可能番号を返す
int search_cshot(){
for(int i=0;i<CSHOT_MAX;i++){
if(cshot.flag==0)
return i;
}
return -1;
}
//通常ショット登録
void ch0_shot_pattern(){
int k;
int n=cshot0num[ch.power<200?0:1];
for(int i=0;i<n;i++){
if((k=search_cshot())!=-1){
cshot[k].flag=1;
cshot[k].cnt=0;
cshot[k].angle=-PI/2;
cshot[k].spd=20;
cshot[k].x=ch.x+cshot0pos_x;
cshot[k].y=ch.y+cshot0pos_y;
cshot[k].power= (n<2 ? 20 : 12) +ch.power/100;//2筋なら20,4筋なら12(50)
cshot[k].knd=0;
cshot[k].img=img_cshot[0];//画像番号代入(49)
}
}
se_flag[2]=1;//発射音オン
if(ch.power>=100){
for(int i=0;i<(ch.power<300?2:4);i++){
if((k=search_cshot())!=-1){
cshot[k].flag=1;
cshot[k].cnt=0;
cshot[k].angle=option0ang;
cshot[k].spd=20;
cshot[k].x=option_bb[i%2].x;
cshot[k].y=option_bb[i%2].y;
cshot[k].power=10-7*(i/2);//マイナスにならないよう注意(50)
cshot[k].knd=1;
cshot[k].img=img_cshot[1];//画像番号代入(49)
}
}
}
}
//低速通常ショット登録
void ch1_shot_pattern(){
int k;
int n=cshot0num[ch.power<200?0:1];
for(int i=0;i<n;i++){
if((k=search_cshot())!=-1){
cshot[k].flag=1;
cshot[k].cnt=0;
cshot[k].angle=-PI/2;
cshot[k].spd=20;
cshot[k].x=ch.x+cshot0pos_x/3;//低速中なら位置を中心側へ
cshot[k].y=ch.y+cshot0pos_y/2;
cshot[k].power= (n<2 ? 20 : 12) +ch.power/100;//2筋なら20,4筋なら12(50)
cshot[k].knd=0;
cshot[k].img=img_cshot[0];//画像番号代入(49)
}
}
se_flag[2]=1;
if(ch.power>=100){
for(int i=0;i<(ch.power<300?2:4);i++){
if((k=search_cshot())!=-1){
cshot[k].flag=1;
cshot[k].cnt=0;
cshot[k].angle=option0ang;
cshot[k].spd=20;
cshot[k].x=option_bb[i%2].x;
cshot[k].y=option_bb[i%2].y;
cshot[k].power=10-7*(i/2);//マイナスにならないよう注意(50)
cshot[k].knd=1;
cshot[k].img=img_cshot[1];//画像番号代入(49)
}
}
}
}
//オプションのぼんぼん計算
void calc_option_bb(){
if(ch.power>=100){//パワー100以上ならオプションをつける
for(int i=0;i<2;i++){
if(CheckStatePad(configpad.slow)==0){//低速移動中じゃないなら
option_bb.x=ch.x+OPTION_X*(i==0 ? -1 : 1);
option_bb.y=ch.y+OPTION_Y+sin(PI2/150*option_bb.cnt)*20;
}
else{
option_bb[i].x=ch.x+OPTION_X/2*(i==0 ? -1 : 1);
option_bb[i].y=ch.y+OPTION_Y/2;
}
option_bb[i].cnt++;
}
if(option_bb[0].flag==0)
option_bb[0].flag = option_bb[1].flag = 1;
}
else{
if(option_bb[0].flag==1)
option_bb[0].flag = option_bb[1].flag = 0;
}
}
Re:この関数の意味は?
Posted: 2010年1月14日(木) 21:06
by jay
ありがとうございます。
jがifの()の中の部分で-1が真の値、
1が偽(else)の値(または0)ですね。
今回の場合if文に直すと、
if(j==0)
plmn=1;
else
plmn=-1;
ということでいいのでしょうか?
Re:この関数の意味は?
Posted: 2010年1月14日(木) 21:13
by sizuma
>ftさん
>これを条件演算子を一切使わずにプログラムを書く
条件演算子の説明を読めばわかるとおもうのですが・・・・
>int plmn=(j ? -1 : 1)
これを
int plmn;
if(j){
plmn = -1;
}else{
plmn = 1;
}
括弧を使わない人が多いでしょうが、僕は1行でも括弧を書きたいと思ってますので、お好みで。
こんな感じで全部書き換えればいいと思います。
僕は?演算子は見やすくなるのでいいと思います。
Re:この関数の意味は?
Posted: 2010年1月14日(木) 22:29
by Dixq (管理人)
ホントわかりにくい書き方してますね・・。すみません。
> if( j )
って書き方は本当はしない方が無難です。
それに伴って
j ? -1 : 1;
も、すっきり見えますが、誤解のもとなので、
j!=0 ? -1 : 1;
もしくは
if( j!=0 ){
plmn = -1;
} else {
plmn = 1;
}
と書いた方が良いでしょう。
すっきり書くのもいいですが、
誰もが見て誤解しないコード、自分が後でメンテナンスしやすいコードを書くことも重要ですね。
Re:この関数の意味は?
Posted: 2010年1月14日(木) 22:54
by jay
確かにスッキリするのは良いですが、分からなければ意味がないですもんね。
とりあえず理解は出来たのでありがとうございました。
Re:この関数の意味は?
Posted: 2010年1月15日(金) 16:57
by Naohiro19
jay さん>
a > 20 ? a = 20 : a = 10;
aが20より大きければaに20が入り、それ以外はaに10が入ります。
つまり
if( a > 20){ a = 20; }else{ a = 10; }
とまったく同じです。
Re:この関数の意味は?
Posted: 2010年1月15日(金) 17:56
by box
> a > 20 ? a = 20 : a = 10;
>
> aが20より大きければaに20が入り、それ以外はaに10が入ります。
おかしいな…。
私のところでは、コンパイル時に「左辺値が必要」という意味の
エラーが出ました。
a = (a > 20) ? 20 : 10;
と勘違いされてるのかな?
Re:この関数の意味は?
Posted: 2010年1月15日(金) 18:14
by hoge
> > a > 20 ? a = 20 : a = 10;
> >
> > aが20より大きければaに20が入り、それ以外はaに10が入ります。
>
> おかしいな…。
> 私のところでは、コンパイル時に「左辺値が必要」という意味の
> エラーが出ました。
Cでコンパイルしていませんか?
C++だとコンパイルできますよ。

Re:この関数の意味は?
Posted: 2010年1月15日(金) 18:16
by たかぎ
> jay さん>
>
> a > 20 ? a = 20 : a = 10;
>
> aが20より大きければaに20が入り、それ以外はaに10が入ります。
>
> つまり
> if( a > 20){ a = 20; }else{ a = 10; }
> とまったく同じです。
そんなことはありません。
条件演算子は代入演算子より優先順位が高いので、
((a > 20 ? a = 20 : a) = 10;
のように解釈しようとしてエラーになります。
また、式と文では同じ意味にはなりません。

Re:この関数の意味は?
Posted: 2010年1月15日(金) 18:19
by たかぎ
> Cでコンパイルしていませんか?
> C++だとコンパイルできますよ。
そうか、C++か。紛らわしいですね。
Re:この関数の意味は?
Posted: 2010年1月15日(金) 21:17
by box
> Cでコンパイルしていませんか?
> C++だとコンパイルできますよ。
くだんの文脈ではCかC++の判断ができなかったので、
さしあたり、私がよく知っている方の言語とみなして
コンパイルしてみたのでありました。
C++では、おっしゃるとおり問題なくコンパイルできました。
どうもありがとうございます。
Re:この関数の意味は?
Posted: 2010年1月15日(金) 22:04
by たかぎ
Cの場合、
conditional-expression:
logical-OR-expression
logical-OR-expression ? expression : conditional-expression
ですが、C++の場合、
conditional-expression:
logical-or-expression
logical-or-expression ? expression : assignment-expression
ですので、微妙に文法が異なります。
この辺が原因ですね。