본문 바로가기
번역/Bjarne Stroustrup's C++ Style and Technique FAQ

How do I write this very simple program?

by 겜게준 2017. 8. 12.

번역


이런 간단한 프로그램은 어떻게 짜나요?

종종, 특히 학기가 시작할 때, 아주 간단한 프로그램을 어떻게 작성하는지에 대한 질문을 많이 받습니다. 예를 들어서, 해결해야 하는 문제가 몇 개의 숫자를 읽어서, 무언가를 해야 한다고 가정하고 해답을 한번 작성해봅시다.

다음은 위에서 말한 것을 수행하는 샘플 프로그램입니다:

      #include<iostream>
#include<vector>
#include<algorithm>
using namespace std;

int main()
{
vector<double> v;

double d;
while(cin>>d) v.push_back(d); // read elements
if (!cin.eof()) { // check if input failed
cerr << "format error\n";
return 1; // error return
}

cout << "read " << v.size() << " elements\n";

reverse(v.begin(),v.end());
cout << "elements in reverse order:\n";
for (int i = 0; i<v.size(); ++i) cout << v[i] << '\n';

return 0; // success return
}

다음은 이 프로그램을 몇 가지 분석한 것입니다:
  • 표준 라이브러리를 사용한 표준 ISO C++ 프로그램입니다. 표준 라이브러리의 기능들은 .h 접미사가 붙지 않은 헤더 파일에 std 네임스페이스에 선언되어있습니다.
  • 이 프로그램을 Windows 머신에서 컴파일을 하고싶다면, "console application"[각주:1]으로 컴파일해야 됩니다. 소스파일이 .cpp 접두사가 붙어있는지, 또는 컴파일러가 c 소스라고 판단할 수 있다는 것을 명심하십시오.
  • main() 함수는 int형 데이터를 반환합니다.
  • 표준 벡터로 데이터를 읽으면 임의의 버퍼가 오버플로우 되는 것을 막는 이점이 있습니다.
  • !cin.eof()는 스트림의 포맷을 확인하는 것입니다. 자세히 말하자면, end-of-file로 인하여 루프가 끝났는지 확인합니다. (아니라면, 예상했던 type/format 입력을 받지 못한 것입니다.) 더 자세한 정보는 여러분 c++ 책에 있는 "stream state"를 확인하세요
  • 벡터는 스스로의 크기를 알기 때문에, 요소들을 세지 않았습니다.
  • 네, 저도 몇몇 아주 엄격한 컴파일러의 경고를 피하고자 int형 대신 vector<double>::size_type형으로 선언할 수 있다는 것을 알고 있습니다. 그러나, 이 경우에는 너무 규율 적이고 산만하다고 생각합니다.
  • 이 프로그램에는 명시적인 메모리 관리를 하지 않았고, 메모리 릭도 없습니다. 벡터는 엘리먼트들을 저장할 때 사용하기 위해서 메모리 트랙을 유지합니다. 벡터가 엘리먼트를 위해 더 많은 메모리가 필요할 때에는, 더 많이 할당합니다.[각주:2] 벡터가 스코프를 벗어나게 되면, 메모리를 해제합니다.[각주:3] 그러므로, 사용자들은 벡터 요소에 대한 메모리 할당과 해제를 상관 쓰지 않아도 됩니다.
  • 문자열을 읽고 싶다면, How do I read a string from input?을 확인하세요.
  • 이 프로그램은 "end of file"을 입력받았을 때, 입력을 끝냅니다. Unix 머신에서 프로그램을 돌려서 키보드 입력을 받는다면, "end of file"은 Ctrl-D 입니다. 만약 버그로 end-of-file을 인식하지 못하는 Windows 머신이라면, "end"라는 단어로 입력이 종료되는 조금 복잡한 버전의 프로그램을 선호해야 할 수도 있습니다.
#include<iostream>
#include<vector>
#include<algorithm>
#include<string>
using namespace std;

int main()
{
vector<double> v;

double d;
while(cin>>d) v.push_back(d); // read elements
if (!cin.eof()) { // check if input failed
cin.clear(); // clear error state
string s;
cin >> s; // look for terminator string
if (s != "end") {
cerr << "format error\n";
return 1; // error return
}
}

cout << "read " << v.size() << " elements\n";

reverse(v.begin(),v.end());
cout << "elements in reverse order:\n";
for (int i = 0; i<v.size(); ++i) cout << v[i] << '\n';

return 0; // success return
}

간단한 것을 쉽게 처리하기 위해 어떻게 표준 라이브러리를 사용해야 하는지에 대한 예제는 TC++PL4.의 "Tour of the Standard Library"를 확인하세요




원문

How do I write this very simple program?

Often, especially at the start of semesters, I get a lot of questions about how to write very simple programs. Typically, the problem to be solved is to read in a few numbers, do something with them, and write out an answer. Here is a sample program that does that:

#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;

int main()
{
vector<double> v;

double d;
while(cin>>d) v.push_back(d); // read elements
if (!cin.eof()) { // check if input failed
cerr << "format error\n";
return 1; // error return
}

cout << "read " << v.size() << " elements\n";

reverse(v.begin(),v.end());
cout << "elements in reverse order:\n";
for (int i = 0; i<v.size(); ++i) cout << v[i] << '\n';

return 0; // success return
}

Here are a few observations about this program:

  • This is a Standard ISO C++ program using the standard library. Standard library facilities are declared in namespace std in headers without a .h suffix.
  • If you want to compile this on a Windows machine, you need to compile it as a "console application". Remember to give your source file the .cpp suffix or the compiler might think that it is C (not C++) source.
  • Yes, main() returns an int.
  • Reading into a standard vector guarantees that you don't overflow some arbitrary buffer. Reading into an array without making a "silly error" is beyond the ability of complete novices - by the time you get that right, you are no longer a complete novice. If you doubt this claim, I suggest you read my paper "Learning Standard C++ as a New Language", which you can download from my publications list.
  • The !cin.eof() is a test of the stream's format. Specifically, it tests whether the loop ended by finding end-of-file (if not, you didn't get input of the expected type/format). For more information, look up "stream state" in your C++ textbook.
  • A vector knows its size, so I don't have to count elements.
  • Yes, I know that I could declare i to be a vector<double>::size_type rather than plain int to quiet warnings from some hyper-suspicious compilers, but in this case,I consider that too pedantic and distracting.
  • This program contains no explicit memory management, and it does not leak memory. A vector keeps track of the memory it uses to store its elements. When a vector needs more memory for elements, it allocates more; when a vector goes out of scope, it frees that memory. Therefore, the user need not be concerned with the allocation and deallocation of memory for vector elements.
  • for reading in strings, see How do I read a string from input?.
  • The program ends reading input when it sees "end of file". If you run the program from the keybord on a Unix machine "end of file" is Ctrl-D. If you are on a Windows machine that because of a bug doesn't recognize an end-of-file character, you might prefer this slightly more complicated version of the program that terminates input with the word "end":
#include<iostream>
#include<vector>
#include<algorithm>
#include<string>
using namespace std;

int main()
{
vector<double> v;

double d;
while(cin>>d) v.push_back(d); // read elements
if (!cin.eof()) { // check if input failed
cin.clear(); // clear error state
string s;
cin >> s; // look for terminator string
if (s != "end") {
cerr << "format error\n";
return 1; // error return
}
}

cout << "read " << v.size() << " elements\n";

reverse(v.begin(),v.end());
cout << "elements in reverse order:\n";
for (int i = 0; i<v.size(); ++i) cout << v[i] << '\n';

return 0; // success return
}

For more examples of how to use the standard library to do simple things simply, see the "Tour of the Standard Library" Chapter of TC++PL4.


  1. IDE나 msvc같은 컴파일러에서 설정할 수 있습니다. [본문으로]
  2. 2의 배수크기로 할당됩니다. [본문으로]
  3. c++은 기본적으로 해당 스코프에 벗어날 때 할당된 객체들의 소멸자가 호출됩니다. [본문으로]

댓글