IT/튜토리얼 및 가이드
-
이전에 만든 Ren'Py 튜토리얼 모음2025.05.23
-
[입문자 튜토리얼] - C언어 소스 코드 파일 분리 2편 (feat. 헤더파일)2021.12.19
이전에 만든 Ren'Py 튜토리얼 모음
https://educated-tarsier-f16.notion.site/Renpy-e7a73823dce74af1bfac2d7bd437f615?pvs=4
Renpy 튜토리얼 — 입문자 대상 스터디 주도 | Notion
1시간 만에 게임을 만드는 게 가능하다고?
educated-tarsier-f16.notion.site
저는 Python 기반 오픈소스 게임 엔진인 Ren'Py로 취미 개발 또한 종종 해왔습니다.
최근 블로그 유입 기록을 보니 Ren'Py 관련 학습자료를 찾는 분들이 있어,
예전에 개인적으로 만들어뒀던 입문용 자료를 이번에 공개하게 되었습니다.
📚 Ren'Py 튜토리얼 페이지를 다시 공개하게 된 계기
예전에 이 블로그에 Ren'Py 관련 도구를 개발하고 오픈소스화한 소식을 간단히 올린 적이 있는데요,
그 덕분인지 최근 블로그 통계에서 "Ren'Py 튜토리얼"이나 "비주얼노벨 엔진" 관련 키워드로 유입되는 분들이 종종 보이더라고요.
2023년 당시 저는 거의 Ren'Py 전도사처럼 지냈습니다. 일단 제가 오타쿠라 기본적으로 제 친구들도 다 오타쿠였습니다. 그래서 비개발자인 오타쿠 친구들을 모아 디스코드나 줌을 켜고 비주얼노벨 만들기 과외를 하곤 했고, 실습에 쓸 수 있도록 입문자용 자료도 따로 만들어뒀습니다. 다만 너무 기초적인 내용이라 웹에는 따로 공개하지 않았고, 친구들끼리만 공유하는 정도였어요.
🛠️ Ren'Py 프레임워크로 직접 응용 시스템 기능과 확장도구까지 만들어봤습니다.
Ren'Py 자체 문법도 물론 공부했지만, 저는 거기서 더 나아가서
공식문서에는 없는 내부 Python 코드나 SDK 레벨에서 프레임워크 구조를 분석하고,
렌더링 관련 버그나 UI 상호작용 관련 이슈들을 직접 해결해보는 경험도 했습니다.
예를 들어:
- 드래그 앤 드롭 기반 포인트 앤 클릭 인터페이스
- 2D 맵 위에서 캐릭터 이동 가능한 하이브리드 VN-RPG 모듈 (e.g. 메이플스토리처럼)
- Ren'Py SDK 내부의 displayable 객체를 직접 활용한 커스터마이징
- Shader 응용, 이벤트 처리 흐름 정밀 조정 등...
이런 것들은 대부분 영문 튜토리얼에서도 거의 다루지 않는 주제들이었고, 직접 써보고 만든 도구 중 일부는 오픈소스로도 공유했습니다.
드래그-드롭 관련 시스템 등 요즘 수요가 있는 인터랙티브 매커니즘들도 프로젝트 진행 시에 좀 만들어뒀었는데, 그것들은 좀 다듬은 뒤에 배포하려다보니 아직 공개는 안했습니다. 구직 일정이 마무리되면 시간 날 때 더 정리해서 공개할 계획입니다.
참고로, 제가 만든 Ren'Py 관련 도구 중 일부는 Awesome-Ren'Py 오픈소스 큐레이션에 등재되었고,
Ren'Py 공식 포럼(Resource Topics)에도 소개된 바 있습니다.
🎮 시작은 예상 못 한 팀플 과제에서
사실 처음부터 게임 개발을 하려던 건 아니었어요.
2023년 여름, 졸업요건 때문에 계절학기로 고전문학 수업을 듣게 됐는데, 거기서 "콘텐츠나 게임을 만들어 오라"는 기말 과제가 있었어요.
다른 팀들은 밸런스게임 웹사이트를 활용해서 캐릭터 MBTI 테스트를 만들거나, PPT 애니메이션으로 마무리했지만…
저는 그걸 몰라서 하루이틀 독학한 다음에 진짜로 Ren'Py로 코드를 짜서 게임을 만들었습니다.
판소리 창작은 자신 없고, 그렇다고 게임 외에는 자신있는 마땅한 콘텐츠도 없고,
당시에 한국어로 된 자료도 거의 없어서 영어 공식 문서만 붙잡고 며칠 독학하며 급하게 만들었죠.
자료가 없어서 좀 어려웠던 기억이 남았다보니, 이전에 만든 튜토리얼 자료를 이번에 조금 정리해서 페이지를 공개하게 됐습니다.
[참고] 웹 게임 배포 – PaaS 클라우드 첫 사용 경험
그렇게 고전문학 수업 과제는 PC용 빌드로 제출하고, 발표·시연은 goormIDE를 활용한 웹 배포 버전으로 진행했습니다.
당시가 처음으로 PaaS 클라우드를 써본 경험이었고,
저는 웹을 잘 모르던 시점이라 정적 파일 배포를 어떻게 할 지 좀 난감한 상태였는데.
문제 상황과 목표를 커뮤니티에 공유하자 고인물분들이 여러 무료 클라우드와 더불어 goormIDE라는 걸 알려주셨습니다. 덕분에 직접 웹 게임을 올려볼 수 있었죠.
이후 재미를 느껴, 9월에는 해외 디스코드 팀과 함께
할로윈 테마의 글로벌 게임잼에도 참가했습니다.
Ren'Py 사용자들은 GitHub를 사용하는 사람이 좀 드물고 Itch.io라는 플랫폼을 더 많이 활용하는데,
이곳에선 게임·도구·에셋 배포는 물론, 브라우저 플레이까지 다 지원해 굳이 클라우드 인프라를 쓸 필요도 없었습니다. (내 돈 ㅠㅠ)
이래서 경험이 중요한가 봅니다.
👶 지금 보면 부족한 자료지만, 질문은 언제나 환영입니다
공개한 튜토리얼은 제가 초보였던 시절 만들었던 자료라 지금 보면 부족한 점이 많아요.
응용편부터는 완성이 안된 부분들도 좀 있고요. 그럼에도 누군가에겐 첫걸음이 될 수도 있다는 생각에 공유해봅니다.
관심 있는 분들은 언제든 질문 주세요 — 단순 문법부터 심화 구조 분석까지 다룰 수 있습니다.
📢 스터디 참여도 환영합니다
튜토리얼 페이지에 Ren'Py 스터디용 디스코드 초대 링크도 함께 올려뒀어요.
관심 있는 분이 있다면, 제가 다시 무료 스터디나 그룹 과외 형태로 운영해볼 수 있을 것 같습니다.
수요가 있다면 단순 기초뿐 아니라, Ren'Py에서 구현하기 어려운 고급 상호작용 기능들도 함께 다뤄보거나 아니면 응용기능에 대한 구현방법 등을 알려주는 질의응답 채널도 운영할 수 있을 것 같습니다.
✅ 참고 - 내 포트폴리오 자료들 (렌파이 관련)
https://educated-tarsier-f16.notion.site/Spooktober-VN-Jam-1f39bf46184a801c837dd6e4eb0ad2e4?pvs=4
글로벌 비주얼노벨 게임잼 (Spooktober VN Jam) | Notion
📌 프로젝트 개요
educated-tarsier-f16.notion.site
https://educated-tarsier-f16.notion.site/700-1ed9bf46184a80c5b9abdfc765ed9ac1?pvs=4
개발자 도구 오픈소싱 기록 (최소 700+ 다운로드) | Notion
📌 프로젝트 개요
educated-tarsier-f16.notion.site
'IT > 튜토리얼 및 가이드' 카테고리의 다른 글
서비스 디자인 (기술 / 기획) 가이드 배포 (2) | 2025.05.02 |
---|---|
[개인적인 팁] 영어 논문 쉽게 읽는 법 (5) | 2022.03.01 |
[번역] C에서 시그널을 보내고 처리하는 방법 (kill, signal, sigaction) (0) | 2022.01.06 |
[입문자 튜토리얼] - C언어 소스 코드 파일 분리 2편 (feat. 헤더파일) (0) | 2021.12.19 |
[입문자 튜토리얼] - C언어 소스 코드 파일 분리 1편 (feat. 코드를 깔끔하게) (0) | 2021.12.19 |
서비스 디자인 (기술 / 기획) 가이드 배포
참고 - 서비스 및 소프트웨어 디자인 역량 (해커톤 수상)
2025년 Microsoft 주최 Azure AI Developer 해커톤에서 Design Award로 서비스 설계 부문 수상을 얻었습니다.
IoT–클라우드–프론트 구조를 직접 설계한 프로젝트인 AzureFarming은 사용자 경험 중심의 시스템 아키텍처와 기능 설계로 좋은 평가를 받았습니다. 자세한 프로젝트 설명은 아래의 게시글에서 확인할 수 있습니다.
📐 기획/설계 가이드 템플릿 제작 계기
협업 중 기획에 막막함을 느끼는 개발자/학생 분들을 자주 봐왔습니다. 이를 도우며 “혼자서도 컨셉을 구체화할 수 있는 방식”의 필요성을 느껴, 답을 채워가며 생각을 정리할 수 있는 문서화 구조로 구성된 템플릿을 제작하게 되었습니다. 구체적이고 타당한 기획으로서 완성되게끔, 모호하지 않게 키워드와 항목을 특정했습니다.
실제 예비창업패키지나 공공데이터 공모전, 해커톤 그리고 대학 프로젝트에서의 경험을 통해 사업계획서와 기술문서를 반복적으로 작성해왔고, 해당 실전 경험에서 얻은 인사이트를 반영했습니다. 해외 개발자와도 공유할 수 있도록 영문 버전도 함께 제작했습니다.
질문에 답하듯 작성하는 항목 중심 템플릿으로,
막연한 아이디어도 자연스럽게 구체화될 수 있도록 설계되어 있습니다.
Service Planning Document | Notion
Designed for individuals or teams with little planning experience to easily organize side projects or small startup ideas.
educated-tarsier-f16.notion.site
[KR] 미니 서비스용 기획-설계 가이드 | Notion
마지막 업데이트 : 2025/5/1
educated-tarsier-f16.notion.site
✍️ 구성 요약
단계 | 목적 | 주요 내용 |
1단계 | 아이디어 구조화 | 기능 정의, 사용자 문제 도출, 컨셉 정리 등 |
2단계 | 실전 문서화 | 추천 툴, 프로젝트 목적 별 맞춤 가이드, 프로젝트 명세서, UI 설계서, API 문서, 발표자료 등 |
기획 시 주의사항
기획 초심자가 가장 자주 하는 실수는 기능에 대한 욕심입니다.
❌ “친환경 생활 종합 플랫폼”
✅ “버린 쓰레기 무게를 기록해 환경 점수를 시각화하는 앱”
기능이 많다고 좋은 게 아닙니다. 핵심 문제 해결을 하나로 좁히는 것이 더 효과적인 선택입니다.
실제로 저도 2022년 예비창업패키지 서류심사에서, 기획 범위가 넓어 실현 가능성에 대한 신뢰도가 낮다는 피드백을 받은 바 있습니다. 많은 문제를 해결하려는 기획은 오히려 소규모 팀이나 한정된 예산에서 완성 가능성을 떨어뜨릴 수 있습니다.
이런 경험을 바탕으로, 배포한 템플릿은 하나의 구체적인 문제와 솔루션에 집중할 수 있도록 항목을 구성했습니다.
🧠 GPT와 함께 활용하는 팁
❓ GPT와 함께 기획 구체화하는 법
1단계를 혼자 진행하기 어렵다면, GPT에게 템플릿을 보여주고 컨셉에 맞는 기획 방향을 추천받아 보세요.
GPT가 되묻는 항목에 답하며 대화하듯 수정해 나가면, 아이디어를 훨씬 빠르게 정리할 수 있습니다.
📄 PPT 원고 작성도 쉽게!
1단계 내용을 GPT에게 전달하면, 기획 PPT를 구성할 텍스트 초안을 만드는 데 활용할 수 있습니다.
"키워드 중심으로 간결하게 정리해줘"라고 요청하면 중복 없이 정제된 내용을 뽑을 수 있습니다.
🧩 심화 문서화도 AI와 함께!
2단계로 넘어가면 실제 프로젝트 서류를 작성해야 합니다.
이때 1단계 결과를 GPT에게 전달하고 특정 기술설계 또는 기획문서 형식을 요청하면 훨씬 수월하게 진행할 수 있습니다.
예시) “UI 설계서/유저 플로우/API 명세서 형식으로 정리해줘”
📌 포인트는 '문서 형식 이름'을 정확히 말하는 것!
형식을 명확히 요청하면, GPT가 해당 구조를 따라 더 전문적으로 정리해줍니다.
해당 키워드의 유무로 결과가 판이하게 달라져 기술설계까지도 훨씬 쉽고 빠르게 완성됩니다.
📄 추가 - 프론트엔드 기술 문서 예시
- 기술 스택 정리 및 MVP 우선순위 표
- UI/UX 화면 설계서
- 스타일 가이드
- 컴포넌트 설계 문서
- 상태관리 구조도
- API 명세서
- 협업 가이드 및 전달 문서
👉 이 구조는 현재 프론트엔드 입문자와 앱 개발 협업 시에도 사용하고 있으며, 손쉽게 따라할 수 있는 실무형 포맷으로 구성되어 있습니다.
🛠 개선 예정 안내
아직 부족한 부분도 많습니다.
예를 들어 경쟁 분석 항목은 일부 중복된 구성이 있어, 추후 정리가 필요해 보입니다.
하지만 입문자들이 방향을 잡는 데는 충분히 도움이 될 것이라 생각해 우선 배포하게 되었습니다.
저 역시 기획 방식이나 문서 구성 방식을 외부에 제대로 공유한 적이 거의 없어서,
이번 기회에 살짝 공개해보는 의미도 있습니다. 😊
앞으로 더 개선된 버전이 생기면 업데이트하고, 날짜를 함께 표기해두겠습니다
✉️ 마무리하며
이 템플릿은 기획이 낯선 입문자, 학생, 그리고 사이드 프로젝트 참여자들이 막연한 아이디어를 구체적인 문서로 발전시킬 수 있도록 돕기 위해 제작되었습니다. 전문가 분들께는 참고용으로만 권장드리며, 본인의 방식대로 자유롭게 확장해 주셔도 좋습니다.
🙋♀️ 피드백과 질문은 언제든 환영입니다.
가장 빠른 답변을 원하신다면 Discord의 san0901 계정으로 DM 주세요. (알림 누락 방지를 위해 먼저 친구 추가를 권장드립니다.)
'IT > 튜토리얼 및 가이드' 카테고리의 다른 글
이전에 만든 Ren'Py 튜토리얼 모음 (0) | 2025.05.23 |
---|---|
[개인적인 팁] 영어 논문 쉽게 읽는 법 (5) | 2022.03.01 |
[번역] C에서 시그널을 보내고 처리하는 방법 (kill, signal, sigaction) (0) | 2022.01.06 |
[입문자 튜토리얼] - C언어 소스 코드 파일 분리 2편 (feat. 헤더파일) (0) | 2021.12.19 |
[입문자 튜토리얼] - C언어 소스 코드 파일 분리 1편 (feat. 코드를 깔끔하게) (0) | 2021.12.19 |
[개인적인 팁] 영어 논문 쉽게 읽는 법
본 포스팅은 영어 논문 읽기를 헤메는 입문자용 야매 가이드라인입니다.
특히 공학이나 IT 논문을 읽는 중에 참고하시면 좋을 것입니다^^.
논문을 많이 읽어오신 능숙한 분께서는 본인 방식대로 하시는게 제일 좋습니다.
이건 아주 개인적인 팁이므로, 참고만 해주세요~
근황 - 연구실 인턴 출근 (학기 병행)
최근 포스텍 MCNL 연구실에서 연구실 인턴을 하게 되었습니다. (학교가 비대면 수업으로 확정되면 3학년 복학과 동시에 병행할 생각이고, 그렇지 않다면 쭉 1학기 간은 연구실에만 대면 출근할 생각입니다.)
과거에 학술동아리에서 AI논문 리뷰활동을 한 적이 있지만, 그때는 내용을 이해도 못하고 얼추 캡쳐만 해서 정리한 내용만 ppt에 넣고 그랬던 것 같습니다. 최근에 제대로 논문을 읽으려니 너무 힘들더라구요.
영어를 해석하는 것의 문제가 아니라 그냥 내용이 한줄 한줄 머리에 안들어오고 흘러나간다고 할까요. 흐름도 잡기 힘들었습니다.
그러던 와중 좋은 방법을 발견해서 논문을 끝까지 잘 읽을 수 있게 되었습니다. 개인적인 팁이지만, 처음 논문을 읽기 시작하는 분들께 도움이 될 수 있을까 싶어 그 방법을 공유합니다.
그럼 시작합니다~
논문을 읽는 것은 어렵다.
더군다나 그게 영어라면 더 그렇다. 또 논문은 한 문장이 너무 길고, 또 모르는 전문 용어로만 가득차있다. 그래서 번역기 돌려서 한글로 봐도 뭔뜻인지 알기 힘들다.
읽다가 흐름을 놓치는 경우가 대부분이다. 읽기 시작해봐도 이전 단락 내용들을 계속 까먹으니, 흐름을 잃게 된다. 막히기 시작하니 점점 한줄 조차 읽기 힘들다.
수능 비문학 지문처럼 분석하며 읽어라.


문제 원인 - 영어가 아니라 '독해력'이 문제다.
일단 영어 논문이다보니, 영어 실력이 있으면 물론 너무 좋다.
근데 영어 논문은 기본적인 영어 해석이 가능한 경우에도 읽기가 힘들다... 문장 구조부터가 복잡하니까. 즉, 영어 실력만의 문제가 아니라는 소리다.
알고보니, 우리의 문제는 독해력이었다...!

국어 수능 비문학 킬러 지문들을 생각해보자. 아니면 검색해서 읽어보자. 한국말인데도 외국어 같은 그 지문이 잘 읽히는 가? 당연히 아니다... 그게 영어로 되있는게 영어 논문인데, 이건 더욱이 잘 읽힐 리가 없다.
영어실력보다는 독해력의 문제인거다.
읽은 글 흐름들을 머리속에 잘 잡아둬야하는데, 이걸 잡아두지 못하니 읽는 데 진도를 못나가는 거였다.
특히 영어 + 전문용어에 더불어 수식구가 길게 달린 글이다보니, 아무래도 글 흐름을 잡고 기억해놓기 너무 힘들지 않은가!
국어 수능비문학도 외계어 같은데, 하물며 영어라고 하면... 쉽지 않을 것이다.
해결 방안 - 메모를 통해 글의 흐름을 붙잡자.
그러니 이걸 해결하기 위해서는 밑줄과, 각 단락의 핵심 + 주제 찾기를 하는 것이 좋다.
맞다. 우리가 고3 시절 국어 비문학 지문을 읽고 풀 때 주로 쓰던 풀이 방법이다.
눈알만 굴리지 말고 손으로 바쁘게 밑줄 치고 메모를 하자.
손이 바쁠수록 머리는 편하게 읽을 수 있게 된다!!!!!
흐름을 놓쳐도, 이전 단락 요약문(1줄)만 보는 것으로 다시 흐름을 잡을 수 있게되니까 말이다.
내 방식은 3회독을 기본으로 하니, 1회독은 부담없이 시작해보도록 한다.
1회독 방법
1회독에는 디테일을 완벽하게 잡는다는 마음을 버리자. 첫 술에 배부르랴? 자세히 공부하는 것은 2~3회독부터이다.
흐름만 슥 훑는다는 느낌으로 가본다. 1회독에서는 흐름만 잡아도 훌륭한거다!
먼저, 비문학 분석을 위한 기본적인 팁 2가지를 먼저 소개한다.
1. 형광펜으로 밑줄 긋기
나는 이 테크닉만으로 읽는 속도 + 이해하는 속도를 훨씬 올릴 수 있었다.
일단 형광펜을 3가지 준비한다.
-
- 연핑크 - 중요한 것. 흐름 상 메인 문장.
- 연핑크색 밑줄 부분은 짧아야한다. 따라서, 수식어와 보충설명 부분은 다 빼고 딱 본론만 쳐놓는다.
- 이렇게 하면, 연핑크색만 봐도 흐름을 잃지 않고 따라갈 수 있다.
- 핫핑크 - 핵심 문장. 주제문.
- 핫핑크색 문장은 가장 중요한 주제 문장에만 쳐놓자.
- 연두 - 모르는 것, 더 공부할 것
- 논문을 보면 모르는 용어가 굉장히 많이 나오는데, 당장 필요한 부분만 간단히 찾아보자.
- 연핑크 - 중요한 것. 흐름 상 메인 문장.
모르는 부분이 많아도 되니까, 흐름을 잃지 않고 따라가는 것을 최우선으로 하자.
2회독 때부터 연두색 부분에 대한 조사 및 정리를 할 것이니, 1회독 시점에서는 맘을 편히 가져도 된다.
논문의 서론 파트에 언급된 것들 중 중요한 배경지식들이 당연히 존재하지만, 직접적으로 연관되지 않는 단어들도 굉장히 많기 때문이다. 어차피 중요한 용어는 뒤에도 반복해서 나오게 되니, 그때 그 용어들만 다시 공부해보면 된다.
또, 모르는 영단어 같은 경우는 중간중간 아래에 작게 한글 뜻을 써놓기도 했다.
2. 각 단락 요약하기
밑줄을 치며 읽었는가?
이제 각 단락 아래에 1줄 요약을 남겨보자.
단락 아래에 단락 요약을 1줄 이내로 이렇게 짧게 남기기만 해도, 흐름을 잡기 굉장히 수월해진다.
이런 식으로 단락 요약을 하게되면, 중요하지 않은 서론 부분에 긴 시간을 빼앗기지 않으면서 흐름을 잡기 매우 편하다.
본론 부분의 흐름도 잃지 않고 따라가는 데 큰 도움이 된다.
강력 추천하는 방식.
3. 논문 구조에 따라 읽기
이제 논문 구조에 따라서 어떻게 읽어야하는 지 요령을 준다.
논문 구조는 주로
- 개요-서론
- 실험 과정 & 원리
- 결과 분석
- 결론
이런 구조로 되어있다.
개요 - 서론
개요에는 주로 배경지식이나 현재 상황 등이 나오기 마련이다.
그런데 모르는 게 너무 많은 경우에는 답이 없다. 모르는 걸 전부 찾아보느라 흐름을 놓치기도 쉽고, 찾아봤던 내용들도 다 까먹고 만다.
그러니 이 부분에서 모르는 용어가 좀 나와도 초록색으로 밑줄 치고, 간단하게 검색만 해보고 넘어가자. 1회독이기도 하고, 지금 앞부분에 집착해봐야 시간만 날릴 가능성이 높다.
어차피 뒤에 반복될 부분이 그 중 절반도 안된다. 반복되는 부분은 그때 가서 다시 검색해보게 될 것이라 상관 없다.
개요에서 제일 중요한 것은, 연구 주제와 목표 부분이 나오는 핵심 문장 하나를 건지는 것이다. 그 외에는 무시하고 넘어가자.
개요 부분에서 너무 많은 시간을 뺏기지 말고, 적당히 넘어가는 것이 좋다. 그 시간에 이 논문의 실험과 그 원리 파트를 이해하는 것이 훨씬 이득이다.
서론에서는 이 논문에 관련된 배경분야의 지식-인용 논문들이 많이 소개된다. 따라서 단락 요약으로 대강 흐름만 잡고 넘어가자.
실험 과정 & 원리
제일 중요한 부분이다. 개요 부분에서 봤던 핵심 주제문을 되새기며 들어간다.
서론-개요에서 연두색으로 밑줄친 부분이 다시 반복되는 지 보자. 여기서 그게 또 등장한다면, 그 용어에 대해서는 다시 검색해서 확실히 이해해줘야한다.
그 다음엔, 실험의 구조나 원리같은 것들을 천천히 정독하며 이해해보자. 이 부분만 잘 잡아놔도 끝까지 무사히 완주할 수 있다. 그렇지만 복잡한 수식이나 그런 부분이 나오면 이해하기가 어려워진다. 이때는 논문에 나오는 각 수식/도표 파트에 대한 부연설명을 해당 수식에 직접 표기해가며 읽어준다. 수식이나 도표만 봐도 해당 설명이 덕지덕지 붙어있으면, 글을 왔다갔다해가며 설명을 찾을 필요가 없어진다. 이때, 단락 요약도 빼먹으면 안된다.
손을 바쁘게 쓸 수록 머리가 덜 아픈 부분이니, 손으로 많이 써가면서 표기해주자.
결과 비교 & 분석
이 부분도 단락 요약으로 흐름을 잡아가며 넘어간다.
어떤 면에서 어떤 성능이 어떻게 향상되고 어쩌고~ 이런 디테일하고 복잡한 부분은 지금 이해할 필요 없다. 2회독 3회독에서 자세히 볼 거다.
결론
이 부분에서 실험 결과가 어땟는 지 대강 요약 해주는 경우가 많다.
내가 앞서 흐름에 잘 맞게 논문을 읽었는 지 확인할 수 있다.
복습하는 느낌으로 가볍게 쭉 읽어가며 끝내자.
2회독 방법
1회독에서 밑줄 긋기와 단락 요약을 전부 해놓은 상태이니, 할 것이 많이 줄었다.
흐름은 대략 잡을 수 있게 되었으니, 이전에 연두색으로 밑줄 쳐놓은 부분을 모두 다시 검색해보며 알아두자.
그 부분에 대해서는 따로 메모장, 블로그, 노트 등에 기록하며 정리해두면 더 좋다. 논문을 확실히 이해하기 위해서는, 논문에 언급된 배경지식들도 알아놓으면 좋기 때문이다.
또, 다시 흐름을 따라 읽어내려가면서 지난 번에 중요했던 부분들도 다시 복습해준다.
이제 복습의 효과로 실험이나 그 원리 관련해서 이해도가 좀 더 높아진 상태일 것이다.
이 상태에서 실험 결과와 과정 관련해서 디테일한 부분들도 이해해가며 읽어준다. 이해가 안되면 이부분도 직접 요약문을 옆에 메모해가며 읽는다.
너무 이해가 안되는 부분은 몇번 읽어주고 넘어가자. 3회독도 남았으니 이때 반복 학습해주면 이해 될 것이다.
3회독 방법
중요한 배경지식와 그 용어 관련해서는 따로 어디에 정리를 하며 공부하면 더욱 좋다. (블로그나 메모장, 노트 등)
2회독과 같은 방법으로 논문을 다시 읽는다. 이해가 안되는 부분이 남아있을테니 그 부분을 집중적으로 읽으며 이해하려 노력한다.
이제는 논문 관련해서 논문 리뷰 또는 그와 같은 정리 자료(블로그 포스팅이나 ppt)를 만들어도 좋다.
추가) 요즘 알게된 사실인데, 번역기에 영어 -> 중국어 -> 한국어 이렇게 3단계를 거쳐 변환하면 매끄럽게 번역이 된다는 이야기도 있더라구요. 영어랑 중국어 어순이 비슷해서 그렇다나요. 저는 이 방법을 써본 적은 없는데, 혹시 참고하실 분은 한번 시도해보셔도 좋을 것 같아요~
이렇게 개인적인 야매 가이드라인이 끝났습니다. ㅎㅎ
도움이 되셨다면 좋아요 눌러주세요~
댓글이나 지적 환영합니다 ^^
'IT > 튜토리얼 및 가이드' 카테고리의 다른 글
이전에 만든 Ren'Py 튜토리얼 모음 (0) | 2025.05.23 |
---|---|
서비스 디자인 (기술 / 기획) 가이드 배포 (2) | 2025.05.02 |
[번역] C에서 시그널을 보내고 처리하는 방법 (kill, signal, sigaction) (0) | 2022.01.06 |
[입문자 튜토리얼] - C언어 소스 코드 파일 분리 2편 (feat. 헤더파일) (0) | 2021.12.19 |
[입문자 튜토리얼] - C언어 소스 코드 파일 분리 1편 (feat. 코드를 깔끔하게) (0) | 2021.12.19 |
[번역] C에서 시그널을 보내고 처리하는 방법 (kill, signal, sigaction)
Sending and Handling Signals in C (kill, signal, sigaction)
- 참고하면 좋은 자료 (만화) : sigterm vs sigkill 차이점
- What is SIGTERM? What's the difference between SIGKILL & SIGTERM?
해당 영상의 내용을 정리한 자료입니다. 문제 시 댓글 주시면 삭제하겠습니다.
최근 42 과제 미니톡을 진행하며, 시그널 프로그래밍에 관심이 생겨 이것저것 유튜브로 강의와 영상을 찾아보고 있었습니다. 그 중에 흥미롭고 짧은 영상이 있어 내용을 정리하여 공유합니다.
시그널이란?
시그널은 당신이 프로세스와 상호작용할 수 있는 가장 간단한 방법 중 하나입니다.
mac이나 리눅스와 같은 모든 unix 스타일 운영체제에서 말이에요.
혹시 리눅스나 맥같은 unix 운영체제를 쓰고있으신가요? 그동안 몰랐겠지만, 당신이 프로그램을 종료시키기 위해 ctrl + C를 누를 때마다 시그널들을 사용하고 있던 겁니다.
시그널 처리 (시그널 핸들러)
그럼 이제 예시를 하나 살펴보도록 할까요.
절대 종료되지 않는 무한루프 프로그램이 있다고 해봅시다. 그냥 영원히 실행되고 있는거에요.
보통 학생들의 경우에 이런 코드는 실수로 작성된 것이겠지만, 이건 설명하려는 목적이니까 일부러 이렇게 만들어봤습니다.
#include <stdlib.h>
#include <unistd.h>
int main()
{
while (1)
{
printf("Wasting your cycles. %d\\n", getpid());
sleep(1);
}
}
이런 경우 아래와 같은 실행 화면이 무한히 나타나게 되는데요. 그러면 당신은 이 화면을 잠시 보다가, 프로세스를 죽이기 위해서 주로 ctrl+C를 누르게 될거에요.
이때 당신은 알지 못했겠지만 프로세스에 SIGINT 시그널을 보낸 것입니다. 이 시그널은 기본적으로 해당 프로세스를 방해하고 그 프로세스를 끝내라고 전해주는 역할을 해요.
아직까진 별로 재미없네요. 그럼 내용을 조금 바꿔서 더 재밌게 해볼까요.
이제는 ctrl + C를 눌렀을 때 다른 일들이 일어나도록 만들어볼거에요.
일단 특정한 시그널을 받았을 때 언제든지 호출되는 그런 함수를 만들어 볼 수가 있어요. 그리고 시그널 함수를 이용해서 그 함수를 등록할 수 있습니다.
그래서 여기서는 SIGINT 시그널을 받았을 때 handler 함수가 실행되도록 했습니다.
#include <unistd.h>
#include <signal.h>
#include <stdlib.h>
void handler(int num)
{
write(STDOUT_FILENO, "I won't die\\n", 13);
}
int main()
{
signal(SIGINT, handler);
while (1)
{
printf("Wasting your cycles. %d\\n", getpid());
sleep(1);
}
}
그럼 이걸 실행시켜 보는 중에 ctrl + C를 누르면 이렇게 나옵니다.
그동안 봐온 것 중 가장 건방진 C 프로그램이 만들어지죠.
프로그램이 절대 죽지 않는다는 데, 그럼 이때는 어떻게 할 수 있나요.
운 좋게도 제가 보낼 수 있는 다른 시그널들이 있네요. 이 프로그램이 자기 process ID를 출력하도록 만든거 기억나시나요? 이 다음 파트를 좀 더 쉽게 하기 위해 만들었던 거였어요.
그럼 이제 SIGTERM이라는 시그널을 보내는 걸 해봅시다.
SIGTERM은 해당 프로세스로 가서 그 프로세스 스스로를 종료시키라고 강하게 명령합니다.
그런데 제가 아직 SIGINT 이외의 시그널들을 보내는 법은 설명하지 않았죠. 바로 kill 명령어를 사용하면 시그널을 보낼 수 있어요.
좀 폭력적인 느낌이 들기도하는 별로인 이름이죠. 그렇지만 꼭 저 말 뜻 그대로 되는 하는 것은 아니에요. 네 가끔은 프로세스들을 죽이기도 하지만 가끔은 그렇지 않다네요...
간단히 말하면, 그냥 메시지를 보내는 거에요.
프로그램 내부에서(코드 중에서) kill()을 호출할 수도 있지만 이런 식으로 명령어로도 실행할 수 있답니다.
$ kill -TERM 28272
내가 보내고 싶은 시그널과 프로세스 ID를 같이 입력해주면?
와 이걸 보세요. 프로세스를 죽이는 데 성공했습니다.
그렇지만 SIGTERM도 같이 처리하려는 제 건방진 자아는 아무도 막을 수 없죠. 이렇게 signal 함수를 통해 SIGTERM에 대한 핸들러를 추가해줍니다.
#include <unistd.h>
#include <signal.h>
#include <stdlib.h>
void handler(int num)
{
write(STDOUT_FILENO, "I won't die\\n", 13);
}
int main()
{
signal(SIGINT, handler);
signal(SIGTERM, handler);
while (1)
{
printf("Wasting your cycles. %d\\n", getpid());
sleep(1);
}
}
그럼 이렇게 나오네요.
$ kill -TERM 28297
kill -TERM 명령어를 입력해봤자 아직 너무 잘 살아있는 상태에요. 그렇지만 운 좋게도 우리에겐 아직 sigkill이라는 방법이 남았습니다. 아마 가끔씩 사람들이 kil -9 이런 이야기를 하는 걸 들어본 적 있을 거에요. 그거랑 같은 방법입니다. 한번 해봅시다!
하하 이제 저 프로세스에게 따끔한 맛을 보여줍시다. 하하 정의의 무게가 느껴지시나요 여러분.
$ kill -KILL 28297
그럼 계속해서 SIGKILL도 핸들러가 관리하도록 해볼까요.
#include <unistd.h>
#include <signal.h>
#include <stdlib.h>
void handler(int num)
{
write(STDOUT_FILENO, "I won't die\\n", 13);
}
int main()
{
signal(SIGINT, handler);
signal(SIGTERM, handler);
signal(SIGKILL, handler);
while (1)
{
printf("Wasting your cycles. %d\\n", getpid());
sleep(1);
}
}
그렇지만 운 좋게도, 그건 먹히지 않을거에요. SIGKILL은 저런 방식으로 처리할 수 없습니다. SIGKILL은 간단히 말해 요청(request)가 아닌 명령(order)이기 때문이에요.
외부 명령어 창에서 KILL -9 28450을 입력해주니 프로세스가 kill 된 것을 볼 수 있습니다.
$ kill -9 28450
시그널의 다양한 역할
시그널은 단지 프로세스를 죽이는(kill) 것 뿐만 아니라, 더 많은 일들을 할 수 있습니다.
예를 들자면, 프로세스를 멈출 수 있고요 (stop).
$ kill -STOP 28486
멈췄던 프로세스를 계속 이어지도록 할 수도 있습니다. (continue)
$ kill -CONT 28486
또, 통신을 목적으로 사용자 정의 시그널 (SIGUSER1, SIGUSER2)를 사용할 수도 있습니다. 그것들은 당신이 정의하고자 하는 대로 정의됩니다.
그리고 정말 특이하게도, 프로그램은 segfault가 되었을 때조차 시그널을 받습니다. 진짜에요.
그럼 이걸 빨리 확인 해보도록 할까요.
#include <unistd.h>
#include <signal.h>
#include <stdlib.h>
void handler(int num)
{
write(STDOUT_FILENO, "I won't die\\n", 13);
}
int main()
{
int *p = NULL;
signal(SIGINT, handler);
signal(SIGTERM, handler);
signal(SIGKILL, handler);
*p = 45 // segfault를 일으킨다
while (1)
{
printf("Wasting your cycles. %d\\n", getpid());
sleep(1);
}
}
위 코드를 실행하면 세그폴트를 일으킬 거에요. 그리고 실제로 확인해봐도 그렇네요.
이때 시그널에서 Segfault를 처리해주었지만 상황을 해결하지는 못했습니다. 잘못된 포인터 문제를 해결하지 못했어요. 시그널을 처리해줘도 잘못된 메모리 접근을 계속할 뿐입니다.
#include <unistd.h>
#include <signal.h>
#include <stdlib.h>
void handler(int num)
{
write(STDOUT_FILENO, "I won't die\\n", 13);
}
void seghandler(int num)
{
write(STDOUT_FILENO, "Seg Fault!\\n", 10);
}
int main()
{
int *p = NULL;
signal(SIGINT, handler);
signal(SIGTERM, handler);
signal(SIGKILL, handler);
*p = 45 // segfault를 일으킨다
while (1)
{
printf("Wasting your cycles. %d\\n", getpid());
sleep(1);
}
}
$ killall a.out
결국 해당 명령어를 통해 프로세스를 종료해주었습니다.
이건 “어떻게 시그널이 작동하며, 세그폴트에서도 보내지는 게 해당 시그널이라는 걸 확인하기 위해서” 보여준 것일 뿐이니, 이런 방식으로 세그폴트를 해결하지는 마세요. 그냥 포인터를 다시 점검해보는게 훨씬 바람직합니다.
시그널의 필요성
오케이 알았어요. 근데 왜 대체 이런 게 필요하죠?
- 프로세스를 kill하는 것 외에도, 사용자 정의 시그널들을 사용하여 어떤 일이 일어났는 지 프로세스에게 알려줄 수 있기 때문입니다.“야 내가 너한테 해줘야하는 그 일 지금 끝냈어.”
- 같이 작동하는 2개의 프로세스가 있을 때, 하나의 프로세스가 작업을 끝내고 나서 다른 프로세스에게 이렇게 시그널을 보낼 수 있어요.
- 다른 흔한 케이스 중 하나는, 어떤 안좋은 일이 생겼을 때 시그널을 처리하도록 하는 것입니다.
- kill 되었을 때나, 누군가 ctrl + C를 눌렀을 때나, kill -9 같은 어떤 경우든 간 상관없습니다. 당신은 프로그램이 종료되기 전에 파일을 닫고 메모리를 해제하는 등의 처리를 해주고 싶을 것입니다. 프로그램이 실제로 종료되기 전에 일관적인 상태로 만드는 작업이요. 이런 걸 항상 사용하지는 않겠지만 일단 그렇다고 치자고요. 가끔 ctrl + C 실행 시 취해지는 행동들이 충분하지 않을 수 있습니다. 가끔씩은 아주 장렬히 실패해야할 수도 있죠.
Sigaction 함수
마지막으로 몇 가지만 더 말해볼게요.
저는 예시에서 signal() 함수만 사용해서 설명했습니다. 왜냐면 그게 제일 간단하기 때문이에요. 그렇지만 signal의 기능들을 포함하는 sigaction이라는 더 새로운 함수가 존재합니다. 이건 더 많은 옵션과 정보를 제공해주며, 당신이 시그널들을 관리할 때 프로세스에 대한 더 많은 제어를 가능하게 해줍니다.
그러니 sigaction을 사용한다면 당신의 코드는 좀 더 이식성이 좋아집니다. 그래서 더 추천되는 방식인 거에요.
(man sigaction을 터미널에 입력해 해당 함수의 메뉴얼을 확인할 수 있음)
이건 제가 sigaction을 사용했을 경우의 원본 코드입니다.
#include <unistd.h>
#include <signal.h>
#include <stdlib.h>
void handler(int num)
{
write(STDOUT_FILENO, "I won't die\\n", 13);
}
void seghandler(int num)
{
write(STDOUT_FILENO, "Seg Fault!\\n", 10);
}
int main()
{
struct sigaction sa;
sa.sa_handler = handler;
sigaction(SIGINT, &sa, NULL);
sigaction(SIGTERM, &sa, NULL);
while (1)
{
printf("Wasting your cycles. %d\\n", getpid());
sleep(1);
}
}
그나저나, 이쯤되면 여러분은 제가 printf() 대신에 write() 함수를 사용했다는 사실을 눈치 채셨을 거에요. 이거에는 따로 이유가 있습니다.
핸들러들은 비동기적으로 실행되기 때문에, 그것들은 당신의 코드를 어떤 시점에서나 방해할 수 있습니다. 그러니 여러분들은 sigal handler 안에서 어느 코드나 실행할 수 있는 건 아니에요.
standard library에서 몇몇 함수들은 sync signal safe라고 나열되어있습니다. 이건 그 함수들을 signal handler 안에서 실행하기에 안전하다는 뜻입니다. 다른 코드들과 함께 비동기적으로 실행할 수 있다는 것이죠. 그 항목에는 여러가지 함수들이 존재하는데 printf는 그 항목에 존재하지 않네요. 그래도 write()는 존재합니다. 그래서 이걸 사용한거에요. 또 그게 실제로 printf가 사용하는 것이기도 하니까요. 더 투박하긴 하겠지만 안전하잖아요.
그렇지만 signal handler 함수 내에서 printf를 사용했을 때 그게 항상 충돌한다는 뜻은 아닙니다. 그냥 그게 충돌할 가능성이 있고, 항상 안전함을 보장하지는 않는다는 뜻이죠.
그래도 명백한 이유도 없이 랜덤한 시점에 충돌나는 그런 프로그램은 아무도 좋아하지 않을거에요.
지금까지 signal에 대해 설명했습니다.
여러분들은 이걸 모든 프로젝트에 사용하지는 않을 것이고 분명 매일 사용하지도 않을 거에요. 그래도 이젠 signal이 필요한 경우 그걸 사용할 수 있을겁니다.
이 영상이 여러분들의 미래 프로젝트에 도움이 되었기를 바랍니다.
'IT > 튜토리얼 및 가이드' 카테고리의 다른 글
서비스 디자인 (기술 / 기획) 가이드 배포 (2) | 2025.05.02 |
---|---|
[개인적인 팁] 영어 논문 쉽게 읽는 법 (5) | 2022.03.01 |
[입문자 튜토리얼] - C언어 소스 코드 파일 분리 2편 (feat. 헤더파일) (0) | 2021.12.19 |
[입문자 튜토리얼] - C언어 소스 코드 파일 분리 1편 (feat. 코드를 깔끔하게) (0) | 2021.12.19 |
[Github] 깃허브 왕초보 사용법 - 기본편3 (0) | 2021.12.19 |
[입문자 튜토리얼] - C언어 소스 코드 파일 분리 2편 (feat. 헤더파일)
지난 시간에는...
지난 시간에는 어떤 게 알아보기 어려운 코드인지, 그 문제점을 알아보았다. 또 그걸 해결하기 위한 "코드 깔끔하게 짜는 법"을 알아보았다.
"한 파일안에 코드 줄 수가 너무 많다고요? 그러면 나더러 어떻게 하란거에요. 뭐 다른 방법이 있나요?"
오늘은 이 질문에 대한 답변을 하는 시간을 갖도록 한다.
자, 저번에서 그 한 파일에 있던 코드들을 1. 배열을 이용한 함수, 2. 연결리스트를 이용한 함수, 3. 메인함수와 그 외의 함수라는 총 3가지의 분류로 나누어, 각각을 따로 파일에 담았다하자. 그럼에도 아직 문제가 남아있다.
"파일을 여러 개로 나눠요? 그러면 main.c 파일에서 어떻게 다른 파일의 함수를 읽어오나요? 게다가 컴파일은 어떻게 해요?"
사용자 정의 헤더파일
우선, 코드를 길게짜는 사람이라면, 함수의 원형을 main문 위쪽에 선언해주는 방법을 아마 알 것이다.
#include <stdio.h>
void hello(); // 반환값이 없는 hello 함수 원형 선언
int main()
{
hello(); // hello 함수 호출
return 0;
}
void hello() // 반환값이 없는 hello 함수 정의
{
printf("Hello, world!\n"); // Hello, world! 출력
}
main문에서 위쪽에 함수를 선언해주면, 어느 위치에 함수가 오더라도 메인에서 이 함수를 읽어들여 프로그램을 돌릴 수 있다.
파일을 여러개로 나눌 경우에도 마찬가지다. 함수 파일마다 내 전체함수들의 프로토타입과 사용되는 구조체를 전부 상단에 넣어주면 될 것 같다. 근데 그러면 깔끔하지가 않다... 방법이 없을까?
이 경우 쓰게 되는 게 사용자 정의 헤더파일이다.
C언어 기초 - 헤더파일 만드는 방법과 사용하는 방법
본문 목표 프로젝트가 복잡하고 규모가 클 수록, 코드가 많이 길어지게 된다. 코드가 길어지면 가독성이 떨어지게 된다. 가독성이 떨어지면, 코드 개발이 복잡해지고, 오류가 발생할 확률이 높
diyver.tistory.com
위 블로그를 참고하면 좋다.
헤더 파일 예시
#ifndef _EXAMPLE_H_
#define _EXAMPLE_H_
/*
* include할 헤더 목록 적기
*/
typedef struct 구조체 명
{
...
} 구조체;
int 함수1();
int 함수2();
void 함수3();
void 함수4();
#endif
다음과 같은 방식으로 헤더파일에 모든 include할 헤더목록, 구조체명, 내가 사용한 모든 함수의 프로토타입을 적어준다.
해당 파일의 이름을 example.h라고 저장했다고 해보자.
그럼 내가 가진 모든 C 소스 파일의 위쪽에 모두 #include "example.h" 라는 선언을 한줄만 추가해주면 된다.
그럼 모든 파일의 상단에 내가 사용할 구조체&함수들을 전부 선언해놓은 것과 동일한 효과가 난다!
여기에서 #include <example.h>가 아닌, "example.h"로 따옴표를 사용해줘야만 한다. 사용자가 정의한 이런 헤더파일은 원칙적으로 따옴표를 써야하기 때문이다.
그럼 이제, 어떻게 main 파일에서 다른 파일의 함수들을 읽어오냐는 질문에 대한 답변은 끝이 났다.
그러면 이제 남은 질문은?
그렇게 여러 개로 나눠진 파일들을 어떻게 묶어서 컴파일 해요?
이거다.
다음 포스팅에서 이어서 이것을 설명하도록 하겠다.
다음 포스팅에서는 컴파일의 대략적인 과정과, 컴파일러, 컴파일 명령어 그리고 makefile에 대해 배운다.
'IT > 튜토리얼 및 가이드' 카테고리의 다른 글
[개인적인 팁] 영어 논문 쉽게 읽는 법 (5) | 2022.03.01 |
---|---|
[번역] C에서 시그널을 보내고 처리하는 방법 (kill, signal, sigaction) (0) | 2022.01.06 |
[입문자 튜토리얼] - C언어 소스 코드 파일 분리 1편 (feat. 코드를 깔끔하게) (0) | 2021.12.19 |
[Github] 깃허브 왕초보 사용법 - 기본편3 (0) | 2021.12.19 |
[Github] 깃허브 왕초보 사용법 - 기본편2 (0) | 2021.12.19 |
[입문자 튜토리얼] - C언어 소스 코드 파일 분리 1편 (feat. 코드를 깔끔하게)
서론
사실 이 포스팅을 쓰게 된 것에는 깊은 사연이 있다... 얼마 전 지인의 팀플 코드를 같이 디버깅해본 적이 있다. 이때 나는 약간 충격을 받았다. 코드가 어려워서? 그것도 조금은 있겠지만.... 제일 큰 이유는 한개의 소스 파일에 1200줄 이상 들어있는 코드와...기능이 각기 다른 수십 개의 함수가 main.c라는 한 개의 파일에 뒤섞여서 코드의 흐름을 알아볼 수 없었기 때문이다.
특히나 나는 그 코드를 같이 짠 것도 아니고 처음 읽는 입장이니까 더욱 코드를 파악하기 어려웠다. 코드 파악에만 몇 시간이 걸렸다.
사실 예전의 나는 오히려 그것보다 훨씬 코드를 정말 어지럽게 짜고 함수를 나누지 않았기 때문에... 내가 절대 뭐라할 수 없는 일인 것 안다. 그렇지만 코드를 깔끔하게 짜는 법은 절대 학교에서 누군가 가르쳐주지 않더라...
따라서 내 소박한 지식을 나눠보고자 포스팅을 쓴다.
아직도 난 많이 부족하겠지만, 그래도 내가 거쳐온 과정을 통해 최소한 코드를 분류하고, 정리하고, 파일과 함수를 나누는 법은 잘 숙지하게 되었다고 생각한다. (실제로 내가 활동 중인 42서울 코드 규정에는 함수 개당 길이 제한, 변수 개수 제한 등등 까지 있다)
더보기
코드 문제점 파악
해당 과제는, 한 txt 파일을 읽어와서 그 안의 데이터베이스를 검색-삭제-추가하는 그런 프로젝트였다. 여기에서 모든 기능을 각각 배열과 연결리스트로 둘다 구현해야하는 그런 것이었다.
일단 문제상황이 어떤 느낌이었는 지 대략 의사코드로 함수를 써보겠다..
#include <헤더>
#include ...
..
배열_검색_3()
링크드리스트_데이터추가2()
링크드리스트_출력()
배열에_데이터 추가2()
배열_검색_2()
배열_데이터추가1()
링크드리스트_검색2()
링크드리스트 어쩌고3()
배열검색어쩌고1()
링크드리스트 어쩌고2()
배열_출력()
.... 등등 수십개의 함수
int main()
{
... (100줄이 훨씬 넘는 메인문)
return (0)
}
이 코드의 문제점은 대략 이렇다.
- 배열과 관련된 함수들은 그들끼리, 연결리스트 관련 함수는 그것들끼리 모여있어야 보기 편한데, 여기엔 배열이나 연결리스트 관련 함수가 순서 상관없이 마구 뒤섞여있다.
- 배열_검색() 관련 함수는 검색 함수1, 2, 3끼리 위아래 붙어서 모여있어야 보기 편한데, 관련 함수들이 위 아래 중간 할 것 없이 수십개의 함수 사이에 숨어서 무차별적으로 분포한다.
- 배열을 검색하는 기능을 가진 함수들을 차례차례 찾아서 살펴보는 것 자체가 미로찾기 수준이다. 하나를 찾으면 다음 함수를 찾으려고 코드를 샅샅이 뒤지는 과정을 반복한다.
- 이때 코드 흐름을 놓치기 쉽다. 그러면 처음부터 다시 읽기 시작해야한다....(오마이갓)
- 배열을 검색하는 기능을 가진 함수들을 차례차례 찾아서 살펴보는 것 자체가 미로찾기 수준이다. 하나를 찾으면 다음 함수를 찾으려고 코드를 샅샅이 뒤지는 과정을 반복한다.
- 일단 main이 너무 밑바닥에 존재해서 너무 읽기가 힘들다. 게다가 설사가상으로 메인 함수까지 굉장히 길었다.
- main 함수조차 너무 길고, 흐름이 분류되있지 않아서 파악이 힘들었다.
이러면 어떤 문제가 생기는 가?
- 코드를 짠 사람이 아니라면 그 누구라도 코드를 파악하기 힘들다.
- 코드에 문제가 생겼을 때 어느 부분인지 찾는 게 힘들다.
- 심지어 문제가 난 부분을 알더라도 위쪽으로 한참 이동해서 해당 함수를 살피다가~ 아래쪽 끝까지 메인으로 내려와 메인을 고쳐 다시 실행해보고~ 이러는 데 불필요한 시간이 엄청나게 소요된다.
- 메인문을 봐도 코드의 흐름 자체가 안보인다.
좋은 프로그래머의 요건
실제 프로그래머는 혼자서 일을 하지 않는다. 사람이기 때문이다. 작은 프로젝트 정도는 혼자 할 수 있겠다. 그런데 회사에서 그리고 사회에서 요구하는 건 큰 프로젝트다. 그러니 필연적으로 누군가와 일을 분담해서 하게 될 수 밖에 없다. 심지어 프리랜서라고 해도 그 일감은 회사나 업체의 큰 일을 나눠받아서 하는 것이다.
이때 코드를 남이 파악하기 어렵게 짜버린다면 어떻게 되겠는가. 당신의 코드를 받은 뒤 프로젝트의 나머지 부분을 이어서 만들어야하는 동료가 많이 곤란해진다.
코드를 어렵게 짠다는 것은 결코 바람직하지 않다. 실력이 좋은 프로그래머는 이해하기 쉬운 깔끔하고 간단한 코드를 짠다. 항상 남이 읽을 경우를 염두에 두고 코드를 깔끔하게 만드는 연습을 해야한다.
이 문제 상황을 통해 어떻게 코드를 구성하면 보기 좋고 깔끔한 지 구상해 볼 수 있다.
그 방법은 다음과 같다.
코드 깔끔하게 구성하는 법
위의 문제상황에 있는 문제점들을 정확히 반대로 뒤짚으면 그 해결책이 된다.
바닥에 쌓여있는 책들을 도서관 책장에 정리한다고 생각하며 이 방법들을 읽어보자.
- 배열-연결리스트 관련 함수들이 순서 상관 없이 마구 뒤섞여 있다.
- 해결책 : 배열관련 함수는 배열 관련 함수끼리, 연결리스트 관련 함수는 연결리스트 관련 함수끼리 순서를 묶어서 정리한다.
- 배열_검색() 함수들이 코드 여기저기 멀찍멀찍 아무데나 분포한다.
- 해결책: 비슷한/같은 기능을 하는 함수들끼리 위아래로 붙어있게끔 모아서 정리한다.
- 메인 문이 너무 길다 :
- 해결책 : main을 깔끔하게 짜려면 다음 방법을 써야한다. 흐름을 명시적으로 나타내는 함수명을 가진 함수들로 기능을 나눠 코드를 나눠담는다. main의 코드 줄 수는 무조건 짧게 유지하는게 좋다. 무조건이다.
함수는 너무 길지 않게 만드는 것이 바람직하다. 안된다면 그 안의 자잘한 기능들/조건문 같은 것들을 또다른 작은 함수로 빼서 최적화시켜라.
파일 나누기
자 이제 코드를 분류 별로 기능별로 순서를 묶어 정리했다고 해보자. 그런데 아직도 한 파일에 코드가 너~~~~무 많이 들어있다...
만약 회사일으로 프로그래밍을 한다고 가정해보자.
당신은 몇 천줄 몇 만줄의 소스코드를 짯다. 그리고 한개의 소스 파일에 그 코드를 전부 넣어두었다. 그런데 이 몇 만줄이나 되는 코드에서 문제가 난다. 그러면 심지어 간단한 문제라 할지라도, 문제를 찾기가 정말정말 오래 걸릴 것이다.
코드를 위로 갔다 아래로 갔다 메인과 위쪽 함수들을 번갈아 위아래로 쉐킷쉐킷하며 읽는다. 그러면 간단한 문제 하나 찾지 못하고, 코드와 함수간에 스크롤로 이동하는데만 99%의 시간을 뺏기게 될 것이다.
"그러면 나더러 어떻게 하란거에요. 뭐 다른 방법이 있나요?"
있다!
바로 파일을 여러 개로 나누는 것이다.
저 팀프로젝트 코드의 경우에, 연결리스트 관련 함수는 use_Linkedlist.c, 배열 관련 함수는 use_Array.c 라는 파일에 나눠담는다고 해보자. 그리고 그 이외의 함수와 메인문은 main.c에 담는다.
이런 경우, 함수를 파악하기 엄청 수월해진다.
"파일을 여러 개로 나눠요? 그러면 main.c 파일에서 어떻게 다른 파일의 함수를 읽어오나요? 게다가 컴파일은 어떻게 해요?"
바로 사용자 헤더파일을 만들어 모든 파일 상단에 선언해놓는 것이다. 그리고 그 여러개의 파일들을 함꺼번에 컴파일하려면 명령어를 사용하거나, makefile을 사용하면 된다.
이대로는 너무 포스팅이 길어질 것 같으니 다음 편에 이어서 파일 나누기 (헤더파일 만들기, Makefile이 무엇인지)를 이어서 설명하도록 하겠다.
'IT > 튜토리얼 및 가이드' 카테고리의 다른 글
[번역] C에서 시그널을 보내고 처리하는 방법 (kill, signal, sigaction) (0) | 2022.01.06 |
---|---|
[입문자 튜토리얼] - C언어 소스 코드 파일 분리 2편 (feat. 헤더파일) (0) | 2021.12.19 |
[Github] 깃허브 왕초보 사용법 - 기본편3 (0) | 2021.12.19 |
[Github] 깃허브 왕초보 사용법 - 기본편2 (0) | 2021.12.19 |
[Github] 깃허브 왕초보 사용법 - 기본편1 (1) | 2021.12.19 |