type
어떤 유형의 값을 저장할 지
object
메모리에 이름을 붙여 다음에 다시 저장 / 확인이 가능하게 만든 공간
value
object에 들어 있는 값.
리터럴 = 10 , 3.14f.’a’.true
operator
operand(피연산자) : expression(연산자가 들어 있는 식)
쉼표 연산자의 경우 앞과 뒤를 이어붙이는 연산자(연속적으로 실행한다)
int x = 1, y = 2;
// 왼쪽은 저장하는 용도 오른쪽은 가져오는 용도로 쓰임
x, y = y, x;
// 위 식의 의미
// x; y=y; x;
// 쉼표 연산자가 하는 일은 왼쪽과 오른쪽 문장을 합쳐주는 역할을 함
// 피연산자는 expression(식)을 지원함
// 문법으로는 허용하지만 실제로 사용하면 문제가 발생하는 경우가 많음
std::cout << x << ":" << y << std::endl;
=Compiler 의 작동 순서
lexicon(어휘)
단어 외우기
단어를 파악할 수 있는 것들로 추려 내는 과정
syntax(구문)
구성을 검사 / 문법에 맞는지 찾아 냄
semantic(의미)
의도 의미를 찾아냄
컴파일로 생성된 것
Statement(문장,구문)
; 으로 마무리되는 문장
들여쓰기는 보기 편하게 하기 위해서
{ ~ } : statement를 그룹화하기 위해서 쓰는 것
연관있는 코드를 그룹으로 묶어주기 위한 것
모든 것이 ;으로 끝나지는 않음
ex>Pre-processor Directive(지시문)
function definition(함수 정의)
comment (주석)
// 해당 기호 이후 줄 전체를 주석화
/* ~~
*/
/// 다른 기능(summary return 등등)
불필요한 주석을 쓰지 말자 (이미 다 알고있는)
expression(식,표현식)
연산자를 가진 문장
= expression statement
int x = 1;
std::cout << "x의 값은" << x << "입니다." << std::endl;
모니터에 << x의 값은 을 보내고 << 보내고 << 보내고 << 보내고
<< 모두 연산자이다
flow control (흐름 제어)
if statement
;이 없다
if (조건식)
{
}
int number1, number2;
std::cout << "첫번째 숫자:"; //모니터 출력
std::cin >> number1; //입력
std::cout << "두번째 숫자:";
std::cin >> number2;
if (number1>number2)//비교연산자 사용-비교연산자는 참이나 거짓을 만들어냄
{
std::cout << "첫 번째 숫자가 큽니다" << std::endl;
}
else if(number1 = number2)
{
std::cout << "두 번째 숫자가 같습니다" << std::endl;
}
else
{
std::cout << "두 번째 숫자가 큽니다" << std::endl;
}
int inputNumber;
std::cout << "숫자를 입력하세요:";
std::cin >> inputNumber;
unsigned int absoluteNumber; //양수만 배정하는 타입으로 정함
if (inputNumber > 0)
{
absoluteNumber = inputNumber;
}
else
{
//=0
// <0
absoluteNumber = -inputNumber; //absoluteNumber = inputNumber * -1;
}
std::cout << "절대값=" << absoluteNumber << std::endl;
_🖐️while/ if 문에서 중괄호를 생략하지 마세요!!!
사용할 수 있지만 좋은 습관이 아님 혼동하기 쉬움_
3항 연산자
=>(조건식) ? 참일때 선택할 값(expression1): 거짓일때 선택할 값(expression2);
연산자임으로 이 문장 하나로 연산이 가능해짐
(inputNumber>0)? absouluteNumber = inputNumber:abosuluteNumber = -inputNumber;
>> 연산자이기 때문에 다른식으로 쓸 수 있음
absoluteNUMBER = (inputNumber>0)? inputNumber : -inputNumber;
if문은 statement(문장) 3항 연산자는 operator(연산자) operator는 피연산를 사용해 계산 결과를 만들어 내어 최종적으로 결과를 알려줌 if문은 참일 때 령을 수행해줌
if(c=0)
if(b=0)
if(a=0)
>> if(a=0 && b=0 && c=0)
else(a!=0 || b!=0|| c!=0)
std::cout << "숫자를 입력 하세요:";
int number;
std::cin >> number;
switch (number)
{
case 1: // number = 1일 때
std::cout << "일" << std::endl;
break;
case 2:
std::cout << "이" << std::endl;
break;
case 3:
std::cout << "삼" << std::endl;
break;
default:
std::cout << "기타" << std::endl;
break;
}
std::cout << "숫자를 입력 하세요:";
int number;
std::cin >> number;
switch (number)
{
case 1: // number = 1일 때
std::cout << "일" << std::endl;
break;
case 2:
std::cout << "이" << std::endl;
break;
case 3:
std::cout << "삼" << std::endl;
break;
default:
std::cout << "기타" << std::endl;
break;
}
변수의 SCOPE ( 범위) - Lifecycle
==
int x = 1;
이 변수는 어디까지 유효한가? - 중괄호 블록에 달려있다
중괄호를 벗어나면 메모리의 x 변수를 사용 불가능하다 ( 없어진다)
중괄호로 범위를 지정하는 역할을 하게됨
{
int number1 = 1;
{
int number2 =1; // 이 블록 안에서만 유효하다는 뜻 이 영역에 한정됨
// 이 지역에 한정되어 있음 - local variable : 지역 변수
}
이 밖에서 변수number2를 출력하면 에러가 발생함
number1 출력은 에러가 발생하지 않음
}
이렇게 사용가능하지만 혼동되기 쉬움으로 사용하지 말자
for (int counter = 1; counter <= 10; ++counter) // 이 때 변수의 범위는 중괄호 까지만
{
std::cout << counter << std::endl;
}
counter 변수는 중괄호 벗어냐면 사용할 수 없음
int counter = 1;
for (counter = 1; counter <= 10; ++counter)
{
std::cout << counter << std::endl;
}
int counter = 1;
for (; counter <= 10; ++counter) // 초기화 식을 생략할 수 있음
{
std::cout << counter << std::endl;
}
출력: 11
int counter = 1;
for (; counter <= 10; ) //단일문장에서는 전위 후위 의미 없음
{
std::cout << ++counter << std::endl; // 2~11 출력
}
for 문과 while 문
for(초기화식,조건식,증감식) // 식들은 생략이 가능함으로 다양하게 사용
초기화식
while(조건식)
{
증감식
}
무한 루프
for (;;)
while(true)
타입은 해당 오브젝트가 사용가능한 값 + 적용할 수 있는 연산도 같이 정해짐
즉 타입은 값과 연산에 영향을 준다
오브젝트는 주어진 타입의 값을 저장하는 메모리 공간
오브젝트는 메모리에 있다
>> run time : 메모리에 오브젝트가 존재하려면 프로그램이 실행되어야함
>> 컴파일 사애는 메모리에 오브젝트가 존재할 수 없다
값은 주어진 타입으로 메모리의 비트들을 해석한 결과이다
>> int x 001010 이면 10(10진수)
>> char x >> 빈칸과 비슷한 기호(글자)로 해석되게 됨
타입에 의해서 해석된 결과이다
변수 : 오브젝트에 이름을 붙여 둔 것이다
변수 선언 (declaration) : 객체에 이름을 지정하는 만들어내는 구문이다
변수 정의(definition): 객체를 메모리 공간에 할당하는 구문이다
int x // 선언- 객체에 이름을 정의한 것이다
x = 1 ; // 정의 - 메모리 공간에다가 값을 집어넣는 것이다
두가지가 합쳐진 것이
int x =1; // 초기화
type safe (타입안전성) vs type unsafe
타입안정성은 타입을 무엇을 쓰는 상관이 없다
c++ 언어는 type safe하지 않다. 타입에 엄격하다 type을 중요하게 여긴다
int는 int만 char 는 char만
int myInteger = 1;
std::string myString = "hello";
myString = myInteger;
std::cout << myString << std::endl;
//변환은 되는데 값이 이상하다
long long myLongLong;
myLongLong = myInteger;
// 실행 변환도 되고 값이 정상으로 나옴
// 4바이트 짜리 공간을 8바이트로 넣는다 : 확대변환
int 4byte
long long : 8byte
myInterger = myLongLong;
// 반대의 경우에 문제가 생김
char myCharacter = 'a';
myCharacter = myInteger;
//실행은 되지만 값은 안나옴(이상함)
그러면 타입에 엄격한 것은 무언인가?
type conversion ( 타입 변환)
너무 엄격하게 하면 프로그래머가 힘들어함 >> c++컴파일러에는 타입을 변환하는
기능이 있음 이것이 타입 컨버전이다
type conversion에는 narrow conversion과 wide conversion
>> 축소 변환 : 8byte 에서 4 byte로 변환
>> 확대 변환 : 4byte 에서 8 byte로 변환
float 에서 int
int 에서 float ? 어던게 문제가 될까?
값의 손실이 생기면 narrow = 에러의 주범이기도하다
초기화 식
int x = 1;
유니폼 초기화식
int y{1};
int y{1.6}; >> 에러 double타입은 int로 줄일 수 없습니다 라고 나오며 에러
>> 안전한 코딩을 위해서는 유니폼 초기화식을 사용해보자
char{10}; >> 들어감
char{1025}; >> 컴파일 에러 발생
char {255}; >>에러 왜? 양수와 음수 부호 >> 127까지
>> 실수할수 있는 것을 방지해줌
unsigned char {255} >> 가능 (부호가 없기 때문에)
int value{10/3}; >> 연산자가 들어있는 익스프레션은 계산 결과로 인식
= value{결과}; >> 에러가 나지 않고 실행됨 0.3인데 왜 실행되는가? 원래는 3.3은 들어가지 않음
왜 가능하냐? 타입은 해당 오븝젝트가 사용가능한 값 + 적용할 수 있는 연산때문에
정수/정수 의 사칙연산은 모두 정수로 나옴 그래서 형태가 변환할 필요가 없음
왜나햐면 연산은 타입에 의해서 정해지기 때문이다
implicit conversion(암시적)
자동으로 변환 : 컴파일러가 하는 변환
>> int x =1.3f
explicit conversion(명시적)
수동으로 변환 : 프로그래머가 직접 변환함
프로그래머가 직접 명시적으로 코드에 쓰는 것 >> 암시적이라는 것이 없음
int x = int(1.3f);
int y = (int)1.3f;
>> 타입과 값을 쓰고 괄호로 구분해주면됨
>>(타입)값
>>(값)타입
int z = int 1.3f; 문법상 맞지 않음
std::cout << (float(10) / float(3));
for (int i = 97; i <= 122; i++)
{
std::cout << char(i) << std::endl;
}
for (char i = 97; i <= 122; i++)
{
std::cout << i << std::endl;
}
for (char i = 'a'; i <='z'; i++)
{
std::cout << i << std::endl;
}
int main()
{
// 몫과 나머지를 구하시오.
int x = 3;
int y = 2;
x/y ; >> 몫
x%y ; >>나머지
}
첫번째 무나는 하나의 알파벳,또는 하나의 밑줄(_)로 시작
두번째부터는 알파벳,숫자,밑줄이 올 수 있음
대소문자 구분(x와 X는 서로 다른 이름)
C++에서 이미 정의한 예약어(KEYWORD)는 사용할 수 없습니다
int x;
x = 2147483647; // integer가 저장할 수 있는 가장 큰 수
std::cout << x + 1 << std::endl; //제일 큰 수에 1을 더하면 -가 나옴
//보수라는 개념과 마이너스 부호개념때문에 제일 큰 수에 1을 더하면 가장 작은 숫자가 나옴
//담을 수 있는 공간보다 더 담아서 넘처흐름 (overflow) 가장 치명적인 문제 중 하나이다.
//체력이나 재화에 큰 문제를 일으킴
std::cout << x - 1 << std::endl;
camelcase
timeElapsed,myTotalScore 등과 같이 소문자로 시작하고 단어가 바뀌면 첫글자를 대문자
Pascal
TimeElapsed,MyTotalScore 처럼 단어의 시작을 모두 대문자
Hungarian
int nMyLife
float fMyLife;
변수명 앞에 타입을 약자로 표시
int abcdefghizklmnopqrstuvwzxyz; //이름에 코드 의미가 담기도록 쓰는게 좋다
//짧고 의미를 가지도록 변수명을 정하기
int variable1, variable2, variable3; // 동일한 타입의 경우에만 변수를 ,로 한 번에 나타낼수 있음
int myNumber; //선언(declaration)
myNumber = 1; //대입
//초기화
int myNumber = 1;
int variable1 = 1, variable2 = 2, variable3 = 3;
//쓰레기값 : 메모리에는 이전에 쓴 흔적이 남아있음 그 값을 쓰레기값이라고 부름(garbage value)
//변수를 선언만 하고 그냥 사용하게 하면 쓰레기값이 나옴 그래서 무슨 결과가 나올 지 몰라 실행하지 않게됨
//따라서 변수를 만들 때는 가급적이면 선언과 대입을 나누지 말고 한번에 하는 초기화를 사용해야함
value(값)
리터럴(literal) : 직역이라는 뜻의 벨류
프로그램을 작성하면 컴파일해서 기계어로 변환되고 최종적으로 이진수로변경됨
1 >> 000000001
int x =0;
각각의 타입마다 리터럴이 있음
bool 타입의 경우 true or false의 리터럴만 사용가능함
int의 경우 100
//리터럴
int myInterger=10;
float myFloat=3.14f; //f붙이면 float 안 붙이면 double타입
bool myBoolean=true;
bool myBoolean = false;
char myCharacter = 'g';
//8진수 리터럴에 접두어 0이 붙음 그래서 032의 경우 8진수의 3 ,2라는 뜻
//escape sequence character : 탈출 문자, 특수기호
char myCharacter = ''';
줄바꿈 std::endl;
\r >> carriage return 첫번째 글자로 되돌리기
\n >> new line 다음줄로
\t >> horizontal tab
\v >> veritcal tab 줄바꿈 여러번
\0 >> null character 중요
char myCharacter = '\'\"\\';
std::cout << myCharacter;
std::cout << '\t';
std::cout << "hello";
//std::endl; 줄바꿈 윈도우와 리눅스 자동으로 해줌
int myNumber = 0;
std::cout << myNumber << std::endl;
// 컴퓨터가 이해한 것은 마이넘버에서 벨류를 가져와라의 뜻이다
//constant variable
const int variable=1; //상수는 바꿀 수 없기 때문에 반드시 초기화가 이루어져야함
std::cout <<3.14f<<std::endl;
///
std::cout <<3.14f<<std::endl;
/////
std::cout <<3.14f<<std::endl;
//상수를 잘 사용하는 것이 매우 중요함
const float pi = 3.14f;
const int myValue =1;
const boo isDragon = true;
int num1 = 0;//초기화하기
std::cout << "숫자를 입력하세요:" << std::endl;
std::cin >> num1;
std::cout << "입력한 숫자는:";
std::cout << num1;
std::cout << std::endl;
//만약 숫자가 아니라 문자가 입력되면 0으로 나오게됨
//c++언어는 타입에 매우 엄격함 int를 만들면 무조건 int밖에 못들어감
//타입이 맞지 않으면 0값으로 나오게됨
//문자열인 경우
std :: string name=" ";
std :: cout << naem<< std::endl;
std::string name = "hello";
std::cin >> name;
std::cout << name << std::endl;
//타입만 맞으면 알아서 들어오도록 설정해줌
//타입이 맞지 않으면 c++ 언어의 경우 타입에 민감해 문제가 생길 수 잇다
#include <iostream>
//입력과 출력이 stream되는 중+ 하나씩 가는 중이다+스트리밍 방식
int main() //entry point(진입점) = 앱이 실해오딜때 자동으로 작동되는 함수
{
std::string name = "hello";
std::cin >> name;
std::cout << name << std::endl;
//타입만 맞으면 알아서 들어오도록 설정해줌
}
연산을 담당하는 기호
= : asssignment operator
좌측 피연산자(operand)에 우즉 피연산자를 대입한다
operand의 갯수에 따라서
단항(unary)
이항(binary)
삼항(ternary)
% : 나머지
var1 = var2 % var3; 나머지(정수만 가능)
+ : 단항 연상자
var 1 =+var2; 양수부호 (+1)*var2
컴퓨터가 하는 연산
논리부정(not)
논리곱(and) a and b >> a 그리고 b >> a 하고 b >> a 이면서 b이여야만함
논리합(or) a 이거나 b이면됨
베타적논리합(xor-exclusive or) 서로 배제한다 둘이 다르면 1 같으면 안됨(0)
논리 기호(논리 연산자)과 비트 연산은 다름
비트 연산은 컴퓨터가 계산에 사용하는 것
산술연산자를 비트연산으로 바꿔 연산하게됨
비트연산자(bitwise operator)
not : !
and : &
or : |
xor : ^
ex) !3 은 bit 연산 not
3은 정수(int)
3.3f는 float
int x ;
!x; (x는 int)
[& &&] [| ||]는 계산하는 방식이 달라짐
>> <<
var1 = var2>>var3; 쉬프트 연산자
cf) std::cout << 스트림 연산자와 모양은 같지만 다른 의미
컴퓨터는 값을 비트로 저장함 예를 들어 1010
x>>2; 방향이 오른쪽 = 오른쪽으로 두칸을 옮겨라는 뜻
그러면 오른쪽으로 보내고 나머지 0으로 채워짐
001010
그리고 버려짐
0010
x<<2; 왼쪽으로 보냄
101000
버려짐
1000
왼쪽으로 1칸 밀면 곱하기2 ^2
오른쪽으로 1칸 밀면 나누기2 /2
assign operator
x = 0;
1 증가 시키기위해서는
x = x + 1
x = 1
앞의 연산자를 실행한 후에 대입을 해라
+=
-=
*= 곱
/= 나누기
%= 나머지
= 대입 연산자
int myNumber = 0;
myNumber += 1;
int myNumber = 0;
myNumber += 1;
myNumber = myNumber +1;
myNumber++;
++ /-- : 증감 연산자(increment decrement operator) / 단항연산자
하나씩 증가하거나 감소할때만 사용할 수 있음
int myNumber = 0;
std::cout << myNumber++;
결과는 0으로 나옴 왜?
연산자가 2개이기 때문 <<이거와 ++ 가 존재함
연산자 계산 순서가
std::cout<<myNumber 하고
++;하게됨 그래서 증가하지 않음
일단 mynumber보내고 그다음 증가
std::cout << ++myNumber;
전위 연산자(prefix)와 후위 연산자(postfix)
int value1 = 1;
int value2;
int value3;
value2 = value1++;
value3 = value1;
std::cout << value2 << std::endl;
std::cout << value3;
전위 : ++value; 읽을때 증가 후 대입
후위 : value++; 읽을때 대입 후 증가
for (int count = 0; count < 3; count++)
//하나의 명령어가 3개 연산자가 하나의 경우에는 대입되는것이 무시됨
{
}
for (int count = 0; count < 3; ++count)
{
}
//단독으로 사용하면 대입할 만한 것이 없기 때문에 그냥 증가함 후위 전위 차이가 무시됨
계산 결과의 타입이 다름 boolean값으로 나옴
bool : true false
==
!=
<
<=
>
>=
&& : 이항
|| : 이항
! : 단항
비트 연산자는 두 개의 연산을 비트 단위로 항상 수행함
논리 연산자는 명제의 참과 거짓을 다루는 것
cf) 명제란 명확하게 참 거짓이 존재하는 것 즉 논리 연산자는 참 거짓을 다룸
cf) 비트는 숫자 자체를 계산하는 것
a && b 에서 a 가 false면 b는 계산하지 않아도 false라서 계산하지 않게됨
a = b (대입)
if(x=1) 안됨 (x==1)
{
}
a>b<c
int a =3,b=2,c=1;
if(a>b>c)
{
what?
}
>> true>c로 바뀌게 됨
true는 1+ 0이외의 모든 수 false는 0
1>c로 되서 false로 됨
if (a>b and b>c)(a>b && b>c)
{
what?
}
서로 다른 논리 연산자로 만들어서 두개로 묶어줘야함
연산자가 여러가지여서 순서가 어지러울 때 여러줄로 해보자
int value1 = 5,value2 = 3;
std::cout << value1 & value2 << std::endl; // 연산자 순서로 인해 오류
// 우선순위 정해주기
**비트연산자와 논리 연산자의 차이점 확인하기**
std::cout << (value1 & value2) << std::endl; //비트연산자
std::cout << (value1 && value2) << std::endl; //논리연산자
비트 연산자는 5를 이진수 101로 3을 11로 변경한 후 더하면 001로 1이 출력
논리 연산자는 0이면 거짓 0이 아닌 다른 숫자는 참
value1에 5 >> 참
value2에 3 >> 참
따라서
참 && 참 이므로 참
출력하면 1(참)
**flag개념 =게임개발과 관련된**
RPG에서 Q1 Q2 Q3 만약에 Q3는 1,2번 클리어 해야 열린다면
Q1,Q2에 플래그를 새움(클리어 했냐 아니냐 두가지로)- 컴퓨터는 0과 1만 저장
bool isQuest1;
bool isQuest2;
비트 플래그의 개념을 사용하면
int isClear; 하나로 가능함
integer는 4바이트 >> 32비트의 크기를 가짐
따라서 플래그를 32개 표현할 수 있음
그래서 한 개의 변수에 32개의 퀘스트 변수를 하나로 표기할 수 있음
각각 비트단위로 플래그를 세워서 쓰면 편하게 됨
색상 도 비트 플래그로 사용
빛의 삼원색으로 색상 구분
int red
int green
int blue
>>하나로 쓸수 있음
int color
색상 지정할때 0~255로 저장함
색상 성분이 1byte안에 들어가야함
그래서 3색임으로 3byte
int 4byte
red / green/ blue / alpha(투명도) 4가지로 각각 바이트 단위로 끼워넣어서
int 하나로 됨
예를들어
a/r/g/b >> 1byte
color >> 24비트(3byte)를 오른쪽으로 밀어버리면
0/0/0/a만 남기게됨
즉 a(알파)만 뽑게됨
blue만 뽑으려면
color << 24비트만큼 왼쪽으로 밀어버리면
b000
다시 이것을 오른쪽으로 밀면
000b
blue만 남기게됨
반대로 red를 끼워넣기
000r를 왼쪽으로 2칸밀면
0r00