2011년6월3일_C과제6풀이(5의 배수, 10진수를 2진수로 변환, 주사위게임, 히스토그램), 예제2(call by value, call by reference)
C과제6 풀이 |
1. 두 정수 사이의 5의 배수의 갯수를 구하기
① 범위 n1(5) < x < n2(21)
② 반복 for(i = n1 + 1 ; i < n2 ; i++)
③ 비교 if(i % 5 == 0)
④ 증가 cnt++;
⑤ 예외처리 if(n1 > n2) n1과 n2교환. //최소값이 최대값보다 큰 경우 값을 서로 교환.
2. 1Byte 범위의 정수를 입력 받아 각 비트의 값을 출력
num입력 받음.
① num & (1 << 0) → 0번 비트
② num & (1 << 1) → 1번 비트
③ num & (1 << 2) → 2번 비트
④⑤⑥⑦ 생략.
⑧ num & (1 << 7) → 7번 비트
결과가 0이면 0출력, 0이 아니면 1출력하게 하면 됨.
1: for(i = 0 ; i < 8 ; i++)
2: {
3: if(0 == ((1 << i) & num))
4: {
5: printf("%d : 0\n", i);
6: }
7: else
8: {
9: printf("%d : 1\n", i);
10: }
11: }
<다른 방법>
num입력 받음.
① (num >> 0) & 1 → 0번 비트
② (num >> 1) & 1 → 1번 비트
③ (num >> 2) & 1 → 2번 비트
④⑤⑥⑦ 생략.
⑧ (num >> 7) & 1 → 7번 비트
결과가 0또는 1이 나오므로 그대로 출력하면 되니 if( )문을 사용하지 않아도 되나 원본 데이터가 사라진다.
1: for(i = 0 ; i < 8 ; i++)
2: {
3: printf("%d : %d\n", i, 1 & (num >> i));
4: }
3. 주사위 게임
srand((unsigned)time(NULL));
unsigned는 unsigned int를 줄인 것. 시간값을 시드값으로 넣어 항상 다른 패턴으로 시작하도록 하는 함수.
for(i = 0 ; num > i ; i++)
printf(“dice value : %d”, rand( ) % 6 + 1);
rand( )의 반환값을 6으로 나눈 나머지는 6을 넘을 수 없어 0 ~ 5사이의 값을 갖게 됨.
여기에 1을 더하면 1 ~ 6사이의 랜덤한 값이 얻어짐.
도전. 히스토그램
N1(7) N2(2) N3(5)
----------------------------
* * * 6 1 4 (0보다 큰가 비교한 뒤에 *을 출력하고 -1시킴)
* * * 5 0 3 (0보다 큰가 비교한 뒤에 *을 출력하고 -1시킴)
* * 4 0 2 (N2는 0보다 크지 않으므로 공백문자를 출력함. N2는 감소하지 않음)
* * 3 0 1 (0보다 큰가 비교한 뒤에 *을 출력하고 -1시킴)
* * 2 0 0 (0보다 큰가 비교한 뒤에 *을 출력하고 -1시킴)
* 1 0 0 (N3가 0보다 크지 않으므로 공백문자를 출력함. N3도 감소하지 않음)
* 0 0 0 (0보다 큰가 비교한 뒤에 *을 출력하고 -1시킴)
0 0 0 (N3가 0보다 크지 않으므로 공백문자를 출력함. N3도 감소하지 않음)
1: for(i = 0 ; i < 10 ; i++)
2: {
3: if(n1 != 0)
4: {
5: printf("* ");
6: n1--;
7: }
8: else
9: {
10: printf(" ");
11: }
12: if(n2 != 0)
13: {
14: printf("* ");
15: n2--;
16: }
17: else
18: {
19: printf(" ");
20: }
21: if(n3 != 0)
22: {
23: printf("* ");
24: n3--;
25: }
26: else
27: {
28: printf(" ");
29: }
30: }
예제2 |
1. 입력 받은 정수를 교환한 후 출력
temp = N1;
N1 = N2;
N2 = temp;
2. swap( ) call by value
1: void swap(int val1, int val2)
2: {
3: int temp;
4:
5: temp = val1;
6: val1 = val2;
7: val2 = temp; //내부에서 교환이 일어나고
8:
9: return ; //아무것도 반환하지 않음.
10: } //여기서 인자val1,2와 temp가 소멸됨.
11:
swap함수를 호출하면서 val1과 val2의 값을 넘겨 주었으나,
C언어에서는 두 개 이상의 변수를 반환할 수 없고,
swap( ) 내부에서 아무리 값을 바꾸어도 다른 함수의 값에는 영향을 줄 수 없다.
3. swap( ) call by reference
1: void swap(int *pN1, int *pN2)
2: {
3: int temp;
4:
5: temp = *pN1;
6: *pN1 = *pN2; //pN1에 들어 있는 주소를 참조하여 값을 바꿈.
7: *pN2 = temp; //swap을 호출한 함수의 지역변수는 값이 바뀌어짐.
8:
9: return ; //아무것도 반환하지 않음.
10: } //여기서 지역변수와 인자들이 소멸됨.
11:
*pN1과 *pN2에 저장된 주소값을 참조하여 직접 swap( )을 호출한 함수의 값들을 교환함.
4. C과제6 1번에 swap( ) 적용
1: void ProcessCount(int a, int b, int *pCount)
2: {
3: int temp, i;
4:
5: //a가 크면 a와 b를 교환
6: if(a > b)
7: {
8: temp = a;
9: a = b;
10: b = temp;
11: }
12:
13: //5의 배수의 갯수를 카운트
14: for(i = a + 1 ; i < b ; i++)
15: {
16: if(i % 5 == 0) *pCount = *pCount + 1;
17: }
18:
19: return ;
20: }
21:
return문으로 반환하지 않고 *pCount에 저장된 주소로 값을 기록/읽기를 수행.
일반변수 | 포인터변수 | |
선언 | int a; | int *pA; |
값 | a | *pA |
주소 | &a | &pA |
참조(주소) | pA |
포인터는 특별하게 *를 앞에 붙여 자신에 저장된 값을 참조하여 그 주소에 있는 값을 읽거나 쓸 수 있다.