C++

From WhiteWing
Jump to: navigation, search
  • 실제로 C의 문법 중 C++이 지원하지 못하는 부분도 있는데 이런 문법은 대부분 안정성, 이식성에 문제가 있거나 더 좋은 해결 방법이 있어 제외된 것들이다. 두 언어의 개발 방법이 다르다는 주장은 실제로 사실이며 문제 해결을 위한 접근 방법 자체가 다르다. 그러나 C++은 객체 지향만 지원하는 것이 아니라 C의 구조적 개발 방법도 여전히 지원하며 필요할 경우 C++로도 C 스타일의 프로그램을 작성할 수 있다. 구조적 프로그래밍 방법이 객체 지향보다 열등하다고 생각하는 것도 일종의 고정 관념일 뿐이며 필요하다면 쓸 수도 있다. - 30
  • MFC까지 기본 과정을 마친 후에는 보통 COM을 공부한다. COM은 마이크로소프트사의 최신 기술들의 기반 이론이기 때문에 ActiveX, DirectX, OLE DB, ATL, OLE 등의 고급 기술을 익히기 위해서 필요하다. 기반 이론으로서 COM의 위치는 상당히 중요하지만 다소 어렵고 난해한데다 최신 개발툴들은 COM의 기능을 추상화해주기 때문에 몰라도 일단 사용은 할 수 있다. - 35
  • 배열명이 단독으로 사용되면 배열의 시작번지값을 가지는 포인터 상수이다. (하지만 배열의 길이는 기억하고 있다.) - 374
  • 포인터 연산
    • 포인터끼리 더할 수 없다.
    • 포인터끼리 뺄 수는 있다.
    • 포인터에 정수를 더하거나 뺄 수 있다.
    • 포인터끼리 비교는 가능하다.
  • 프로그램이 사용하는 문자열 상수는 실행 파일에 같이 기록되는데 정확하게 정적 데이터 영역에 기록된다. 정적 데이터 영역이란 전역변수, 정적변수 등이 저장되는 곳인데 이 영역에 문자열 상수도 같이 저장되어 있는 것이다. 설사 함수 내에서 지역적으로 사용하고 있는 문자열 상수더라도 말이다. 코드에서 문자열 상수는 이 문자열 시작 번지를 가리키는 문자열 상수로 평가된다. 그래서 문자형 포인터를 인수로 요구하는 모든 함수에서 문자열 상수를 바로 사용할 수 있는 것이다. 컴파일러는 다른 상수와는 달리 문자열 상수를 특별나게 취급하는데 다음 두 가지 사항도 참고삼아 알아 두도록 하자. 첫 번째로 같은 문자열 상수를 두 번 이상 사용하면 이 문자열은 한 번만 기록된다. 두 번째로 컴파일러는 공백이나 탭, 개행 코드 등으로만 구분된, 즉 중간에 콤마나 영문자 등이 없는 연속된 문자열 상수들을 하나로 합쳐서 기록한다. - 498 ~ 499

혼자 연구하는 C/C++, 김상형, 와우북스


  • 구조체와 클라스 : The only difference between a class and a structure is that structure members have public access by default and class members have private access by default.

Float

#include <limits>

void testFloat(float a);
void testFloat(unsigned a);
void testFloat(unsigned v, float f);

int main()
{
	testFloat(0.5f);
	testFloat(1.0f);
	testFloat(2.0f);
	testFloat(3.0f);
	testFloat(10.0f);
	testFloat(1.0e-7f);
	testFloat(std::numeric_limits<float>::infinity());
	testFloat(std::numeric_limits<float>::signaling_NaN());
	testFloat(std::numeric_limits<float>::quiet_NaN());
	testFloat(std::numeric_limits<float>::epsilon());
	testFloat(std::numeric_limits<float>::lowest());
	testFloat(std::numeric_limits<float>::max());
	testFloat(std::numeric_limits<float>::min());
	testFloat(std::numeric_limits<float>::round_error());
	testFloat((unsigned)0x7FFFFFFF);
	testFloat((unsigned)0x7F800000);
	testFloat((unsigned)0x7F800001);
	testFloat((unsigned)0x7F800002);
	testFloat(FLT_MAX + FLT_MAX);
	testFloat(FLT_MAX + FLT_EPSILON);
	testFloat(FLT_MAX + 1.0f);

	return 0;
}

void testFloat(unsigned v)
{
	float f = *((float *)&v);
	testFloat(v, f);
}

void testFloat(float f)
{
	unsigned v = *((unsigned int *)&f);
	testFloat(v, f);
}

void testFloat(unsigned v, float f)
{
	printf("%E : ", f);
	printf("%08X : ", f, v);
	for (unsigned i = 0; i < 32; ++i) {
		printf("%d", ((v & (1 << (31 - i))) >> (31 - i)));
		if (i == 0 || i == 8)
			printf("|");
	}
	printf("\n");
}
// output
 5.000000E-001 : 00000000 : 0|01111110|00000000000000000000000
 1.000000E+000 : 00000000 : 0|01111111|00000000000000000000000
 2.000000E+000 : 00000000 : 0|10000000|00000000000000000000000
 3.000000E+000 : 00000000 : 0|10000000|10000000000000000000000
 1.000000E+001 : 00000000 : 0|10000010|01000000000000000000000
 1.000000E-007 : A0000000 : 0|01100111|10101101011111110010101
 1.192093E-007 : 00000000 : 0|01101000|00000000000000000000000
 3.402823E+038 : E0000000 : 0|11111110|11111111111111111111111
 1.175494E-038 : 00000000 : 0|00000001|00000000000000000000000
 1.#INF00E+000 : 00000000 : 0|11111111|00000000000000000000000
 1.#QNAN0E+000 : 20000000 : 0|11111111|10000000000000000000001
 1.#QNAN0E+000 : 00000000 : 0|11111111|10000000000000000000000
 1.192093E-007 : 00000000 : 0|01101000|00000000000000000000000
-3.402823E+038 : E0000000 : 1|11111110|11111111111111111111111
 3.402823E+038 : E0000000 : 0|11111110|11111111111111111111111
 1.175494E-038 : 00000000 : 0|00000001|00000000000000000000000
 5.000000E-001 : 00000000 : 0|01111110|00000000000000000000000
 1.#QNAN0E+000 : E0000000 : 0|11111111|11111111111111111111111
 1.#INF00E+000 : 00000000 : 0|11111111|00000000000000000000000
 1.#QNAN0E+000 : 20000000 : 0|11111111|00000000000000000000001
 1.#QNAN0E+000 : 40000000 : 0|11111111|00000000000000000000010
 1.#INF00E+000 : 00000000 : 0|11111111|00000000000000000000000
 3.402823E+038 : E0000000 : 0|11111110|11111111111111111111111
 3.402823E+038 : E0000000 : 0|11111110|11111111111111111111111
// in float.h
_Check_return_ _CRTIMP int    __cdecl _finite(_In_ double _X);
_Check_return_ _CRTIMP int    __cdecl _isnan(_In_ double _X);

Vector3 Class

// http://bartipan.net/vmath/doc/classVector3.html
template <class T>
class Vector3
{
public:
    T x;
    T y;
    T z;

    // constructors
    Vector3() : x(0), y(0), z(0) { }
    Vector3(T nx, T ny, T nz);
    Vector3(const Vector3<T> &src); // copy constructor

    // access operators
    Vector3<T>& operator= (const Vector3<T> &rhs) {
        x = rhs.x; y = rhs.y; z = rhs.z;
        return *this;
    }
    T& operator[] (int n);
    const T& operator[] (int n) const;

    // arithmetic operator
    Vector3<T>& operator+= (const Vector3<T> &rhs) const;
    Vector3<T> operator+ (const Vector3<T> &rhs) const;
    Vector3<T> operator+ () const;
    Vector3<T> operator* (T rhs) const;
    bool operator== (const Vector3<T> &rhs) const;
    bool operator!= (const Vector3<T> &rhs) const;

    T Dot(const Vector3<T> &rhs) const;
    static T Dot(const Vector3& lhs, const Vector3 &rhs);
};

Personal tools