기초 CS

킴스코딩클럽·2022년 10월 23일
1

CS기초 시리즈

목록 보기
44/71

오늘의 내용

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;

programming language

=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항 연산자

3항 연산자
 =>(조건식) ? 참일때 선택할 값(expression1): 거짓일때 선택할 값(expression2);
연산자임으로 이 문장 하나로 연산이 가능해짐

(inputNumber>0)? absouluteNumber = inputNumber:abosuluteNumber = -inputNumber;
>> 연산자이기 때문에 다른식으로 쓸 수 있음
absoluteNUMBER = (inputNumber>0)? inputNumber : -inputNumber;

if문은 statement(문장) 3항 연산자는 operator(연산자) operator는 피연산를 사용해 계산 결과를 만들어 내어 최종적으로 결과를 알려줌 if문은 참일 때 령을 수행해줌


if 문 중첨 여러개는 논리연산자를 활용해서 쓰기

if(c=0)
	if(b=0)
		if(a=0)

>> if(a=0 && b=0 && c=0)
	else(a!=0 || b!=0|| c!=0)

값에 의한 if문 분기

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 문과 whilefor(초기화식,조건식,증감식) // 식들은 생략이 가능함으로 다양하게 사용

초기화식
while(조건식)
{
	증감식
}


무한 루프
	for (;;)
	while(true)

TYPE, OBJECT,VALUE

타입은 해당 오브젝트가 사용가능한 값 + 적용할 수 있는 연산도 같이 정해짐
즉 타입은 값과 연산에 영향을 준다
오브젝트는 주어진 타입의 값을 저장하는 메모리 공간
오브젝트는 메모리에 있다
	>> 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을 중요하게 여긴다
 intintcharcharint 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;
    //타입만 맞으면 알아서 들어오도록 설정해줌
}

연산자(operator)

연산을 담당하는 기호

= : 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.3ffloat
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로 바뀌게 됨

true1+ 0이외의 모든 수 false0
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를 이진수 101311로 변경한 후 더하면 0011이 출력
논리 연산자는 0이면 거짓 0이 아닌 다른 숫자는 참
value1에 5 >> 참
value2에 3 >> 참
따라서
참 && 참 이므로 참 
출력하면 1()

**flag개념 =게임개발과 관련된**

RPG에서 Q1 Q2 Q3 만약에 Q3는 1,2번 클리어 해야 열린다면
Q1,Q2에 플래그를 새움(클리어 했냐 아니냐 두가지로)- 컴퓨터는 01만 저장

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
profile
공부 기록용

0개의 댓글