๋ชฉ์ฐจ ¶
2. Chapter 4 Organizing programs and data ¶
- ์ด๋ค ์ข
๋ฅ์ ๋ฌธ์ ๋ฅผ ํผ๋ค.
- ๋ค๋ฅธ ๊ฒ๋ค๊ณผ ๋
๋ฆฝ์ ์ด๋ค.
- ์ด๋ฆ์ ๊ฐ์ง๊ณ ์์ด์ผ ํ๋ค.
3์ฅ๊น์ง ๋ดค๋ ๊ฒ์ ์ฒซ๋ฒ์งธ๊ฒ๋ง ์๊ณ , ๋๋จธ์ง ๊ฒ์ ์๋ค. ํ๋ก๊ทธ๋จ์ด ์์๋๋ ๋ณ๋ก ์๊ด์์ง๋ง, ์ปค์ง๊ธฐ ์์ํ๋ฉด์๋ถํฐ 2,3๋ฒ์งธ ๊ฒ์ด ๊ฒฐ์ฌ๋๋ฉด, ๋์ค์ ์ ์ด๊ฐ ๋ถ๊ฐ๋ฅํด์ง๋ค. C++์์๋ ๋ค๋ฅธ ์ธ์ด์ ๋ง์ฐฌ๊ฐ์ง๋ก ํจ์ + ์๋ฃ๊ตฌ์กฐ๋ฅผ ์ ๊ณตํจ์ผ๋ก์จ, ํ๋ก๊ทธ๋จ์ ๊ตฌ์กฐํ์ํฌ์ ์๋ ๋ฐฉ๋ฒ์ ์ ๊ณตํ๋ค. ๋ํ ํจ์ + ์๋ฃ๊ตฌ์กฐ๋ฅผ ๋ฌถ์ด์ ๊ฐ์ง๊ณ ๋ ์ ์๋ class๋ผ๋ ๋๊ตฌ๋ฅผ ์ ๊ณตํด์ค๋ค.(Chapter9๋ถํฐ ์์ธํ ์ดํด๋ณธ๋ค.)
๊ทธ๋ฌ๋ฏ๋ก ์ด๋ฒ์ฅ๋ถํฐ๋ ํ๋ก๊ทธ๋จ์ ๋๋ ์, ์๋ก ๋ค๋ฅธ ํ์ผ์ ์ ์ฅ, ์ปดํ์ผํ๋ ๋ฒ๊ณผ, ๋์ค์ ํฉ์น๋ ๋ฒ ๋ฑ์ ๊ณต๋ถํ ๊ฒ์ด๋ค.
2.1. 4.1 Organizing computations ¶
~cpp cout << "Your final grade is " << setprecision(3) << 0.2 * midterm + 0.4 * final + 0.4 * median << setprecision(prec) << endl;์ด๋ ๊ฒ ์๊ฒผ๋ค. ๋์งธ์ค์ ๋ฑ๊ธ ๊ณ์ฐํ๋ ๋ถ๋ถ์ ๋ค์๊ณผ ๊ฐ์ด ํจ์๋ก ๋ฝ์๋ผ ์๊ฐ ์๋ค.
~cpp double grade(double midterm, double final, double homework) { return 0.2 * midterm + 0.4 * final + 0.4 * homework; } /* ... */ int main() { /* ... */ cout << "Your final grade is " << setprecision(3) << grade(midterm, final, sum / count) << setprecision(prec) << endl; return 0; }
~cpp return_type function_name(parameter lists...) { ํจ์ ๋ด์์ ํ ์ผ๋ค }์ด๋ ๊ฒ ํ๋ฉด ๋๋ค.
2.1.1. 4.1.1. Finding medians ¶
~cpp double median(vector<double> vec) { typedef vector<double>::size_type vec_sz; vec_sz size = vec.size(); if (size == 0) throw domain_error("median of an empty vector."); sort(vec.begin(), vec.end()); vec_sz mid = size/2; return size % 2 == 0 ? (vec[mid] + vec[mid-1]) / 2 : vec[mid]; }
2.1.2. 4.1.2 Reimplementing out grading policy ¶
~cpp double grade(double midterm, double final, const vector<double>& hw) { if(hw.empty()) // ์ฑ ์์๋ hw.size()==0 ์ด๋ผ๊ณ ๋์ด ์์ง๋ง // empty()๋ฉ์๋๋ฅผ ํธ์ถํ๋ ๊ฒ์ด ๋ ํจ์จ์ ์ด๋ผ๊ณ ํ๋๊ตฐ์. throw domain_error("student has done no homework"); return grade(midterm, final, median(hw)); }
- const vector<double>& hw : ์ด๊ฒ์ ์ฐ๋ฆฌ๋ doubleํ const vector๋ก์ ์ฐธ์กฐ๋ผ๊ณ ๋ถ๋ฅธ๋ค. reference๋ผ๋ ๊ฒ์ ์ด๋ ํ ๊ฐ์ฒด์ ๋๋ค๋ฅธ ์ด๋ฆ์ ๋งํ๋ค. ๋ํ const๋ฅผ ์์ผ๋ก์จ, ์ ๊ฐ์ฒด๋ฅผ ๋ณ๊ฒฝํ์ง ์๋๋ค๋ ๊ฒ์ ๋ณด์ฅํด์ค๋ค. ๋ํ ์ฐ๋ฆฌ๋ reference๋ฅผ ์์ผ๋ก์จ, ๊ทธ parameter๋ฅผ ๋ณต์ฌํ์ง ์๋๋ค. ์ฆ parameter๊ฐ ์ปค๋ค๋ ๊ฐ์ฒด์ผ๋, ๊ทธ๊ฒ์ ๋ณต์ฌํจ์ผ๋ก์จ ์๊ธฐ๋ overhead๋ฅผ ์์จ์ ์๋ ๊ฒ์ด๋ค.
~cpp vector<double> homework; vector<double>& hw = homework; // hw๋ homework์ ๊ฐ๋ค. ์ฆ, ์ด๋ฆ์ ๋ค๋ฅด์ง๋ง, hw๋ฅผ ๊ณ ์น๋ฉด homework๋ ๊ฐ์ด ๊ณ ์ณ์ง๋ค. ์๋? ๊ฐ์ผ๋๊น
- grade() function : ์ฐ๋ฆฌ๋ ์๊น grade๋ผ๋ ํจ์๋ฅผ ๋ง๋ค์์๋ค. ๊ทธ๋ฐ๋ฐ ์ด๋ฒ์ ์ด๋ฆ์ ๊ฐ์ผ๋ฉด์ parameter๋ ์กฐ๊ธ ๋ค๋ฅธ grade()๋ฅผ ๋ ๋ง๋ค์๋ค. ์ด๋ฐ๊ฒ ๊ฐ๋ฅํ๊ฐ? ๊ฐ๋ฅํ๋ค. ์ด๋ฌํ ๊ฒ์ ํจ์์ overloading์ด๋ผ๊ณ ํ๋ค. ํจ์ ํธ์ถํ ๋ ์ด๋ค๊ฒ ํธ์ถ๋ ๊น๋ ๋ฐ๋ผ๊ฐ๋ parameter lists์ ์ํด ๊ฒฐ์ ๋๋ค.
- exception : ์ฌ์ฉ์์๊ฒ ๋ฌด์์ด ์๋ชป๋์๋๊ฐ๋ฅผ ์๋ ค์ฃผ๋ exception์ ๋์ ธ์ค๋ค.
2.1.3. 4.1.3 Reading homework grades ¶
~cpp istream& read_hw(istream& in, vector<double>& hw) { double x; while(in >> x) // ์ฐจ์ฐจ ์ดํด๋ณผํ ์ง๋ง ์ด๊ฑด ์๋ชป๋์๋ค. hw.push_back(x); } read_hw(cin, homework); // ํธ์ถ
- hw๊ฐ ๋์ด์ค๋ฉด์ hw์์ ์๋ฌด๊ฒ๋ ์๋ค๋ ๊ฒ์ ๋ณด์ฅํ ์ ์๊ฒ ๋๊ฐ? ๋จผ์ ๋ฒ์ ์ฐ๋ ํ์๋ค์ ์ ์๊ฐ ๋ค์ด์์์ง๋ ๋ชจ๋ฅธ๋ค. ํ์คํ๊ฒ ์์ ์ฃผ๊ธฐ ์ํด hw.clear()๋ฅผ ํด์ฃผ์.
- ์ while ๋ฃจํ๊ฐ ์ธ์ ๋ฉ์ถ์ง ์์ ์๋๊ฐ? ํ์ผ์ ๋์ ๋๋ฌํ๊ฑฐ๋, ์
๋ ฅ๋ฐ์๊ฒ ๋ฑ๊ธ์ด ์๋๋์ผ ๊ฒ์ด๋ค.
- ํ์ผ์ ๋์ ๋๋ฌํ๋ค๋ ๊ฒ = ์ฝ๊ธฐ ์คํจ
- ์
๋ ฅ๋ฐ์๊ฒ ๋ฑ๊ธ์ด ์๋๋(์ ์๋ฅผ ์
๋ ฅํด์ผ ๋๋๋ฐ ์ด์ํ ๊ฒ์ ์
๋ ฅํ์๋) istream ๊ฐ์ฒด in์ ์คํจ ์ํ๊ฐ ๋๋ค. ๋ํ ๊ทธ๊ฒ์ ์ฝ์ง ์๋๋ค. ํ์ผ์ ๋์ ๋๋ฌํ๊ฒ ์ฒ๋ผ...
- ํ์ผ์ ๋์ ๋๋ฌํ๋ค๋ ๊ฒ = ์ฝ๊ธฐ ์คํจ
- ์ด ์ํฉ์ ํด๊ฒฐํ๊ธฐ ์ํด, ๊ทธ๋ฅ in๊ฐ์ฒด์ ์ํ๋ฅผ ์ด๊ธฐํํด์ค๋ฒ๋ฆฌ์. in.clear() ๋ชจ๋ ์๋ฌ ์ํ๋ฅผ ๋ฆฌ์
์์ผ์ค๋ค.
~cpp istream& read_hw(istream& in, vector<double>& hw) { if(in) { hw.clear(); double x; while(in >> x) hw.push_back(x); in.clear(); } return in; }
DeleteMe) ๋๋ฒ์งธ๊ฐ ์ ์ดํด๊ฐ ์๊ฐ๋ค.. ๋๊ฐ ์ ์์๋ ๋ถ์ ๋ช
์พํ ์ค๋ช
๋ถํ๋๋ฆฝ๋๋ค.
2.1.4. 4.1.4 Three kinds of function parameters ¶
- median ํจ์๋ฅผ ๋ณด๋ฉด, vector<double> ํ๋ผ๋ฉํฐ๊ฐ ์ฐธ์กฐ๋ก ๋์ด๊ฐ์ง ์๋๋ค. ํ์์๊ฐ ๋ง์์ง์๋ก ๋งค์ฐ ํฐ ๊ฐ์ฒด๊ฐ ๋ ํ
๋ฐ ๋ญ๋น๊ฐ ์๋๊ฐ? ํ๊ณ ์๊ฐํ ์๋ ์์ง๋ง, ์ด์ฉ์ ์๋ค. ํจ์ ๋ด๋ถ์์ ์ํ
์ ํด๋ฒ๋ฆฌ๊ธฐ ๋๋ฌธ์ ์ฐธ์กฐ๋ก ๋๊ธฐ๋ฉด, ์ปจํ
์ด๋์ ์ํ๊ฐ ๋ณํด๋ฒ๋ฆฐ๋ค.
- grade ํจ์๋ฅผ ๋ณด๋ฉด, vector๋ const ์ฐธ์กฐ๋ก ๋๊ธฐ๊ณ , double์ ๊ทธ๋ ์ง ์๋ค. int๋ double๊ฐ์ ๊ธฐ๋ณธํ์ ํฌ๊ธฐ๊ฐ ์๊ธฐ ๋๋ฌธ์, ๊ทธ๋ฅ ๋ณต์ฌ๋ก ๋๊ฒจ๋ ์ถฉ๋ถํ ๋น ๋ฅด๋ค. ๋ญ ๊ฐ์ ๋ณ๊ฒฝํด์ผ ํ ๋๋ผ๋ฉด ์ฐธ์กฐ๋ก ๋๊ฒจ์ผ๊ฒ ์ง๋ง... const ์ฐธ์กฐ๋ ๊ฐ์ฅ ์ผ๋ฐ์ ์ธ ์ ๋ฌ๋ฐฉ์์ด๋ค.
- read_hw ํจ์๋ฅผ ๋ณด๋ฉด, ๋ณต์ฌ๋ ํ์ง ์๊ณ , ๊ทธ ๊ฐ์ ๋ณ๊ฒฝํ๊ธฐ ์ํด ์ฐธ์กฐ๋ง ์ผ๋ค.
2.1.5. 4.1.5 Using functions to calculate a student's grade ¶
~cpp try { // ํ๋ค๊ฐ ์์ธ ๋ฐ์ํ๋ฉด, ์ค๋จํ๊ณ } catch(domain_error) { // ์ด๋ฆฌ๋ก ์จ๋ค. ๋ง์ฝ์ try ์์์ ์์ธ ์ ๋จ๋ฉด catch ์์ ์ํ์ํ๋ค. }
์ฌ๊ธฐ๊น์ง ์ต์ข
์์ค
~cpp #include <ios> #include <iomanip> #include <iostream> #include <string> #include <vector> #include <algorithm> #include <stdexcept> using namespace std; double grade(double midterm, double final, double homework); double grade(double midterm, double final, const vector<double>& hw); double median(vector<double> vec); istream& read_hw(istream& in, vector<double>& hw); int main() { cout << "Please enter your first name: "; string name; cin >> name; cout << "Hello, " << name << "!"; cout << "Please enter your midterm and final exam grades: "; double midterm, final; cin >> midterm >> final; cout << "Enter all your homework grades, " "follewd by end-of-file: "; vector<double> homework; read_hw(cin, homework); try { double final_grade = grade(midterm, final, homework); streamsize prec = cout.precision(); cout << "Your final grade is " << setprecision(3) << final_grade << setprecision(prec) << endl; } catch(domain_error) { cout << endl << "You must enter your grades. " "Please try again." << endl; return 1; } return 0; } double grade(double midterm, double final, double homework) { return 0.2 * midterm + 0.4 * final + 0.4 * homework; } double grade(double midterm, double final, const vector<double>& hw) { if(hw.size() == 0) throw domain_error("Student has done no homework"); return grade(midterm, final, median(hw)); } double median(vector<double> vec) { typedef vector<double>::size_type vec_sz; vec_sz size = vec.size(); if(size == 0) throw domain_error("median of an empty vector"); sort(vec.begin(),vec.end()); vec_sz mid = size / 2; return size % 2 == 0 ? (vec[mid] + vec[mid-1]) / 2 : vec[mid]; } istream& read_hw(istream& in, vector<double>& hw) { if(in) { hw.clear(); double x; while(in >> x) hw.push_back(x); in.clear(); } return in; }
2.2.1. 4.2.1 Keeping all of a student's data together ¶
~cpp struct Student_info { string name; double midterm, final; vector<double> homework; };
~cpp istream& read(istream& is, Student_info& s) { is >> s.name >> s.midterm >> s.final; read_hw(is, s.homework); return is; }
- is >> ์ ๋ณด๋ฉด, string์ ์ฝ์๋ค๊ฐ double์ ์ฝ๊ธฐ๋ ํ๋ค. ์ด๊ฒ ๊ฐ๋ฅํ ์ด์ ๋ ์ค๋ฒ๋ก๋ฉ ๋๋ฌธ์ด๋ค.
- Student_infoํ ๋ณ์ s์ ๊ฐ์ ๋ณ๊ฒฝ์ํค๊ธฐ ์ํด ์ฐธ์กฐ๋ก ๋๊ฒจ์คฌ๋ค.
~cpp double grade(const Student_info& s) { return grade(s.midterm, s.final, s.homework); }
~cpp sort(vec.begin(), vec.end());
- ์ vec์ doubleํ ๊ฐ์ ๋ด๊ณ ์์๊ธฐ 떄๋ฌธ์, ์์๋๋ก sortํ๋ฉด ๋์์๋ค. ํ์ง๋ง ์ฐ๋ฆฌ๊ฐ ๋ง๋ Student_info๋ ์ด๋ป๊ฒ sort๋ฅผ ํ ๊น?
~cpp sort(students.begin(), students.end()); // ๊ณผ์ฐ? #!$%#@^#@$#
- ๋ฌด์์ ๊ธฐ์ค์ผ๋ก sort๋ฅผ ํ ๊ฒ์ธ๊ฐ? ์ด๋ฆ? midterm? final? ์์๊ฐ ์๋ค. ๋ฐ๋ผ์ ์ฐ๋ฆฌ๋ predicate๋ผ๋ ๊ฒ์ ์ ์ํด ์ฃผ์ด์ผ ํ๋ค. ๋ค์๊ณผ ๊ฐ์ด ํด์ฃผ๋ฉด ๋๋ค.
~cpp bool compare(const Student_info& x, const Student_info& y) { return x.name < y.name; } sort(students.begin(), students.end(), compare);
2.2.2. 4.2.3. Generating the report ¶
2.3. 4.3. Putting it all together ¶
~cpp #ifndef GURAD #define GUARD /* ... ... ... */ #endif