
質問です。
配列を使い、その値の合計値を出す際に私はループカウンタを利用して足す手法を
思いつくのですが、それ以外の方法があると聞きました。
ですが、それ以外の方法が思いつかなく質問させてください。
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で質問しましょう!
似たような質問が見つかりました
- PHP 配列の値の更新方法について 1 2022/08/05 09:49
- C言語・C++・C# C 言語の Gauss Jordan 法について 2 2022/12/28 11:16
- C言語・C++・C# このプログラミング誰か教えてくれませんか 1 2022/06/02 15:27
- Java javaでのプログラム(配列)について質問です. 2 2022/10/14 22:27
- C言語・C++・C# C言語プログラム変更 2 2022/12/21 15:03
- Visual Basic(VBA) VBA横データを縦にしたいです 2 2023/08/08 19:38
- C言語・C++・C# C言語の課題が出たのですが自力でやっても分かりませんでした。 要素数がnであるint型の配列v2の並 3 2022/11/19 17:41
- C言語・C++・C# C言語初心者 構造体 課題について 2 2023/03/10 19:48
- Java Java モンスターブリーダー 1 2023/02/05 09:44
- C言語・C++・C# c言語の問題です 課題1 (二分探索木とセット) 大きさ size の配列 array を考える。す 2 2023/01/10 21:08
このQ&Aを見た人はこんなQ&Aも見ています
関連するカテゴリからQ&Aを探す
おすすめ情報
このQ&Aを見た人がよく見るQ&A
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
関数から配列を返すには?
-
配列の要素数に変数を入れたい...
-
define で 配列
-
c言語
-
ループカウンタを使用せず、配...
-
C言語 ファイルの指定された行...
-
C#で構造体の配列を持った構造...
-
C言語において、 配列要素をひ...
-
構造体を引数とする関数について
-
Cのエラー
-
MFC - ダイアログボックスのPic...
-
要素数・要素の値が未定の配列...
-
MFCのCArrayを使った二次元配列
-
.NET C++で、構造体の配列をnew...
-
配列における数値の比較について
-
5人分の氏名と英語、国語、数...
-
2番目の最大値を求める
-
C言語 構造体でつまずいています
-
構造体のextern方法
-
関数への構造体の配列の渡し方<...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
関数から配列を返すには?
-
配列の要素数に変数を入れたい...
-
define で 配列
-
c言語
-
C#で構造体の配列を持った構造...
-
C言語 ファイルの指定された行...
-
C言語において、 配列要素をひ...
-
C言語の課題が出たのですが自力...
-
C#で配列が空かを判定するには?
-
構造体のextern方法
-
C言語の配列のコピーについて
-
c言語 構造体
-
C言語 数値の連続入力について
-
MFC - ダイアログボックスのPic...
-
C++DLLからC#へのコールバック...
-
配列のアドレス部
-
要素数・要素の値が未定の配列...
-
C言語についてです 5人のテスト...
-
.NET C++で、構造体の配列をnew...
-
2番目の最大値を求める
おすすめ情報