

_（掛け算の計算時間について私に混乱がありました。774RRさんのご回答を御覧ください）_

1000×1000ぐらいの大きな配列（画像など）があるとします。`i`行目の先頭のアドレスを得るためには、

[code]

      double lightness[1000][1000];
      // ...
      long i = 200;                        // ここでは i = 200 とする
      double *pLightness = lightness[i];   
    
[/code]

とすれば良いですが、これを`0`から`999`の`i`に対して繰り返すとなると、`i`が増えるにつれて、アドレスを得るのにかかる時間も増えるとおもいます。（`[]`の仕様のせい）

[code]

      for (i = 0; i < 1000; i++) {
        *pLightness = lightness[i]; // i行目の先頭のアドレス
        // ...（アドレスを使った操作）
      }
    
[/code]

`i = 0`から`999`まで順に行列の`i`行目の先頭のアドレスを得るのに、これより速い方法はありますか？  
できれば、"`pLightness += 1000`する"よりもさらに速くてエレガントな方法があればいいなと思っているのですが…

質問の動機としては、`i`行`j`列のアドレスが得られている際に、右隣の、`i`行`j+i`列のアドレスを得るには、アドレスの入ったポインタをインクリメントすれば速いので、`i`についても同じことができないかと思ったことです。

[code]

      // (i, j) = (300, 0) から (300, 999) まで lightness[i][j] のアドレス pLightness を使った操作をするコード
      i = 300;
      pLightness = lightness[i]; // 300行目の先頭のアドレス
      for (long j = 0; j < 1000; j++, pLightness++) {
        // ...（アドレスを使った操作）
      }
    
[/code]

うーん、基礎的な内容の質問なので、「参考書読め」とか「もうちょっと頭使え」という話なのかもしれないですが、どうかご容赦ください。


CC BY-SA 4.0
2020-07-03T09:49:53.127
68245
2020-07-03T11:20:59.963
2020-07-03T11:20:59.963
40538
40538
question
c array ポインタ
２次元配列の任意の行の先頭のアドレスを"素早く"取得する方法があればご教授ください


> これを0から999のiに対して繰り返すとなると、iが増えるにつれて、アドレスを得るのにかかる時間も増えるとおもいます。

オイラの思いつく限りのすべての処理系において `lightness[i]` の計算時間は O(1) つまり処理時間は `i`
の値に関係なく一定です。一定にならないハードウエア・ソフトウエア実装が想像できないです。

`&lightness[i][j]` がすでにあるとき  
`&lightness[i][j+1]` を求めるに要するコストと  
`&lightness[i+1][j]` を求めるに要するコストとでは  
確かに違いがありますが、アセンブラ命令にして数命令、誤差の範囲です。ポインタ値の計算ののちにアクセスを開始する際のキャッシュのヒットミスペナルティのほうが圧倒的に大っす。


CC BY-SA 4.0
2020-07-03T10:36:40.857
68252
2020-07-03T10:36:40.857
8589
68245
answer