
質問です。
配列を使い、その値の合計値を出す際に私はループカウンタを利用して足す手法を
思いつくのですが、それ以外の方法があると聞きました。
ですが、それ以外の方法が思いつかなく質問させてください。
int a[10] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
int nSum = 0;
for ( int i = 0; i < 10; i++ )
{
nSum += a[i];
}
return nSum;
ここでループカウンタを使用せず、配列の全てを足すにはどうしたら良いでしょうか。
No.11
- 回答日時:
配列の最後に終端となるデータを設定して
int a[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -1 };
int nSum = 0;
int *p = a;
for(; *p >= 0; *p++) {
nSum += *p;
}
または
while (*p>=0) {
nSum += *p++;
};
No.10
- 回答日時:
#8 さん
> 一番高速という意味では、
> (中略)
> だと思います。
確かに.(^^;
ループアンローリングという手がありましたね.
#9 さん
> x86系CPUなら
> [(ベースアドレス)+(1要素サイズ)*(オフセット)]
> のアドレスに格納されているの値の参照を1クロックで
> 行うことができるので、
そうなんですが,要素サイズは 1,2,4,8 バイト限定ですよね.
今回のように要素が基本データ型ならいいんですが,一般の構造体だと使えない場合が多いですね.
No.9
- 回答日時:
少なくともx86系CPUなら
[(ベースアドレス)+(1要素サイズ)*(オフセット)]
のアドレスに格納されているの値の参照を1クロックで
行うことができるので、ループカウンタを使用することで
遅くなるということはないと思います。
まあ、ループ内で行う処理や最適化の質にもよるでしょうけど。
ループ数が固定なら、コンパイラによってはNo.8のような
形にまで最適化してくれるそうですし。
No.8
- 回答日時:
一番高速という意味では、
int a[10] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
return a[0]+a[1]+a[2]+a[3]+a[4]+a[5]+a[6]+a[7]+a[8]+a[9];
だと思います。
一般に、効率を上げるには汎用性を捨てるのが最も効果的です。
No.7
- 回答日時:
★あぁ…間違った!
・noocyte さん、ご指摘有り難う御座います。
●質問者さんへ
・間違い⇒『nSum += *a++;』
・正しい⇒『nSum += *p++;』
・以上。すみませんでした。
No.6
- 回答日時:
#3 です.
#5 さんに先に書かれちゃいましたが,これがたぶん一番高速な
(少なくとも他の方法より遅くはないはず) 方法です.
(なので私はよく使います.)
int a[10] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
int nSum = 0;
// 以下,#5 さんと実質的に同じコード
const int * const endOfArray = &a[10]; // a[] の直後のアドレスを指す.
const int *element = a; // a[] の要素を指す.
while(element < endOfArray) nSum += *element++;
この方法だと,ループ内の処理は,
(どうせやらないといけない,配列要素の参照と nSum への加算を除けば)
次の2つだけです.
・element < endOfArray の判定
・element++
他方質問文のように,普通にループカウンタを添字にする方法だと,
次の処理が必要です.
・i < 10 の判定
・i++
・i から &a[i] を求める処理.つまり次の2つ.
size_t offset = sizeof(a[i]) * i; // a[] の先頭に対する a[i] のバイト・オフセット
const char *address = (char*)a + offset; // a[i] のバイトアドレス
(もっとも,後者はコンパイラが最適化によって
前者のようなコードに変換してくれるかもしれません.)
#4 さん
> nSum += *a++;
a は定数なのでエラーですよ~.(笑)
No.4
- 回答日時:
★『配列の添え字を使うな!』という事かな?
・それならば、配列をポインタにセットして要素分だけループして加算します。
・これ以外では、私も思い浮かびません。
・下にサンプルを載せます。
サンプル:
int a[10] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
int *p = a;
int nSum = 0;
for ( int i = 0 ; i < 10 ; i++ ){
nSum += *a++;
}
return nSum;
最後に:
・配列とポインタの学習ですかね。
・やっぱり『ループカウンタを使用せず』の意味がよく分かりません。
・とりあえず、上記のサンプルをどうぞ。
・以上。おわり。
配列とポインタの学習、その通りです。
使うだけなら、こう使えば動く。としか知らない面が多く
それを実際に職業にしている方から、違う方法もあるよ。と言われたもので・・・
参考にさせていただきます!
No.3
- 回答日時:
再帰呼び出しを使う方法もあります.
int a[10] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
int SumOfArray(const int array[], unsigned nElements)
{
return (nElements <= 0) ? 0 :
(array[0] + SumOfArray(array + 1, nElements - 1));
}
int main(void)
{
int nSum = SumOfArray(a, 10);
printf("nSum = %d\n", nSum);
return 0;
}
ループカウンタを使う場合に比べて遅いし,
配列の要素数が非常に多いとスタックオーバーフローしてしまいますが.
/* 私はCよりも先に Lisp を覚えました.(笑) */
おー!こんな方法もあるんですね!
>ループカウンタを使う場合に比べて遅いし,
>配列の要素数が非常に多いとスタックオーバーフローしてしまいますが.
私はまだまだ初心者なので、方法として教えて頂けたのは大変ありがたいです!
No.2
- 回答日時:
>ループカウンタを使用せず
というのが配列の要素を指定するのに使わない
という意味なら下記のようにすることができます
配列の最後の要素にストッパーとしての値を入れて
それを検出するまで加算、という風にすればfor文を使わなくても実現できます
-----引用
/* 正数のカウント */
for( i = 0; i < inputCount; i++ ){
if ( *data > 0 ){
sum = sum + *data;
count++;
}
data++;
}
http://www.na.rim.or.jp/~m_tanabe/c/pointer8.html
-----引用
>ループカウンタを使用せず
というのが配列の要素を指定するのに使わない
という意味なら下記のようにすることができます
その通りです。言葉が足りずすみません。
引用サイト見てみます!ありがとうございます
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
このQ&Aを見た人はこんなQ&Aも見ています
関連するカテゴリからQ&Aを探す
おすすめ情報
このQ&Aを見た人がよく見るQ&A
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
関数から配列を返すには?
-
C言語において、 配列要素をひ...
-
辞書式順序
-
MFC - ダイアログボックスのPic...
-
C言語 配列の長さの上限
-
BCBで配列の要素数(0)の場合
-
「#undef」と「#define」の使い...
-
char*を初期化したいのですが
-
C++Builder 2009 テキスト...
-
C言語・要素除去
-
Redimした動的配列はEraseする...
-
【速いブラインドタッチ】手を...
-
DXライブラリでの2Dの描画...
-
配列を使わずに、変数名を動的...
-
malloc でのメモリ取得状況の可...
-
c言語のポインタへの文字列入力...
-
メモリ解放について
-
C言語のintとcharの違いってな...
-
構造体→文字列→構造体 をする方法
-
CStringからchar*への型変換に...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
関数から配列を返すには?
-
配列の要素数に変数を入れたい...
-
C言語において、 配列要素をひ...
-
c言語
-
C言語 ファイルの指定された行...
-
define で 配列
-
C#で構造体の配列を持った構造...
-
C言語の課題が出たのですが自力...
-
char型配列をint型に代入するには
-
C#で配列が空かを判定するには?
-
MFCのCArrayを使った二次元配列
-
コンボボックスでデフォルト値...
-
MFC - ダイアログボックスのPic...
-
c言語 構造体
-
2番目の最大値を求める
-
C言語から質問です。
-
Cのエラー
-
プログラミングに関する問題が...
-
C言語の2次元配列 容量が大き...
-
Visual C++を 用いたテキストフ...
おすすめ情報