«   2025/06   »
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30
Archives
관리 메뉴

printf("ho_tari\n");

C언어(7) 본문

(Telechips) AI 시스템 반도체 SW 개발자 교육/C

C언어(7)

호타리 2025. 2. 26. 16:44

2025.02.26

 

파일 입출력

 

팩토리얼 프로그래밍

int factorial(int n)
{
	if (n <= 1) return(1);
	else return (n * factorial(n - 1));
}

 

팩토리얼 함수의 호출 순서

- factorial(5) = 5 * factorial(4) = 5 * 4 *factorial(3) = 5 * 4 * 3 * factorial(2) = 5 * 4 * 3 * 2 * factorial(1) = 5 * 4 * 3 * 2 * 1

 

순환 알고리즘의 구조

 

- 만약 순환 호출을 멈추는 부분이 없다면?

- 시스템 오류가 발생할 때까지 무한정 호출하게 된다.

 

팩토리얼의 반복적 구현

int factorial_iter(int n)
{
	int k, v = 1;
	for (k = n; k > 0; k--)
	{
		v = v * k;
	}
	return(v);
}

 

거듭제곱 구현 함수

double slow_power(double x, int n)
{
	int i;
	double result = 1.0;
	for (i = 0; i < n; i++)
	{
		result = result * x;
	}
	return(result);
}

 

순환적인 알고리즘

power(x, n)

if n == 0
	then return 1;
else if n이 짝수
	then return power(x * x, n / 2);
else if n이 홀수
	then return x * power(x * x, (n - 1) / 2);

 

 

피보나치 수열의 계산

 

- 순환 호출을 사용하면 비효율적인 예

- 0, 1, 2, 2, 3, 5, 8, 13, 21, ...

 

순환 호출을 사용했을 경우의 비효율성

- 같은 항이 중복해서 계산됨

int fib(int n) 
{
	if (n == 0) return 0;
	if (n == 1) return 1;
	return (fib(n - 1) + fib(n - 2));
}

 

- 재귀호출 이용

 

- 반복문 이용

 

 

하노이 탑 문제

 

문제는 막대 A에 쌓여있는 원판 n개를 막대 C로 옮기는 것이다.

- 한 번에 하나의 원판만 이동할 수 있다

- 맨 위에 있는 원판만 이동할 수 있다

- 크기가 작은 원판 위에 큰 원판이 쌓일 수 없다

- 중간의 막대를 임시적으로 이용할 수 있으나 앞의 조건들을 지켜야 한다

void hanoi_tower(int n, char from, char temp, char to) {
	if (n == 1)
	{
		printf("원판 1을/를 %c에서 %c로 옮긴다.\n", from, to);
	}
	else
	{
		hanoi_tower(n - 1, from, to, temp);
		printf("원판 %d을/를 %c에서 %c로 옮긴다.\n", n, from, to);
		hanoi_tower(n - 1, temp, from, to);
	}
}

 

스택의 특징

- 후입선출(LIFO, Last In First Out) : 가장 최근에 들어온 데이터가 가장 먼저 나감

 

스택의 연산

- push() : 스택에 데이터 추가

- pop() : 스택에 데이터 삭제

 

전역 변수로 구현하는 방법

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#define MAX_STACK_SIZE 100 // 최대 스택의 크기

typedef int element;

element stack[MAX_STACK_SIZE];
int top = -1;

// 공백 상태 검사
int is_empty() {
	return (top == -1);
}

// 포화 상태 검사
int is_full() {
	return (top == (MAX_STACK_SIZE - 1));
}

// 삽입 함수
void push(element item) {
	if (is_full())
	{
		fprintf(stderr, "스택 포화 오류\n");
		return;
	}
	else
	{
		stack[++top] = item;
	}
}

// 삭제 함수
element pop() {
	if (is_empty())
	{
		fprintf(stderr, "스택 공백 오류");
		return;
	}
	else
	{
		return stack[top--];
	}
}

// 피크 함수
element peek() {
	if (is_empty())
	{
		fprintf(stderr, "스택 공백 오류");
		return;
	}
	else
	{
		return stack[top];
	}
}

int main(void){
	push(1);
	push(2);
	push(3);
	printf("%d\n", pop());
	printf("%d\n", pop());
	printf("%d\n", pop());
}

 

구조체로 구현하는 방법

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>

#define MAX_STACK_SIZE 100 // 최대 스택의 크기
#define MAX_STRING 100

typedef struct {
	int student_no;
	char name[MAX_STRING];
	char address[MAX_STRING];
}element;

element stack[MAX_STACK_SIZE];
int top = -1;

// 공백 상태 검사
int is_empty() {
	return (top == -1);
}

// 포화 상태 검사
int is_full() {
	return (top == (MAX_STACK_SIZE - 1));
}

// 삽입 함수
void push(element item) {
	if (is_full())
	{
		fprintf(stderr, "스택 포화 오류\n");
		return;
	}
	else
	{
		stack[++top] = item;
	}
}

// 삭제 함수
element pop() {
	if (is_empty())
	{
		fprintf(stderr, "스택 공백 오류");
		return;
	}
	else
	{
		return stack[top--];
	}
}

// 피크 함수
element peek() {
	if (is_empty())
	{
		fprintf(stderr, "스택 공백 오류");
		return;
	}
	else
	{
		return stack[top];
	}
}

int main(void) {
	element input_item = {
		20250226,
		"Steve Kim",
		"Korea"
	};
	element output_item;

	push(input_item);
	output_item = pop();
	
	printf("학번 : %d\n", output_item.student_no);
	printf("이름 : %s\n", output_item.name);
	printf("주소 : %s\n", output_item.address);
}

 

 

 

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>

#define MAX_STACK_SIZE 100 // 최대 스택의 크기

typedef int element;

typedef struct {
	element data[MAX_STACK_SIZE];
	int top;
}StackType;

// 스택 초기화 함수
void init_stack(StackType* s) {
	s->top = -1;
}

// 공백 상태 검사
int is_empty(StackType* s) {
	return (s->top == -1);
}

// 포화 상태 검사
int is_full(StackType* s) {
	return (s->top == (MAX_STACK_SIZE - 1));
}

// 삽입 함수
void push(StackType* s, element item) {
	if (is_full(s))
	{
		fprintf(stderr, "스택 포화 오류\n");
		return;
	}
	else
	{
		s->data[++s->top] = item;
	}
}

// 삭제 함수
element pop(StackType* s) {
	if (is_empty(s))
	{
		fprintf(stderr, "스택 공백 오류");
		return;
	}
	else
	{
		return s->data[s->top--];
	}
}

// 피크 함수
element peek(StackType* s) {
	if (is_empty(s))
	{
		fprintf(stderr, "스택 공백 오류");
		return;
	}
	else
	{
		return s->data[s->top];
	}
}

int main(void) {
	StackType s;

	init_stack(&s);

	push(&s, 1);
	push(&s, 2);
	push(&s, 3);

	printf("%d\n", pop(&s));
	printf("%d\n", pop(&s));
	printf("%d\n", pop(&s));
}

/* 포인터
int main(void) {
	StackType *s;

	s = (StackType*)malloc(sizeof(StackType));

	init_stack(&s);

	push(&s, 1);
	push(&s, 2);
	push(&s, 3);

	printf("%d\n", pop(&s));
	printf("%d\n", pop(&s));
	printf("%d\n", pop(&s));
}
*/

 

 

동적 할당으로 구현하는 방법

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>

#define MAX_STACK_SIZE 100 // 최대 스택의 크기

typedef int element;

typedef struct {
	element* data; // 동적 메모리로 사용된 스택
	int capacity; // 스택의 현재 크기
	int top;
}StackType;

// 스택 초기화 함수
void init_stack(StackType* s) {
	s->top = -1;
	s->capacity = 1;
	s->data = (element*)malloc(s->capacity * sizeof(element));
}

// 공백 상태 검사
int is_empty(StackType* s) {
	return (s->top == -1);
}

// 포화 상태 검사
int is_full(StackType* s) {
	return (s->top == (MAX_STACK_SIZE - 1));
}

// 삽입 함수
void push(StackType* s, element item) {
	if (is_full(s))
	{
		s->capacity *= 2;
		s->data = (element*)realloc(s->data, s->capacity * sizeof(element));
	}
	s->data[++(s->top)] = item;
}

// 삭제 함수
element pop(StackType* s) {
	if (is_empty(s))
	{
		fprintf(stderr, "스택 공백 오류");
		return;
	}
	else
	{
		return s->data[(s->top)--];
	}
}

// 피크 함수
element peek(StackType* s) {
	if (is_empty(s))
	{
		fprintf(stderr, "스택 공백 오류");
		return;
	}
	else
	{
		return s->data[s->top];
	}
}

// 스택 삭제 함수
void delete(StackType* s) {
	free(s);
}

int main(void) {
	StackType* s;

	init_stack(&s);

	push(&s, 1);
	push(&s, 2);
	push(&s, 3);

	printf("%d\n", pop(&s));
	printf("%d\n", pop(&s));
	printf("%d\n", pop(&s));

	free(s->data);
}

 

스택의 응용 : 괄호 검사

 

- 괄호의 종류 : 대괄호, 중괄호, 소괄호

- 왼쪽과 오른쪽 괄호의 개수가 동일

- 왼쪽 괄호가 오른쪽보다 먼저 나옴

- 괄호 사이에는 포함 관계만 존재

 

stack.h 헤더파일 생성

#pragma once
#ifndef __stack_h__
#define __stack_h__

#define MAX_STACK_SIZE 100 // 최대 스택의 크기

typedef int element;

typedef struct {
	element* data; // 동적 메모리로 사용된 스택
	int capacity; // 스택의 현재 크기
	int top;
}StackType;

void init_stack(StackType* s;
int is_empty(StackType* s);
int is_full(StackType* s);
void push(StackType* s, element item);
element pop(StackType* s);
element peek(StackType* s);
void delete(StackType* s);

#endif

 

 

bracket_check.c 파일

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include "stack.h"

int check_matching(const char* in);

int main(void) {
	char* p = "{ A [ (i + 1)] = 0; }";
	if (check_matching(p) == 1)
	{
		printf("%s 괄호검사 성공\n", p);
	}
	else
	{
		printf("%s 괄호검사 실패\n", p);
	}
}

int check_matching(const char* in) {
	StackType s;
	char ch, open_ch;
	int i, n = strlen(in);

	init_stack(&s);

	for (i = 0; i < n; i++)
	{
		ch = in[i];
		switch (ch)
		{
		case '(': case '[': case '{':
			push(&s, ch);
			break;
		case ')': case ']': case '}':
			if (is_empty(&s)) return 0;
			else
			{
				open_ch = pop(&s);
				if ((open_ch == '(' && ch != ')') || (open_ch == '[' && ch != ']') || (open_ch == '{' && ch != '}'))
				{
					return 0;
				}
				break;
			}
		}
	}
	if (!is_empty(&s)) return 0;
	return 1;
}

 

main.c 파일

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include "stack.h"

// 스택 초기화 함수
void init_stack(StackType* s) {
	s->top = -1;
	s->capacity = 1;
	s->data = (element*)malloc(s->capacity * sizeof(element));
}

// 공백 상태 검사
int is_empty(StackType* s) {
	return (s->top == -1);
}

// 포화 상태 검사
int is_full(StackType* s) {
	return (s->top == (MAX_STACK_SIZE - 1));
}

// 삽입 함수
void push(StackType* s, element item) {
	if (is_full(s))
	{
		s->capacity *= 2;
		s->data = (element*)realloc(s->data, s->capacity * sizeof(element));
	}
	s->data[++(s->top)] = item;
}

// 삭제 함수
element pop(StackType* s) {
	if (is_empty(s))
	{
		fprintf(stderr, "스택 공백 오류");
		return;
	}
	else
	{
		return s->data[(s->top)--];
	}
}

// 피크 함수
element peek(StackType* s) {
	if (is_empty(s))
	{
		fprintf(stderr, "스택 공백 오류");
		return;
	}
	else
	{
		return s->data[s->top];
	}
}

// 스택 삭제 함수
void delete(StackType* s) {
	free(s);
}

 

미로 탐색 문제

- 현재의 위치에서 가능한 방향을 스택에 저장해놓았다가 막다른 길을 만나면 스택에서 다음 탐색 위치를 꺼낸다.

 

스택s와 출구의 위치x, 현재 생쥐의 위치를 초기화

while (현재의 위치가 출구가 아니면)

 do 현재위치를 방문한 것으로 표기

    if(현재위치의 위, 아래, 왼쪽, 오른쪽 위치가 아직 방문되지 않았고 갈 수 있으면)

        then 그 위치들을 스택에 push

    if(is_empty(s))

        then 실패

        else 스택에서 하나의 위치를 꺼내어 현재 위치로 만든다.

성공

 

stack.h 헤더파일

#pragma once
#ifndef __stack_h__
#define __stack_h__

#define MAX_STACK_SIZE 100 // 최대 스택의 크기

// typedef int element;
typedef struct {
	short r;
	short c;
} element;

typedef struct {
	element* data; // 동적 메모리로 사용된 스택
	int capacity; // 스택의 현재 크기
	int top;
} StackType;

void init_stack(StackType* s);
int is_empty(StackType* s);
int is_full(StackType* s);
void push(StackType* s, element item);
element pop(StackType* s);
element peek(StackType* s);
void delete(StackType* s);

#endif

 

mouse_maze.c 파일

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include "stack.h"

#define MAZE_SIZE 6

// e : 마우스의 현재 위치, 1 : 벽, 0 : 길, x : 목표 지점
char maze[MAZE_SIZE][MAZE_SIZE] = {
	{'1', '1', '1', '1', '1', '1'},
	{'e', '0', '1', '0', '0', '1'},
	{'1', '0', '0', '0', '1', '1'},
	{'1', '0', '1', '0', '1', '1'},
	{'1', '0', '1', '0', '0', 'x'},
	{'1', '1', '1', '1', '1', '1'},
};

// 위치 삽입
void push_loc(StackType* s, int r, int c) {
	if (r < 0 || c < 0) return;
	if (maze[r][c] != '1' && maze[r][c] != '.')
	{
		element tmp;
		tmp.r = r;
		tmp.c = c;
		push(s, tmp);
	}
}

// 미로 화면 인쇄
void maze_print(char maze[MAZE_SIZE][MAZE_SIZE]) {
	printf("\n");
	for (int r = 0; r < MAZE_SIZE; r++)
	{
		for (int c = 0; c < MAZE_SIZE; c++)
		{
			printf("%c", maze[r][c]);
		}
		printf("\n");
	}
}

element here = { 1, 0 }, entry = { 1, 0 };

void main() {
	int r, c;
	StackType s;

	init_stack(&s);
	here = entry;
	while (maze[here.r][here.c] != 'x')
	{
		r = here.r;
		c = here.c;
		maze[r][c] = '.';
		maze_print(maze);
		push_loc(&s, r - 1, c);
		push_loc(&s, r + 1, c);
		push_loc(&s, r, c - 1);
		push_loc(&s, r, c + 1);
		if (is_empty(&s))
		{
			printf("실패\n");
			return;
		}
		else
		{
			here = pop(&s);
		}
	}
	printf("성공\n");
}

 

main.c 파일

#include "stack.h"

// 스택 초기화 함수
void init_stack(StackType* s) {
	s->top = -1;
	s->capacity = 1;
	s->data = (element*)malloc(s->capacity * sizeof(element));
}

// 공백 상태 검사
int is_empty(StackType* s) {
	return (s->top == -1);
}

// 포화 상태 검사
int is_full(StackType* s) {
	return (s->top == (MAX_STACK_SIZE - 1));
}

// 삽입 함수
void push(StackType* s, element item) {
	if (is_full(s))
	{
		s->capacity *= 2;
		s->data = (element*)realloc(s->data, s->capacity * sizeof(element));
	}
	s->data[++(s->top)] = item;
}

// 삭제 함수
element pop(StackType* s) {
	if (is_empty(s))
	{
		fprintf(stderr, "스택 공백 오류");
		return;
	}
	else
	{
		return s->data[(s->top)--];
	}
}

// 피크 함수
element peek(StackType* s) {
	if (is_empty(s))
	{
		fprintf(stderr, "스택 공백 오류");
		return;
	}
	else
	{
		return s->data[s->top];
	}
}

// 스택 삭제 함수
void delete(StackType* s) {
	free(s);
}

 

 

네트워크

 

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

#pragma comment(lib, "ws2_32.lib")

#define PORT 8080
#define BUFFER_SIZE 1024

int main(void) {
	WSADATA wsa;
	WSAStartup(MAKEWORD(2, 2), &wsa);

	SOCKET server_fd, new_socket;
	struct sockaddr_in address;
	int addrlen = sizeof(address);
	char buffer[BUFFER_SIZE] = { 0 };
	char* message = "Hello from server";

	// 소켓 설정
	server_fd = socket(AF_INET, SOCK_STREAM, 0);
	address.sin_family = AF_INET;
	address.sin_addr.s_addr = INADDR_ANY;
	address.sin_port = htons(PORT);

	// 소켓 연결
	bind(server_fd, (struct sockaddr*)&address, sizeof(address));
	listen(server_fd, 3);

	printf("서버 대기 중... 포트 : %d\n", PORT);

	// 접속 대기
	new_socket = accept(server_fd, (struct sockaddr*)&address, &addrlen);

	// 데이터 수신
	while (1)
	{

		memset(buffer, 0, sizeof(buffer));
		recv(new_socket, buffer, BUFFER_SIZE, 0);
		printf("클라이언트 : %s\n", buffer);
		if (strcmp(buffer, "stop") == 0) break;
	}

	// 접속 종료
	closesocket(new_socket);
	closesocket(server_fd);
}

SerialPortMon 실행 파일

SerialPortMon.exe
2.02MB

 

0226.c
0.00MB
bracket_check.c
0.00MB
main.c
0.01MB
mouse_maze.c
0.00MB
stack.h
0.00MB
main.c
0.00MB

'(Telechips) AI 시스템 반도체 SW 개발자 교육 > C' 카테고리의 다른 글

C언어(9)  (0) 2025.02.28
C언어(8)  (0) 2025.02.27
C언어(6)  (0) 2025.02.25
C언어(5)  (0) 2025.02.24
C언어(4)  (0) 2025.02.21