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

Cfaq 2

은근히 이게 항상 헤갈린다.. + Q 4.3 ‘*p++’은 ‘p’를 증가시키는 것인가요, 아니면, ‘p’가 가리키는 것을 증가시 키는 것인가요? Answer *, ++, --와 같은, 피연산자가 하나인 연산자는 (unary operator라고 합니 다.) 항상 오른쪽에서 왼쪽으로 결합합니다. 따라서 *p++는 *(p++)와 같 습니다; 일단 p를 증가시킨 다음, p가 증가하기 전에 가리키던 곳의 값을 리턴합니다. p가 가리키는 것을 증가시키려면 (*p)++을 (또는, 부작용이 일어나도 상관없는 경우, ++*p를 써도 됩니다) 쓰면 됩니다. Q 16.7 External structure를 푸는 코드를 받았습니다만, 실행하면 항상 “unaligned access”라는 에러가 납니다. 이게 무슨 뜻인가요? 실..

Cfaq 1

(d != 0 && n / d > 0) 위와 같이 사용하면 숫자가 0으로 나눠지는 것을 방지 할 수 있다! 흠.. 신기하군.. + Q 3.6 조건에 따라서 &&, || 연산자의 오른쪽이 평가되지 않는다고 보장할 수 있 나요? Answer 보장합니다. if (d != 0 && n / d > 0) { /* average is greater than 0 */ } 이나, if (p == NULL || *p == '\0') { /* no string */ } 는 C 코드에서 매우 자주 볼 수 있는 것입니다. 이는 이른바 ‘short circuit’ 이라고 합니다. 만약 이 ‘short circuit’이 없다면, 첫번째 예제의 &&의 오 른쪽에서, d가 0일 경우, 0으로 나누는, ‘divide by 0’ 에러가 ..

Writing Efficient C and C Code Optimization

4.2 나눗셈 그리고 나머지 표준적인 프로세서에서의 분모와 분자의 32bit 나눗셈은 20~140의 실행 사이클을 가지고 있다. 나눗셈을 이용하면 다음과 같은 시간이 소비된다. Time (numerator / denominator) = C0 + C1* log2 (numerator / denominator) = C0 + C1 * (log2 (numerator) - log2 (denominator)). 널리 쓰이는 버젼은 약 20+4.3N의 사이클을 보여준다. ARM 뿐만 아니라 프로세서를 막론하고 이런 연산은 피하는게 바람직하다. 나눗셈연산은 가능하다면 곱셈으로 대체해서 사용하기 바란다. 예를들어 (a/b) > c 는 b * c가 integer 범위안이라는 것을 안다면 a > (c * b)로 다시 쓰일 수..

맘에 드는 코드(* 왕복 구문)

일부러 flag를 써가면서 * 을 왕복 시킬 필요가 없이 switch문을 이용하면 좀 더 깔끔하게 처리가 되네. for (;;) { switch(i) { case 0: PC_DispStr(0, 1, "* ", DISP_FGND_YELLOW+DISP_BGND_BLACK), i=1; break; case 1: PC_DispStr(0, 1, " * ", DISP_FGND_YELLOW+DISP_BGND_BLACK), i=2; break; case 2: PC_DispStr(0, 1, " * ", DISP_FGND_YELLOW+DISP_BGND_BLACK), i=3; break; case 3: PC_DispStr(0, 1, " * ", DISP_FGND_YELLOW+DISP_BGND_BLACK), i=4; brea..

포인터 연산

int *ptr; int num[] = {2,4,6,8,10}; ptr = num; *ptr++; *ptr++; (*ptr)++; (*ptr)++; 예문이 위와 같을 때 *ptr의 값과 후치연산 후 ptr의 주소 값 이동은? 결과는 드래그 2(주소 : num[0] + 1) 4(주소 : num[0] + 1 + 1) 7(주소 : num[0] + 1 + 1) -> 후치연산 후, 주소 연산이 아니라 포인터가 가르키는 값이 증가했다. 8(주소 : num[0] + 1 + 1) -> 후치연산 후, 주소 연산이 아니라 포인터가 가르키는 값이 증가했다.

const 정리

const : const 바로 뒤에 오는 것을 바꿀 수 없다고 생각하면 쉽다. //기본 타입 int n = 10; int* const p1 = &n; // n의 값을 바꿀 수는 있지만 p1이 다른 변수를 가리킬 수 없다. const int* p2 = &n; // n의 값을 바꿀 수는 없지만 p2이 다른 변수를 가리킬 수 있다. const int* const p3 = &n; // n의 값도 바꿀 수 없고 p1이 다른 변수도 가리킬 수도 없다. //클래스 타입 Point pt; Point* const ppt1 = &pt; // pt의 멤버 변수의 값을 바꿀 수는 있지만 다른 객체를 가리킬 수 없다 const Point* ppt2 = &pt; // pt의 멤버 변수의 값을 바꿀 수는 없지만 다른 객체를 가리킬..

포인터 이정도는 알아야 된다

(1) int *var[5]; (2) int (*var)[5]; (3) long *var(long, long); (4) long (*var)(long, long); (5) double (*var(double(*)[3]))[3]; 정답은 드래그~ 해설 (1) int 형 자료에 대한 포인터를 5개를 갖는 배열 (2) int형 자료 5개를 가지는 배열에 대한 포인터 (3) long 형 인수 두개를 받아 long 형 자료에 대한 포인터를 반환하는 함수 (4) long 형 인수 두개를 받아 long 형 자료를 반환하는 함수에 대한 포인터 (5) double 형 자료를 3개 갖는 배열에 대한 포인터를 인수로 받고, double 형 자료를 3개를 갖는 배열에 대한 포인터를 반환하는 함수

포인터 배열? 배열 포인터?

int *p[4] : 포인터 배열 int (*p)[4] : 배열 포인터 int *p[4] 랑 int (*p)[4] 은 다른 것입니다. * 보다 [] 가 우선 순위가 높습니다. !!!! + 배열과 포인터와의 관계 1차 배열 과 그 포인터 : int a [4]; int (*p) ; => p = a; 실행 시 문제없음 2차 배열 과 그 포인터 : int a [3][4]; int (*p)[4] ; => p = a; 실행 시 문제없음 3차 배열 과 그 포인터 : int a [2][3][4]; int (*p)[3][4] ; => p = a; 실행 시 문제없음