게임 개발자를 위한 C++ 문법 1-4, 5

1. WHAT
- 포인터 배열: 포인터를 원소로 갖는 배열 > int* ptrArr[4]; >> 크기가 4, 각 원소가 int*
#include <iostream>
using namespace std;
// 포인터 배열: 포인터를 원소로 갖는 배열
int main() {
int a = 10, b = 20, c = 30;
int* ptrArr[3] = { &a, &b, &c }; // 포인터 배열 선언 및 초기화
// 포인터 배열을 이용하여 값 출력
cout << "*ptrArr[0]: " << *ptrArr[0] << endl; // 10
cout << "*ptrArr[1]: " << *ptrArr[1] << endl; // 20
cout << "*ptrArr[2]: " << *ptrArr[2] << endl; // 30
cout << "ptrArr[2]: " << ptrArr[2] << endl; // c의 주소
cout << "&c: " << &c << endl; // c의 주소
return 0;
}
배열 안에 각 변수의 주소를 저장 > 배열[인덱스] == 주소 , *배열[인덱스] == 주소의 값
- 배열 포인터: 배열 포인터는 배열 전체를 가리키는 포인터 > 다차원 배열을 제어할 때 많이 사용
#include <iostream>
using namespace std;
// 배열 포인터: 배열 전체를 가리키는 포인터
int main() {
int arr[3] = { 100, 200, 300 };
int (*ptr)[3] = &arr; // 배열 포인터 선언
// 배열 포인터를 이용하여 배열 요소 접근
cout << "(*ptr)[0]: " << (*ptr)[0] << endl; // 100
cout << "(*ptr)[1]: " << (*ptr)[1] << endl; // 200
cout << "(*ptr)[2]: " << (*ptr)[2] << endl; // 300
return 0;
}
- 포인터 배열 vs. 배열 포인터
#include <iostream>
using namespace std;
// 포인터 배열과 배열 포인터의 차이점 확인
int main() {
int x = 1, y = 2, z = 3;
int* ptrArr[3] = { &x, &y, &z }; // 포인터 배열 (각 원소가 int* 타입)
int arr[3] = { 10, 20, 30 };
int (*ptr)[3] = &arr; // 배열 포인터 (배열 전체를 가리킴)
// 포인터 배열을 통한 접근
cout << "*ptrArr[0]: " << *ptrArr[0] << endl; // 1
cout << "*ptrArr[1]: " << *ptrArr[1] << endl; // 2
cout << "*ptrArr[2]: " << *ptrArr[2] << endl; // 3
// 배열 포인터를 통한 접근
cout << "(*ptr)[0]: " << (*ptr)[0] << endl; // 10
cout << "(*ptr)[1]: " << (*ptr)[1] << endl; // 20
cout << "(*ptr)[2]: " << (*ptr)[2] << endl; // 30
return 0;
}
- 상수 레퍼런스 : const int& cref = x; > 복사 과정 없이 x의 값을 읽을 수는 있지만 x값을 수정할 수는 없음
#include <iostream>
using namespace std;
// 상수 레퍼런스를 사용하여 변수를 보호하는 예제
int main() {
int x = 100;
const int& cref = x; // x를 읽기 전용으로 참조
cout << "cref: " << cref << endl; // 100
// cref = 200; // ❌ 오류 발생! 상수 레퍼런스는 값을 변경할 수 없음
x = 200; // 원본 변수 x는 변경 가능
cout << "x 변경 후 cref: " << cref << endl; // 200
return 0;
}
/*
출력 결과:
cref: 100
x 변경 후 cref: 200
*/
- 초기화 되지 않은 포인터 접근 > 오류 > 예외처리 잘하기
- 클래스
#include <iostream>
#include <algorithm> //max 함수 사용
#include <string>
using namespace std;
class Student
{
//동작 정의(이를 멤버함수라고 합니다)
double getAvg();
int getMaxNum();
//데이터 정의(이를 멤버변수라고 합니다.)
int kor;
int eng;
int math;
};
double Student::getAvg()
{
return (kor + eng + math) / 3.0;
}
int Student::getMaxNum()
{
return max(max(kor, eng), math);
// 다른 방법 return max({ kor, eng, math });
}
- 생성자에 :charge(initialCharge) -> 멤버 초기화 리스트
public:
// 생성자: 기본값은 100으로 설정
Battery(int initialCharge = 100) : charge(initialCharge) {
if (charge < 0) {
charge = 0;
} else if (charge > 100) {
charge = 100;
}
}
멤버 변수를 생성자 본문이 실행되기 전에 초기화
- 멤버 초기화 리스트가 필수인 경우!!!
const 멤버일 때 > 대입x, 초기화 리스트로만 초기화 가능
참조자일 때 > 선언과 동시에 초기화
복잡한 멤버 객체가 있을 때
성능 측면
생성자 오버로드 시 일관성이 유지
2. FIX

안전성과 최적화를 위해 const와 멤버 초기화 리스트를 습관화 하자... ⭐⭐⭐
#include <iostream>
using namespace std;
class Fraction {
private:
int numerator; //분자
int denominator; //분모
int gcd(int a, int b) const { //private 로 옮김, const 추가
while (b != 0) {
int temp = b;
b = a % b;
a = temp;
}
return a;
}
public:
/*Fraction() {
this->numerator = 0;
this->denominator = 1;
}*/
Fraction():numerator(0), denominator(1){} //생성자 초기화 리스트
Fraction(int num, int denom) {
this->numerator = num;
//this->denominator = denom;
//분모가 0일때 예외처리 해야함
this->denominator = (denom != 0) ? denom : 1;
}
void simplify() {
int num=gcd(this->numerator, this->denominator);
this->numerator /= num;
this->denominator /= num;
}
Fraction multiply(const Fraction& other) const{ //const 추가, 참조자 변경
return Fraction(this->numerator*other.numerator,this->denominator* other.denominator);
}
void display() const { //const 추가
cout << this->numerator << '/' << this->denominator << endl;
}
};
int main() {
Fraction A(1, 2);
Fraction B(3, 4);
Fraction C = A.multiply(B);
C.simplify();
C.display();
return 0;
}
-> 수정 부분 주석에 정리함 (1-5 숙제 2)
내가 작성한 코드와 답안 코드를 비교해보니..
내가 쓴 것도 잘 돌아가지만 안전성과 최적화 부분에서 차이나는 것을 알 수 있었다.
효율적인 코드 작성을 위해 더 많이 배워야겠다...
3. RESULT
- 미니 실습
#include <iostream>
using namespace std;
void PrintNumber(int* pNumber) {
cout << *pNumber <<' ';
}
int main() {
int numbers[10] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
int* ptr = numbers;
for (int i = 0; i < 10; i++) {
PrintNumber(ptr + i);
}
for (int i = 0; i < 10; i++) {
PrintNumber(&ptr[i]);
}
return 0;
}
- 도전 실습
#include <iostream>
using namespace std;
void SwapByPointer(int* pA, int* pB) {
int temp = *pA;
*pA = *pB;
*pB = temp;
}
void SwapByReference(int& refA, int& refB) {
int temp = refA;
refA = refB;
refB = refA;
}
int main()
{
int a = 30;
int b = 80;
cout << "Before: " << a << ' ' << b << endl;
SwapByPointer(&a, &b);
cout <<"Swap By Pointer: " << a <<' ' << b << endl;
SwapByReference(a, b);
cout << "Swap By Reference: " << a << ' ' << b << endl;
return 0;
}'내배캠Unreal_TIL > C++' 카테고리의 다른 글
| [C++] Google C++ Style Guide, 구글 코드 컨벤션 (1) | 2025.12.11 |
|---|---|
| [TIL] 2025-12-11 | C++ 객체지향 프로그래밍, 상속과 다형성 (0) | 2025.12.11 |
| [TIL] 2025-12-09 | C++ 난수 생성, string 클래스와 getline(), 화면 초기화 (0) | 2025.12.09 |
| [TIL] 2025-12-08 | C++ 가변 인자 (0) | 2025.12.08 |
| [TIL] 2025-12-05 | C++ 프로그래밍 기초, strtok 함수 (0) | 2025.12.05 |