ママのスキンケアのお悩みにおすすめアイテム

C言語を勉強中 b += a ? 1 : 0;  という1文があり??な状態になってしまいました。(+=、?:の意味はわかります。おそらく。)

これは aが0以外ならb=b+1;、aが0ならb=b+0; (aは条件であり、bにたされるわけではない。)。if文より文が短く、処理も早い、という利点。 で間違いないですか?


自信を持って次に進みたいので、どなたか教えていただきたいと思います。お願いします。

このQ&Aに関連する最新のQ&A

A 回答 (6件)

★解釈は合っています。


>if文より文が短く、処理も早い、という利点。 で間違いないですか?
 ↑
 条件演算子(三項演算子)は『if』文を使わないため関数の引数や『for』文の式にも
 記述できるメリットがあります。
 私はマクロ関数などでは良く使います。
 もちろん代入文とかでも使うこともあります。
 多用すると分かりにくくなるため注意が必要かもしれませんね。

サンプル1:
int i;

for ( i = 0 ; i < (sw ? 100 : 200) ; i++ ){
 :
}
※変数『sw』の真偽により繰り返しの回数を100か、200に制御しています。
※通常あまりこのような事はしませんが、for文の条件式として利用できます。

サンプル2:
int sign;

sign = ((value < 0) ? -1 : (value > 0) ? +1 : 0);
※変数『value』の符号情報を sign に -1、0、+1 をセットします。
※このような使い方はマクロ関数を用意してたまに利用しています。

その他:
>自信を持って次に進みたいので、どなたか教えていただきたいと思います。お願いします。
 ↑
 それなら1つ問題です。
 (1)ans = (a ? b : c ? d : e);
 (2)ans = (a ? b ? c : d : e);
 この2つの式は動作が全く異なりますが、日本語(文章)で説明できますか?
・補足にどう解釈したかを書いてみて下さい。

この回答への補足

まずは、回答ありがとうございます。
それと、私の勉強に付き合っていただきありがとうございます。
(1) aが真ならb、aが偽ならc ? d : e 
          ↓
  aが真ならans = b、aが偽かつcが真ならans = d、aが偽かつcも偽ならans   = eの3パターンに。
(2) aが真ならb ? c : d 、aが偽ならe 
          ↓
  aが真かつbも真ならans = c、aが真かつbが偽ならans = d、aが偽ならans = e
と考えました。どうですか?

補足日時:2008/01/23 04:04
    • good
    • 0
この回答へのお礼

回答ありがとうございます。
出題していただいた問題を解いてみましたので、お時間あるときにでも、ぜひ正否を教えていただきたいです。
回答で示して頂いた例も、こんな使い方があるのかと、驚きました。未熟すぎな私ですが、プログラミングの幅が広がったと思います。
お時間を割いていただき本当にありがとうございます。

お礼日時:2008/01/23 04:32

★Tacosan さん、ご指摘ありがとうございます。


 質問者さんへ訂正します。
 間違い⇒なお ? の前は条件式ですので変数だけの場合はその内容が『真』=0、『偽』=0以外を判定します。
 正しい⇒なお ? の前は条件式ですので変数だけの場合はその内容が『偽』=0、『真』=0以外を判定します。
 ※良く見たら真偽が逆転していました。恥ずかしいです。ごめんなさい。

最終問題の解答:
(a) (b) (ans)    (x) (y) (z)
真  真  ans = 1;  2  2  4
真  偽  ans = 1;  2  2  4
偽  真  ans = 2;  1  3  4
偽  偽  ans = 4;  1  2  5

こんな感じになります。
>if文より文が短く、処理も早い、という利点。
この記述は私がC言語を始めた最初のころに本に書かれていました。
今の時代はコンパイラの最適化が優れていますので処理が処理が早くなるかは分かりません。

>b += a ? 1 : 0;
この場合は私も if を使って記述します。
その方が見やすいです。

※昔は速度を気にして1つの変数を使いまわしたり、『resister』キーワードを付けていました。
※最近はこんな小細工しなくてもCPU処理が全体的に高速処理してくれますのであまり気にしなくても
※良いです。それよりもループ処理に時間が掛からないようにアルゴリズムを見直すべきです。

★最後に変わった使い方を紹介します。(普段はこんな使い方はしません)
#include <stdio.h>
#include <stdlib.h>

// メイン関数
int main( void )
{
 int a;
 
 printf( "『CTRL-D』+『Enter』キーで終了します。\n" );
 
 while ( scanf("%d",&a) == 1 ){
  (a > 0) ? printf("(プラス)です。\n\n") :
  (a < 0) ? printf("(マイナス)です。\n\n") : 0;
 }
 return 0;
}
キーボードから +1、-1、0 と打ち込んでみて下さい。
以上。
    • good
    • 0
この回答へのお礼

回答だけではなく、使用例や理解する為の問題まで考えていただいてありがとうございました。やっぱりプログラミングは実際に使ってみるのが一番ですね。大変勉強になりました。

お礼日時:2008/01/24 03:09

正直なはなし, 今どきの普通のコンパイラなら


b += a ? 1 : 0;

if (a)
++b;
の間に速度差があるとは思えないですね. 読み易さは明らかに後者の方が優れているので, 前者のように書く必要はないと思います.
ちなみに挙げ足とりになって申し訳ないのですが「式の値が 0 なら偽, 0 でなければ真」ですね>#4.
あとついでにいうと, C において 5+3 == 8 という式が条件判断に使えるように, 5+3 という式も条件判断に使えます>#3. 前者は「条件が成り立てば 1, 成り立たなければ 0」を返すだけです. true とか false などという高尚なものは C にはありません (ちなみに Pascal にもない).
    • good
    • 0
この回答へのお礼

訂正して頂いてありがとうございます。

お礼日時:2008/01/24 02:39

★答え合わせ


>(1) aが真ならb、aが偽ならc ? d : e 
>          ↓
>  aが真ならans = b、aが偽かつcが真ならans = d、aが偽かつcも偽ならans   = eの3パターンに。
>(2) aが真ならb ? c : d 、aが偽ならe 
>          ↓
>  aが真かつbも真ならans = c、aが真かつbが偽ならans = d、aが偽ならans = e
>と考えました。どうですか?
 ↑
 正解です。
>(1)ans = (a ? b : c ? d : e);
>(2)ans = (a ? b ? c : d : e);
 ↑
 これらはカッコを使うと分かりやすくなります。
 ↓
 (1)ans = (a ? b : (c ? d : e));
 (2)ans = (a ? (b ? c : d) : e);
 ※もし条件演算子で入れ子にする場合は積極的にカッコをいれた方が良いでしょう。
 ※私はカッコを入れるタイプです。もちろん省略しても同じですが誰が見ても分かるようにしておく。

(1)の解答:
(a) (c) (ans)
真  真  ans = b;
真  偽  ans = b;
偽  真  ans = d;
偽  偽  ans = e;

(2)の解答:
(a) (b) (ans)
真  真  ans = c;
真  偽  ans = d;
偽  真  ans = e;
偽  偽  ans = e;

その他:
 一覧として書き出せば良く分かります。
 なお ? の前は条件式ですので変数だけの場合はその内容が『真』=0、『偽』=0以外を判定します。
 分かっているとは思いますが、通常は関係演算子などと組み合わせて利用します。
・最後にもう1つ問題です。
 int x = 1;
 int y = 2;
 int z = 4;
 
 ans = (a ? x++ : b ? y++ : z++);
 このような場合はどうなるでしょうか?
・また補足に書いてみて下さい。
 ans、x、y、zのそれぞれの値も書いて下さい。

この回答への補足

(a) (b)
真 真 ans=1,x=2,y=2,z=4
真 偽 ans=1,x=2,y=2,z=4
偽 真 ans=2,x=1,y=3,z=4
偽 偽 ans=4,x=1,y=2,z=5
でどうですか?
たしかx++は式を評価したあとにx=x+1;とおぼえてるんですが…。

補足日時:2008/01/24 02:52
    • good
    • 0

おはようございます



aが、0とか、0以外と理解しているようですが、三項条件文は、正確に言うと、aの条件が、trueか、falseです。

つまり、b+=(5+3)?1:0;という、書き方は、三項条件文では、間違いになります。正確には、b+=((5+3)==8)?1:0;が、正しい書き方になります。if分に置き換えると、

if (5+3==8)
{
  b=b+1;
}
else
{
  b=b+0;
}
と、理解しやすくなります。

それと、"if分より処理が早い"と言うのは、現代では、コンパイラ(C言語を解釈して、コンピュータが理解できるコードに変更する)の性能や、CPU(マルチコアや、キャッシュ)の性能によって、大幅に異なりますので、一概には言えません。

インクリメント演算子、一つをとっても、++i;と、i++;で、実行環境では、処理スピードも変化する場合もあります。

処理スピードは、コンパイラのオプティマイズに任せて、人から見た時に判りやすいコードを書くこと(コメントを多く)をお勧めします^^
    • good
    • 0
この回答へのお礼

回答ありがとうございます。
どこかでif文を多用すると処理が遅くなるという話を聞いたことがあって、それが頭の隅に残ってたんですが、そんなに気にすることでもないのですね^^)。

お礼日時:2008/01/24 02:36

>aが0以外ならb=b+1;、aが0ならb=b+0; (aは条件であり、bにたされるわけではない。

)
そう。

>if文より文が短く、処理も早い、という利点。
別に短かくはないでしょう

if ( a ) b++;

の方が明確だと思いますけど。
    • good
    • 0
この回答へのお礼

プログラミングは同じ働きでも書き方によって、見やすさや理解のしやすさが全く違ってくるということが実感できました。if(a) b++;はとても見やすく、わかりやすいですね。回答ありがとうございました。

お礼日時:2008/01/23 03:44

このQ&Aに関連する人気のQ&A

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

このQ&Aを見た人はこんなQ&Aも見ています

このQ&Aを見た人が検索しているワード

このQ&Aと関連する良く見られている質問

Q#if 1 #elseの意味について

#if 1
 文 
#else 
 文
#endif
という表記に関して、「#if 1」が「必ず有効」という事はわかるのですが、ここでの「#else」とは「1」でない時ということで、「#if 0」と同じ意味と考えていいのでしょうか?

Aベストアンサー

>「#if 0」と同じ意味
「#if~#endif」がすこーぷの範囲ですから、似ていますが、正確には違います。

「#if 1」であれば、「#if 1~#else」の間の処理が有効、「#else~#endif」が無効、
「#if 0」であれば、「#else~#endif」の間の処理が有効、「#if 0~#else」が無効
と排他になります。

QLNK2019: 未解決の外部シンボルのエラーが出る

Microsoft Visual Studio 2008
Version 9.0.21022.8 RTM
Microsoft .NET Framework
Version 3.5 SP1
----------------------------------------------------------------
新しいプリジェクト→Win32 コンソール アプリケーション(ソリューションのディレクトリを作成 チェック外す)→Windows アプリケーション(空のプロジェクト チェック外す)
----------------------------------------------------------------
 プログラム

 mymain.cpp
#include "myhelper.h"
#include "mymain.h"

//自キャラのデータ
Point2D g_jikipos = {40, 400};//自キャラの座標

//画像ハンドル
int g_jikiimage[11];

//色々なファイルの読み込み
int LoadFiles(){
//画像ファイル読み込み
if(LoadDivGraph("media\\player01.bmp",
11,11,1,64,64,g_jikiimage) == -1) return -1;

return 1;
}


 mymain.h
//他から呼び出させるMyMainの関数
void MyMain();
int LoadFiles();


 myhelper.h(サンプルなので打ちミスはない)
#include "DxLib.h"
#include <limits.h>
#include <math.h>

//構造体宣言
//座標またはベクトルを記録する構造体
struct Vector{
float x,y;
};
typedef Vector Point2D;
//線を記録する構造体
struct Line2D{
Point2D startpos, endpos;
float katamuki;//傾きをラジアン値で記録
Vector speed;//移動している場合は速度をセット
};
//球体を記録する構造体
struct Ball2D{
Point2D position;
float hankei;//半径
};
//四角形を記録する構造体
struct Rect2D{
Point2D lefttop;
Point2D rightbottom;
float width;
float height;
};


//ライブラリ関数
Point2D PosInView(Point2D in);
int XInView(float inx);
int YInView(float iny);
void ScrollToLeft(float jikiposx);
void ScrollToRight(float jikiposx);
void ScrollToUp(float jikiposy);
void ScrollToDown(float jikiposy);
void DrawLineInView(float x1, float y1, float x2, float y2, int Color, int Thickness);
void DrawCircleInView(float x, float y, float r, int Color, int FillFlag);
void DrawAnimation(float x, float y, double ExtRate, double Angle,int TurnFlag,
int *imgarray, int allframe, float fps);
//ベクトル関数
Vector CreateVector(Vector in, float veclen);
Vector AddVector(Vector v1, Vector v2);
Vector SubVector(Vector v1, Vector v2);
Vector AddVectorInFrameTime(Vector pos, Vector speed);
Vector AddVectorInFrameTime2(Vector pos, Vector speed, Vector accel);
Vector Normalize(Vector in);
Vector RotateVector(Vector in, float radian);
float VectorLengthSquare(Vector in);
float DotProduct(Vector v1, Vector v2);
float CrossProduct(Vector v1, Vector v2);
void SetLine2DKatamuki(Line2D *in);
void DrawLine2D(Line2D in, int Color, int Thickness);
void DrawBall2D(Ball2D in, int Color, int Fill);
//当たり判定関数
bool HitTestLineAndBall(Line2D linein, Ball2D ballin);
bool IsPointAtLineFace(Line2D linein, Point2D ptin);
bool HitTestLineAndLine(Line2D line1, Line2D line2);
bool HitTestBallAndBall(Ball2D a, Ball2D b);
bool HitTestPointAndBox(Rect2D rect, Point2D pt);
//タイマー関数
void SetSimpleTimer(int idx, int time);
int GetPassedTime(int idx);


//グローバル変数
extern float g_frametime;
extern Rect2D g_framerect;//画面領域(当たり判定)
extern Point2D g_current_field_pos;//現在の左上座標
extern Rect2D g_stagesize;//ステージサイズ

//定数宣言
const float ZEROVALUE = 1e-10f;
const float PIE = 3.1415926f;
const int SCROLL_LIMIT = 200;
----------------------------------------------------------------
 エラー内容
1>myhelper.obj : error LNK2019: 未解決の外部シンボル "void __cdecl MyMain(void)" (?MyMain@@YAXXZ) が関数 _WinMain@16 で参照されました
1>C:\Documents and Settings\Owner\My Documents\Visual Studio 2008\Projects\my\Debug\my.exe : fatal error LNK1120: 外部参照 1 が未解決です
1>my - エラー 2、警告 0
ビルド: 0 正常終了、1 失敗、0 更新不要、0 スキップ
----------------------------------------------------------------
画像を貼り付けときます
(見えにくい場合→http://www.dotup.org/uploda/www.dotup.org154142.jpg.html)
初心者なのでわかりやすくお願いします

Microsoft Visual Studio 2008
Version 9.0.21022.8 RTM
Microsoft .NET Framework
Version 3.5 SP1
----------------------------------------------------------------
新しいプリジェクト→Win32 コンソール アプリケーション(ソリューションのディレクトリを作成 チェック外す)→Windows アプリケーション(空のプロジェクト チェック外す)
----------------------------------------------------------------
 プログラム

 mymain.cpp
#include "myhelper.h"
#include "mymain.h"

//自...続きを読む

Aベストアンサー

ファイル構成から推測するに
mymain.cpp というファイルに
void MyMain(void) {
// ここに処理を書く
}
という関数が必要なようです。

Qint型からchar型への変換

タイトル通り、int型からchar型への変換の仕方がわかりません!><
どうしたらいいのでしょうか?

Aベストアンサー

#include <stdio.h>


char buf[5];
int no;

no = 10;
sprintf(buf, "%d", no);

Qprintf で二進表示を行いたい。

すみません。教えていただきたいことがあります。
printf で普通のintの値をフォーマット指定子を使用して二進表示をしたかったのですが見当たりませんでした。
どうにかintの内容を二進で確認したいのですが、どのようにすれば良いですか?
宜しくお願いします。

Aベストアンサー

★2進整数を表示する関数を自作すればよい。
・作り方は簡単で、最上位ビットから順に『0』と『1』を調べていき、ビットが
 立っていれば『putchar('1');』にして、ビットが OFF なら『putchar('0');』
 にすれば良いでしょう。
・下にサンプルを載せますので使いやすいように改良して下さい。

サンプル:
unsigned int bit = (1 << (sizeof(int) * 8 - 1));
int value = 12345; ←これが表示したい int 型の整数値です。

printf( "value の 2進表記は " );

for ( ; bit != 0 ; bit >>= 1 ){
 if ( value & bit ){
  putchar('1');
 }
 else{
  putchar('0');
 }
}
printf( " です。\n" );

最後に:
・1バイトが 8 ビットの環境が前提です。→まぁ、普通は 8 ビットですが…。
・上記のサンプルを関数などにすれば使いやすくなります。→print_bin()など
・以上。おわり。

★2進整数を表示する関数を自作すればよい。
・作り方は簡単で、最上位ビットから順に『0』と『1』を調べていき、ビットが
 立っていれば『putchar('1');』にして、ビットが OFF なら『putchar('0');』
 にすれば良いでしょう。
・下にサンプルを載せますので使いやすいように改良して下さい。

サンプル:
unsigned int bit = (1 << (sizeof(int) * 8 - 1));
int value = 12345; ←これが表示したい int 型の整数値です。

printf( "value の 2進表記は " );

for ( ; bit != 0 ; bit >>= 1 ){
 if...続きを読む

Qファイル出力の場所を指定

現在C++にてhtmlファイルを出力するプログラムを作っているのですが、出力場所を指定することはできるのでしょうか?(現在はそのプログラムソースが保存されている場所と同じファイル内に出力されますが、それをデスクトップに出力するなど。)
もし、方法がありましたら、教えてください。
ソースや参考HPのURLなどのせていただけたらありがたいです。
環境はVisualStudio.NET2003です。
よろしくお願いします。

Aベストアンサー

単にファイル名の前にパスを指定する。

絶対パス指定
fp=fopen("c:/temp/test.txt","w");

相対パス指定
fp=fopen("./hoge/test.txt","w");


デスクトップはOSやユーザによって場所が異なるので、少し面倒です。
XPの場合環境変数を利用してこんな感じで出来ると思います。

例:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

void main(void)
{
FILE *fp;
char fname[1024];
strcpy(fname,getenv("USERPROFILE"));
strcat(fname,"/デスクトップ/test.txt");
fp=fopen(fname,"w");
//処理
fclose(fp);
}

Qintとlongは同じ?

#include <stdio.h>
#include <limits.h>

int main() {
printf("%d\n%d", INT_MAX, LONG_MAX);
return 0;
}

出力
214783647
214783647

Win7 64bit (VC++2010)
CentOS 32bit (gcc)

どちらの環境でも同じ出力結果となりました。
intとlongなぜ同じになってしまったのでしょうか。

Aベストアンサー

long は 32ビットの整数(signedの場合 -2147483648~+2147483647、unsignedの場合
0~4294967295)
int は システムにおける 標準
という定義です。

32ビットシステムの場合は同じになります。

DOS時代はシステムが 16ビットのため、intは -32768~+32767(または 0~65535)でした。

short int とすることで 16ビット互換となります。

Qfgetsなどのときのstdinのバッファを消すには?

こんにちは,今C(C++でない)を使用しています。
たとえば,
char str[20]
fgets(str,sizeof(str),stdin)
としたときに20字以上を打つと,stdinのバッファに20字以上の分が残ったままになります。

C++などでは
fflush(stdin)で,うまくいきますが,普通のCでは対応がされていないみたいでうまくいきません。

よろしくお願いします。

Aベストアンサー

あ,テキスト入力だからこんな大掛かりなことしなくてもいいんだ.
末尾に'\n'が出るまで掃出せばいいんですよね.

fgets(str, sizeof(str), stdin);
if ( str[strlen(str)-1] != '\n' ){
while( getchar() != '\n' );
}

でいいんだ.失礼しました.

Qfatal error LNK1120: 外部参照 1 が未解決です

またわからないことが・・・
教えて下さい。
以下をVC++2005でコンパイルすると、

MSVCRTD.lib(crtexew.obj) : error LNK2019: 未解決の外部シンボル _WinMain@16 が関数 ___tmainCRTStartup で参照されました。
C:\Documents and Settings\tomato\My Documents\Visual Studio 2005\Projects\a\Debug\a.exe : fatal error LNK1120: 外部参照 1 が未解決です。

と警告がでて通りません。
何のことでしょうか。

#include<stdio.h>
#include<process.h>

struct meibo{
  char name[20];
  char tel[20];
  char address[20];
};

void message( void );
void input( FILE *fp, int cnt , struct meibo *a, int *end );

void main( void )
{
  struct meibo a[20];
  FILE *fp;
  int cnt, end;

  if( (fp=fopen( "meibo.dat", "w" ) ) == NULL ){
    printf( "Can not open the meibo.dat.\n" );
    exit( 1 );
  }

  message();

  fprintf( fp, "番号, 名前, TEL, 住所\n" );
  fflush( fp );

  cnt = 0;
  end = 0;
  while( end == 0 ){
    input( fp, cnt, &a[cnt], &end );
    cnt++;
    fflush( fp );
    if( cnt == 20 ){
      printf( "人数が一杯です.終了します.\n" );
      end = 1;
    }
  }
  fclose( fp );
}

void message( void )
{
  printf( "名前, TEL, 住所, endを入力してください.\n" );
  printf( "継続の時はend=0," );
  printf( "中止の時は,end=1と入力してください.\n" );
}

void input( FILE *fp, int cnt, struct meibo *a, int *end )
{
  printf( "名前-->" );
  scanf( "%s", a->name );
  printf( "TEL -->" );
  scanf( "%s", a->tel );
  printf( "住所-->" );
  scanf( "%s", a->address );
  printf( "Exit? Continue:0 Exit:1 -->" );
  scanf( "%d", end );
  printf( "\n" );
  fprintf( fp, "%2d, %s, %s, %s\n",
    cnt+1, a->name, a->tel, a->address );
}

またわからないことが・・・
教えて下さい。
以下をVC++2005でコンパイルすると、

MSVCRTD.lib(crtexew.obj) : error LNK2019: 未解決の外部シンボル _WinMain@16 が関数 ___tmainCRTStartup で参照されました。
C:\Documents and Settings\tomato\My Documents\Visual Studio 2005\Projects\a\Debug\a.exe : fatal error LNK1120: 外部参照 1 が未解決です。

と警告がでて通りません。
何のことでしょうか。

#include<stdio.h>
#include<process.h>

struct meibo{
  char name[20];
...続きを読む

Aベストアンサー

http://www.a.math.ryukoku.ac.jp/~hig/course/compsci2_2005/man/faq.html
にある現象と同じではないでしょうか、一度お試しください。

QC言語 配列の長さの上限

C言語で配列Array[N]の長さNの上限っていくらなんでしょうか?
もし可能なのであれば上限を2147483647にしたいのですが、方法を教えてください。

Aベストアンサー

そもそもWindowsの32bit版はアプリが仮想メモリ空間を2GBしか使えません。2GBを超えるには64bit版が必要です。
たとえ64bit版OSだとしても添え字が2147483647って、単純なintの配列だとしても4x2147483647=8GB必要ですね。実メモリ16GBとかのPCを用意しますか?
そもそも配列で2147483647個必要なアルゴリズムに問題ありだと思います。

Q#ifdef の使い方

組み込み系のプログラムを現在勉強しています。
#ifdefについて質問させて頂きます。

下記コードの場合

#ifdef A
---- (1) Y = Z;
#else
-----#if B
------- (2) X = Z;
----#endif
#endif

("-"は空白と思ってください。)

この場合、Aが定義されていれば(1)が実行しコンパイル終了(#endif)。
Aが定義されていない場合、#else に行き、Bが定義されている場合は
(2)を実行してコンパイル終了(#endif)という理解であっていますか?

またこうした方が分かりやすいなど、アドバイス頂けると幸いです。
ご返答よろしくお願いします。

Aベストアンサー

言葉の使い方に若干の不安を覚えます。

> Aが定義されていれば(1)が実行しコンパイル終了(#endif)。

「Aが定義されていれば(1)の部分のみがコンパイルされる」と言うべきでしょう。コンパイル時には(1)を実行しませんし、#endifでコンパイルが終了するわけでもありません。

> Bが定義されている場合は

#ifdef Bではなく#if Bなので、「Bが真であれば」が正しいです。

> またこうした方が分かりやすいなど

質問文にあるコードなら、下記のようにすると少し見やすくなります。

#ifdef A
---- (1) Y = Z;
#elif B
---- (2) X = Z;
#endif


このQ&Aを見た人がよく見るQ&A

人気Q&Aランキング