C++을 사용하다 보면 중간 값을 구하는 연산으로 흔히들 아래와 같이 쓴다 mid = (l + r ) / 2; mid = (left + right) / 2; // 또는 mid = (start + end) / 2;가끔 다른 사람들이 짜 놓은 소스코드를 보면 아래와 같이 돼있는 걸 본적이 있다. mid = l + (r - l) / 2; mid = left + (right - left) / 2; mid = start + (end - start) / 2;수학적으로는 전혀 차이가 없는데 저렇게 나누는 이유는? Overflow 때문이다. 변수들이 int로 선언된 경우, left + right가 INT_MAX를 넘어서는 경우 overflow가 일어나서 원하는 결과대로 수행이 되질 않는다. 따라서 최소한의 방어벽을 치..
배열과 포인터가 동치라는 것은 이미 알고 있다. 예를 들어서 a[3]은 *(a+3) 이 되는 것이다. 하지만 다른 점은 배열은 포인터 상수로 선언 된다는 점이다. 즉 * const 이다. 따라서 int a[3]; int b[3]; 이 있을 때, a는 a[3]배열의 시작 주소를 나타내고 b 역시 b[3]배열의 시작 주소를 나타내지만 a = b; 는 할 수 없다. 왜냐면 const이기 때문에!! 해주고 싶다면 int a[3], int *b; 를 하고 b = a; 한다면 이것은 가능하겠다!! 자 이제... 2차원 배열의 포인터는 어떻게 선언할까? 그냥 대충 생각하면 꼭 int a[3][4]; int **p = a; 가 될 것 같이 생겼지만.. 되지 않는다. 왜일까? int a[3][4];로 선언한 이차원 배열..
이중 포인터를 사용하는건 주로 포인터의 동적 배열을 나타내기 위해서 이다. 우선 아래와 같은 클래스가 하나 있다고 가정 해보자. class CTest { public: CTest() {} int a; }; 이녀석에 대한 포인터를 선언하고 객체 하나를 생성하려면 어떻게 해야할까? 다음과 같이 써주면 된다. CTest *pTest = new CTest; 이렇게 하면 pTest는 CTest의 객체를 참조한다. 근데 이제 CTest객체가 여러개 필요한 상황이 나오면 어떻게 해야할까 처음에 아무 생각없이 아래와 같이 했었다. CTest *pTest1 = new CTest; CTest *pTest2 = new CTest; ... 필요한게 정해져있다면 뭐 저래도 괜찮겠지만.. 그래도 매직넘버를 늘리는건 좋지 않다....
클래스를 주고 받을땐 레퍼런스를 사용하자!! 클래스 전체를 call by value로 넘긴다면 그 메모리는 어머어머하지만 레퍼런스로 넘기게 되면 겨우 포인터 변수의 크기 만큼만 넘기고 끝이다. 예를 들어서 AddPoint(POINT point); 라는 Method가 있다면 AddPoint(const POINT &point); 가 나을 것이다. (const는 적절히 써주자) 물론 호출한 놈의 인스턴스가 사라지지 않는 것이 확실히 될 때 얘기다.
http://www.devpia.com/MAEUL/Contents/Detail.aspx?BoardID=50&MAEULNo=20&no=829244&ref=829244 나는 분기문을 좀 싫어한다 -.-;; 뭔가 소스가 길어지는 느낌이라서.. 예를 들어 단순히 form열기 같은 것을 하는데 switch문으로 길게 늘리는게 뭔가 안깔끔해 보인다. switch(nIndex) case: 0 Form1열기 case: 1 Form2열기 case: 2 form3열기 이걸 간결히 해주기 위해 아래처럼 쓸 수 있다. Form arFrom[3]; arForm[0] = Form1; arForm[1] = Form2; arForm[2] = Form3; arForm[nIndex].폼열기 이걸 다른 곳에도 응용해 보면, 입력한 숫자에..
상속한 클래스를 넘겨 줬을 때 해당 클래스의 자료형이 뭔지 정확히 알기 위해 사용한다. 컴파일 시에 RTTI를 사용하여 컴파일 하면 vtable을 사용 할 수 있다. vtable은 가상 함수 테이블인데 아래의 소스를 함 보자. class Parent{ public: virtual void func(Parent obj); }; class Child : public Parent{ public: virtual void func(Parent obj); }; 이런 클래스가 있을 때 Parent p; Child c; p.func(p); p.func(c); 이렇게 하면 함수 func에서는 인자로 들어온 Parent obj에 대하여 이것이 Child인지 Parent 인지 알 길이 없다. 자바에서는 걍 p.getClas..
dynamic_cast const_cast reinterpret_cast static_cast A가 B의 superclass일 때 A* a; B* b = new B(); a = (A *)b; 이거는 dynamic_cast(b);와 같음 dynamic_cast는 safe함. 서브->슈퍼 캐스팅은 상관 없지만 슈퍼->서브 캐스팅은, C style로 캐스팅하면 캐스팅이 되긴 하지만, 참조 할 수 없는 멤버를 참조 하려 하면 런타임 에러가 발생함. dynamic_cast를 이용하면 서브->슈퍼 일때만 캐스팅 하고 아닐 대는 null을 참조함. 따라서 null 체크를 통해 런타임 에러를 방지할 수 있다. 덧, 포인터로 선언한 클래스 일때만 된다. Parent *p1 = new Child; Parent *p2 = ..
- Total
- Today
- Yesterday
- it
- algorithm
- 드라이버
- jni강좌
- Cloud
- gcc
- winapi
- Visual C++
- kering
- NDK
- API
- 안드로이드
- db
- C++
- 프로그래밍
- android
- Quiz
- AWS
- linux
- C
- driver
- jni
- MFC
- Troubleshooting
- Python
- source
- database
- java
- 리눅스
- 음악
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 31 |