2009년 05월 20일
뭐랄까..
우리나라의 컴공 교육에 대한 생각이 들게 하는 면접
아니.. 아무리 요새 C를 안쓰고 고급언어 어쩌고 한다 해도..
이건 좀 아니잖아..;;
참고로 이정도 수준은 전공도 아니고, 1학년 교양수업 수준이다. 원글에서 답을 쓴 사람은 대체 무슨 생각으로 답을 쓴건지 잘 모르겠는데.. 몇줄 되지도 않는 간단한 코딩이다. 문제를 보자.
int main()
{
str[] = "abcde";
reverse(str);
printf("%s\n");
}
결과
edcba
void reverse(char* str)
{
/// 구현하시오
}
간단하다. 뒤집는 거잖아? 이 문제 자체에도 몇가지 에러가 있지만 그건 그냥 넘어가자. 여하튼 문제에서 reverse 함수의 프로토타입을 지정했으므로, 이 프로토타입을 지키도록 하자. char * 형을 받아서 void 형을 리턴하는 함수이다.
void reverse(char *str)
{
int i;
int size=strlen(str);
char *s=(char *)malloc(sizeof(char)*(size));
for(i=0;i<size;++i)
{
s[i]=str[size-i-1];
}
memcpy(str, s, size);
free(s);
}
전형적인 옛날 C 스타일로 해봤다. 참고로 요새는 C도 버전업 되어서, VS2008 정도에서 C를 코딩하면 CPP 스타일을 사용할 수 있다고 한다. 뭐 직접 돌려보지는 않았지만 혹시나 궁금하시면 복사해서 돌려보시라. 물론 malloc.h이랑 string.h 의 include는 기본이다. 굳이 포인터를 복잡하게 조작하고, 스왑 알고리즘 어쩌고 할 이유가 없다. 단순히 문자열만큼 메모리 잡아서 거꾸로 써준 담에 원본 날리고 복사하면 끝이다. (혹시 안돌아가면 쪽팔..;; 음)
포인터를 사용한다는 것은 다른 말로 메모리를 직접 건드린다는 소리다. 자바나 파이선, 루비, 기타 상위 언어들과 C가 다른 점은, C는 좀더 로우한 메모리 구조를 건드릴 수 있다는 것이다. 따라서 메모리를 다루는 데 좀더 자유도도 높고, 직접적인 연산을 사용할 수 있어 여러 작업들에서 좀더 높은 성능을 보일 수 있다. 하지만 그만큼 Memory Curruption이나 Memory Leak 같은 여러 문제를 생각해줘야 한다. 굳이 하지 않아도 되는, 힙 메모리를 할당받아 버퍼를 쓴 이유가 사실 이 얘기를 꺼낼라고..(..)
간단히 문자열을 뒤집는 것일 뿐이지만, 사실 저 문제의 포인트는 문자열 처리와 메모리 관리라고 본다. C의 문자열처리(NULL문자)와, 메모리구조에 대한 기본적인 지식이 없으면 원글에서처럼 이상한 코딩이 될 수밖에.. 누군지는 모르겠지만 저 사람은 문자열이 어떻게 메모리에 올라가고, C가 문자열을 어떻게 다루는지, C는 메모리를 어떻게 사용하는지에 대한 지식이 전혀 없는 것 같다.
뭐 여하튼, 간단해 보여도 배울 때 잘배우자. 석사 병특이 이런것도 못풀면 쪽팔리잖아 정말;;
참. 혹시 심심하면 이런거나 해보시라. 이것 역시 문자열을 뒤집는 문제다. 간단한 c++ 문제니 쉽게 풀 수 있을 것이다.
#include<iostream>
#include<string.h>
const int MAX_LEN=1024;
using namespace std;
const int& extern __stdcall Swap(const void* strSource, void* strDestination, const size_t& const size); //Swap 함수 선언
int main()
{
char* str=new char[MAX_LEN];
char* swap_str;
int SC=0, i;
cout<<"Input: ";
cin.getline(str, MAX_LEN);
SC=strlen(str)+1;
swap_str=new char[SC];
Swap(str, swap_str, SC);
cout<<"\nOutput\nBefore: ";
for(i=0;i<SC;i++) cout<<*(str+i);
cout<<"\nSwap: ";
for(i=0;i<SC;i++) cout<<*(swap_str+i);
cout<<endl;
delete str;
delete swap_str;
return 0;
}
결과
Input: abs def ass vsd
Output
Before: abs def ass vsd
Swap : vsd ass def abs
const int& __stdcall Swap(const void* strSource, void* strDestination, const size_t& const size)
{
// 구현하시오
}
즉, 이건 문자열을 단순히 뒤집는 게 아니라, 공백으로 구분된 단어를 뒤집는다. 예를들어 apple lemon orange 라고 입력하면 orange lemon apple 이라고 나온다. 조건은, stack 등의 자료구조를 쓰지 말 것. 포인터 연산으로 처리할 것. 단어의 개수에 구애받으면 안됨(MAX_LEN을 늘려서 단어를 더 많이 받으면 더 받은만큼 될 수 있도록). 문자 코드는 ansi. 참, 프로토타입은 웬만하면 정해진 형식을 지켜주는 게 좋다. Swap 함수의 리턴값은 뭐 마음대로..^^; (난 단어의 개수를 집어넣었었다.)
ps. 아놔. 나 이런거 가급적 안쓸라 했는데 이거 참..;;
# by | 2009/05/20 22:13 | 트랙백 | 덧글(13)






☞ 내 이글루에 이 글과 관련된 글 쓰기 (트랙백 보내기) [도움말]
(웃흥)
그리고 아무래도 메모리구조에 대한 썰을 풀어보기 위해 써봤음-_-;
void reverse(char *str)
{
unsigned int i=0;
unsigned int size=0;
char temp;
while(*(str+i))
i++;
size=i;
for(i=0;i<size/2;++i)
{
temp=str[size-i-1];
str[size-i-1]=str[i];
str[i]=temp;
}
}
아아 마구마구 찔린다.. 나 뭐 먹고 살지.. OTL
사실 시스템 프로그래밍 이외의 분야에서 아직도 C 교육이 유효한 이유가 이런 것 때문이라고 보거든요. 뭐 개인적인 생각이겠지만.
뭐 static 메서드에 관한 이야기라든지 virtual 메서드가 포함된 클래스의 사이즈라든지.. this 포인터의 활용에 대한 문제 같은 것도 있군요.
저는 각 단어 개별로 뒤집으란 줄 알고 abc defg hijkl => cba gfed lkjih 가 되도록 만들었..
이래서 난독증은 곤란한데 말이죠. 흐으.