qsort연습문제

문제

char name[100]int height를 멤버로 갖는 구조체가 있다. 이 구조체내의 데이터를 height에 따라 오른차순으로 정렬하도록 compare()함수를 만들라.

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

// todo : try increasing/decreasing order

struct kid
{
	char name[100];
	int height;
};

int compare(const void* first, const void* second);

int main()
{

	struct kid my_friends[] = 
	{
		"Jack Jack", 40, "Genie", 300, "Aladdin", 170, "Piona", 150
	};

	**int n = sizeof(my_friends) / sizeof(my_friends[0]);**

	qsort(my_friends, n, sizeof(my_friends[0]), compare);

	for (int i = 0; i < n; i++)
		printf("%s %d\\n", my_friends[i].name, my_friends[i].height);

	return 0;
}

int compare(const void* first, const void* second)
{
	**if (((struct kid*)first)->height > ((struct kid*)second)->height)**
		return 1;
	else if (((struct kid*)first)->height > ((struct kid*)second)->height)
		return -1;
	else
		return 0;
}

생각보다 간단하게 풀었다. 문제 핵심은 굵은 글씨부분임.

qsort()의 자세한 동작은 모르나, 어쨌든 첫번째 들어온 배열의 인덱스를 알아서 인식해 정렬하는건 알 수 있음. 문제는 우리 인덱스가 구조체로 되어있다는 점임. 그래서 그 인덱스안에서도 비교가능한 정수가 들어있는 height 멤버를 가리키게 했어야했음.

void* 로 들어오는 인자는 단순 구조체배열의 각 인덱스 object이므로, 가장 안쪽 괄호는 struct kid*로 맞춰준다. 그 다음이 애매했는데, 파라미터로 들어온 구조체 배열의 한 인덱스전체를 간접참조해 멤버를 찾아가게 했더니 해결되었다.

뭐든지 해결하고 나면 간단해 보이는 법… 자그마치 25분이나 고민했다.

Untitled

ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ

함수 포인터의 배열 연습문제

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

//enum e_options { u, i };
void update_string(char* str, void(*pf)(char*));
void TransPose(char* str);
void ToUpper(char* str);
void ToLower(char* str);

int main()
{
	
	**char options[] = { 'u', 'l' };
	int n = sizeof(options) / sizeof(char);

	typedef void(*FUNC_TYPE)(char*);
	FUNC_TYPE operations[] = { ToUpper, ToLower };**

	printf("Enter a string\\n>> ");

	char input[100];
	while (scanf("%[^\\n]%*c", input) != 1)
	{
		printf("Please try again.\\n>> ");
	}

	TransPose(input);
	fputs(input, stdout);

	return 0;
}

void ToUpper(char* str)
{
	while (*str)
	{
		*str = toupper(*str);
		str++;
	}
}

void ToLower(char* str)
{
	while (*str)
	{
		*str = tolower(*str);
		str++;
	}
}

void TransPose(char* str)
{
	char selc; // choose between 'u' and 'l'

	printf("Choose an optaion: \\n");
	printf("u) to upper\\nl) to lower\\n");
	while ((scanf("%c", &selc)) == 1)
	{
		if (selc == 'u')
		{
			update_string(str, ToUpper);
			break;
		}
		else if (selc == 'l')
		{
			update_string(str, ToLower);
			break;
		}
		else
		{
			printf("pleas try again");
			while (getchar() != '\\n')
				continue;
			continue;
		}
	}
	selc = 0;
}

void update_string(char* str, void(*pf)(char*)) 
{
		(*pf)(str);
}

구현은 했는데… 생각대로 하다보니 주어진 보기를 안쓰고 구현했다… 1시간정도 걸림.

볼드 처리한 부분을 일절 안씀… 저걸 사용해서는 어떻게 구현할까.. 이게 2라운드다.

근데 놀랍게도 홍정모님은 초보들이 나처럼 코딩할줄 알았나보다. 저렇게 하고 나서 다음단계로 볼드처리한 부분을 사용해서 코딩하는 방법을 알려준다.

우선 첫번째 아이디어는 내가 만든 transpose()함수를 그냥 main()안에다가 구현한다. 사실 나는 주어진 transpose()가 뭐를 위한 함수인지 도무지 감이 안왔다. 그래서 update_string()을 실행하기 위해 메뉴를 띄우고 선택지를 입력받고… 포인터를 이용해 input을 조작하는것 모두 transpose()안에다가 넣어놨었는데… 홍정모님의 의도가 아니었나보다.