2015년 6월 8일 월요일

[C++11] R-Value 레퍼런스


[C++11] R-Value 레퍼런스 C++11 / Programming
2014.04.29. 17:16 수정 삭제
전용뷰어 보기
C++11에서는 R-Value 라는 용어가 새로 등장했습니다. 이와 함께 L-Value 라는 용어도 등장했는데 L-Value는 사실 기존 C++ 부터 사용하던 레퍼런스의 다른 말입니다. R-Value 레퍼런스와 기존 레퍼런스를 구분하기 위해 L-Value 라는 용어를 사용한 것이죠.
그렇다면 L-Value와 R-Value가 뭘까요? 그냥 보면 왼쪽에 있는 값과 오른쪽에 있는 값 같습니다. 저도 처음에는 그렇게 생각했습니다.

정확하게 정의하자면 L-Value는 왼쪽 오른쪽 어디에도 올수 있는 값이고 R-Value는 오른쪽에만 올수 있는 값입니다. 그리고 L-Value는 참조가 가능하고 R-Value는 참조가 불가능합니다.
int a = 1; // a는 L-Value이고 1은 R-Value 입니다.
int b = a; // b는 L-Value입니다.
// 1 = a; // 에러가 발생합니다. 1은 R-Value이므로 왼쪽에 올수 없습니다.

대충 이해가 가시나요? 값을 참조하는 경우를 살펴봅시다.
int a = 1;
int *b = &a; // a는 L-Value이므로 참조가 가능합니다.
// int c = &1; // 1은 R-Value이므로 참조가 불가능합니다.


그런데 C++11에서 R-Value를 참조 가능하게 만들었습니다. 이동 시맨틱과 퍼펙트 포워딩을 위해 적용한 개념이라고 합니다. 이동 시맨틱과 퍼펙트 포워딩은 추후 정리하겠습니다.
그럼 R-Value를 어떻게 참조할까요? R-Value를 참조하기 위해 약간 다른 참조 연산을 사용합니다.

int &&a = 1; // &&가 R-Value 참조 연산자이고 에러가 발생하지 않습니다.
L-Value 처럼 아래와 같은 코드도 가능합니다.
int a = 1;
int &&b = 2;
b = a; // b의 값이 1로 바뀝니다.


[인도베다수학] 뺄셈

두 자릿수의 뺄셈
뺄셈도 덧셈과 마찬가지로 일의 자리의 수를 0으로 만들면 암산이 쉬워집니다.
35 - 19 = 35 - 20 + 1 = 15 + 1 = 16

세 자릿수의 뺄셈
빼는 수의 십의 자리와 일의 자리의 수를 0으로 만들면 됩니다.
247 - 189 = 247 - 200 + 11 = 47 + 11 = 58

[C++11] 람다 표현식

람다의 장점
코딩을 하다보면 종종 함수 포인터나 함수 객체(Class 변수를 함수처럼 사용)를 인자로 넘겨줘야 하는 경우가 있습니다. 이러한 경우 기존에는 함수를 별도로 선언하거나 Class를 정의해서 사용해야 했습니다.
다른 곳에서 사용하지 않고 그곳에서만 한번 사용하는 경우 별도의 선언은 코딩 양을 늘리고 코드를 읽을때 그 함수를 쫓아가서 확인해야 하는 수고가 있습니다.
람다는 함수 인자가 필요한 곳에서 바로 함수를 선언함과 동시에 인자로 넣을 수 있는 장점이 있습니다. 이로 인해 코드의 양을 줄이고 가독성을 높일수가 있습니다.
std::vector<int> vec;
vec.push_back(1);
vec.push_back(2);
vec.push_back(3);

std::for_each(vec.begin(), vec.end(), [](int val){
std::cout << val << std::endl;
});
빨간색 부분이 람다 함수입니다. 

람다 함수
람다 함수 원형은 []{} 입니다. []는 람다 소재자이고 {}는 람다 몸체입니다. [](){} 처럼 ()를 추가하여 일반 함수처럼 인자를 전달할수도 있습니다. 람다 함수 몸체를 한번 채워보겠습니다.
[]{ std::cout << "Hello World" << std::endl; }; 

많 이 보았던 Hello World를 출력하는 함수입니다. 하지만 이렇게만 코딩하면 실제로 출력이 되지 않습니다. 람다 함수를 선언만 하고 호출은 하지 않았기 때문입니다. 람다 함수를 호출하려면 다음과 같이 뒤에 ()를 붙여주면 됩니다.
[]{ std::cout << "Hello World" << std::endl; }(); 


인자를 넘기려면 앞의 ()에 일반 함수와 같이 인자를 정의하고 뒤의 ()에 넘겨줄 인자를 넣으면 됩니다.
[](int i){ std::cout << "Argument "<< i <<std::endl;}(5);

이렇게 하면 Argument 5 가 출력됩니다.

반환 타입은 일반 함수와 달리 -> 기호를 이용해서 지정합니다.
 bool isTrue = []()->bool{ return true; }();

반환 타입을 지정하지 않았을 경우에는 함수 내부의 결과값을 가지고 컴파일러가 자동으로 추정합니다. 만약 컴파일러가 추정하지 못할 경우 void 타입으로 추정합니다.

람다 함수의 장점 중 하나가 람다 함수 외부의 변수를 바로 참조할수 있다는 것입니다. 람다 소재자인 []가 그 역할을 하는데 캡처절이라고도 부릅니다.
int a = 1;
int b = 2;

int c = [&]{ return a + b; }();
std::cout << "Result " << c << std::endl;

실행해보면 Result 3 이 출력됩니다. [&]가 람다 함수 외부 변수를 참조 타입으로 캡처했기 때문입니다.
참 조 타입이 아니라 값으로 캡처할 수도 있는데 차이점은 참조 타입으로 캡처했을 경우 람다 함수 내부에서 값을 변경하면 함수 외부에도 적용된다는 점이고 값으로 캡처했을 경우 외부에 적용이 되지 않는다는 점입니다. 이 부분은 일반 함수와도 같습니다.
이 외에도 여러가지 캡쳐 규칙이 있습니다.
[]: 아무것도 캡처하지 않음
[&]: 모든 외부 변수를 참조로 캡처
[&x]: x만 참조로 캡처하고 다른 변수는 캡처하지 않음
[&x, &y]: x, y만 참조로 캡처하고 다른 변수는 캡처하지 않음
[=]: 모든 외부 변수를 값으로 캡처
[x]: x를 값으로 캡쳐
[x, y]: x, y만 값으로 캡처하고 다른 변수는 캡처하지 않음
[&x, y]: x를 참조로 캡처하고 y는 값으로 캡처

한 함수 내에서 람다 함수를 선언하고 이를 여러변 사용해야 할 경우에는 auto 키워드를 사용하여 람다 함수를 변수로 할당하고 호출하면 됩니다.
auto printValue = [](int i){ std::cout << i << std::endl; };
printValue(1);
printValue(2);

[Cocos2d-x] 기본 구조

Node
Cocos2d-x의 최상위 클래스 이고 모든 클래스는 Node를 상속받습니다. 주요 클래스인 Sprite, Lable, Menu, Layer, Scene 등도 모두 Node를 상속받고 Node가 제공하는 다양한 프로퍼티를 사용할수 있습니다. 
또한 스케줄러를 가지고 있어서 게임 루프를 만들때 사용되며 중지나 재시작 기능도 제공합니다.

Director
한 어플리케이션에서 단 하나의 인스턴스만 존재합니다. 게임을 진행하다 보면 여러가지 장면 전환이 필요한데 이 장면 전환을 관리하는 클래스가 Director입니다.

Scene
하 나의 게임에는 여러 장면이 있는데 그 장면이 Scene입니다. Scene 안에는 게임의 여러가지 요소인 Sprite나 Menu등을 넣어서 세부적인 게임 화면을 구성할수 있습니다. 하지만 Scene은 터치 이벤트를 받을수 없습니다.

Layer
게 임 화면을 보면 배경, 주인공, 상태 정보 등 각각 독립적으로 움직이는 여러 요소들이 있습니다. 이러한 요소들을 모두 한 화면으로 만들면 관리가 어렵기 때문에 Layer를 사용해서 독립적으로 관리할수 있습니다. 하나의 Scene안에는 여러 Layer를 넣을수 있고 터치 이벤트도 받을수 있습니다.

Sprite
배경, 움직이는 물체와 같이 이미지를 관리하는 역할을 합니다. 이미지를 출력하거나 숨기고 움직이게 할수 있습니다.

Action
Sprite의 애니매이션 처리를 위해 주로 사용됩니다. 이동, 회전, 점프, 크기 변환등 다양한 액션을 제공하고 결합할 수도 있습니다. 또한 reverse 액션도 가능합니다. 
액션에는 To와 By 두 종류가 있는데 By는 현재 위치에서 액션을 수행하고 To는 지정한 위치로 액션을 수행합니다.

[영어듣기] 영어 방송 사이트

제가 자주 듣는 영어 방송 사이트 입니다. 들리지는 않지만 들으려고 노력하고 있습니다. ㅠㅠ

TBS eFM
http://www.tbsefm.seoul.kr
프로그램을 다운받아 설치하면 웹사이트에 들어가지 않아도 방송 청취가 가능합니다. 발음도 또박또박하고 중간 중간에 노래도 나와서 편하게 들을수 있습니다. 
주로 한국에 관한 내용을 다루기 때문에 이해하는데 도움이 됩니다.

Arirang
http://www.arirang.co.kr/
TV 와 Radio가 있는데 전 TV를 더 선호합니다. Radio는 K-Pop이 너무 많이 나오더군요. 노래 좋아하시는 분들은 Radio를 들어도 괜찮을것 같습니다. TV는 주로 뉴스가 나옵니다. 발음은 TBS eFM 보다는 알아듣기 어렵더군요 (저만? -_-)
여기도 주로 한국에 관한 내용을 다루고 있습니다.

BBC World Service
www.bbc.co.uk/worldservice
세 계 곳곳의 방대한 내용을 다루고 있고 말도 빨라서 매우 어렵습니다. (역시 저만? -_-) 영국과 미국 현지인의 영어를 체험해보고 싶으신 분은 좋을 것 같습니다. 전 위의 두 사이트에서 모두 음악만 나올때 이 사이트를 이용합니다. ㅋㅋ

2015년 6월 7일 일요일

[인도베다수학] 덧셈

두 자릿수의 덧셈
두 자릿수의 덧셈을 할때 둘중 하나의 일의 자리의 수를 0으로 만들면 반올림을 하지 않아도 되기 때문에 암산이 쉬워집니다.
58 + 79 = 58 + 80 - 1 = 138 - 1 = 137

세 자릿수 이상의 덧셈
세 자릿수 이상의 덧셈을 할때 둘중 하나의 일의 자리와 십의 자리의 수를 0으로 만들면 암산이 쉬워집니다.
195 + 238 = 200 + 238 - 5 = 438 - 5 = 433

[C++11] 유니폼 초기화

vector를 하나 만들었다고 가정합시다. 기존 C++에서는 vector에 객채를 넣으려면 객체를 모두 생성하여 vector 변수에 넣어줘야 했습니다. 하지만 C++11에서는 vector 변수를 생성함과 동시에 객체들을 생성해 넣을 수가 있습니다.
// 이름과 나이를 넣는 class Person이 있다고 가정하고
vector<Person> persons {
{20, "Park"}, {21, "Lee"}, {22, "Song"}, {23, "Kim"}
};


위와 같이 한방에 생성할수 있습니다. vector 뿐만 아니라 다른 STL에도 적용 가능하니 코드를 줄이는데 효과적입니다.