- ベストアンサー
こんな処理は可能ですか?(動的な命名)
以下のように、switchでnumの値を分岐させてその値ごとに tmp[j][i]に格納する変数を変えたいのですが、こういうことはもっと スマートにできないでしょうか? int num = (ランダムな数取得); for ( int j = 0; j < 100; j++ ){ for ( int i = 0; i < 100; i++ ){ switch ( num ){ case 1: tmp[j][i] = num1[j][i]; break; case 2: tmp[j][i] = num2[j][i]; break; case 3: tmp[j][i] = num3[j][i]; break; ・ ・ ・ } } } ーーーーーーーーーーーーーーーーーーーーーーーーーーーーー 上のコードを int num = (ランダムな数取得); char *str = "num"; strcat( str, (char *)num ); //文字列の連結 tmp[j][i] = (*str)[j][i]; 見たいな雰囲気でスマートにできるのではないかと思ったのですが・・。 動的な関数呼び出しとか##演算子とかそういうのと組み合わせてこんなことは 実現できないでしょうか?
- みんなの回答 (9)
- 専門家の回答
質問者が選んだベストアンサー
実行してからメモリが確保されて値が入るので、処理を走らせる前の段階では、 つまりコンパイルの段階ではそもそも変数の値どころか値を入れる器すらないのです。 構造体で出来そうならそれでいいんじゃないでしょうか。 もしかしたらもっとキレた方法を思いつく方もいるかもしれませんが、 今の私ではさっぱりです。
その他の回答 (8)
- herbest
- ベストアンサー率42% (15/35)
あ……しまった。 コンパイル時に変数の値を得られるわけないですよね。 大変失礼しました。
お礼
さらに質問なのですが、 コンパイル時に変数の値が得られないということは こういう処理は無理と考えた方がよいのでしょうか? 大人しく他の方が教えてくださった構造体を使う方法を使おうかと迷っています・・。
- herbest
- ベストアンサー率42% (15/35)
いまさらかもしれませんが、こんな感じでどうでしょ。 int num = (ランダムな数取得); #define _( NO ) num##NO for ( int j = 0; j < 100; j++ ){ for ( int i = 0; i < 100; i++ ){ tmp[j][i] = _(num)[j][i]; } } } #undef _/* _( NO ) */
お礼
すみません、これを実行すると、 'numnum':定義されていない識別子です。 と出てきました。恐らく_(num)[j][i]のnumがそのまま展開されているからだと思いますが・・。
- Oh-Orange
- ベストアンサー率63% (854/1345)
回答例1: tmp、num1、num2、num3などの型がchar型とした場合(別の型や構造体ならその型を指定) char *ptr; switch ( num ){ case 1: ptr = (char *)num1; break; case 2: ptr = (char *)num2; break; case 3: ptr = (char *)num3; break; ・ ・ ・ default:ptr = NULL; } if ( ptr != NULL ){ memcpy( tmp, ptr, (100 * 100 * sizeof(char)) ); ←メモリのコピー関数 } else{ /* num のエラー処理など */ } 回答例2: 上と同じですがもっと高速にした場合(num は 1~10 とした場合) static char *table[] ={ NULL, (char *)num1, (char *)num2, (char *)num3, ・ ・ ・ (char *)num10, }; if ( (num >= 1) && (num <= 10) ){ memcpy( tmp, table[num], (100 * 100 * sizeof(char)) ); ←メモリのコピー関数 } else{ /* num のエラー処理など */ } 補足: num が 1~10 と必ず決まっているのならば if の判定は不要→さらに高速に処理!
他の方の回答でほぼ問題ないと思うのですが、一点だけ。 #2 さんの回答に対する質問者さんのお礼で、構造体にすれば初期化できないとありましたが、できると思いますよ。 コンパイラに依存するかも知れませんが... 初期化リストをもう一重 {..} でくくれば出来ませんか?
お礼
なるほど。そういう手がありましたか。ありがとうございます。
- PROMETHEUS
- ベストアンサー率58% (31/53)
typedef struct {int array_data[100][100]; } array_data; array_data num1 = { { { 0,0,0,0,0,1,0,0,0 }, { 0,0,1,0,0,0,0,0,0 }, { 0,0,0,0,1,0,0,0,0 }, { 0,0,0,0,0,0,0,1,0 }, } }; array_data num2 = { ... }; array_data num3 = { ... }; array_data *array_data_list[] = { 0, &num1, &num2, &num3 }; と定義して、numに乱数を入れたら array_data tmp; array_data *p = array_data_list[num]; tmp = *p; でtmpに値が入るはずです。
お礼
なるほど。これは使えそうですね。ありがとうございました。
- ngsvx
- ベストアンサー率49% (157/315)
C言語は久しく触っていないので、間違っているかもしれません。。。 私なら、まず#2さんのようにします。 しかし、何かの事情でnum1、num2...のようにしなければいけない場合、 次のようにします。 int* src; swicth(num){ case 1: src = num1; break; case 2: src = num2; break; . . } for ( int j = 0; j < 100; j++ ){ for ( int i = 0; i < 100; i++ ){ tmp[j][i] = src[j][i]; } } 「スマート」かどうかは人それぞれですのでわかりませんが。
お礼
回答ありがとうございます。 ただ、このやり方だとあまり手間的に変わらない気も・・。
- ham_kamo
- ベストアンサー率55% (659/1197)
No.1さんの書かれているように3次元配列にするか、 struct numbers { char num[100][100]; } と構造体にしておいて、 struct numbers number[10]; : : int num = (ランダムな数取得); for ( int j = 0; j < 100; j++ ){ for ( int i = 0; i < 100; i++ ){ tmp[j][i] = number[num].num[j][i]; みたいにするとか。
お礼
この方法は私も考えたのですが、 int num1[yの要素数][xの要素数] = { { 0,0,0,0,0,1,0,0,0 }, { 0,0,1,0,0,0,0,0,0 }, { 0,0,0,0,1,0,0,0,0 }, { 0,0,0,0,0,0,0,1,0 }, }; 見たいな感じで変数ごとに大量の初期化と代入をさせている為、構造体を使うと 一度に代入することができなくなるのでちょっと都合が悪いです。
- herbest
- ベストアンサー率42% (15/35)
num変数を三次元配列にするのでは都合が悪いですか?
お礼
回答ありがとうございます。3次元配列が使えるケースなら楽だったのですが、 ちょっと都合が悪いです。
お礼
なるほど・・。分かりやすい説明をありがとうございました。 今まで何でできないんだろうって悩んでいましたが謎がひとつ減った気がします。