1

1 つ以上の親配列/構造体/共用体にネストされている 1 つの配列/構造体/共用体で複数の数値/文字列を読み取る最良の方法は何ですか?

一時変数のない最初の例:

printf("%d %d\n", a[9][3], a[9][4]);

一時変数を使用した最初の例:

int *b = a[9];
printf("%d %d\n", b[3], b[4]);

上記の最初の例の一時変数は非常にばかげていると思いますが、下の 2 番目の例では意味があり、1 つを使用した方がよさそうですよね?

一時変数のない 2 番目の例:

foo[i]->bar.red[j][0]++;
foo[i]->bar.red[j][1]++;
foo[i]->bar.red[j][2]++;
foo[i]->bar.red[j][3]++;

一時変数を使用した 2 番目の例:

int *p = foo[i]->bar.red[j];
p[0]++;
p[1]++;
p[2]++;
p[3]++;

では、どこに線を引きますか?コンパイラは、この方法で最適な効率のアセンブリを生成するために必要な間接処理を挿入するのに十分スマートであることを認識していますが、(非常にパフォーマンスが重要なコードを想定して) 例外があるのでしょうか? また、コードの明快さ/保守性の観点から、経験則は何ですか?

4

3 に答える 3

3

まず、これは純粋にコードの読みやすさ/保守性の問題であり、個人の好みであると思います。コンパイラは今日の私たちより賢いです (冗談)。:-)

個人的には、通常、一時変数 (または関数、これはそれらにも適用されます) を抽出することを次の 2 つのケースで考えます。

  • その名前が自明であり、最初の表現以上のものを伝えるように名前を付けることができる場合、または
  • コードの一部を少なくとも 3回繰り返す必要がある場合。

したがって、最初の例はそのままにしておきます。

printf("%d %d\n", a[9][3], a[9][4]);

2 つ目は次のようになります。

int *p = foo[i]->bar.red[j];
p[0]++;
// ...

または、(常にではありませんが、多くの場合)より良い:

int *bar_red = foo[i]->bar.red[j];
bar_red[0]++;
// ...
于 2012-01-06T03:47:18.007 に答える
2

私の経験則は次のとおりです。コードを理解しやすくする明確で意味のある名前を付けることができる場合は、一時変数を追加します。2 番目のアドバイスは次のとおりです。この変数を使用する (小さな) 部分を中かっこで囲みます。このようにして意図が明確になり、リファクタリングが必要な場合にコードの準備がほぼ整います (中かっこ内のコードは関数に簡単に抽出できます)。

2 番目のサンプルでは、​​次のようになります。

/*previous code
...
*/
int *quadruplet = foo[i]->bar.red[j];
{ /*intentionaly meaningless braces that prepare the introduction 
  of a function (incrementQuadruplet) in a later refactoring if needed*/
  quadruplet[0]++;
  quadruplet[1]++;
  quadruplet[2]++;
  quadruplet[3]++;
}
/*following code
...
*/
于 2012-01-06T04:06:05.907 に答える
1

これはあなたの質問に正確に答えるものではありませんが、これはほとんどのプログラマーが頻繁に陥る罠であるため、これを強調することはできません。

経験則は次のとおりです。時期尚早の最適化は避けてください。
現代のコンパイラは、自力で些細な最適化を実行するのに十分賢いです。
理解しやすく、保守しやすく、所属するチームのコーディング標準/慣行に従っているコードを記述します。
要件に従って正しく作業し、ボトルネックがないかコードをプロファイリングしてから、見つかったコードを最適化してください。ボトルネックになる。

于 2012-01-06T03:25:04.527 に答える