728x90

1. 비트연산자

1) 2진수와 16진수
- 컴퓨터의 기본 정보단위는 bit와 byte로 표현
- 2진수, 16진수 표기가 편리한 경우가 있음
1 bit: 2진수 한 자리
1 byte: 16진수 두 자리
2진수 4자리 == 16진수 1자리

2) 비트 연산
- 비트 단위로 처리되는 연산
1: 참 
0: 거짓
- 비트 연산의 종류: 비트 단위 논리 연산, 비트 단위 이동 연산

<비트 단위 논리 연산>
(1) x & y  
- x와 y 비트 단위 AND(논리곱) 연산
- 둘 다 비트가 1인 경우: 1
- 둘 중 하나라도 비트가 0인 경우: 0

(2) x : y 
- x와 y 비트 단위 OR(논리합) 연산
- 둘 중 하나라도 비트가 1인 경우: 1
- 둘 다 비트가 0인 경우: 0

(3) x ^ y 
- x와 y 비트 단위 XOR 연산
비트의 합이 홀수 or 1의 개수가 홀수 or 두 비트가 다른 경우: 1
비트의 합이 짝수 or 1의 개수가 짝수 or 두 비트가 같은 경우: 0

(4) ~ x

- x 에 대한 NOT 연산
- 비트가 1인 경우: 0
- 비트가 0인 경우: 1

<비트 단위 이동 연산>
(1) x << n
- x를 n비트 왼쪽 이동
- 왼쪽 n개의 비트는 삭제
- 오른쪽에 남은 공간은 0으로 채우기

(2) x>>n
- x를 n비트 오른쪽 이동
- 오른쪽 n개의 비트는 삭제
- 왼쪽에 남은 공간은 0으로 채우기

3) 비트연산의 피연산자
- 피연산자는 정수형(char, int, long 등) 에 대해서만 연산 가능
- 특별한 이유가 없으면 unsigned 정수 사용 (0과 양수)
- 이동 연산에서 빈자리는 0으로 채우는 것이 기본이지만, signed 정수는 1로 채워지는 경우도 있음

2. 재귀 함수

1) 함수 호출과 반환
- 어떠한 함수가 존재한다 가정할 때, 해당 함수를 여러번 반복하여 호출하면?
- 하나의 함수가 반복하여 여러번 요청을 처리하는 것이 아니다.
동일한 기능을 가진 3개의 함수가 각각의 요청을 처리하는 것이다.

- 따라서 하나의 함수의 내부에서 동일한 이름의 함수를 호출 할 수 있다.
- 일을 시행하고 있는 해당 함수가 다시 일을 처리하는 것이 아닌, 
- 동일 기능의 다른 함수에게 요청하는 것이기 때문

2) 재귀 함수 동작 과정
하위 함수를 주어진 만큼 반복하여 호출하여, 

- 최하위 함수까지 간 이후
최상위 함수로 차례대로 복귀한다

예시)

void circle(int x){
	printf("call: x=%d\n", x);
	if (x > 1) circle(x-1);
	printf("return: x=%d\n", x);
}

int main(){
	circle(3);
	return 0;
}



>> 출력

call: x=3 // circle(3) 호출
call: x=2 // circle(2) 호출
call: x=1 // circle(1) 호출
return: x=1 // circle(1) 마무리
return: x=2 // circle(2) 마무리
return: x=3 // circle(3) 마무리



3) 재귀 함수
함수 내부에서 자기와 동일한 이름의 함수를 호출하는 함수
- 유사 개념: 점화식
- 주의 사항: 재귀 호출의 종료 조건이 없으면 제대로 동작하지 않음
- 점화식에서 초기항이 없으면 정의되지 않는 것과 유사

3. 라이브러리 활용

1) 난수(Random Number) 생성
- 난수: 정의된 범위 내에서 임의로 추출되는 수
- C언어에서는 난수를 생성하는 함수 제공
- ex) rand(), srand(), time()

(1) rand() 함수
<stdlib.h>에 선언되어 있음
0 ~ RAND_MAX 사이의 임의의 수 리턴
- RAND_MAX는 stdlib.h에 정의된 상수 (32767)

예시)

#inlcude<stdio.h>
#include<stdlib.h>

int main(){
	for (int i = 0; i<5; i++){
		printf("%d", rand());
	}
	return 0;
}



(2) srand() 함수
<stdlib.h>에 선언되어 있음
rand() 함수의 시드(seed) 변경
시드(seed) 값이 동일하면, 특정 회차의 rand() 함수로 생성한 난수는 항상 동일하게 나온다.
- 따라서 완전히 랜덤한 난수 값을 생성하기 위해서는 srand()로 시드 값도 변경해 줄 필요가 있음

예시)

#inlcude<stdio.h>
#include<stdlib.h>

int main(){
	// 0. 시드값이 동일할 때 첫번째 난수 값 확인해보기
	for (int i = 0; i<5; i++){
		srand(30000); // 시드값 30000 고정
	printf("%d", rand()); // 시드값 30000의 첫 난수
	}

	// 1. 시드값 변경하면서, 난수 생성
	for (int i = 0; i<5; i++){
		srand(i); // 시드값 변경
		printf("%d", rand());
	}
	return 0;
}



(3) time() 함수
<time.h>에 선언되어 있음
현재 시스템의 시간에 의해 결정되는 정수 리턴
- 실행할 때마다 시드를 바꾸기 위해서 사용

예시) 실행할 때 마다 시드값을 랜덤하게 바꾸기

#inlcude<stdio.h>
#include<stdlib.h> // rand 함수 사용을 위해
#include<time.h> // time 함수 사용을 위해

int main(){
	srand( time(NULL) ); // 시드를 현재시간으로 지정
	// 시드가 시간에 따라 매번 바뀌어 완전히 랜덤한 난수 생성
	for (int i = 0; i<5; i++){
		printf("%d", rand()); 
	}
	return 0;
}



(4) min 이상 max 미만의 난수 생성하기
>> rand() / ((double)RAND_MAX +1) * (max-min) + min

rand() : 0~RAND_MAX 사이의 임의의 정수 생성
/ ((double)RAND_MAX +1) : 생성된 정수를 [0, 1) 사이의 소수로 변환
* (max-min) : [0, 1) 사이의 소수를 [0, max-min) 사이의 값으로 변환
+ min : 수를 min 만큼 이동시켜, [min, max) 사이의 수로 변환

2) 실행시간 측정
clock() 함수 사용
<time.h>에 선언되어 있음
호출 당시의 시스템 시각을 CLOCKS_PER_SEC (time.h에 정의된 상수) 단위로 반환
- 초 단위의 시간을 얻기 위해서는 clock() 함수에 의해 측정된 시각을 CLOCKS_PER_SEC로 나누어야 함

예시) 난수 생성 함수 실행시간 측정

#inlcude<stdio.h>
#include<stdlib.h> // rand 함수 사용을 위해
#include<time.h> // time 함수 사용을 위해

int main(){
	clock_t start, finish;
	double duration;

	start = clock(); // 시작 시각
	srand( time(NULL) ); // 시드를 현재시간으로 지정
	// 시드가 시간에 따라 매번 바뀌어 완전히 랜덤한 난수 생성
	for (int i = 0; i<5; i++){
		printf("%d", rand()); 
	}
	finish = clock(); // 종료 시각

	duration = (double)(finish - start) / CLOCKS_PER_SEC; // 실행시간 계산
	printf("실행 시간: %lf 초\n", duration); // 실행시간 출력

	return 0;
}



728x90

+ Recent posts