배열array 
- 비슷한것이 나열되어 있는것

학생성적을 기록하고 싶은데
학생이 여러명이면?
int형을 학생의 이름으로 여러개 선언하면 기억하기힘들다.

해결책
같은형의 변수를 여러개 불러올수 있다.
배열 사용 : int student[5];
배열은 0부터 시작한다.
생성한 배열보다 큰 배열번호에 입력하면 에러가 난다.

배열 초기화하기
int a[3] = { 1,2,3 };
int a[] = { 1,2,3 };
int a[3];
a[0] = 1; 
위에 방식으로 초기화 할 수 있다.

[]로 선언하는 배열의 크기는 시작할때 정해주어야한다.
사용하고 싶다면 #define를 사용한다.

기본자료형말고 구조체등도 배열로 선언할 수 있다.

#include <iostream>

using namespace std;

//구조체선언
struct Rectangle
{
	int length;
	int width;
};

enum StudentName
{
	Jack,	//0
	Dash,	//1
	Violet,	//2
};

int main() 
{
	//배열만들기
	int a[3] = { 1,2,3 };

	cout << sizeof(a) << endl;
	a[Jack] = 1;
	a[Dash] = 2;
	a[Violet] = 3;

	int sum = 0;
	for (int i = 0; i < sizeof(a) / 4; i++) {
		sum += a[i];
		cout << a[i] << endl;
	}
	cout << sum << endl;

	cout << sizeof(Rectangle) << endl;
	//구조체 배열선언하기
	Rectangle r[10];
	cout << sizeof(r) << endl;
	r[0].length = 1;
	r[0].width = 2;
	
	//cin >> sum;
	//int ab[sum] <-형식은 안됌 사용하고싶다면 매크로 #define을 사용한다. 
	return 0;
}

 

배열의 메모리 알아보기
int형으로 선언할때 배열의 주소는 배열의 첫번째 주소를 가르킨다.
그리고 int형은 4Byte이기때문에 4씩 증가하는걸 볼수 있다.

함수의 파라미터로 배열을 보내면 배열의 주소가 달라진다.
배열의 데이터를 복사해온다.
복사해올때 포인터로 넘어온다. 
파라미터로 넘어온 배열을 sizeof를 해보면 포인터변수의 사이즈가 출력된다.

 

#include <iostream>

using namespace std;

#define NUM 2

void doSomething(int students[]) 
{
	cout << "doSomething" << endl;
	cout << (int)&students << endl;
	//포인터의 사이즈가 출력된다.
	cout << "sizeof: " << sizeof(students) << endl;
	cout << students[0] << endl;
	cout << students[1] << endl;
}

int main()
{
	int a[NUM];

	cout << (int)&a << endl;
	cout << (int)&a[0] << endl;
	cout << (int)&a[1] << endl;
	a[0] = 1;
	a[1] = 2;
	cout << sizeof(a) << endl;

	doSomething(a);

	return 0;
}

배열 반복문 활용

배열은 같은타입의 데이터가 메모리에 일렬로 나열되어있는것이다.
반복문을 활용하면 배열을 사용하기 쉽다.

sizeof로 배열의 크기를 알아볼수 있는데 파라미터로 넘어가면
포인터의 주소만 가르키기때문에 불가능하다.

 

#include <iostream>

using namespace std;

int main()
{
	const int num = 3;
	int a[num] = { 1,50,3 };

	//배열 크기 알아보기
	int a2[] = { 1,50,3 };
	const int num2 = sizeof(a2) / sizeof(int);

	int totalScore = 0;
	int maxScore = 0;

	for (int i = 0; i < num; i++) {
		totalScore += a[i];
		cout << a[i] << endl;
		maxScore = (maxScore < a[i]) ? a[i] : maxScore;
	}

	double avgScore = static_cast<double>(totalScore) / num;
	cout << "avg : " << avgScore << endl;
	cout << "max : " << maxScore << endl;
	return 0;
}

난수만들기
random number만들기
컴퓨터는 랜덤숫자를 만들 수 없다.

 

#include <iostream>
#include <cstdlib>
#include <ctime>
#include <random>

using namespace std;

int main()
{
	//시드넘버
	srand(5324);
	//시드넘버변경하기
	srand(static_cast<unsigned int>(time(0)));
	for (int i = 1; i <= 100; i++) {
		cout << rand() <<"\t";
		if (i % 5 == 0) {
			cout << endl;
		}
	}

	random_device rd;
	mt19937 ran(rd());
	uniform_int_distribution<> dice(1, 32);

	for (int a = 0; a < 5; a++) {
		cout << a << " : ";
		for (int i = 0; i < 6; i++) {
			cout << dice(ran);
			if (i == 5) {
				cout << endl;
			}
			else {
				cout << "\t";
			}
		}
	}
	
	return 0;
}

cin은 console에서 text입력받을때 사용한다.

ignore는 첫번째 버퍼에 값만 사용한다.
즉 2 3 4 여러개 입력해도 2만 입력이된다.
사용법 : cin.ignore(32767,'\n');

cin에서 변수형에 맞춰 입력이 틀렸을 경우 fail로 사용할 수 있다.

cin 올바른 사용예

#include <iostream>

using namespace std;

int main()
{
	int a;
	while (true) {

		cin >> a;
		
		if (cin.fail()) {
			cin.clear();
			cin.ignore(32767, '\n');
			cout << "다시입력" << endl;
		}
		else {
			break;
		}

	}
	cout << "a : " << a << endl;
	return 0;
}

for문
가장 많이 사용되는 반복문

for(사용할 변수(초기화);조건;증감연산자;){}
위에 방법으로 사용한다.
마지막 조건에 증감연산자말고 다른 조건도 가능하다.
로직 실행순서
for (int i = 0; i < 10; i++)//iteration
1.int i = 0;변수를 초기화한다.
2.i < 10;조건을 확인하고 {}을 실행한다.
3.i++를 실행한다.
4.i < 10;조건을 확인하고 {}을 실행한다.
5.i++를 실행한다.

특이점은 변수는 초기에 한번만 생성한다.
또 증감연산자는 {}에 로직이 사용되고 마지막에 증가시킨다.

변수,증감연산자(다른조건)는 여러개 만들 수 있다.

while문과 마찬가지로 unsigend int 오버플로우를 주의해야한다.

#include <iostream>

using namespace std;

int pow(int b, int e)
{
	int result = 1;
	for (int count = 0; count < e; count++) {
		cout << result << " * " << b << " = "<< endl;
		result *= b;
	}
	return result;
}

int main()
{
	cout << "test" << endl;
	for (int i = 0; i < 10; i++)//iteration
	{
		cout << i << endl;
	}

	//제곱구하기
	pow(2, 4);

	//여러개 변수 선언하기
	for (int i = 0,s = 0; (i + s) < 100; i++, s += 5) {
		cout << "i : " << i;
		cout << "\ts : " << s << endl;
	}//end of for i

	//2중 for문사용
	//구구단 사용
	for (int i = 2; i < 10; i++) {
		cout << i << endl;
		for (int s = 1; s < 10; s++) {
			cout << "\t" << i << " * " << s << " = " << i * s << endl;
		}
	}
	return 0;
}

break,contunue
반복문을 제어하는 방법

break는 현재{}에서 빠져나간다.
무한루프에서 빠져나올때 자주 사용한다.

continue는 조건에 맞으면 다음반복문(숫자 증감)으로 넘어간다.
do-while문에서는 while조건에 증감연산을 해주어야한다.

#include <iostream>

using namespace std;

void breakOrReturn()
{
	while (true)
	{
		char ch;
		cin >> ch;
		if (ch == 'b')
			break;
		
		if (ch == 'r')
			return;
	}
	cout << "break or return?" << endl;
}

int main()
{
	int count = 0;
	//while,for모두 사용가능하다 break사용하기
	while (true) {
		
		if (count > 10) {
			break;
		}
		cout << count << endl;
		count++;
	}

	//break 확인 함수
	breakOrReturn();

	//continue사용하기
	for (int i = 0; i < 20; i++) {
		if (i % 2 == 0) {
			continue;
		}
		cout << i << endl;

		//아래로직과 같다.
		/*if (i % 2 == 0) {
			cout << i << endl;
		}*/
	}

	//continue사용하요 특정숫자 뺴고 출력하기
	int i = 0;
	do
	{
		if (i == 5) {
			continue;
		}
		cout << i << endl;
	} while (i++ < 10);

	return 0;
}

반복문 while
컴퓨터의 장점
- 정확하다.
반복을 지루해하지 않는다.

현업에선 while문 보단 for문을 많이 사용한다.
하지만 while문을 꼭 사용하는 곳이 있다.

while(조건=true){}형식으로 사용한다.
조건이 완료되지 않으면 무한루프에 빠진다.

{}안에 변수를 선언에 사용할려면 static을 사용한다.
조건에 true를 입력하고 내부에서 if(조건)break;로 사용할 수 있다.

while문안에 while문을 사용할 수 있다.

while문은 가시적으로 간결하다.

문제점 
unsigned int에 --를 사용하면 오버플로우가 발생하여 문제가 생길 수 있다.

#include <iostream>

using namespace std;

int main()
{
	int a = 0;
	//a가 10보다 작다면 이라는 조건을 사용했다.
	while ( a < 10) {
		//변수사용하기! 잘 사용안한다.
		//static int a = 0;
		cout << "a : " << a << endl;
		a++;
	}

//goto문으로 while과 같이 동작하기
startNumAdd:

	cout << "goto a : " << a << endl;
	if (a < 20) {
		a++;
		goto startNumAdd;
	}

	a = 2;
	//unsigned를 사용하면 오버플로우가 발생하여 문제가 생긴다.
	//unsigned int count = 0;
	//while (count >= 0) {
	//	cout << count << endl;
	//	count--;
	//}

	//중복while문
	//구구단출력
	while (a < 10) {
		int b = 1;
		cout << "a : " << a << endl;
		while (b < 10) {
			cout << "\t"<< a << " * " << b << " = " << a*b << endl;
			b++;
		}
		a++;
		b = 0;
	}

	return 0;
}

do-while문
while문과의 차이
while문은 조건에 따라 한번도 실행안될 수 있다.
do-while문은 무조건 한번은 실행된다.

for,while,do-while문중 활용도는 가장 낮다.

#include <iostream>

using namespace std;

int main() 
{
	int select = 0;

	do
	{
		cout << "selectNum : " << select << endl;
		cout << "1~5 select" << endl;
		cin >> select;
	} while (select < 0 || select > 5);

	return 0;
}

switch-case 조건문

if문과 다르게 맞는 조건 뒤에 로직은 모두 동작한다.
멈추고 싶다면 break;를 사용한다.
{}scope를 사용가능하다 if문과 다르게 {}가 없더라도 여러줄 인식이된다.

주의할점
switch문 앞부분에 변수를 선언할 수 있으나 초기화는 못한다.
case문에서 값을 정해줄 수 있다.
{}scope가 없을시 case문에서 선언한 변수는 
switch문 앞부분에 선언한 것처럼 적용된다.

 

#include <iostream>

using namespace std;

enum class Colors
{
	BLACK,
	WHITE,
	RED,
	GREEN,
	BLUE,
};

void printColorName(Colors c)
{
	switch (c) {
		//여기에 선언된것과 같다.
		//int a;
	case Colors::BLACK:
		//{}scope가 있으면 내부에서만 적용된다.
		int a;
		a = 5;
		cout << "BLACK";
		break;
	case Colors::GREEN:
		//GREEN이 선택되면 a의 값은 garbage값이 출력된다.
		cout << a << endl;
		cout << "GREEN";
		break;
	default:
		cout << "X" << endl;
	}
	cout << endl;
}

int main()
{
	printColorName(Colors::BLACK);
	
	return 0;
}

goto


반복문 대신에 과거에 자주사용했다.
어셈블리어로 가면 동작은 거의 같다.
지정한곳으로 가게 명령하는 것이다.
레이블이름을 지어 그위치로 돌아간다.
책갈피로 생각하면된다.

 

돌아갈곳 지정은 돌아갈곳(이름지정):
돌아가기 작동은 goto 돌아갈곳;으로 한다.

주의할점
지금은 거의 사용하지 않는다.

 

#include <iostream>

using namespace std;

int main()
{
	double x;

//돌아갈곳 설정하기
notGood :

	cout << "cin start" << endl;
	cin >> x;
	if (x < 0.0)//goto문 실행방법
		goto notGood;

	return 0;
}

프로그래밍은 CPU에서 할일은 지정해주는것이다.
할일을 지정해줄때 분기,반복등 여러 조건을 정해줄 수 있다.
중단Halt
- exit(숫자)
점프Jump
- goto,break,continue
조건분기Conditional branches
- if,switch
반복(루프)Loops
- while,do while,for
예외처리
- try,catch.throw

등이 있다.

 

중단Halt

exit(0)

#include <iostream>
#include <cstdlib>

using namespace std;

int main() 
{
	//출력 2번하는 프로그램
	cout << "test" << endl;
	//return은 return type에 맞춰서 값을줘야하지만 exit(숫자)는 상관없이 종료한다.
	exit(0);
	cout << "good" << endl;
	
	return 0;
}

조건문 if
if(bool타입){}조건으로 사용한다.
if문다음 else if()는 다음 조건을 설정할 수 있다.
else{}는 if의 조건이 안맞을때 실행된다.
논리연산자 사용이 가능하다.
return을 사용할 수 있다.

주의할점
{}(scope)을 안쓰면 아래 한줄만 동작한다.
if(조건)안에 정수가 0(false)이아니면 true로 인식한다.
논리연산자가 아닌 =을 사용하면 값을 대입하고 그값으로 if문이 작동한다.

 

#include <iostream>

using namespace std;

int main()
{
	int x,y;
	cin >> x;
	cin >> y;
	//논리연산자 사용
	if (x == y && x > 0) {
		cout << "x = y && x > 0" << endl;
	}
	
	if (x > 10) {
		cout << x << endl;
	}
	else if (x > 5) {
		cout << x << " = 10 > x > 5 " << endl;
	}
	else {
		cout << x << " < 5" << endl;
	}

	//0이 아니면 true로 본다.
	if (1) {
		cout << "if(1)" << endl;
		x = 10;
	}

	cout << x << endl;

	//return하는 if
	if (x == 10) {
		return 10;
	}
	return 0;
}

자료형을 불러올때 별명(가명) 붙여주기

typedef,using을 이용한다
예를 들어 자료형 double중에 거리에 사용되는 double형을 

별명을 붙여 사용한다면 공통으로 사용된 자료형을 관리하기 쉽다.
또 복잡한 자료형에 사용하면 보기 좋고 사용하기도 좋다.

#include <iostream>
#include <cstdint>
#include <vector>

using namespace std;


int main()
{
	typedef double distance_t;
	//고정너비 변수
	std::int8_t i(97);


	//컴파일러입장에선 같다.
	double distance;
	distance_t distance2;

	//vector<pair<string, int>> 를 줄여사용하기
	typedef vector<pair<string, int>> pairlist_t;
	//using사용
	using pairlist_t1 = vector<pair<string, int>>;

	return 0;
}

구조체struct

 

하나의 자료형으로 복잡한것(사람정보)을 구현하기 어렵다.
구조체를 이용해 하나의 사용자 정의 자료형으로 구현할 수 있다.
여러정보집합의 다수개의 정보를 저장할때도 구조체가 좋다.

 

구조체안에 함수를 구현할 수 있다.
구조체안에 구조체를 구현할 수도 있다.
구조체 대입,구조체 반환값도 가능하다.


sizeof로 사용Byte를 알수 있다(정확하진않고 조금더 추가될 수 있다).

#include <iostream>
#include <string>

using namespace std;

struct Person
{
	int id;
	double	height;
	float	weight;
	int		age;
	//기본값 정의도 가능하다.
	string	name = "me";
	//구조체안 함수 구현
	void printPersonInfo()
	{
		cout << height << endl;
		cout << weight << endl;
		cout << age << endl;
		cout << name << endl;
	}
};

void printPersonInfo(Person p)
{
	cout << p.height << endl;
	cout << p.weight << endl;
	cout << p.age << endl;
	cout << p.name << endl;
}

int main()
{

	//사람1정보구현
	double	height;
	float	weight;
	int		age;
	string	name;
	//사람2정보구현
	double	height2;
	float	weight2;
	int		age2;
	string	name2;
	
	//구조체구현이 훨씬 간단하다.
	Person person1{1, 2.0,100.0,20,"me" };
	Person person2{2, 2.0,100.0,20,"you" };

	//구조체로 묶여있어 인자로 보내기도 편하다.
	printPersonInfo(person1);
	//구조체안에 함수 구현 출력하기
	person1.printPersonInfo();

	//구조체 대입하기
	Person copyP = person1;
	cout << &person1 << " copyP addr : " << &copyP << endl;

	//사용Byte알아오기
	cout << sizeof(copyP) << endl;

	return 0;
}

열거형 enumerated types

어떤 같은 종류(색,무기종류)를 정할때 그 조건의 값을 다 기억하기는 어렵다.
그럴때 enum으로 자료형을 생성한다.
사용자 지정 자료형으로 생성된다.
내부적으로 정수 0,1,2,3순(100%integer는아님)으로 저장된다.
기본값으로 특정수를 설정하면 그 수부터 저장된다.
ex)처음 기본값을 -3으로 설정하면 -3,-2,-1,0,1순으로 된다.

enum 주의점
enum안에 선언해놓은것은 전역에서 중복될 수 없다.
캐스팅을 할 수 있다. static_cast<enum명>(정수);
cin으로 직접입력받을 수 없어 정수형,문자열으로 우회하여 받아야한다.(비추천)

#include <iostream>
#include <typeinfo>
#include <string>

using namespace std;

enum colorId {//사용자 지정 자료형
	COLOR_BLACK,
	COLOR_RED,
	COLOR_BLUE,
	COLOR_GREEN,
};

enum feelId {//사용자 지정 자료형
	HAPPY,
	JOY,
	//예를들어 colorId와 feelId의 BLUE가 이름이 같다면 에러가난다.
	BLUE,
};

int getColor(int colorId)
{
	if (colorId == 0) {
		return 1;
	}
	else if (colorId == 1) {
		return 2;
	}
}

int main()
{
	colorId apple(COLOR_RED);
	cout << apple << endl;

	//캐스팅하기
	colorId id = static_cast<colorId>(3);
	cout << id << endl;
	//string으로 입력받기(추천하지 않는다.)
	string str;
	getline(cin, str);
	if (str == "BLACK") {
		id = static_cast<colorId>(0);
	}
	cout << id << endl;

	return 0;
}

영역제한 열거형 enum class

enum으로만 생성하면 다른 enum안의 같은 순번의 데이터가

같은 숫자처럼 보일 수 있다.
enum class로 생성하게 되면 비교를 못하게 막아준다.
enum class 명 ::으로 불러온다.
같은 enum class끼리는 비교가 가능하다.
다른 enum class도 캐스팅하면 비교가 가능하긴 하다.

#include <iostream>

using namespace std;

int main()
{
	enum class Color
	{
		RED,
		BLUE,
	};
	enum class Fruit
	{
		BANANA,
		APPLE,
	};

	Color c = Color::RED;
	Color c1 = Color::RED;
	Fruit f = Fruit::BANANA;
	//두 출력 0으로 같지만 class를 선언하면 직접적으로 비교는 안된다.
	cout << static_cast<int>(c)<< " : " << static_cast<int>(f) << endl;

	//다른 enum class는 비교할 수 없다.
	/*if (c == f) {

	}*/
	//같은 class는 비교는 가능하다.
	if (c == c1) {
		cout << "같다." << endl;
	}

	return 0;
}

문자열

 

hello world같은 글을 문자열이라고 한다.
문자열을 사용할땐 string을 include해서 사용한다.
string은 기본자료형이 아닌 사람들이 만들어 놓은 사용자 정의 자료형으로 생각하면된다.
다른 기본자료형처럼 =,(),{}방식으로 정의가 가능하다.
숫자가 입력가능하지만 정수형이 아닌 문자형 ""으로 입력해야한다.
입력받을땐 다른 자료형과 같이 cin사용하는 것이 아닌 std::getline(std::cin,str);을 사용한다.
정수형(int)을 입력받고 std::getline(std::cin,str);을 사용하면 기존 버퍼에 남아있던 정수가 출력된다.
std::cin.ignore(32767,'\n');
std::cin.ignore(std::numeric_limits::max(), '\n');
을 이용해 정수입력이후 문자열을 입력받을 수 있다.
+,+=로 문자열에 문자열을 추가해줄 수 있다. append라고한다.
문자열 길이는 .length()로 확인할 수 있다.
string 문자열은 마지막에 문장마무리표시가 들어가있어 길이 1이 추가된다.

 

#include <iostream>
#include <string>
#include <limits>

using namespace std;

int main()
{
	//문자열을 출력한다.
	//아래글자는 char[12]로 출력된다.
	cout << "hello world" << endl;

	int age = 0;
	cin >> age;
	cout << age << endl;
	//cin 버퍼 초기화
	std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
	const string str = "hello world";
	cout << str << endl;
	//숫자입력
	string num = "123";


	string num2 = "";
	//문자열 입력
	std::getline(std::cin, num);
	std::getline(std::cin, num2);

	//문자열 더하기(append)
	cout << num + num2 << endl;
	num += "test";

	//문자열 길이
	cout << num.length() << endl;
	return 0;
}

형변환

 

변수 자료형 알아보는 방법
typeinfo를 사용해 자료형을 알 수 있다.
typeinfo(변수).name()형식
사용하는 이유
- 리터럴은 double지만 변수가 int형이라면 int로 저장된다.

암시적형변환
- 프로그래머가 설정하지않는데 형변환되는 경우
1. 작은것을 큰것으로 바꿀땐 적용된다.
  ex)float -> double로 변경될때 적용된다.
2. numeric conversion의 문제점
  ex)int -> char 큰자료형(작은자료형의 크기를 넘을때)에서 
             작은자료형으로 갈경우에 제대로 저장되지 않는다.
3.unsigned의 문제점도 있다.unsined int는 int보다 접근순위가 높다.

명시적형변환
- 프로그래머가 설정한 형변환   
- 대표적으로 세가지방법이 있다.
c++스타일
int i2 = int(4.0);
c스타일
i2 = (int)4.0;
다른방법
i2 = static_cast(4.0);

 

#include <iostream>
#include <cmath>
#include <typeinfo>

int main()
{
	using namespace std;

	//int형으로 저장된다.
	int a = 123.4;
	cout << a << endl;
	cout << typeid(4.0).name() << endl;

	float f = 123.4f;
	double d = f;
	d = 123.4567891011;
	f = d;

	int i = 30000;
	char c = i;
	//제대로 저장이 안된다.
	cout << static_cast<int>(c) << endl;

	//명시적형변환
	//c++스타일
	int i2 = int(4.0);
	//c스타일
	i2 = (int)4.0;
	//다른방법
	i2 = static_cast<int>(4.0);
	return 0;
}

+ Recent posts