• ベストアンサー

なぜ、i++なのか?(ものすごくくだらない質問です)

C言語や、それに文法が似ている言語では、 for(i=0; i<10; i++)... のような例をよく見かけます。 ここで、何故か++iよりi++を使うほうを非常によく見かけるのですが、何故なんでしょうか? 単独で使う分にはどちらでも同じなので、実際はどうでもいいのですが。 個人的には、++iは副作用がまずあって、その副作用の結果を返すのに対し、i++は副作用があることは同じですが、「副作用を起こす前の値」を返す演算ということで、i++の方が少々不自然な感じがしますので、++iの方が好きなのですが。 もし、何か特別な理由があることを知ってらっしゃる方がいたらお願いいたします。

noname#130082
noname#130082

質問者が選んだベストアンサー

  • ベストアンサー
  • aris-wiz
  • ベストアンサー率38% (96/252)
回答No.9

C言語の規格書内の例やfor文の説明で、 i++という表現が使用されており、 多くのC言語を教えている書籍や 先人の方々によってそれが伝統的な書き方に なっているからではないでしょうか? 極端な話、変数名だってiである必要もありませんし。。。 また、効率を気にして++iなどにされる方も多いと思いますが、 あくまでも理論上であって、inc命令の使える最近のCPUでは 処理に差が出ないから「よく使われているi++を使う」という人も いると思います。 >++i は処理前、i++ は処理後です。なので処理文中に使うと > 値が違ってきます。 確かにそうですが、for文の(初期化節・条件式・ボイド式)に ついてはループに入る前に評価され、それぞれの節、式に 副作用完了点があるため、前方置換・後方置換どちらで書いても 単項式であるなら、結果は変わりませんしボイド式の中で、 計算順序を気にしなければならない様な複雑な処理を書くべきでは 無いと思います。

noname#130082
質問者

お礼

回答ありがとうございます。 まさか、こんな沢山回答をいただけるとは・・・。 教科書などの書籍の影響ですか。確かにそれも大きいですよね。 昔の教科書とか、確かめてみなければ・・・。 C言語でなくとも、言語の入門書の最初のサンプルが Hellow World になってたり(^^;。 C++言語という名前も、i++の書き方の方が多かったからかもしれませんし。 効率を考えすぎて読みにくいプログラムを作るよりは、CPUや最適化にまかせた方がいいかもしれませんね。 私の質問も、あくまで、前置と後置のどちらでもよい場合に、何故後置が多用されるのか?ということです。 ボイド式以外でも、できるだけ計算順序を勘定に入れなければいけないような記述は避けたほうがいいですよね。私も、インクリメントやデクリメントは式中でなく、出来る限り単独で使う方針です。これは、副作用のある関数を式中に使う場合も同様の注意が必要ですね。

noname#130082
質問者

補足

うわぁ! 何と、K&R「プログラミング言語C」がi++を使ってました。 何とか手に入れたのが古本の「第2版のANSI規格準拠版」なので、はっきりとはわかりませんが、初版でも多分同じなのではないかと思います。 この本によりますと、最初は++iを使ってますが、第2章8節で前置++、--と後置の意味の違いを明記した後は、何故か基本的にi++を使っています。まだ全部を熟読したわけではないのですが、取りあえずこの時点では、何故そうするかの説明は無いようです。 多分、合理的な理由はあるのでしょうが、それとは別に「K&Rでi++を使っているから、たぶんこれが正しいやり方なのだろう」と思って後置の方を使ったプログラマが沢山いたことは間違いないと思います(^^;;;;。 ここらへんが多分正しそうな気がします(^^; K&Rが何故後置を使ったのか?は別質問になりますので、どうしても分からなければ別質問をするとします。取りあえず、考えられることは。 ・K&Rの使っていたコンピュータがi++の方が都合が良かった。 ・while(*s++ = *t++); のようなトリッキーだが便利な機能がCで書けるので、後置を使うことにした(C言語を売り出すためには、Fortran、Cobol、Pascalなどの既存の言語との差別化が必要だった)。 ・後置を使うと for(i ~;i ~;i ~)... という形になって形が綺麗である。 あたりが考えられます。 あと、C++ では 演算子のオーバーロードができるために事情が違うわけです。C++ の場合は後置++の方がほとんどの場合効率が悪いので、後置を使う特別の理由がない限りは前置の方を使うのが正しい、わけです。 ところで、#6さんへの回答への補足に間違いがあったのですが、#6さんが突っ込んでくれないので、自分の間違いの指摘をここでさせていただきます(__)。 Javaではクラスのインスタンスを作るときはnewを使うので勘違いしてしまいました。C++ で後置++を定義するときは、newは使わずに局所変数に自分のコピーを作って、それをreturnするのが正式のやり方なんですね。従って、C++;と単独で使った場合には、returnした後に自動的にインスタンスは破棄されるのでメモリリークは発生しない、わけです。 そのかわり、 A=C++; というようなことをやると、まずCの中のauto変数に自分自身のコピーを作ってそれを返すが、auto変数のインスタンスは消えてしまうので、Aはあらためてクラスのインスタンスを作って生成しなければいけない。つまり、自分自身のコピーを作る、という操作が「2回」必要になるわけです。で、Aのインスタンスもいずれは破棄しなければいけないので、破棄も結局は「2回」やらなければいけないわけですね。確かにこれは効率が悪い(^^;;;;; まあ、私はC++の文法もよく知らないし、C++のプログラムを作ったことは1度もないので、この間違いはご容赦ください(__)。 javaでは、そもそも++の再定義ができないし、newはあってもdeleteはないので「悩む必要がない」わけです。 なるほど。「自由には責任が伴う」ので、javaでは「自由を制限することで、責任も減らす」ためにC++より厳しい規則になっていて、そのかわりC++より悩みを少なくしているわけです(^^; 大分、仕組みが分かってきました(^^)。 結局、質問したことは無駄ではなかったわけです。勉強になりましたから(^^)。 ということで、大体分かったので、何か見落としていることがあって、誰かが突っ込んでくれる可能性があるのでしばらく締め切りは待つことにします。しばらくたっても突っ込みがなければ質問を締め切らせていただきます。

その他の回答 (11)

  • kiwa67
  • ベストアンサー率22% (82/357)
回答No.12

#1です。 > 取りあえず、C言語の規格を確認しないと・・・。 規格では、   (*(p++)) に統一されているはずですが、全てのコンパイラが規格どおりとは、限らないということです。

noname#130082
質問者

お礼

補足、ありがとうございました。 そういう意味でしたか。 規格を間違えて覚えてしまったのかと、あわててしまいました。 *p++ を (*p)++ と解釈されるのは困りますねえ。 それでは、++や--の問題というより、 *p++ のような構文的に混乱の可能性のある式は、冗長でも括弧を使って *(p++) と明示した方がよさそうですね。 ありがとうございました。

  • kiwa67
  • ベストアンサー率22% (82/357)
回答No.11

#1 です。 > 個人的な意見ですが好みで++i,i++を使うのは止めた方が > いいです。 > ポインタ処理のアドレス移動とかでバグを生む可能性が高いです。 この件に関して過去の実例として、ポインタ p に対して   *p++ が、処理系によって解釈が違うケースに遭遇しました。 ある処理系では、   *(p++) と解釈されたり、別の処理系では、   (*p)++ と解釈されたり。。。。 移植性を考えた場合、ポインタに ++ は使うべきではないね。 と実感しました。

noname#130082
質問者

お礼

本当ですか? 今の今まで、C言語では、後置演算子は前置演算子より結合が強いとばかり思っていたので。 急いで適当に検索してみましたが、 http://www.grapecity.com/japan/powernews/column/clang/021/page03.htm で、 char *p; のときに while(*p++)... という書き方をしていますが、明らかに「構文解析」では while(*(p++))... と解釈し、「実行順序では」whileの条件判断では最初の *p が使われ、その後に、pがインクリメントされていますけどねえ。 取りあえず、C言語の規格を確認しないと・・・。 いろいろ勉強になります。ありがとうございました。(いろいろな勉強に時間がかかりそうなので締め切りは遅くなりそうです)。

  • Tacosan
  • ベストアンサー率23% (3656/15482)
回答No.10

C++ でインクリメント/デクリメント演算子を使うようになると ++i を好きになれるかもしれない>#9. 後置の方が, 明らかに処理量が多いんですよね. ついでにいうと前置と後置の根本的な違いは「その演算によって得られる値」だけであり, 「インクリメントするタイミング」ではありません>#7. つまり printf("%d\n", ++i); を printf("%d\n", i+1), i=i+1; と解釈しても全く問題ありませんし逆に printf("%d\n", i++); を i=i+1, printf("%d\n", i-1); と解釈しても構わない. というか, (C/C++ では) 「いつインクリメントされるか」に依存してはならないことになってる.

noname#130082
質問者

お礼

ご回答ありがとうございます! 勉強しなければならないことが、どんどん増えてきます(^^;。 C++ で ++、-- をやると、前置の方が好きになるかも、ですか。 それでは、++C 言語とするべきだったかもしれませんね(^^;。 後置だと、「元の値」を覚えていなければならないので処理は増えますよねえ。そこらへんも不自然さを感じていたのです。 >「いつインクリメントされるか」に依存してはならないことになってる めもめも。また勉強になりました<(__)>。

noname#130082
質問者

補足

検索してみると、C++では違いが大きいということになってますね。 http://d.hatena.ne.jp/cubicdaiya/20080606/1212695409 http://z56.blog.so-net.ne.jp/2008-07-21 後置の場合、元の値を覚えていなければならない、ということは、オブジェクトを生成・破棄しなければならなくなるわけですね。 取りあえず、C++をやることになったら、気をつけます。 ありがとうございました。

  • tadys
  • ベストアンサー率40% (856/2135)
回答No.8

CPUによっては機械語の命令の中に「ポストインクリメント命令」と「プリディクリメント命令というものを持ったものがありこのCPUを使う時は *i++ は1命令で実行が出来るが *++i は2命令が必要、 *--i は1命令で実行が出来るが *i-- は2命令が必要、 という風になります。 そのため *++i を繰り返し実行する場合には 実行速度を上げるために *i++ に置き換えることがあります。 ++i と i++ では速度に差は出ないのですが * が付く場合には ++i と i++ に差が出てきます。 こういうCPUが多かったためインクリメントする時は i++ を使う事が習慣になったと思われます。

noname#130082
質問者

お礼

回答、ありがとうございます! へえ、「ポストインクリメント命令」と「プリディクリメント命令」なんてものがあったんですか! 知りませんでした(。_。; (また、つまらん無知を晒してしまった・・・。) そういう事情もあったんですね。勉強になりました<(__)>。 まあ、インクリメント・デクリメントにポインタが絡んでくるとやっかいですね。頭が痛くなります。 CPUの違いは、できればコンパイラの方で吸収してくれると助かるのですが、なかなか世の中甘くないですね。

noname#88772
noname#88772
回答No.7

 こんにちは。  なかなか深い質問です。通常はそのまま何も考えずに使ってしまう ことが多いです。  個人的な意見ですが好みで++i,i++を使うのは止めた方がいいです。 ポインタ処理のアドレス移動とかでバグを生む可能性が高いです。  ++i、i++ の根本的な違いは、埋め込んだその処理文内でインクリメント するタイミングです。 ++i は処理前、i++ は処理後です。なので処理文中に使うと値が違ってきます。  以下のプログラムで確認できると思います。i はあえてカウンタとして 使用していません。printf() が一つの処理と考えてください。 i の値が違っているのが解ると思います。  ご参考までに。 ------ ここから ------ #include <stdio.h> int main( void ) { int count, i; printf("--- 1 ---\n"); i=0; // i を初期化 for( count=0; count<10; count++ ) { printf( " [1] i : %d\n", i++ ); } printf("--- 2 ---\n"); i=0; // i を初期化 for( count=0; count<10; count++ ) { printf( " [2] i : %d\n", ++i ); } return 0; } ------ ここまで ------

noname#130082
質問者

お礼

丁寧な回答、ありがとうございました。 まあ、私が「好み」と言ったのは、あくまで、どちらを使っても結果が変わらない場合での話ですので、結果が違ってくるときは当然正しい使い方にする、という意味です(^^;。 もっとも、世の中がi++に慣れているなら、こちらの意地を通す意味もないんで大勢に従う方がいいとは思います。 私も式や関数の引数にインクリメントやデクリメントをする場合は注意が必要だと思います。for文の中でも、i++の部分がもっと複雑な場合は要注意ですし。 私はもう何年もプログラムしてませんが、たぶん私の場合は(自分が後で読むときを考えて)効率より読みやすさを優先して、i++は単独で使うと思います。例えば、yuji_syamiさんの例で言えば、 printf( " [1] i : %d\n", i++ ); は、 printf( " [1] i : %d\n", i ); i++; と書いて、 printf( " [2] i : %d\n", ++i ); は、 i++; printf( " [2] i : %d\n", i ); と書くと思います。これらの場合は前置でも大丈夫ですね。

  • BLK314
  • ベストアンサー率55% (84/152)
回答No.6

ymmasayanさんは勘違いされていると思われます http://ja.wikipedia.org/wiki/For%E6%96%87 を参照してください カウンタの更新が行われるのは ループ内の文を実行した後です。 初期条件には何ら影響を与えません。 従って ++iとi++で始まる数が変わるなんてことはありません int _tmain(int argc, _TCHAR* argv[]) { for (int i = 0; i < 10; ++i) { printf("i = %d\n", i); } for (int j = 0; j < 10; j++) { printf("j = %d\n", j); } return 0; } 上記プログラムを実行しましたが iもjもともに0 から 9で同じです 本題に戻りますが 私も以前は i++派でした。 hidebunさん同様、日本語で考えていたからです。 しかし STLを使うようになり 自分で ++の前置, 後置を書くようになってから ++iに改めました。効率が悪いことに築いたからです。 まあ、きっかけは、"Effective C++"なのですが(笑) 実際にコーディングしてみるとより実感できます。 ま、intなどをカウンタにしている場合はほとんど変わらないので どっちでもいいともいえます。 ただ、クラスになると、(BOX化など)話は別で できるだけ効率に気を配ったほうが良いと考えます。

noname#130082
質問者

お礼

ご回答ありがとうございます。 まさか、こんな質問に、こんなに回答が付くとは思っても見ませんでした(^^;。 C++は扱ったことがないので(領域管理とか、多重継承とか、オーバーロードとかが辛そうだった)、これから勉強しないとBLK314さんの回答の意味をきちんと理解するのは難しいですけど・・・。STLの名前は知ってるんですが中身は知らなくて<(__)>。C++は演算子のオーバーロードができるんでしたね。 もっとも、C言語の範囲でも、++i と i++ の働きをする関数を作ろうとすると、i++ の方が処理が余計にかかりそうですね。それがクラスとなれば、確かに効率の差は大きいかもしれません。

noname#130082
質問者

補足

私がC++を誤解していなければの話ですが。 CFooというクラスで、前置++と後置++が定義されている場合、前置++ではコピーは必要ないが、後置++では多分、自分自身をコピーしてから、何らかのインクリメント処理をするわけですね。とすると、CFoo型へのポインタを扱う場合、前置と後置ではインスタンスが同じか違うか、という差が出るわけですね。 というより、 CFoo x(・・・); の場合、 ++x; はともかく、単独の x++; は、以前のxのコピーが破棄されずに残って、もろにメモリリークを引き起こすのでしょうかね。 C言語だと単独で使う分には前置++も後置++も結果は同じになりますけど、C++ のクラスでは結果はおそらく違うことになりますね。 その場合だと、好みの問題ではなくなりますね。

  • asuncion
  • ベストアンサー率33% (2126/6288)
回答No.5

>#4さん >i++なら0から処理開始 >++iなら1から処理開始です。 おっしゃっている意味が全くわかりません。 詳しいご説明をお願いいたします。

noname#130082
質問者

お礼

コメント、ありがとうございます。 #4さんのコメントがなかなかないようですので、想像ですが、私の私見を述べさせていただきます。 #4さんは「++i」は「まずiをインクリメントする」という意味で、「i++」は「後からiをインクリメントする」ととらえていたために、勘違いをなさっていたのではないかと想像します。 しかし、こういうことは、前置++と後置++がある以上、必ず勘違いをされる方が出てくる、ことはほとんど確実と思われます。 私の疑問も、こういう勘違いは必ず出てくるので、後置++のようなものを使うのはいいのだろうか?という疑問も含まれているのです。 結局、私の私見では、前置と後置の++、--の両方があるのは、勘違いをほとんど必ず引き起こすので、片方に統一した方がいいのではないか?という結論に傾いています。

  • ymmasayan
  • ベストアンサー率30% (2593/8599)
回答No.4

初期値i=0との絡みだと思います。 i++なら0から処理開始 ++iなら1から処理開始です。 私は前者のほうが勘違いしにくいような気が。 逆に終了条件は要注意ですが。

noname#130082
質問者

お礼

回答、ありがとうございます。 しかし、大変失礼ですが、この私の質問の形ではどちらも同じ結果になるはずだと思いますけど。 ++iは確かに「先にiを増加させる」ものですが、終了判定やfor文のbodyより先ではなかったと思います。 もっとも、どちらにしても繰り返しは、初期値の設定間違いと終了判定の間違いがバグの温床であることには間違いはないですね(^^)。注意してしすぎることはないでしょう(^^)。 私もより注意が必要だという確認になりました。 ありがとうございます<(__)>。

  • hidebun
  • ベストアンサー率50% (92/181)
回答No.3

日本語の語順で考えながらコードを書くからじゃないですか? 「増やす(++)iを」よりも、「iを増やす(++)」と考えるほうがしっくりくる。 ソースコードを眺めているときに、心の中で、音読したりしませんか? 英語圏の人は、どう書くんでしょうね。

noname#130082
質問者

お礼

日本語ってのは考えませんでした。確かに、日本語は後置記法の方が合っているとは前から思ってはいましたが。 しかし、C++ と言う名前は日本人じゃないような・・・。 どちらにしても、日本人にとっては後置の方が見やすそうですね。 ありがとうございました。

  • Tacosan
  • ベストアンサー率23% (3656/15482)
回答No.2

見やすいから, でしょうね. 理論上は ++i の方が速くなる可能性があるんですが.

noname#130082
質問者

お礼

回答ありがとうございます(^^)。 やはり、見やすさ、という方が多いですね。 速さに関しては、確かに機械語にはインクリメント命令があるわけだから++iは使い場所によっては非常にはやくなりますね。まあ、コンパイラの最適化でそれほど大きな差が出ないかもしれませんが。 とはいえ、共同でプログラムを作ったり、何度も「バージョンアップ」をしなければならないソフトの世界では、見やすさもはやさのうちかもしれませんね。

関連するQ&A

  • 問題がとけません

    以下の設問に答えよ。 型はC言語の基本型でchar型を除いたもので答えよ。 1.次の演算結果の型と値を求めよ。 100/10*5 2.次の演算結果の型と値を求めよ。 1.0f/2 3.次の演算結果の型と値を答えよ。 100/10*5.0 4.次の演算結果の値を答えよ。 54321-54321/100*100 5.次の演算結果の値を答えよ。※(int)(式)は,式の値の小数点以下を切り捨ててint型に変換する。 (int)(123/5.0+0.5) 6.次の演算結果の型と値を答えよ。 5<2 7.次の演算結果の型と値を答えよ。 5.0>2 8.変数a,b,cに関して,a<b<cの真偽を評価する論理式を書け。 9.次の文が実行された後,変数i,kの値はいくらになっているか。変数はどちらもint型とする。 i=0; k=0; k=5+(++i); 10.次の文が実行された後,変数kの値はいくらになっているか。変数はどちらもint型とする。 i=5; k=5; k *= i<0 ? (-i) : i; 11.次の文Aは実行されるか。kの型はintである。文法的な誤りはない。 if(k = 0)  文A

  • C言語の副作用に関する未定義

    C言語で副作用を持つ演算を含む場合は、その副作用が実行されるタイミングが未定義となっているようですが、 以下のコード int a[10]; int i; while (i < 10) a[i++] = i; では、 a[i++] = i; の代入演算子(=)の結合規則が右から左であるため、aのインデックスとしてiが参照されるよりも早くiの値を代入しているため、未定義にならないと思うのですが、実際はどうなのでしょうか? (a[i] = i++; の場合は完全に未定義になる。) 実際にこのようなコードを書くことは無いと思いますが、気になったもので。 もしご存知の方がおいででしたら教えていただけないでしょうか。 よろしくお願いします。

  • JavaでC言語のポインタ演算風な使い方は

    Java初心者です。ずっとC言語をやっていました。 Javaにはポインタは存在せず(実際は参照渡しなのでポインタその ものなのですが)、ポインタに対する演算はありませんよね。 C言語で、 int buf[2*10]; int *dst = buf; for(i=0;i<10;i++){ dst[0]=a; dst[1]=b; dst += 2; } のようなソースをJavaで書こうとすると、 for(i=0;i<10;i++){ buf[i*2+0]=a; buf[i*2+1]=b; } しか思いつきません。 コンパイルして最適化されれば問題ないと思いますが、 なんか配列中の演算が演算量をとりそうで、気になっています。 もっと高速に処理されるような書き方はないものでしょうか? アドバイスよろしくお願いします。

    • ベストアンサー
    • Java
  • プログラムの高速化について質問です。

    プログラムの高速化について質問です。 現在C言語でプログラムをかいているのですが、 1.プログラムの量を減らすため、*やforを使って繰り返し演算をする。 2.なるべく*やforを減らすため、長いプログラムにする この二つではどちらのほうがプログラムを高速化することが出来るのでしょうか?

  • 教えて下さい。C言語の文法の意味!!

    教えて下さい。C言語の文法の意味!! いくつか質問しますので、詳細を教えてください。 何かのファイルを取得しようとしているのは分かるのですが・・・ *-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-   <定義部分> char buff[0x805];   char *tp,strbs[20],yo[50] *-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-   例:)tp=&buff[5*16+5+(16*21+6)];   質問1:"5*16+5+(16*21+6)"の意味 ポインタ?、なぜこのような計算方法?   どんな結果になるのかを知りたいです。 *-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-   例:)sprintf(strbs,"%08d",*((unsigned int*)(tp-4)));   例:)for(i=0;i<20;i++)yo[i]=*(tp-65+i);yo[i]=0;   質問2:"tp-4"とか"tp-65+i"の意味 どのような計算で結果を求めるものなのでしょうか。 *-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*- 上記の意味を知りたいのですが、どこにも載っていません。 どなたかご存知の方は教えて頂きたく、宜しくお願いします。

  • C初心者に課題をください。

    現在学校でC言語の勉強をしています。 自分のC言語の実力は、基本情報のC言語がちょっと理解できるぐらいです。 しかも、Cを読むのは慣れていますが、あまり書いたことはありません。 そこで、C言語の実力向上を図って、自分に課題を出していろんなプログラムを作って行きたいのですが、さっそく何を作ればいいのかわかりません。 過去に自分がこんなプログラムを作ったとか、よい案がありましたら何でもいいので是非教えてください。 大体の機能と、あればヒントとか教えてくれる程度でいいです。 例) どんなプログラム?:電卓 機能:入力例(500*3)→表示(1500) 四則演算ができる。 続けて演算子と数値を入力すると表示結果と計算する。 よろしくお願いします。

  • 表示方法(?)について質問です。

    C言語初心者です。 ######################### #for(a;a<100;a++) # #printf("aの値:%d\n",a); # ######################### CUIで表示結果を ######################### #aの値:"変化する場所" #                  #########################                 の様に一行表示で値のみを変化する様にしたいのですが、如何したら良いでしょうか、是非ご教示ください。

  • 余りの演算子%について

    C言語の質問です。 -2%10  の演算に対して 8 を期待していたのですが、 演算結果は、 -2 でした。 -2 を 8 にする演算は、存在しないんでしょうか?

  • php と C# の ビット演算

    PHPでビット演算をしていますが、 PHPでたとえば、 c = a >> b でビット演算した値と、 C#で演算した値と aの値を大きくした場合、 4000000000以上? は結果が違ってきます。 C#とPHPではビット演算のアルゴリズムが違うのでしょうか? よろしくお願いします。

    • ベストアンサー
    • PHP
  • C言語の[]について質問です。

    for (i = 1; (i < 16) && (c[n[i]] == 0); i++){ c[n[i]] = 1; } 上記のような文法がありました。c[n[i]]で使われてる[[]]の意味がちょっと分かりません。 出来れば上記のような文の条件を説明していただけませんか? 宜しくお願いします。

専門家に質問してみよう