C++(1~24강)

Brandon JE·2022년 6월 11일
0

iwanttocreategame

목록 보기
1/1

이문서는 어소트락 게임아카데미 C++ 강의 기반으로 작성 되었습니다.

C++ 자료형

정수

1바이트는 256 가지 상태를 표현가능합니다. (0 ~ 255)
unsigned 양의 정수형만 사용 사능하고 signed는 음의 정수 양의 정수 모두 표현 가능 합니다.
기본적으로 아무것도 적지않으면 signed 입니다.

8개의 자릿수 8비트중 제일 앞의 자리를 MSB라고 합니다.
앞의 자릿수가 0이면 양수 0 ~ 127 앞의 자릿수가 1이명 음수 -128 ~ 0 입니다.

2의보수법은 8비트의 각자리를 반전시킨다음 +1 합니다(양수를 대응하는 음수를 찾는 방법)

밑의 그림은 참고 자료 입니다.

실수

정수 표현 방식과 실수 표현 방식은 다릅니다
실수 표현 방식은 정밀도에 의존합니다.
따라서 double(8) 자료형이 float(4) 보다 더아래의 소수점까지 정확하게 표현이 가능 합니다.

정수는 정수끼리, 실수는 실수 끼리 연산하되, 두 표현방식의 피 연산자가 연산될 경우 명시 적으로 변환 합니다

예제) float f = 10.2415f + (float)20;

위의 예제처럼 10.2415 값뒤에 "f"를 붙인 경우는 데이터 타입이 4바이트 float형 입니다.
만약 f를 붙이지 않으면 데이터타입은 double형 입니다.

연산자

대입 연산자
"="

산술 연산자
+, -, *, /, %
(%는 모듈러러스 연산자라고도 불리며 나머지를 구할때 사용합니다. 피연산자가 모두 정수 일때 사용 가능하며 실수일땐 에러 발생합니다.)

아래 예제코드에서 자동으로 형변환이 일어나 int자료형에 맞게 값이 변환되지만 경고가 발생합니다.

int data = ( 10.f / 3.f );
-> int data = (int)( 10.f / 3.f );

(경고가 발생되길 원하지 않으면 위처럼 작성하면 됩니다.)

증감 연산자
한단계 증가 또는 감소
++, --
(연산자는 특별한 사유가 없는한 전위로 사용 합니다. 해당 영상 강사님 추천)

예제) int data = 0;
data = data++ (후위, 후치)

후위 연산자를 사용하는 경우, 연산자 우선순위가 가장 나중으로 밀립니다.
그래서 data에 먼저 대입되고 1이 증가합니다. 실제 data의 값은 0 입니다.

data = ++data (전위, 전치)

전위 연산자는 먼저 증가하고 대입합니다.

논리 연산자

!(역): 참을 거짓으로 거짓을 참으로 만듭니다.
&&(곱, and): 둘다 참일때만 참입니다.
||(합, or): 둘중에 하나만 참이어도 참이며, 둘다 거짓이면 거짓입니다.
참(true), 거짓(false): 참이면 1, 거짓이면 0 이며, 사이즈는 1바이트 입니다.

bool

bool truefalse = ture; //1
bool truefalse = false; //0
bool Istrue = 100; //bool은 1과0 밖에 없기 때문에 
0이 아닌수는 True로 받아들여서 1 입니다.

!(역)

Istrue = true; //1
Istrue = !Istrue; //0
int Itrue = 100; //1
Itrue = !Itrue; //0
int jtrue = 0;
jtrue = !jtrue; //1

&&(곱, and)

int itrue = 0 && 200; //0

||(합, or)

int itrue = 0 || 200; //1

비교 연산자

==: 둘의 값이 같은지 비교 하는 연산자 입니다.
!=: 둘의 값이 다른지 비교 하는 연산자 입니다.
기타 등등 (<, <=, >=, >)
(결과는 참, 거짓으로 반환 합니다)

구문, 삼항연산자

논리 연사자와 비교연산자는 주로 아래의 구문과 삼항연산자로 같이 자주 쓰입니다.

구문
if, else: if 조건이 참일 경우 if구문이 실행, 최후 무조건 else가 실행
switch case: 해당 값이 일치하면 여러개의 case문 중에 일치하는 case 문 호출

삼항연산자
?:

iTest가 20이면 100이 할당되고 아니면 200이 할당 됩니다.

예제) iTest == 20 ? iTest = 100 : iTest = 200;

비트연산자

쉬프트 연산자 <<, >>

unsigned char byte = 10 ;
byte <<= 3 ; // 2^n 배수
byte >>= 3 ; // 2^n 나눈 몫

종류: 비트 곱(&), 합(|), xor(^), 반전(~)
비트단위로 연산을 진행합니다.

비트 곱(&): 둘다 1인 경우에만 1입니다.

합(|): 둘중 하나라도 1이면 1입니다.

xor(^): 같으면 0, 다르면 1

반전(~): 1은 0으로, 0은 1로

상태 값을 입력하기 위해 각자리에 맞는 입수를 입력 합니다
아래 예제는 2진수로 나타내어 2^n 입니다

#define HUNGRY 1 ;
#define HUNGRY 2 ;
#define HUNGRY 4 ;
#define HUNGRY 8 ;
#define HUNGRY 16 ;

하지만 보통 상태를 나타낼 때엔 16진수를 사용 합니다.
여담이긴하지만 아래 코드를 보면 보통 자리는 40씩 커지고 2배씩커지는 이유는 2^n이기 때문입니다. 그리고 0x080에서 0x100 될때나 0x008에서 0x010 될때 왜 20이 늘어나는지 몰랐었습니다. 그래서 생각한 결과 0x010이 16이니까 0x080 + 0x080 은 16이니까 0x100이된것 같습니다.

#define HUNGRY 0x001 ;
#define HUNGRY 0x002 ;
#define HUNGRY 0x004 ;
#define HUNGRY 0x008 ;
#define HUNGRY 0x010 ; 16진수 16 입니다
#define HUNGRY 0x020 ; 16진수 32 입니다
#define HUNGRY 0x040 ; 16진수 64 입니다
#define HUNGRY 0x080 ; 16진수 128 입니다
#define HUNGRY 0x100 ; 16진수 256 입니다
#define HUNGRY 0x200 ; 16진수 512 입니다
#define HUNGRY 0x400 ; 16진수 1024 입니다
#define HUNGRY 0x800 ; 16진수 2048 입니다

상태 추가
unsigned int iStatus = 0 ;
iStatus |= HUNGRY ;
iStatus |= THIRSTY ;

상태 확인
if ( iStatus & THIRSTY )
{

}

특정 자리 비트 제거 (암기하는게 좋음)
iStatus &= ~THIRSTY ;

전처리

제일 먼저 처리하는 구문을 의미 합니다.

전처리의 장점
1. 가독성
2. 유지보수 측면에서 유리

예제) #define HUNGRY 1 ;
	 #define <stdio> ;

변수

~

변수의 종류 및 설명

  • 지역변수: 괄호안에 선언된 변수
  • 전역변수: 함수 외부에 선언된 변수
  • 정적변수:
  • 외부변수:

지역변수
괄호안에 선언된 변수(함수, 지역)
{
변수명 규칙
전역변수와 지역변수에 똑같은명의 변수명이 있다고 하더라도 괄호 안에서 호출하면 지역 변수 우선순위가 더높습니다.
}

함수(1)

기능을 수행하는 코드의 집합 입니다.

int main ()
{
	iData = Add( 100, 200 ) ;
    return 0 ;
}
int Add ( int a, int b ) ;

main() 함수

코드의 시작점이며, 이함수가 종료되면 프로그램이 종료 됩니다.

반복문

반복문은 if, while 문이 있습니다.

for ( 반복자 초기화 ; 반복자 조건 체크 ; 반복자 변경 )
{
	조건이 참인 경우 반복되는 코드 구문
}

for ( int i = 1; i <= 10; ++i )
{
	printf("Outout Test\n") ;
}
while ( 조건체크 )
{
	조건이 참일경우 실행되는 코드 구문
}

int i = 0 ;
while ( i < 2 )
{
	printf( "Output Test" ) ; 
}

continue, break

컨티뉴, 브레이크는 for, while 문 둘다 똑같이 동작 합니다.

아래예제와같이 조건이 참일 경우 건너뛰고 다음 조건을 실행 합니다.

for ( int i = 1; i <= 10; ++i )
{
	if ( i % 2 == 1 )
    {
    	continue ;
    }
	printf("Outout Test\n") ;
}

아래예제와같이 조건이 참일 경우 코드를 종료하고 반복문을 빠져 나갑니다.

for ( int i = 1; i <= 10; ++i )
{
	if ( i % 2 == 1 )
    {
    	break ;
    }
	printf("Outout Test\n") ;
}

표준 입출력 함수

표준 입출력 함수는 printf(); scanf() 가 있습니다. 콘솔창 이라고도 부릅니다.

아래는 printf 예제이며 %d 는 정수 치환 문자 입니다. %f는 실수 치환문자 입니다.

printf ( "abcd %d \n", 10 ) ;
printf ( "abcd %f \n", 3.14 ) ;
for ( int i = 0; i < 10; i++ )
{
	printf("Output i: %d", i)
}

scanf는 콘솔창으로 부터 지정한 변수에 입력을 받는 함수 입니다.
아래는 입력을 받아 iInput에 할당합니다.

int iInput = 0 ;
scanf_s( "%d", &iInput ) ;

함수(2)

함수가 사용하는 메모리 영역을 "스택 메모리 영역" 이라 합니다.
함수는 재사용을 위해서 사용 합니다.

factorial

각자리를 더하는 것을 팩토리얼 이라고 합니다.

int main()
{
	int i = 4;
    int iValue = 1;
    for ( int j = 0; j < i; ++j )
    {
    	iValue *= ( j + 2 );
    }
}

재귀함수

함수안에서 자기자신을 다시 호출 하는것 입니다.

int Factory(int _iNum)
{
	int iValue = 1;
	for (int j = 0; j < _iNum - 1; ++j)
	{
		iValue *= (j + 2);
	}
	//Factory(10); //주석해제하면 스택 오버플로우가 발생합니다.
	return iValue;
}; 

수행을 완료하고 스택에서 사라지고 연산값은 cpu의 레지스터 메모리에 잠시 저장되고 호출했던 곳에서 저장된 값을 꺼내가는 형태 입니다.
재귀함수는 탈출할수있는 예외 처리를 만들어줘야 합니다.
재귀함수의 장점은 가독성이 좋고 , 구현이 용이하며 단점으로는 성능이 많이 떨어진다고 합니다.

재귀함수 팩토리얼

int Factorial_Re( int _iNum )
{
	if (_iNum == 1) 
	{
		return 1;
	}
	return _iNum * Factorial_Re(_iNum - 1);
}

피보나치 수열
1 1 2 3 5 8 13 21 34 55...

int Fibo(int num)
{
	if (1 == num || 2 == num)
	{
		return 1;
	}
	int iPre1 = 1;
	int iPre2 = 1;
	int value = 0;
	for (int i = 0; i < num - 2; ++i)
	{
		value = iPre1 + iPre2;
		iPre1 = iPre2;
		iPre2 = value;
	}
	return value;
}

피보나치수열 재귀함수 버전으로 작성

int Fibo2(int num)
{
	if (1 == num || 2 == num)
	{
		return 1;
	}
	return Fibo2(num - 1) + Fibo2(num - 2);
}
int main()

{
	int iValue = Factory(4);
	iValue = Factory(10);
	iValue = Factorial_Re(10);
	iValue = Fibo(10);
	iValue = Fibo2(3);
}

배열

메모리가 연속적인 구조

아무것도 적지않으면 10개의 자리에 0으로 초기화
int iArray[10] = {1,2,3,4}; //  나머지 6자리는 0으로 초기화 됩니다.
4번째 인덱스에 10을 대입
iArray[4] = 10; 

구조체

사용자 정의 자료형 입니다.

아래는 구조체 기본 문법 형태 입니다.

typedef struct {name}
{
	자료형 변수명;
}struct {name};// 알리아스 개념 입니다.

밑에는 예제 코드 입니다.

typedef struct _tagMyST
{
	int   a;
	float f;
}MYST;

아래처럼 구조체가 다른 구조체로 들어갈수 있습니다.

typedef struct _tagBig
{
	MYST  k;
	int	  i;
	float c;
}BIG;

아래 예제는 int 타입명을 대문자INT 로 사용 하겠다는 정의 입니다.

typedef int INT;

아래는 메인 함수로 호출 예제 입니다.

int main()
{
	//구조체
	MYST t = {100, 3.14f}; // 구조체 초기화
	t.a = 10;
	t.f = 10.3213;
	BIG y;
	y.k.a = 20;
	int iSize = sizeof(MYST);
	return 0;
}

지역변수, 전역변수

변수 종료
1. 지역변수
2. 전역변수
3. 정적변수
4. 외부변수

메모리 영역 종류
1. 스택 영역
2. 데이터영역
3. 읽기 전용(코드, ROM)
4. 힙 영역

전역변수
int i = 1; // data 영역

Void 란 반환 탑입이 없을 경우 작성 합니다
void Test()
{
++i;
}

data 영역 특징
프로그램 시작 시 생성
프로그램 종료 시 해제

지역변수

int main()

{
	//지역변수
	return 0;
}

분할구현

코드는 위에서부터 아래로 순차적으로 실행 됩니다.
( 그런데 함수 선언이 밑에 있고 함수 호출이 위에 있는경우 void Test(); 를 사용 하여 함수가
있다는걸 알려줄수 있습니다 )

코드 헤더 파일과 소스파일 구분하는 이유는 코드의 관리를 위해서 입니다.
코드 헤더 파일예제입니다
아래 예제는 어딘가에 sum 함수가 구현되어있다 라는 명시 입니다

test.h
int sum = sum (int a, int b);

소스파일 예제입니다.

#include <test.h>
int sum (int a, int b)
{
	return a + b;
}

그럼 해당 더하기 함수가 필요할땐 필요한 소스 파일에서 헤더 파일만 #include <test.h>;
하면 해당 함수를 사용 할수 있습니다, 그리고 함수가 만들어져 있어야 사용 됩니다.
구현 되어 있지않으면 오류 발생합니다.
링크과정에서 연결 됩니다.

분할 구현의 문제점

문제점은 #include는 말그대로 코드를 복붙시키는 개념입니다.
그래서 함수 이름이나 변수명이 중복되는 경우가 많습니다
그리고 전역변수를 다른 파일에서도 쓰게하려면 #include 방법은 적절하지 않습니다.
다음 배울 외부변수에서 이같은 문제를 해결 예정입니다.

현재 어소트락 게임아카데미 C++ 강의 24강입니다.
25강부턴 다른 페이지에 작성 예정 입니다.

profile
Web Full-Stack Developer and Writer

0개의 댓글