포인터(完) - 연습문제 풀이
교재에 있는 포인터에 관한 챕터를 모두 끝냈다.
이제 문제를 풀면서 완전히 끝내보자.
책의 필자는 도전3, 4를 먼저 풀도록 권하므로 먼저 풀어보자.
도전 3.
의사 난수(pesudo random number)에 관한 문제이다.
stdlib헤더의 rand함수를 통해 0이상 RAND_MAX만큼 생성하는 rand함수의 값을 적절히 변경하여 0이상 99이하의 난수5개를 출력하라.
rand함수를 100으로 나눈 나머지를 출력하면 끝
#include <stdio.h>
#include <stdlib.h>
int main () {
printf("%d", RAND_MAX);
for (int i = 0; i < 5; i++) {
printf("%d \n", rand()%100);
}
return 0;
}
도전 4.
rand함수는 한번 출력되면 값이 고정이 되버리는 일이 발생한다. 난수를 생성해야하는데 값이 고정되면 안되지 않겠는가. 그래서 ANSI표준은 srand함수를 통해 난수를 생성하기 위한 시드를 받는다. 그런데 이 시드도 생성할때마다 받을수는 없는 노릇. 그래서 실행할때마다 값이 바뀌는 컴퓨터의 시간을 이용하도록 한다.
이제 이것들을 사용하여 두개의 주사위를 던졌을 때의 값을 출력하면 된다.
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main () {
srand((int)time(NULL));
int dice[6] = {1, 2, 3, 4, 5, 6};
for (int i = 1; i <= 2; i++) {
printf("주사위 %d의 결과 %d\n", i, dice[rand()%6]);
}
return 0;
}
풀라고 해서 풀었는데 이게 대체 배열이나 포인터랑 뭔 상관인건지......
도전 1
길이 4x4인 int형 2차원 배열을 선언하고 다음과 같이 초기화하자.
1 | 2 | 3 | 4 |
5 | 6 | 7 | 8 |
9 | 10 | 11 | 12 |
13 | 14 | 15 | 16 |
그리고 모든 요소들을 시계방향으로 90º만큼 회전시켜서 출력하라.
1 | 2 | 3 | 4 |
5 | 6 | 7 | 8 |
9 | 10 | 11 | 12 |
13 | 14 | 15 | 16 |
13 | 9 | 5 | 1 |
14 | 10 | 6 | 2 |
15 | 11 | 7 | 3 |
16 | 12 | 8 | 4 |
16 | 15 | 14 | 13 |
12 | 11 | 10 | 9 |
8 | 7 | 6 | 5 |
4 | 3 | 2 | 1 |
4 | 8 | 12 | 16 |
3 | 7 | 11 | 15 |
2 | 6 | 10 | 14 |
1 | 5 | 9 | 13 |
이건 또 뭐야.....
행을 열로 옮겨서 풀었다.
#include <stdio.h>
void print_arr (int var[][4], int colume) {
for (int i = 0; i < colume; i++) {
for (int j = 0; j < 4; j++) {
printf("%d ", var[i][j]);
}
printf("\n");
}
}
int main () {
int arr[4][4] = {
{1,2,3,4},
{5,6,7,8},
{9,10,11,12},
{13,14,15,16}
};
int turn_arr_90[4][4];
int turn_arr_180[4][4];
int turn_arr_270[4][4];
for (int i = 0; i < 4 ; i++) {
for (int j = 0; j < 4; j++) {
turn_arr_90[j][3-i] = arr[i][j];
}
}
for (int i = 0; i < 4 ; i++) {
for (int j = 0; j < 4; j++) {
turn_arr_180[j][3-i] = turn_arr_90[i][j];
}
}for (int i = 0; i < 4 ; i++) {
for (int j = 0; j < 4; j++) {
turn_arr_270[j][3-i] = turn_arr_180[i][j];
}
}
print_arr(arr,4); printf("\n");
print_arr(turn_arr_90, 4); printf("\n");
print_arr(turn_arr_180, 4); printf("\n");
print_arr(turn_arr_270, 4);
return 0;
}
도전 2
사용자에게 n을 입력받아 n x n크기의 2차원 배열을 만들어서 거기에다가 달팽이배열을 만들자.
진짜 이거 푸는데 며칠은 걸리고도 못하겠어서 다른 분의 풀이를 참조했다. (https://wnsdyd0807.tistory.com/1)
#include <stdio.h>
int main () {
int n; // 길이
int i, j; // 반복문 인자
scanf("%d", &n);
int arr[n][n]; // 배열 생성
int num = 1; // 채워나갈 숫자
int x = 0, y = 0, control = 1; // 가로, 세로, 가로세로 값 증감에 관한 변수
for (i = 0; i < n; i++) {
arr[0][i] = num++; // 맨 첫줄 작성
}
x = i - 1; // x값 조정
for (i = n - 1; i > 0; i--) {
for (j = 0; j < i; j++) { // 세로방향 작성
y += control;
arr[y][x] = num++;
}
control *= -1; // 증 -> 감 -> 증......
for (j = 0; j < i; j++) { // 가로방향 작성
x += control;
arr[y][x] = num++;
}
}
for (i = 0; i < n; i++) { // 출력
for (j = 0; j < n; j++) {
printf("%3d ", arr[i][j]);
}
printf("\n");
}
return 0;
}
도전 5
앞의 난수를 이용하여 가위바위보 게임을 구현하는 문제.
승, 패, 비김을 판단할 변수를 어떻게 전달할까 하다가 포인터 배열을 통해 플게 되었다
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
void is_win (int user, int com, int ** engine) {
if (user == com) {
printf("비겼습니다!\n");
(*(engine[2]))++;
} else if (user < com) {
printf("이겼습니다!\n");
(*(engine[0]))++;
} else if (user == 3 && com == 1) {
printf("이겼습니다!\n");
(*(engine[0]))++;
} else if (user == 1 && com == 3) {
printf("당신이 졌습니다!\n");
(*(engine[1]))++;
} else {
printf("당신이 졌습니다!\n");
(*(engine[1]))++;
}
}
int main () {
srand((int)time(NULL));
int win = 0, lose = 0, draw = 0;
int * engine[3] = { &win, &lose, &draw }; // win, lose, draw
int user, com;
const char * rsp[] = { "바위", "가위", "보" };
while (!lose) {
com = rand()%3;
printf("바위는 1, 가위는 2, 보는 3: ");
scanf("%d", &user);
printf("당신의 선택은 %s 컴퓨터는 %s 선택, ", rsp[user-1], rsp[com]);
is_win(user, com, engine);
}
printf("\n게임의 결과 : %d승 %d무", win, draw);
return 0;
}
도전 6
숫자야구 게임을 만드는 문제. 세자리수이며, 각 자리수는 중복되면 안된다, 그리고 0이 어느 위치에 와도 상관없다.
난수를 발생시켜 중복되지 않는 3개의 숫자를 만든 후에 게임을 진행하면 된다.
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main () {
srand((int)time(NULL));
int com[3]; // 랜덤 숫자 생성
int user[3], temp; // 사용자에게 숫자 입력받음
int cnt = 1, strike = 0, ball = 0; // 시도 횟수, strike, ball
int i, j; //반복인자
for (i = 0; i < 3; i++) {
com[i] = rand() % 10;
for (j = 0; j < i; j++) { // 중복검사
if (com[i] == com[j]) {
com[i] = (com[i] + (rand() % 9 + 1)) % 10; // 중복이 발생한 경우 값을 바꾼다.
}
}
}
printf("Start Game!\n");
while (strike != 3) { // 3 strike = 완전히 맞춤
strike = 0; ball = 0;
printf("3개의 숫자 선택: ");
for (i = 0; i < 3; i++) { // 입력받는다.
scanf("%d", &temp);
user[i] = temp;
}
for (i = 0; i < 3; i++) {
for (j = 0; j < 3; j++) {
if (com[i] == user[j]) { // strike, ball 검사
i == j ? strike++ : ball++;
break;
}
}
}
printf("%d번째 도전 결과 : %dstrike %dball!!\n", cnt++, strike, ball);
}
printf("\nGame Over!");
return 0;
}
교재의 3/4를 완료했다. 남은 부분도 빨리 끝내자.