TL;DR
変数の値域、継続条件に注意しよう!
はじめに
プログラミングをしていて,for文から抜け出せない
という初歩的なミスをして時間を浪費してしまいました.
いないとは思いますが,同じ問題に直面した人のために理由をメモとして残します.
問題
for文を使用していて,デクリメントでループする必要があった.
簡単のため,以下のソースコードで試す.
incrementSum()
は正常に動作するが,decrementSum()
は正常に動作しない(Segmentation fault).
また,decrementSum()
内のsize_t
はauto
に変更しても成功しない.
testCode-failed
#include <iostream>
#include <vector>
using namespace std;
int incrementSum(const vector<int>& v){
int sum = 0;
for(size_t i=0; i<v.size(); ++i){
sum += v[i];
}
return sum;
}
int decrementSum(const vector<int>& v){
int sum = 0;
//for(auto i=v.size()-1; i>=0; --i){ もダメ
for(size_t i=v.size()-1; i>=0; --i){
sum += v[i];
}
return sum;
}
int main(){
vector<int> v(10, 1);
int sum1 = incrementSum(v);
int sum2 = decrementSum(v);
cout << sum1 << " " << sum2 << endl;
return 0;
}
原因
size_t
は正の値しかとらないため,decrementSum()
関数内においてi==0
の次はi==SIZE_MAX
となる.これにより,永遠に条件式を満たし続けてしまい,ループから抜け出せない.
対処
普通に最初の方法で解決したのだが,ついでに他の方法も挙げた.
ベストと思われる解決方法
int
を使うなど考えたのだが,コメントで教えてもらい,これに落ち着いた.
solution_3
int decrementSum(const vector<int>& v){
int sum = 0;
for(size_t i=v.size()-1; i<v.size(); --i){
sum += v[i];
}
return sum;
}
シンプルな解決方法
おとなしくint
を使う.
solution_1
int decrementSum(const vector<int>& v){
int sum = 0;
for(int i=v.size()-1; i>=0; --i){
sum += v[i];
}
return sum;
}
煩雑になる解決方法
これはループ内が煩雑になるため,一番微妙である.
solution_3
int decrementSum(const vector<int>& v){
int sum = 0;
if(!v.size()) return 0;
for(size_t i=v.size(); i>0; --i){
sum += v[i-1];
}
return sum;
}
おわりに
困った人の助けになることを願います.
もっとよい解決方法があれば教えていただけると幸いです.