๋ชฉ์ฐจ ¶
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










