출시·고도화 중
C++ 안내서 · 2/6
이 장에서는 C++ 프로그램의 뼈대가 되는 문법을 살펴봅니다. main 함수, 변수와 auto, 참조, 함수와 오버로딩, 조건문과 반복문, 그리고 출력 방법까지 순서대로 다룹니다.
C++ 프로그램은 main 함수에서 시작합니다. 문장은 세미콜론(;)으로 끝나고, 블록은 중괄호로 묶습니다. 주석은 //(한 줄)과 /* ... */(여러 줄)을 씁니다.
#include <iostream>
int main(int argc, char* argv[]) {
// argc: 인자 개수, argv: 인자 문자열 배열
std::cout << "인자 " << argc << "개, 프로그램: " << argv[0] << '\n';
return 0; // main 에서는 생략해도 0 을 돌려준 것으로 봅니다
}변수는 타입과 이름으로 선언합니다. 중괄호 초기화({})를 쓰면 값이 잘려 나가는 좁히기 변환(narrowing)을 컴파일러가 막아 줍니다. auto는 초기값에서 타입을 추론하고, const는 값을 바꿀 수 없게 합니다.
#include <string>
int count{10};
double ratio = 0.75;
const int max_users{100}; // 바꿀 수 없음
constexpr int buffer = 256; // 컴파일 시간에 값이 정해짐
auto name = std::string{"Kim"}; // std::string
auto total = count * 2; // int
// int bad{3.14}; // 오류: double 에서 int 로 좁히기 변환지역 변수는 초기화하지 않으면 값이 정해지지 않으므로, 선언할 때 항상 초기값을 주는 것이 좋습니다.
참조(&)는 이미 있는 변수의 다른 이름입니다. 함수에 큰 객체를 넘길 때 복사를 피하려고 많이 씁니다. 바꾸지 않을 값은 const 참조로 받습니다.
#include <string>
void add_suffix(std::string& text) { // 원본을 바꿈
text += "!";
}
std::size_t length_of(const std::string& text) { // 복사 없이 읽기만
return text.size();
}
int main() {
std::string greeting{"hello"};
add_suffix(greeting); // greeting == "hello!"
auto n = length_of(greeting); // 6
int value = 1;
int& alias = value;
alias = 5; // value 도 5
}참조는 선언할 때 반드시 대상에 묶이며, 나중에 다른 변수를 가리키도록 바꿀 수 없습니다. 바꿔 가리키거나 "없음"을 나타내야 한다면 포인터를 씁니다.
함수는 반환 타입, 이름, 매개변수로 선언합니다. 이름이 같아도 매개변수 목록이 다르면 여러 함수를 정의할 수 있는데, 이를 오버로딩이라고 합니다. 기본 인자도 지정할 수 있습니다.
#include <string>
int area(int w, int h) { return w * h; }
double area(double radius) { return 3.14159 * radius * radius; }
std::string repeat(const std::string& s, int times = 2) {
std::string out;
for (int i = 0; i < times; ++i) out += s;
return out;
}
// area(3, 4) -> 12, area(1.5) -> 원 넓이
// repeat("ab") -> "abab", repeat("ab", 3) -> "ababab"컴파일러는 호출할 때 넘긴 인자의 타입을 보고 알맞은 함수를 고릅니다. 후보가 모호하면 컴파일 오류가 납니다.
if, switch, while, for는 C와 비슷합니다. C++11부터는 컨테이너의 모든 원소를 도는 범위 기반 for를 쓸 수 있고, C++17부터는 if 안에서 변수를 선언하는 초기화 구문도 쓸 수 있습니다.
#include <iostream>
#include <vector>
int main() {
std::vector<int> scores{90, 72, 85, 60};
for (int s : scores) { // 값 복사
std::cout << s << ' ';
}
for (auto& s : scores) { // 참조로 원소 수정
s += 5;
}
for (const auto& s : scores) { // 읽기 전용
if (s >= 90) std::cout << "A ";
else if (s >= 80) std::cout << "B ";
else std::cout << "C ";
}
if (auto n = scores.size(); n > 3) { // C++17 if 초기화
std::cout << "\n원소 " << n << "개\n";
}
int i = 0;
while (i < 3) { ++i; }
}std::cout은 어느 표준 버전에서나 쓸 수 있는 기본 출력입니다. C++20에는 서식 문자열로 값을 끼워 넣는 std::format(헤더 <format>)이 들어왔고, C++23에는 바로 출력하는 std::print(헤더 <print>)가 추가되었습니다. 다만 표준 라이브러리 구현마다 지원 시기가 달랐으므로, 오래된 컴파일러에서는 쓰지 못할 수 있습니다.
#include <format>
#include <iostream>
#include <string>
int main() {
std::string name{"Lee"};
int score = 92;
std::cout << std::format("{}님의 점수는 {}점입니다.\n", name, score);
std::cout << std::format("{:>8.2f}|\n", 3.14159); // 폭 8, 소수 둘째 자리
}std::format을 쓸 수 없는 환경이라면 std::cout을 쓰거나, 같은 문법을 제공하는 오픈 소스 라이브러리 {fmt}를 씁니다.
main에서 시작하고, 문장은 ;로 끝납니다.auto로 타입 추론, const/constexpr로 불변 값을 만듭니다.const 참조로 받습니다.std::format을 씁니다.
댓글 0개
로그인 · 로그인하면 댓글을 남길 수 있습니다.
첫 댓글을 남겨 보세요.