게임 개발자를 위한 C++ 문법 강의 시작
C++ 강의가 제공되어서 시작하게 되었습니다.
어느 정도 알고 있는 개념이지만 C#을 주 언어로 사용하던 저에게 C++을 익숙하게 만들기 위해서 다양한 예제를 작성하면서 학습을 진행했습니다.
강의를 진행하던 중에 다이아몬드 모양 별 찍기 과제가 있어서 진행해 보았습니다.
다음과 같은 문제여서 저는 공백 구분하는 게 어려울 것 같아서 공백을 ' 1 '로 바꾸고 진행할 생각입니다.
(이 부분이 가장 큰 문제였습니다...)
제가 정리한 풀이법으로는
- lineCount → 라인 수
- StarCount → 별의 수
- HalfBlankCount = (lineCount - StarCount) / 2 → 공백의 수
이렇게 기준을 잡고 시작하게 되었습니다.
#include <iostream>
using namespace std;
int main()
{
int num = 0;
cin >> num;
int lineCount = 2 * num - 1;
int starCount = 1;
int halfBlankCount = 1;
// lineCount → 라인 수
// StarCount → 별의 수
// HalfBlankCount = (lineCount - StarCount) / 2 → 공백의 수
for (int i = 1; i <= lineCount; i++)
{
for (int j = 1; j <= lineCount; j++)
{
halfBlankCount = (lineCount - starCount) / 2;
if (j <= halfBlankCount)
{
cout << " ";
}
else if (j > lineCount - halfBlankCount)
{
cout << " ";
}
else
{
cout << "*";
}
}
if (i < num)
{
starCount += 2;
}
else if (i >= num)
{
starCount -= 2;
}
cout << endl;
}
return 0;
}
부끄럽지만 완성된 코드입니다.
완료 후 코드에 개선할 수 있는 부분이 있을 것 같아서 조금 더 쳐다보고 있었습니다.
다양하게 생각하고 삼항연산이나 다른 것들을 통해서 코드 줄을 줄일 수는 있을 거라 생각했는데 가독성이 안 좋을 것 같아서 그냥 정답을 보기로 했습니다.
여기서 정답 코드를 보고 가지게 된 생각은 " 왜 공백을 1로 그리려고 했을까 "라는 생각이었습니다.
아까 위에서 시작할 때 공백(" ")을 " 1 "로 바꾸고 진행한다 했는데 그 부분이 큰 화근이 되었습니다.
문제에서 원하는 풀이와 제가 가지고 있던 잘못된 부분을 비교하면 아래 사진과 같습니다.
문제를 잘못 인식해서 파란색으로 구분된 필요 없는 부분까지 구현하게 되었습니다.
오랜만에 참신한 생각을 가지게 되어서 코딩테스트가 단순하게 취업을 위한 목표로만 생각했는데 이런 과정들을 겪다 보면 자연스럽게 업무에도 활용도가 높겠다라고 생각하게 되었습니다.
정답 코드도 첨부합니다.
정답코드
#include <iostream>
using namespace std;
int main() {
int n;
// 사용자로부터 입력 받기
cout << "다이아몬드의 크기를 입력하세요 (양의 정수): ";
cin >> n;
// 입력값 검증
if (n <= 0) {
cout << "잘못된 입력입니다. 양의 정수를 입력하세요." << endl;
return 1;
}
// 다이아몬드 상단 출력
for (int i = 1; i <= n; ++i) {
// 공백 출력
for (int j = 1; j <= n - i; ++j) {
cout << " ";
}
// 별 출력
for (int k = 1; k <= 2 * i - 1; ++k) {
cout << "*";
}
cout << endl; // 줄 바꿈
}
// 다이아몬드 하단 출력
for (int i = n - 1; i >= 1; --i) {
// 공백 출력
for (int j = 1; j <= n - i; ++j) {
cout << " ";
}
// 별 출력
for (int k = 1; k <= 2 * i - 1; ++k) {
cout << "*";
}
cout << endl; // 줄 바꿈
}
return 0;
}
ERROR) LNK2005: main already defined in classExam.obj
Exam_01.cpp , Exam_02.cpp을 같은 솔루션 안에서 작성 후 실행 시 발생한 에러
에러 코드는 다음과 같습니다.
1>------ Build started: Project: hello_world, Configuration: Debug x64 ------
1>classExam.cpp
1>example.cpp
1>Generating Code...
1>LINK : C:\Users\soneunsu\source\repos\hello_world\x64\Debug\hello_world.exe not found or not built by the last incremental link; performing full link
1>example.obj : error LNK2005: main already defined in classExam.obj -> 중요한 부분
1>C:\Users\soneunsu\source\repos\hello_world\x64\Debug\hello_world.exe : fatal error LNK1169: one or more multiply defined symbols found
1>Done building project "hello_world.vcxproj" -- FAILED.
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========
========== Build completed at 오후 5:34 and took 01.230 seconds ==========
가장 중요하다 생각하는 부분으로
error LNK2005: main already defined in classExam.obj 부분을 해석해 보겠습니다.
main이 classExam.obj에 선언되어 있어서 발생한 에러다.라는 뜻으로 이해가 되었습니다.
유니티와 C#만 해왔던 저에게 무슨 이런 에러가 있지 했는데 우선 classExam.cpp안에 있는 main() 함수를 주석처리해서 해결했습니다.
정리해 보니 C++에서 main() 함수는 프로그램의 시작점으로, 하나의 프로젝트에 딱 한 번만 정의되어야 하는 걸 알게 되었습니다.
하지만 제가 시도한 건 하나의 프로젝트 안에서 두 개의 main() 함수를 설정해 두니 링크(Link) 단계에서 충돌이 발생하게 된 현상이었습니다.
해결 방법으로는 주석처리, 프로젝트 분리 등으로 하나의 main() 함수를 남기는 것입니다.
여기서 알게 된 내용을 가지고 C++ 컴파일 과정과 같이 설명하면 좋을 것 같아서 정리했습니다.
C++의 컴파일 과정
이해하기 쉬운 내용으로 조금 편하게 작성해 보았습니다.
컴파일 → 컴퓨터가 제가 작성한 코드를 실행 가능한 프로그램으로 만드는 과정입니다.
다음과 같은 과정을 통해서 컴파일이 진행됩니다.
1. 프리프로세싱(Preprocessing)
- 코드 시작 전에 #include, #define 같은 전처리기 지시문을 처리하는 단계
- 예를 들어 #include <iostream>을 보면, iostream 라이브러리의 코드를 네 코드에 붙여 넣기 하는 과정
- 결과물은 확장된 소스 코드가 된다.
2. 컴파일(Compilation)
- 컴파일러가 작성한 제가 작성한 C++코드를 어셈블리 코드로 변환한다.
- 어셈블리 코드는 사람이 읽을 수 있는 기계어
3. 어셈블(Assembly)
- 어셈블리 코드를 진짜 컴퓨터가 읽을 수 있는 목적 코드(Object Code)로 변환
- . obj 파일이나. o 파일이 생성되지만 이건 아직 완전한 실행 파일은 아니다.
4. 링크(Linking)
- 여러 개의. obj 파일들을 묶어서 실행 가능한 프로그램으로 만드는 단계
- 이 과정에서 다음을 해결한다
- 외부 라이브러리 연결: 예를 들어 cout을 사용하면, iostream 라이브러리를 찾아서 연결해야 함.
- 다른 파일 연결: 여러 파일을 작성했을 때 서로 호출하는 함수들을 이어주는 작업.
- 링크 단계에서 에러가 발생하게 되면, 보통 함수나 변수가 중복되었거나, 어디론가 호출했는데 정의가 안 돼 있을 때 발생하게 된다.
저에게 발생한 오류는?
링크 단계에서 main() 함수가 두 번 정의되었다고 나오고 있다.
- 컴파일 단계에서는 각각의. cpp 파일을 독립적으로 처리하니까 문제를 못 잡는다.
- 하지만 링크 단계에서 “main 함수가 두 개네?” 프로그램 시작점을 뭐로 정해야 하는 거지?” 하면서 에러가 발생하게 된 것이다.
Visual Studio 단축키
- 컴파일 → CTRL + F7
- 코드 실행 → F5
- 위 두 단계를 한번에 하는 마법 → CTRL + F5