컴퓨터공부/C & C++ & STL 71

debug에 사용할 메시지

printf("\n Debug line %d, in the function %s, in the file %s.\n", __LINE__, __func__, __FILE__); + C99 에 새로 추가된 __func__ : 현재 function을 적어 줍니다. __FILE__과 __LINE__ 등은 어디 에나 정의되어 있지 않습니다. __FILE__은 몰라도 __LINE__을 # define으로 정의하는 등있는 이유가없습니다. 이 같은 정의하지 않고도 마음대로 선언되는 매크로 것을 통합 매크로라고합니다. ANSI C는 6 종류의 내장 매크로를 규정하고있습니다. 매크로 이름 어떻게 전개되는지 __FILE__ __FILE__ 파일 이름 리터럴 문자열. __LINE__ __LINE__ 줄 번호를 나타내는 10 진..

Cfaq 9

Q 11.18 메시지 “warning: macro replacement within a string literal”은 무슨 뜻 이죠? Answer : ANSI 이전의 어떤 컴파일러/전처리기는 매크로 정의를 다음과 같이 정 의할 경우: #define TRACE(var, fmt) printf("TRACE: var = fmt\n", var) 다음과 같은 식으로 호출하게 되면: CHAPTER 11. ANSI/ISO STANDARD C 193 TRACE(i, %d); 다음과 같이 확장하게 됩니다: printf("TRACE: i = %d\n", i); 즉, 매크로 인자로 나온 이름이 문자열 안에 있는 경우라도 확장시켜 버립 니다. (물론 이러한 버그가 위와 같이 유용하게 쓰일 수도 있지만, 이 것은 대개 초창기 컴..

cfaq 8

Q 10.4 여러 문장으로 이루어진 매크로를 만드는 좋은 방법 좀 알려 주세요. Answer 이런 매크로를 만드는 일반적인 방법은 매크로 자체를 일반 함수처럼 쓸 수 있도록 하는 것입니다. 즉 호출하는 쪽에서 마지막 ‘;’을 직접 써 주게 하고 매크로의 몸통에서는 ‘;’을 따로 써 주지 않는 식으로 쓰는 것입니다. 예를 들면: MACRO(arg1, arg2); 그러므로 매크로 정의는 단순히 여러 statement를 중괄호로 둘러싼 ‘compound statement’ 형식으로 만들 수 없습니다. 왜냐하면 이 매크로가 호 출될 때 세미콜론이 추가적으로 붙는다면 if나 if/else 문장에서 에러가 발생할 수 있기 때문입니다. 다음 코드를 보기 바랍니다: if (cond) MACRO(arg1, arg2); ..

Cfaq7

Q 8.9 제 컴파일러에 버그가 있습니다. sizeof('a')의 값이 sizeof(char)인 1 로 나오지 않고, 2가 나옵니다. Answer 놀랍게도, C 언어에서 문자 상수(character constant)의 타입은 int입니 다. 따라서 sizeof('a')는 sizeof(int)와 같습니다. (C++에서는 조금 다릅니다.) 덧붙여 질문 7.8도 참고하시기 바랍니다. Note 참고로 C++에서 문자 상수의 타입은 char입니다. 즉, sizeof('a')는 sizeof(char)와 같습니다. Q 10.1 다음과 같이 간단한, 함수와 비슷한 매크로를 만들려고 합니다. #define square(x) x * x 그런데, 가끔씩 제대로 동작하지 않습니다. 왜 그럴까요? Answer 매크로 확장(ex..

Cfaq 6

Q 7.29 (질문 6.14를 따라서) 배열을 동적으로 할당한 다음, 이 배열의 크기를 바꿀 수 있을까요? Answer 물론입니다. realloc이 바로 그 역할을 해 주는 함수입니다. (예를 들어, 질문 6.14에 나온 것처럼 dynarray) 동적으로 할당된 배열의 크기를 바꾸 려면 다음과 같은 코드를 씁니다: dynarray = (int *)realloc((void *)dynarray, 20 * sizeof(int)); realloc이 항상 메모리 블럭의 크기를 늘리는데 쓰이는 것은 아닙니다. realloc은, 가능하면, 전달받은 인자와 같은 포인터 값을 돌려주지만, 요 청한 크기에 맞게 메모리 블럭을 다시 찾을 경우에는, 인자로 전달된 포인 터 값과는 다른 값을 돌려줍니다. 이 경우, 인자로 전달..

union을 이용한 float의 이진 출력

union을 이용하여 float의 이진값을 출력하였다. float를 U32로 치환하더라도 이진 출력하기란 쉽지 않다.(사실 난 모르겠다) 하지만 union을 이용하면 아주 쉽게 사용할 수 있다. 굉장해!! + typedef unsigned long U32; typedef union __Union_typecast { U32 ullong; float ffloat; }Union_typecast; int main() { Union_typecast stTypecaster; U32 ulcnt, view; stTypecaster.ffloat = (float)11.1; printf("stTypecaster.ffloat[%f] \n\n", stTypecaster.ffloat); for(ulcnt = 31; ulcnt >..

타입 변환을 안전하게 union으로 하자!!

아래는 union으로 type 변환을 하는것이다. 상수타입에 대해서는 그냥 해도 별 상관이 없기 때문에, 주소 변환을 시도 해보았다. 잘 된다. 사실 이 테크닉이 모든 곳에서 사용 된다고 할 수는 없지만 썩 괜찮다고 본다. 그리고 아래의 type 변환을 U32로 강제로 변환해서 하더라도 문제 없이 돌아가더라. 하지만 주소를 U32로 강제 변환하는 것보다 union으로 하는게 더 안전하다고 본다. + typedef unsigned long U32; typedef struct __Data { U32 x; U32 y; }Data; typedef union __Union_typecast { U32 ullong; Data *pData; }Union_typecast; U32 typecastFunc(Data *In_..

Cfaq5

Q 6.20 정적 또는 동적으로 할당된 다차원 배열을 함수에 전달할때, 서로 구별하지 않고 쓸 수 있는 방법이 있을까요? Answer 완벽한 방법은 없습니다. 다음 선언이 있다고 할 때: int array[NROWS][NCOLUMNS]; int **array1; /* ragged */ int **array2; /* contiguous */ int *array3; /* "flattened" */ int (*array4)[NCOLUMNS]; int (*array5)[NROWS][NCOLUMNS] 포인터들은 질문 6.16에 나온 것처럼 초기화되어 있다고 가정하고 함수 선 언은 다음과 같다고 가정합니다: void f1a(int a[][NCOLUMNS], int nrows, int ncolumns); void f..

Cfaq4

Q 6.1 소스 파일에 char a[6]이라고 정의하고 extern char *a라고 선언해 두 었는데 왜 동작하지 않을까요? Answer 소스 파일에 정의한 것은 문자(char)로 이루어진 배열입니다. 그리고 선언 한 것은 문자를 가리키는 포인터입니다. 따라서 선언과 정의가 일치하지 않 는 경우입니다. 일반적으로, T 타입을 가리키는 포인터(pointer to type T) 의 타입은 T 타입의 배열(array of type T)과 다릅니다. 대신 extern char a[]을 사용하기 바랍니다. Q 6.4 그럼 왜 함수의 formal parameter로 배열과 포인터 선언을 마음대로 바꿔 쓸 수 있다는 것일까요? Answer 편의상 그런 것입니다. 배열 이름은 즉시 포인터로 바뀌기 때문에4, 배열은 ..

Cfaq3

Q 4.12 함수를 호출할 때, 포인터를 써서 호출하는 방식을 봤습니다. 왜 이런 일을 하는 거죠? Answer 원래, 함수를 가리키는 포인터는 * 연산자를 쓸 경우 (그리고 우선 순위를 위해 괄호를 같이 쓸 경우) 진짜(real) 함수 호출로 변경됩니다: int r, func(), (*fp)() = func; r = (*fp)(); 위 코드의 마지막 줄의 의미는 다음과 같습니다: fp는 함수를 가리키는 포 인터이고, *fp는 이 함수를 뜻합니다. 그리고 뒤따르는 ()는 함수 호출에 서 쓰이는 인자를 받는 인자 list입니다. 이때 연산자 우선 순위를 고려해서 *fp를 괄호로 둘러쌉니다. 이러면 완벽한 함수 호출이 됩니다. 다음과 같은 이론도 있습니다: 함수는 항상 포인터를 써서 불려지고, 수식 에서 “..