본문 바로가기
대외활동/시스템프로그래밍

보이드 포인터를 이용한 제네릭 프로그래밍

by hoshi03 2024. 7. 23.

보이드 포인터를 이용한 제네릭 기법은  코드의  재사용성을  높이고, 유연성을  제공하여  다양한  데이터  타입에  대해  

반복적인  코드  작성을  줄일  수  있다.
Generic Programming은 일반적으로  컴파일  시점에 타입 안전성을  보장하며,코드의 성능 최적화에도 도움을 줄 수 있다.
복잡성을  줄이고  유지보수성을  향상시키는데  기여할  수  있다.

 

• 타입에 상관없이 정렬되는 프로그램

 

1. 함수 포인터로 인자를 받는다

2. 받은 인자의 타입에 따라 다른 정렬 메서드를 작성한다

간단해 보이지만 굉장히 복잡했다

C에서의 제네릭 - (void*)  형태

 

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "swap.h"

#define	NAME_SIZE	20

//void*로 주소를 받아와서 비교하는데 사용할 함수 포인터
typedef int (*COMPARE)(void*, void*);

int sort(void *front, void *back);

void bsort(void *base, int nelem, int size, COMPARE fcmp);

int string_sort(void *front, void *back);

int int_sort(void *a, void *b);


int main()
{
	int score[] = {78, 23, 86, 33, 98, 42};
    char name[][NAME_SIZE] = {"yang", "lee", "kim", "park", "kang"};
	int i;

	printf("Before Sort....\n");
	for(i=0; i<sizeof(score)/sizeof(int); i++)
		printf("%d ", score[i]);
	printf("\n\n");

	bsort(score, sizeof(score)/sizeof(int), sizeof(int), int_sort);

	printf("After Sort....\n");
	for(i=0; i<(sizeof(score)/sizeof(int)); i++)
		printf("%d ", score[i]);
	printf("\n\n");

    printf("============================================\n");
	printf("Before Sort....\n");
	for(i=0; i<sizeof(name)/NAME_SIZE; i++)
		printf("%s ", name[i]);
	printf("\n\n");

	bsort(name, sizeof(name)/NAME_SIZE, NAME_SIZE, string_sort);

	printf("After Sort....\n");
	for(i=0; i<sizeof(name)/NAME_SIZE; i++)
		printf("%s ", name[i]);
	printf("\n\n");

	return 0;
}


//quicksort 처럼 사용, 함수 포인터 fcmp를 잘 사용해보자
void bsort(void *base, int nelem, int size, COMPARE fcmp)
{
	int step, cmp, change;
    int rst;

	for(step=1; step<=nelem-1; step++) {
      change = 0;
      for(cmp = 1; cmp<=nelem-step; cmp++) {
		if(fcmp((char*)base+(cmp-1)*size,(char*)base+(cmp)*size) > 0) {
			swap((char*)base+(cmp-1)*size,(char*)base+cmp*size,size);
            change = 1;
		}
	  }
	  if(change == 0) break;
    }
}


int int_sort(void *a, void *b) {
    return (*(int*)a - *(int*)b);
}

int string_sort(void *front, void *back){
	return strcmp((char*)front, (char*)back);
}

 

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "swap.h"

typedef int (*FCMP)(void *, void *);
#define	BASE(i)	((char *)base + (i)*size)
#define	NAME_SIZE	20

void bsort(void *base, int n, int size, FCMP fcmp);
int b_search(void *base, void *target, int n, int size,  FCMP fcmp);
int fcmp1(void *a, void *b); //정수형 자료 검색
int fcmp2(void *a, void *b); //문자열 자료 검색

int main()
{
	int score[] = {78, 23, 86, 33, 98, 42};
    char name[][NAME_SIZE] = {"yang", "lee", "kim", "park", "kang"};
	int i, cnt, s_score;
	char s_name[NAME_SIZE];

	printf("Before Sort....\n");
	for(i=0; i<sizeof(score)/sizeof(int); i++)
		printf("%d ", score[i]);
	printf("\n\n");

	bsort(score, sizeof(score)/sizeof(int), sizeof(int), fcmp1);

	printf("After Sort....\n");
	for(i=0; i<(sizeof(score)/sizeof(int)); i++)
		printf("%d ", score[i]);
	printf("\n\n");

	while(1)
	{
		printf("\nSearch Score ==> ");
		scanf("%d", &s_score);
		if(s_score == -1) break;
		cnt = b_search(score, &s_score, sizeof(score)/sizeof(int), sizeof(int), fcmp1);
		if(cnt != -1) printf("%d data ==> index %d\n",  s_score, cnt);
		else printf("no %d data!!\n", s_score);
	}


    printf("============================================\n");
	printf("Before Sort....\n");
	for(i=0; i<sizeof(name)/NAME_SIZE; i++)
		printf("%s ", name[i]);
	printf("\n\n");

	bsort(name, sizeof(name)/NAME_SIZE, NAME_SIZE, fcmp2);

	printf("After Sort....\n");
	for(i=0; i<sizeof(name)/NAME_SIZE; i++)
		printf("%s ", name[i]);
	printf("\n\n");

	gets(s_name);
	while(1)
	{
		printf("\nSearch Name ==> ");
		gets(s_name);
		if(s_name[0] == '\0') break;
		cnt = b_search(name, s_name, sizeof(name)/NAME_SIZE, NAME_SIZE, fcmp2);
		if(cnt != -1) printf("%s data ==> index %d\n",  name, cnt);
		else printf("no %s data!!\n", s_name);
	}

	return 0;
}

void bsort(void *base, int n, int size, FCMP fcmp)
{
	int step, cmp, change;
    int cnt;

	for(step=1; step<=n-1; step++) {
      change = 0;
      for(cmp = 1; cmp<=n-step; cmp++) {
		if(fcmp(BASE(cmp-1), BASE(cmp)) > 0) {
			swap(BASE(cmp-1), BASE(cmp), size);
            change = 1;
		}
	  }
	  if(change == 0) break;
    }
}

int fcmp1(void *a, void *b)
{
	return ((*(int *)a) == (*(int *)b)) ? 0 : ((*(int *)a) > (*(int *)b)) ? 1 : -1;
}

int fcmp2(void *a, void *b)
{
	return strcmp((char *)a, (char *)b);
}

int b_search(void *base, void *target, int n, int size, FCMP fcmp)
{
	int lt, rt, m, cnt;

	lt = 0;
	rt = n-1;
	while(lt<= rt)
	{
		m = (lt+rt)/2;
		cnt = fcmp(BASE(m),target);
		if(cnt == 0) return m;
		else if(cnt < 0) lt = m + 1;
		else if (cnt > 0) rt = m - 1;
	}

	return -1;
}

int swap(void *dest, void *src, int size){
	void* tmp = malloc(size);
	if (tmp == NULL) return -1;
	memcpy(tmp,dest,size);
	memcpy(dest,src,size);
	memcpy(src,tmp,size);
	free(tmp);
}

'대외활동 > 시스템프로그래밍' 카테고리의 다른 글

C++ 객체지향 프로그래밍  (0) 2024.07.25
컴파일러 최적화  (2) 2024.07.23
부트로더  (0) 2024.07.23
함수 포인터, 구조체 포인터 예제  (0) 2024.07.23
임베디드 C  (4) 2024.07.22