|
|
[19 함수 포인터와 void 포인터]
// [19-1]
// 1) 함수의 자료형은 무엇인가
// 함수의 자료형은 반환형과 매개변수의 자료형으로 매개변수의 자료형은 매개변수의 개수만큼 순서대로 모두 작성해야 한다.
// 2) 함수명의 자료형은 무엇인가
// 함수명은 함수가 저장되는 메모리의 첫 주소를 가리키는 포인터로, 반환형과 매개변수의 자료형의 포인터 타입이다.
// 3) void 포인터의 용도는 무엇인가
// void포인터는 주소만 담는 변수로, 주소가 가리키는 데이터의 타입이 정해지지 않아 모든 데이터를 가리킬 수만 있다.
// 4) void포인터에 간점참조 연산을 적용할 때 주의할 점은 무엇인가
// 간접참조 연산을 할 때 읽어들일 데이터의 범위를 정해주기 위해서 반드시 강제형변환과 같이 써야 한다.
// 5) 함수의 매개변수에 함수 포인터를 활용하는 예제를 찾아 실행해보고 설명하시오.
// 구조체를 정의할 때 enum 키워드를 사용하여 {}안의 문자열을 상수를 의미하는 문자열로 정의하고 해당 구조체로 생성된
// 변수는 그 중 하나의 데이터를 저장하게 된다. 따라서 state타입의 변수는 {}안의 문자열의 개수만큼까지의 정수 중
// 하나의 값을 갖게 되고 이를 변경할 때는 각 위치의 문자열을 대입하여 변경할 수 있다.
#include <stdio.h>
typedef enum { // enum 구조체 선언
STATE_IDLE, STATE_RUN, STATE_ERROR, STATE_MAX // 저장가능 문자열 목록
} State; // 구조체의 타입명
void idleState() { printf("대기 상태\n"); } // 함수 정의
void runState() { printf("실행 중\n"); } // 함수 정의
void errorState() { printf("에러 발생\n"); } // 함수 정의
void (*stateTable[STATE_MAX])() = { // 위 3개를 가리킬 수 있는 함수 포인터 배열 선언
idleState, runState, errorState // 각 포인터에 함수의 주소를 저장한다.
};
int main() {
State current = STATE_IDLE; // 구조체 선언 및 문자열을 이용한 초기화
stateTable[current](); // 포인터의 배열에서 구조체의 값(current의 상태)번째 포인터의 함수 호출
current = STATE_RUN; // 상태 변경
stateTable[current](); // 함수 호출
current = STATE_ERROR; // 상태 변경
stateTable[current](); // 함수 호출
}
// 6) 함수의 매개변수에 void포인터를 활용하는 예제를 찾아 실행해보고 설명하시오.
// 배열의 타입을 모르는 상태에서 void형 포인터를 활용하여 들어오는 배열의 타입에 따라 다른 함수를 호출하여
// 각 타입에 맞는 출력함수를 호출하는 함수를 작성하여 배열과 길이, 타입의 크기와 출력형식을 인자로 받아 동작한다.
#include <stdio.h>
// 모든 타입의 배열의 주소, 배열의 길이, 타입의 길이, 출력 형식에 따라 다른 함수를 가리키는 함수 포인터 선언
void printArray(void* arr, size_t len, size_t typeSize, void (*printElem)(void*)) {
unsigned char* ptr = (unsigned char*)arr; // 1바이트 단위 포인터
for (size_t i = 0; i < len; i++) { // 요소 개수만큼 반복
printElem(ptr + i * typeSize); // typeSize만큼(다음 요소로) 이동해서 함수 호출(출력)
}
printf("\n");
}
void printInt(void* elem) { printf("%d ", *(int*)elem); } // 정수형일 경우 호출
void printDouble(void* elem) { printf("%.2f ", *(double*)elem); } // 실수형일 경우 호출
int main() {
int ints[] = { 1, 2, 3, 4, 5 }; // 배열 선언
double doubles[] = { 3.14, 1.23, 4.56 }; // 배열 선언
printArray(ints, 5, sizeof(int), printInt); // 출력함수 호출
printArray(doubles, 3, sizeof(double), printDouble); // 출력함수 호출
return 0;
}
// 7) 함수포인터를 활용하여 정수의 사칙연산을 수행하는 프로그램을 작성하시오.
#define _CRT_SECURE_NO_WARNINGS
#pragma warning(disable:6031)
#include <stdio.h>
int plus(const int a, const int b);
int minus(const int a, const int b);
int mul(const int a, const int b);
int dev(const int a, const int b);
int main(void) {
int commend, x, y;
int (*funcpt)(int, int) = NULL;
printf("연산을 선택하시오:(1:덧셈, 2:뺄셈, 3:곱셈, 4:나눗셈) : ");
scanf("%d", &commend);
switch (commend) {
case 1: funcpt = plus; break;
case 2: funcpt = minus; break;
case 3: funcpt = mul; break;
case 4: funcpt = dev; break;
default : printf("입력 실패"); return 0;
}
printf("두개의 정수를 입력하시오 : ");
scanf("%d %d", &x, &y);
printf("결과값: %d", funcpt(x, y));
}
int plus(const int a, const int b) { return a + b; }
int minus(const int a, const int b) { return a - b; }
int mul(const int a, const int b) { return a * b; }
int dev(const int a, const int b) { return a / b; }
[20 문제풀이]
// [20-1]
// 1) 4 * 4 배열에 1부터 16까지 순차적으로 저장한 후 배열을 90도 꺾은 형태로 출력하는 프로그램을 작성하여 보자.
#define _CRT_SECURE_NO_WARNINGS
#pragma warning(disable:6031)
#include <stdio.h>
void spin_arr(int arr[4][4], int n);
int main(void) {
int arr[4][4] = { 1, 2, 3, 4, 5, 6, 7, 8, 9,
10, 11, 12, 13, 14, 15, 16 };
spin_arr(arr, 4);
for (int i = 0; i < 4; i++) {
for (int j = 0; j < 4; j++) {
printf("%3d", arr[i][j]);
}
printf("\n");
}
}
// int arr[4][4] => arr[0][0] 의 주소 + 인자로 받은 데이터의 범위 => int [4][4]
void spin_arr(int arr[4][4], int n) {
int temp;
for (int i = 0; i < n; i++) { // 행렬 전치
for (int j = i + 1; j < n; j++) {
temp = arr[i][j];
arr[i][j] = arr[j][i];
arr[j][i] = temp;
}
}
for (int i = 0; i < n; i++) { // 열 역순 배치
for (int j = 0; j < n / 2; j++) {
temp = arr[i][j];
arr[i][j] = arr[i][n - 1 - j];
arr[i][n - 1 - j] = temp;
}
}
}
// 2) 정수 n을 입력받아 n*n크기의 배열에 나선형으로 요소를 채워 출력하는 프로그램을 작성하시오
#define _CRT_SECURE_NO_WARNINGS
#pragma warning(disable:6031)
#include <stdio.h>
#define MAX 10
int main(void) {
int n;
int arr[MAX][MAX] = { 0 };
printf("배열 크기 n을 입력하세요 (최대 %d): ", MAX);
scanf("%d", &n);
int i = 0, j = 0;
int direction = 0;
int value = 1;
int di[4] = { 0, 1, 0, -1 };
int dj[4] = { 1, 0, -1, 0 };
while (value <= n * n) {
arr[i][j] = value++;
int ni = i + di[direction];
int nj = j + dj[direction];
if (ni < 0 || ni >= n || nj < 0 || nj >= n || arr[ni][nj] != 0) {
direction = (direction + 1) % 4;
ni = i + di[direction];
nj = j + dj[direction];
}
i = ni;
j = nj;
}
for (int r = 0; r < n; r++) {
for (int c = 0; c < n; c++) {
printf("%3d ", arr[r][c]);
}
printf("\n");
}
return 0;
}
// 3) 0부터 99 까지의 난수를 5개 생성하는 프로그램을 작성하시오
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main(void) {
srand((unsigned int)time(NULL));
for (int i = 0; i < 5; i++) {
int r = rand() % 100; // 100 아래 값만 추출
printf("%d ", r);
}
printf("\n");
return 0;
}
// 4) 주사위 2개를 굴리는 프로그램을 작성하시오.
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main(void) {
srand((unsigned int)time(NULL));
int d1 = (rand() % 6) + 1, d2 = (rand() % 6) + 1;
printf("주사위 1의 결과 %d\n", d1);
printf("주사위 2의 결과 %d", d2);
}
// 5) 가위바위보 게임
#define _CRT_SECURE_NO_WARNINGS
#pragma warning(disable:6031)
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main(void) {
const char* a[4] = {"", "바위", "가위", "보"};
int w = 0, d = 0, p;
srand((unsigned int)time(NULL));
while (1) {
printf("바위는 1, 가위는 2, 보는 3: ");
scanf("%d", &p);
int r = (rand() % 3) + 1;
printf("당신은 %s 선택, 컴퓨터는 %s선택, ", a[p], a[r]);
if (p == r) {
printf("비겼습니다!\n");
d++;
}
else if (
(p == 1 && r == 2) ||
(p == 2 && r == 3) ||
(p == 3 && r == 1)
) {
printf("이겼습니다!\n");
w++;
}
else break;
}
printf("게임의 결과 : %d승, %d무\n", w, d);
return 0;
}
// 6) 숫자 야구 게임
#define _CRT_SECURE_NO_WARNINGS
#pragma warning(disable:6031)
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main(void) {
srand((unsigned int)time(NULL));
int r[3] = { rand() % 10, rand() % 10, rand() % 10 };
while (r[1] == r[0]) r[1] = rand() % 10;
while (r[2] == r[0] || r[2] == r[1]) r[2] = rand() % 10;
int p[3] = { 0 };
int cnt = 1;
printf("Start Game!\n");
while (1) {
int s = 0, b = 0;
printf("%d번째 시도, 3개의 숫자 입력: ", cnt);
for (int i = 0; i < 3; i++) {
scanf("%d", &p[i]);
}
for (int i = 0; i < 3; i++) {
if (p[i] == r[i]) s++;
for (int j = 0; j < 3; j++) {
if (i != j && p[i] == r[j]) b++;
}
}
printf("%d번째 도전 결과: %d strike, %d ball\n", cnt, s, b);
if (s == 3) {
break;
}
cnt++;
}
printf("Game Over!");
return 0;
}
|
|
