<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>_chamomile.log</title>
        <link>https://velog.io/</link>
        <description></description>
        <lastBuildDate>Fri, 28 Mar 2025 00:56:43 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <image>
            <title>_chamomile.log</title>
            <url>https://velog.velcdn.com/images/_chamomile/profile/2c3d970d-11c1-4a75-9f18-70d982051c3d/social_profile.png</url>
            <link>https://velog.io/</link>
        </image>
        <copyright>Copyright (C) 2019. _chamomile.log. All rights reserved.</copyright>
        <atom:link href="https://v2.velog.io/rss/_chamomile" rel="self" type="application/rss+xml"/>
        <item>
            <title><![CDATA[명세/구현 기반 테스트에 대하여]]></title>
            <link>https://velog.io/@_chamomile/Specification-Structure-Based-Test</link>
            <guid>https://velog.io/@_chamomile/Specification-Structure-Based-Test</guid>
            <pubDate>Fri, 28 Mar 2025 00:56:43 GMT</pubDate>
            <description><![CDATA[<h1 id="테스트를-왜-하는가">테스트를 왜 하는가?</h1>
<p>소프트웨어 테스팅의 주 목적은 소프트웨어의 <strong>작동 여부</strong>(의도에 맞는) 및 <strong>품질 개선</strong>이다.
<img src="https://velog.velcdn.com/images/_chamomile/post/43efcdd8-4b1f-42d5-a8fb-1665195957bd/image.png" alt="">
테스트를 거치지 않고 출시된 소프트웨어는 사용자의 경험을 망칠 수 있다.</p>
<h1 id="어떻게-하는가">어떻게 하는가?</h1>
<p>소프트웨어 테스트는 다양한 분류를 가진다.
시각에 따른 테스트, 사용 목적에 따른 테스트
그리고 소프트웨어의 실행 여부에 따른 정적 테스트와 <strong>동적 테스트</strong>가 있다.
이번 글에서는 동적 테스트를 한번 파헤쳐 보자.</p>
<h1 id="동적-테스트">동적 테스트</h1>
<p>동적 테스트란, <strong>테스트 데이터를 기반</strong>으로 실제 프로그램을 실행하며 오류를 찾는다.
또한, 테스트 정보를 얻는 문서 종류에 따라 명세/구현 기반 테스트로 세분화된다.</p>
<h2 id="명세-기반-테스트">명세 기반 테스트</h2>
<p>명세 기반 테스트는 <strong>&#39;블랙박스 테스트&#39;</strong> 라고도 불린다.
소프트웨어 내부의 구조는 모르는 채로, 입력 값에 대한 예상 출력 값을 정해둔다. 
그리고 예상 출력 결과와 실제 출력 값의 동일함이 해당 테스트의 결과가 된다.</p>
<p><img src="https://velog.velcdn.com/images/_chamomile/post/4279845a-cb2f-4b2f-bf69-06106f7b0cb8/image.png" alt="">
사용자는 치킨의 재료를 넣어 맛있는 치킨이 나오길 원했고, 사용자의 요구는 충족되었다.
극단적인 예시지만, 입력값에 대한 예상 출력 값과 그 결과가 동일하다.
이 경우 성공이라고 할 수 있다.
명세 기반 테스트의 기법을 알아보자.</p>
<h3 id="문법-기반syntax-driven">문법 기반(Syntax Driven)</h3>
<p>문법 기반 테스트라는 말 그대로, 문법을 정한 후 적합/부적합 여부를 예측하여 테스트한다.
<img src="https://velog.velcdn.com/images/_chamomile/post/e2949f43-2887-4600-82cd-a0ea1ea3cd74/image.png" alt="">
 <img src="https://velog.velcdn.com/images/_chamomile/post/3a611965-e6fd-4ddb-b311-a95b27cfc942/image.png" alt=""></p>
<h3 id="동등-분할equivalence-partitioning">동등 분할(Equivalence Partitioning)</h3>
<p>동등 분할 기법은 각 영역의 값을 그룹으로 나눠 임의의 값을 그 그룹의 테스트 결과로 본다.
<img src="https://velog.velcdn.com/images/_chamomile/post/f8faf158-96d6-4009-9000-822888c95fbf/image.png" alt="">
<img src="https://velog.velcdn.com/images/_chamomile/post/a60cbd23-a132-4997-9cdb-199559c606a0/image.png" alt=""></p>
<h3 id="경계-값-분석boundary-value-analysis">경계 값 분석(Boundary Value Analysis)</h3>
<p>동등 분할 기법과 비슷하지만, 입력 값의 경계를 이용하여 기대 결과와 함께 테스트한다.
최소, 중간, 최대의 값과 그 값의 +-1을 보통 테스트한다.
<img src="https://velog.velcdn.com/images/_chamomile/post/58c6d92a-656f-4018-875e-1bfedd58fb31/image.png" alt=""></p>
<h3 id="원인-결과-그래프cause-effect-graph">원인-결과 그래프(cause-effect graph)</h3>
<p>입력 환경의 복잡성을 고려하기 위한 테스트 기법, 원인 결과 그래프를 만들어 위 기법들의 단점을 보완한다.
원인에 해당하는 입력 조건과 그 원인으로부터 발생하는 출력 결과를 가지고 만든다.</p>
<ol>
<li>프로그램을 적합한 크기로 분할</li>
</ol>
<ul>
<li>규모가 큰 프로그램을 분할하여 원인-결과 그래프를 작성할 만한 크기로 분할한다.</li>
</ul>
<ol start="2">
<li>원인과 결과를 찾는다.</li>
</ol>
<ul>
<li>명세서에서 원인과 결과를 찾아 일련번호와 같은 식별자를 각각 부여한다. 여기서 원인은 하나의 입력 조건이고, 결과는 출력 조건이다.</li>
</ul>
<ol start="3">
<li>원인-결과 그래프를 작성한다</li>
</ol>
<ul>
<li>프로그램 명세가 의미하는 내용을 분석하여, 이에 알맞은 원인과 결과를 연결하는 논리 그래프를 작성한다. 그래프를 그리는 과정에서 그래프의 복잡성을 줄이기 위해 중간 노드를 사용할 수 있다.</li>
</ul>
<p>사용되는 기호
<img src="https://velog.velcdn.com/images/_chamomile/post/99afbbf4-0b8d-44ab-b036-d162c44292c4/image.png" alt=""></p>
<p>제한 조건 기호
<img src="https://velog.velcdn.com/images/_chamomile/post/38a9d38e-21e4-4a2e-8d17-31bf5f74f105/image.png" alt=""></p>
<p>원인-결과 그래프를 바탕으로, 결과로부터 그 결과가 생기는 조건을 추적하여 그 사항을 기입한 의사결정 테이블로 변환한다. 의사결정 테이블(decision table)을 사용한 기법에서는 먼저 입력할 대상의 목록을 정한 후 입력 항목에 대해 가능한 모든 조합을 만든다. 
입력 항목이 총점과 리포트인 경우에 가능한 조합이다.
<img src="https://velog.velcdn.com/images/_chamomile/post/d509b9ba-7b60-439e-b1b5-1b17c4fa1348/image.png" alt="">
그리고 조합한 8개 항목에 대한 다음과 같은 예상 결과를 [표 8-11]처럼 A+, A0, B+, B0, C+, C0, D, F로 나열한 후 예상되는 출력 값을 참(True, T로 표기)과 거짓(False, F로 표기)으로 표기한다.</p>
<p>• 1 : 90점 이상(T), 리포트 제출(T) → A+
• 2 : 90점 이상(T), 리포트 미제출(F) → A0
• 3 : 80점 이상(T), 리포트 제출(T) → B+
• 4 : 80점 이상(T), 리포트 미제출(F) → B0
• 5 : 70점 이상(T), 리포트 제출(T) → C+
• 6 : 70점 이상(T), 리포트 미제출(F) → C0
• 7 : 70점 미만(T), 리포트 제출(T) → D
• 8 : 70점 미만(T), 리포트 미제출(F) → F</p>
<p>작성된 의사결정 테이블을 기반으로 테스트 케이스를 도출한다. 
예를 들어, 테스트 케이스 3번째의 테스트 데이터(총점 86점, 리포트 제출)를 생성했다면 결과 값이 B+가 되어야 한다.</p>
<br>

<h2 id="구현-기반-테스트">구현 기반 테스트</h2>
<p>구현 기반 테스트는 <strong>&#39;화이트박스 테스트&#39;</strong> 라고도 불린다.
소프트웨어 내부의 변수 혹은 서브루틴 등의 오류를 찾기 위해 프로그램 코드 내부 구조를 테스트 설계의 기반으로 사용한다.</p>
<p><img src="https://velog.velcdn.com/images/_chamomile/post/5059f0a7-e7b7-4d8e-9103-632b3f14243e/image.png" alt="">
하지만 소프트웨어 내부에 있는 모든 소스 코드를 검사하는 것은 많은 자원을 요구한다.
그렇기에 코드의 일부 경로를 테스트해야 하는데, 이를 위한 기준이 필요하다.
<del>테스트 데이터 생성 기준, 테스트 데이터 적합성 기준을 알아보자</del></p>
<h3 id="문장-검증-기준statement-coverage">문장 검증 기준(Statement Coverage)</h3>
<p>프로그램 내의 모든 문장이 최소한 한 번은 실행될 수 있는 테스트 데이터를 갖는 테스트 케이스를 선정하는 것이다. 이 기준은 다음과 같은 과정으로 수행한다.</p>
<ol>
<li>원시 코드를 제어 흐름 그래프 형태로 표현</li>
<li>가능한 모든 경로를 구한다.</li>
<li>문장 검증 기준을 만족하는 경로를 구한다.</li>
<li>선택한 경로에 해당하는 테스트 케이스를 가지고 실행한다.</li>
</ol>
<h3 id="분기-검증-기준branch-coverage">분기 검증 기준(Branch Coverage)</h3>
<p>분기 검증 기준은 결정 검증 기준이라고도 하며, 문장 검증 기준의 문제점을 해결할 수 있다. 테스트 케이스를 선정하는 기준은 원시 코드에 존재하는 조건문에 대해 T가 되는 경우와 F가 되는 경우가 최소한 한 번은 실행되는 입력 데이터를 테스트 케이스로 사용하는 것이다.</p>
<ol>
<li><p>원시 코드를 제어 흐름 구조의 그래프 형태로 바꾸어 표현한다.</p>
</li>
<li><p>가능한 모든 경로를 구한다
가능한 모든 경로를 나타내고, 분기 검증 기준의 만족 여부를 나타낸다.</p>
</li>
<li><p>모든 경로 중 분기 검증 기준을 만족하는 경로를 선택한다
하지만 모든 분기를 지나치는 것이 모든 조건을 검사하는 것은 아니다.
이와 같은 문제를 해결하는 방법은 조건문 내의 개별 조건식에 대하여 각각 T와 F인 경우를 최소한 한 번씩 수행할 수 있는 테스트 케이스를 선정하는 것이다.</p>
</li>
</ol>
<h3 id="조건-검증-기준condition-coverage">조건 검증 기준(Condition Coverage)</h3>
<p>조건문이 OR인 경우, 첫 조건만 검사하고 뒤의 조건은 넘기게 된다. 뒤의 조건에 오류가 있음을 파악하기 위해 모든 조건을 검사하는 테스트 케이스를 작성하는 방법이다.</p>
<h3 id="분기조건-검증-기준branchcondition-coverage">분기/조건 검증 기준(Branch/Condition Coverage)</h3>
<p>개별 조건식과 전체 조건식을 모두 만족하는 테스트 케이스. 하지만 개별 조건식이 and인경우 마스크 현상으로 뒤의 조건이 씹힌다. 그걸 해결하는 기법이 아래.</p>
<h3 id="다중-조건-검증-기준multiple-condition-coverage">다중 조건 검증 기준(Multiple Condition Coverage)</h3>
<p>각각의 개별 조건문도 모두 검증하는 기법, and의 경우 둘 다 True, T F, F T의 경우를 준비하여 테스트
or의 경우 TT,FT,FF,TF를 모두 준비하여 테스트하는 것.</p>
<h3 id="기본-경로-테스트basic-path-test">기본 경로 테스트(Basic Path Test)</h3>
<p>원시 코드의 독립적인 경로가 최소 한번은 실행되는 테스트 케이스를 찾아 수행. 코드의 경로를 흐름도로 만들고 모든 경로를 실행하는 케이스를 만들어 테스트한다. 논리적인 경로는 갈라지며 이제 이게 순환 복잡도를 나타낸다. 순환 복잡도에 따른 테스트 케이스를 만들어 테스트하면 끝
순환 복잡도가 높을수록 테스트케이스가 많이 필요하고 복잡한 프로그램이라고 할 수 있다.</p>
<h1 id="마치며">마치며</h1>
<p>동적 테스트에 대한 두 가지 분류와 그 안의 다양한 기법들을 알아볼 수 있는 시간이였다.
소프트웨어의 버그는 유저에게 좋지 않은 경험을 제공한다는 생각을 가진 나에게는 이러한 기법의 필요성을 충분히 느끼게 할 수 있었다.
아무런 버그 없는 게임은 존재하지 않는다는 것을 명심하자.</p>
<blockquote>
<p>출처 : [네이버 지식백과] 구현 기반 테스트 (쉽게 배우는 소프트웨어 공학, 2015. 11. 30., 김치수)</p>
</blockquote>
]]></description>
        </item>
        <item>
            <title><![CDATA[[코드트리 조별과제] 문제를 풀어보자.]]></title>
            <link>https://velog.io/@_chamomile/codetree-1</link>
            <guid>https://velog.io/@_chamomile/codetree-1</guid>
            <pubDate>Mon, 05 Aug 2024 07:12:23 GMT</pubDate>
            <description><![CDATA[<p>[테스트] 알파벳 지우기 - 코드트리
<a href="https://www.codetree.ai/missions/4/problems/remove-alphabet/description">https://www.codetree.ai/missions/4/problems/remove-alphabet/description</a></p>
<pre><code class="language-cpp">#include &lt;iostream&gt;
#include &lt;string&gt;
using namespace std;

int main() {
    string string1;
    string string2;
    cin &gt;&gt; string1;
    cin &gt;&gt; string2;

    int sum = 0;

    string num;
    for (int i = 0; i &lt; string1.size(); i++)
    {
        if (48 &lt;= string1[i] &amp;&amp; string1[i] &lt;= 57)
        {
            num += string1[i];
        }
    }
    sum += stoi(num);
    num = &quot;&quot;;
    for (int i = 0; i &lt; string2.size(); i++)
    {
        if (48 &lt;= string2[i] &amp;&amp; string2[i] &lt;= 57)
        {
            num += string2[i];
        }
    }
    sum += stoi(num);

    cout &lt;&lt; sum;
    return 0;
}</code></pre>
<p>알파벳을 지우기 위해 숫자인지 검사하는 코드를 만들어 준다.
&#39;0&#39;보다 크거나 같고 &#39;9&#39;보다 작거나 같은 경우에만 숫자인 것을 알 수 있다.
string에 우선 더해 숫자만 뽑아낸 후 답에 stoi 메서드를 이용하여 더해주면 된다.<img src="https://velog.velcdn.com/images/_chamomile/post/6ad6660a-fac6-4f75-8134-6373ef206ea2/image.png" alt=""></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[고장난 std::cin]]></title>
            <link>https://velog.io/@_chamomile/%EA%B3%A0%EC%9E%A5%EB%82%9C-stdcin</link>
            <guid>https://velog.io/@_chamomile/%EA%B3%A0%EC%9E%A5%EB%82%9C-stdcin</guid>
            <pubDate>Thu, 04 Apr 2024 16:20:50 GMT</pubDate>
            <description><![CDATA[<h2 id="iostream">iostream</h2>
<p>iostream은 C++에 있는 입출력을 위한 헤더 파일이다.</p>
<h3 id="cin의-정체">cin의 정체</h3>
<p>그중 입력을 담당하는 것은 std::cin 인데, 이는 istream에 정의된 객체이다.
<img src="https://velog.velcdn.com/images/_chamomile/post/3a7f4f3b-2843-462a-a1cb-e16699fc0c49/image.png" alt=""></p>
<pre><code class="language-cpp">int a;
cin &gt;&gt; a;</code></pre>
<p>우리는 이러한 코드로 숫자를 입력받을 수 있다.
하지만 정상적인 값이 들어오지 않는 경우도 있을까? 그렇다.
숫자를 입력하세요. 라는 말을 듣지 않는 사용자가 a를 입력하게 되면, cin에는 에러가 발생합니다.</p>
<h2 id="cin의-상태-플래그">cin의 상태 플래그</h2>
<p>에러 발생 여부를 어떻게 확인할 수 있을까요?
그건 바로 cin 내부의 상태 플래그의 값을 확인하는것입니다.
cin 내부의 상태 플래그는 입력을 받을 때 마다 값이 바뀌는데요, </p>
<p><img src="https://velog.velcdn.com/images/_chamomile/post/a0acb37e-039e-431d-a55c-4f823ab9a9fe/image.png" alt=""></p>
<p>failbit : 입력 실패, 숫자 입력 일 때 문자가 입력된 경우
eofbit : 파일의 끝, 읽을 것이 없다.
badbit : 입력값이 손상되었음, 더 읽을 수 없다.
goodbit : 아무 문제도 없음, 정상</p>
<p>이러한 상태 플래그들로 cin의 에러 여부를 파악할 수 있습니다.</p>
<h3 id="를-통한-에외처리">를 통한 에외처리</h3>
<p><code>cin.fail()</code>, <code>cin.eof()</code>, <code>cin.bad()</code>, <code>cin.good()</code>과 같은 멤버함수로 예외처리가 가능하겠죠?</p>
<h2 id="cin이-고장났다">cin이 고장났다!!</h2>
<p>그런데 고장난 cin? 이게 무엇일까요? 
<img src="https://velog.velcdn.com/images/_chamomile/post/01d1fc2e-23b7-47e8-af9b-c671bf28a35f/image.png" alt="">
int를 받고있는 cin이 &quot;안녕하세요&quot;라는 문자를 받게 되면, failbit 플래그가 켜질 것입니다.
그러면 cin은 정상적인 입력 작업을 할 수 없는데요!</p>
<p>그러면 이 고장난 cin을 어떻게 고칠까요?</p>
<h3 id="cinclear">cin.clear()</h3>
<p>그것은 바로 <code>cin.clear()</code>!!
<img src="https://velog.velcdn.com/images/_chamomile/post/190a1dd9-111f-43d0-8b79-3b9e7841eff3/image.png" alt=""></p>
<div style="text-align :center;">cin.clear() 함수는 입력 스트림의 오류 플래그를 재설정하는 데 사용됩니다.</div>
</br>

<p>이를 호출하면 cin의 상태 플래그들이 모두 초기화 되어 정상적으로 돌아옵니다. 만!</p>
<h2 id="cin의-작동방식">cin의 작동방식</h2>
<p>cin은 입력을 받으면 값이 입력버퍼에 저장, 이후 버퍼를 읽어 변수 저장으로 진행됩니다. 
<img src="https://velog.velcdn.com/images/_chamomile/post/95684223-cda7-4c4a-8eb3-a43370a42166/image.png" alt=""></p>
<h3 id="하지만-집이-무너진-cin">하지만 집이 무너진 cin</h3>
<p>하지만 숫자 저장 중 문자가 들어온, cin.fail 상태에서는 <code>cin.clear()</code>을 통해 상태 플래그를 초기화 하여도, cin 입력 버퍼에는 아직 잘못 들어간 문자가 남아있어서 그것을 읽어 int 변수에 넣으려 하기 때문에 다시 fail 플래그가 켜질 것입니다.<img src="https://velog.velcdn.com/images/_chamomile/post/db28e4fc-2e5f-4e6e-bf51-80816ab22672/image.png" alt=""></p>
<h3 id="cin의-집을-고쳐보자">cin의 집을 고쳐보자!</h3>
<p>그렇다면 이 입력 버퍼를 비워야 우리가 겪는 문제를 해결하겠죠?
그러기 위해 사용하는 <code>cin.ignore()</code> 가 있습니다.</p>
<h2 id="cinignore">cin.ignore()</h2>
<p><img src="https://velog.velcdn.com/images/_chamomile/post/1b5113b3-6b18-4963-ab0a-923f7fa1884b/image.png" alt=""></p>
<div style="text-align :center;">cin.ignore() 함수는 입력 버퍼의 내용을 지우는 데 사용됩니다.</div>

</br>

<p>두 개의 인자를 넘겨주어 사용할 수 있는데, <code>streamsize_Count</code> 와 <code>metadelim</code>이라는 값이 필요합니다. 첫 번째는 읽을 문자의 갯수, 두 번째는 읽으면 끊을 문자입니다.
<code>cin.ignore(1000, &#39;\n&#39;)</code>과 같은 코드는, 10개의 문자씩 버리거나 \n을 만나면 버리기.
<img src="https://velog.velcdn.com/images/_chamomile/post/f0f9f709-568d-4e96-900d-10a1ff65d9eb/image.png" alt=""></p>
<p>이런 식으로 입력 버퍼를 비워내면 결국 cin이 정상적으로 돌아오게 됩니다!</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[0319 자료구조 수업일지]]></title>
            <link>https://velog.io/@_chamomile/0319-%EC%9E%90%EB%A3%8C%EA%B5%AC%EC%A1%B0-%EC%88%98%EC%97%85%EC%9D%BC%EC%A7%80</link>
            <guid>https://velog.io/@_chamomile/0319-%EC%9E%90%EB%A3%8C%EA%B5%AC%EC%A1%B0-%EC%88%98%EC%97%85%EC%9D%BC%EC%A7%80</guid>
            <pubDate>Thu, 04 Apr 2024 14:30:07 GMT</pubDate>
            <description><![CDATA[<p>오늘으,ㄴ 문제를 잔뜩풀었다람쥐</p>
<p>3문장 출력하기</p>
<pre><code class="language-cpp">#include &lt;iostream&gt;

using namespace std;

int main() {
    cout &lt;&lt; &quot;9 * 9 = 81\n&quot;;
    cout &lt;&lt; &quot;원주율은 3.1415926535입니다\n&quot;;
    cout &lt;&lt; &quot;선생님이 말했어. &quot;&lt;&lt; &#39;&quot;&#39; &lt;&lt; &quot;공부는 기세야&quot; &lt;&lt; &#39;&quot;&#39;;
}</code></pre>
<p>a b 입력받아 a +b / a - b 반올림 소수점 둘째자리 출력하기</p>
<pre><code class="language-cpp">#include &lt;iostream&gt;
using namespace std;

int main() {
    int a, b;
    cin &gt;&gt; a &gt;&gt; b;

    float answer = (float)(a + b) / (a - b);

    answer *= 100;
    answer += 0.5;
    answer = (int)answer;
    answer /= 100;
    cout &lt;&lt; answer;
}</code></pre>
<p>19세 이상이면서 남자인 사람이 한명이라도 있다면 1을 출력</p>
<pre><code class="language-cpp">#include &lt;iostream&gt;

using namespace std;

int main() {
    int age[2];
    char sex[2];
    bool haveM = false;

    for (int i = 0; i &lt; 2; i++) {
        cin &gt;&gt; age[i] &gt;&gt; sex[i];
    }

    for (int i = 0; i &lt; 2; i++) {
        if (age[i] &gt;= 19 &amp;&amp; sex[i] == &#39;M&#39; &amp;&amp; haveM == false) {
            cout &lt;&lt; 1;
            haveM = true;
        }
    }

    if (haveM == false) cout &lt;&lt; 0;
}</code></pre>
<p>1부터 b까지의 수 중 a 의 배수들의 곱을 구하는 문제</p>
<pre><code class="language-cpp">#include &lt;iostream&gt;

using namespace std;
int main() {
    int a, b, sum = 1;
    cin &gt;&gt; a &gt;&gt; b;
    for (int i = 1; i &lt;= b; i++) {
        if (i % a == 0) sum *= i;
    }
    cout &lt;&lt; sum;
}</code></pre>
<p>n이 주어졌을 때 n을 1,2,3 차례대로 나누어 1 이하가 되는 순간까지의 횟수</p>
<pre><code class="language-cpp">#include &lt;iostream&gt;

using namespace std;
int main() {
    int n;
    int cnt = 1;
    cin &gt;&gt; n;

    while (true) {
        ++cnt;
        n /= cnt;
        if (n &lt;= 1) break;
    }

    cout &lt;&lt; cnt;
}</code></pre>
<p>n의 값이 짝수라면 3을 곱하고 1을 더함
홀수라면 2를 곱하고 2를 더함
1000 이상이 될 때 cnt의 값</p>
<pre><code class="language-cpp">#include &lt;iostream&gt;

using namespace std;
int main() {
    int n;
    int cnt = 0;
    cin &gt;&gt; n;

    for (cnt; n &lt;= 1000; cnt++) {
        if (n % 2 == 0) n = n * 3 + 1;
        else n = n * 2 + 2;
    }

    cout &lt;&lt; cnt;
}</code></pre>
<p>a이상 b이하의 수 중 1920 , 2880의 공약수가 있는지 판단</p>
<pre><code class="language-cpp">#include &lt;iostream&gt;

using namespace std;
int main() {
    int a, b;
    cin &gt;&gt; a &gt;&gt; b;
    bool 있음 = false;
    for (int i = a; i &lt;= b; i++) {
        if (1920 % i == 0 &amp;&amp; 2880 % i == 0) 있음 = true;
    }

    if (있음) cout &lt;&lt; 1;
    else cout &lt;&lt; 0;
}</code></pre>
<p>1이상 n이하의 소수를 오름차순 출력</p>
<pre><code class="language-cpp">#include &lt;iostream&gt;

using namespace std;

void IsPrime(int n);

int main() {
    int n;
    cin &gt;&gt; n;
    IsPrime(n);
}

void IsPrime(int n) {
    for (int i = 2; i &lt;= n; i++) {
        int cnt = 0;
        for (int j = 1; j &lt;= i; j++) {
            if (i % j == 0) cnt++;
        }
        if (cnt &lt;= 2) cout &lt;&lt; i &lt;&lt; &quot; &quot;;
    }

}</code></pre>
<p>n개의 숫자 주어짐 서로 다른숫자 차가 가장 작은걸출력</p>
<pre><code class="language-cpp">#include &lt;iostream&gt;
#include &lt;vector&gt;
using namespace std;


int main() {
    int n;
    vector&lt;int&gt; arr;
    int min = 55555;

    cin &gt;&gt; n;

    for (int i = 0; i &lt; n; i++) {
        int a;
        cin &gt;&gt; a;
        arr.push_back(a);
    }

    for (int i = 0; i &lt; arr.size(); i++) {
        for (int j = 0; j &lt; arr.size(); j++) {
            if (i == j) continue;
            if ((arr[i] - arr[j]) &lt; min &amp;&amp; arr[i] - arr[j] &gt;= 0) min = (arr[i] - arr[j]);
        }
    }

    cout &lt;&lt; min;
}</code></pre>
<p>공백을 포함한 문자열이 입력되었을떄 공백제외 다시출력</p>
<pre><code class="language-cpp">#include &lt;iostream&gt;
#include &lt;string&gt;
using namespace std;


int main() {
    string a, b, answer = &quot;&quot;;
    getline(cin, a);
    getline(cin, b);
    for (int i = 0; i &lt; a.length(); i++) {
        if (a[i] == &#39; &#39;) continue;
        answer += a[i];
    }
    for (int i = 0; i &lt; b.length(); i++) {
        if (b[i] == &#39; &#39;) continue;
        answer += b[i];
    }

    cout &lt;&lt; answer;
}</code></pre>
<p>알파벳과 숫자로 이루어진 문자열 두개가 주어지면 각각 숫자를 이어붙인다음 합쳐서 출력</p>
<pre><code class="language-cpp">#include &lt;iostream&gt;
#include &lt;string&gt;
using namespace std;


int main() {
    string a, b, 이어붙인숫자;
    int answer = 0;

    cin &gt;&gt; a &gt;&gt; b;

    for (int i = 0; i &lt; a.length(); i++) {
        if (a[i] &gt;= &#39;0&#39; &amp;&amp; a[i] &lt;= &#39;9&#39;) 이어붙인숫자 += a[i];
    }

    answer += stoi(이어붙인숫자);
    이어붙인숫자 = &quot;&quot;;
    for (int i = 0; i &lt; b.length(); i++) {
        if (b[i] &gt;= &#39;0&#39; &amp;&amp; b[i] &lt;= &#39;9&#39;) 이어붙인숫자 += b[i];
    }

    answer += stoi(이어붙인숫자);

    cout &lt;&lt; answer;
}</code></pre>
<p>소문자 알파벳이 하나 주어지면 그 전 소문자 출력, a는 z로</p>
<pre><code class="language-cpp">#include &lt;iostream&gt;
#include &lt;string&gt;
using namespace std;


int main() {
    char a;
    cin &gt;&gt; a;
    if (a == &#39;a&#39;) {
        cout &lt;&lt; &#39;z&#39;;
        return 0;
    }
    cout &lt;&lt; (char)(a - 1);

}</code></pre>
<p>영문자 a , 정수 b가 주어지면 a에 해당하는 아스키코드 번호와 b에 대항하는 아스키코드 문자 출력</p>
<pre><code class="language-cpp">#include &lt;iostream&gt;
#include &lt;string&gt;
using namespace std;


int main() {
    char a;
    int b;
    cin &gt;&gt; a &gt;&gt; b;
    cout &lt;&lt; (int)a &lt;&lt; &quot; &quot; &lt;&lt; (char)b;

}</code></pre>
<p>a가 주어지면 재귀함수로 1부터 a까지의 합을 구한 후 출력</p>
<pre><code class="language-cpp">#include &lt;iostream&gt;
#include &lt;string&gt;
using namespace std;

int Fibona(int num);
int answer = 0;
int main() {
    int a;
    cin &gt;&gt; a;
    answer += Fibona(a);
    cout &lt;&lt; answer;
}

int Fibona(int num) {
    if (num &lt;= 0) return 0;
    answer += num;
    Fibona(num - 1);
}</code></pre>
<p>n을 입력받아 별 출력을 5 4 3 2 1 1 2 3 4 5로 하기</p>
<pre><code class="language-cpp">#include &lt;iostream&gt;
using namespace std;
int ban(int n) {
    int b = n;
    if (b == 0) return 0;
    for (int i = 0; i &lt; n; i++) {
        cout &lt;&lt; &quot;*&quot;;
    }
    cout &lt;&lt; endl;

    ban(n - 1);

    for (int i = 0; i &lt; n; i++) {
        cout &lt;&lt; &quot;*&quot;;
    }
    cout &lt;&lt; endl;
}

int main() {
    ban(5);
}</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[Call by(함수 인자 전달 방식)이란..]]></title>
            <link>https://velog.io/@_chamomile/Call-by%ED%95%A8%EC%88%98-%EC%9D%B8%EC%9E%90-%EC%A0%84%EB%8B%AC-%EB%B0%A9%EC%8B%9D%EC%9D%B4%EB%9E%80</link>
            <guid>https://velog.io/@_chamomile/Call-by%ED%95%A8%EC%88%98-%EC%9D%B8%EC%9E%90-%EC%A0%84%EB%8B%AC-%EB%B0%A9%EC%8B%9D%EC%9D%B4%EB%9E%80</guid>
            <pubDate>Wed, 20 Mar 2024 08:56:09 GMT</pubDate>
            <description><![CDATA[<h2 id="call-by---">Call by --?</h2>
<p>함수 인자 전달 방식을 3가지로 나눌 수 있다.</p>
<p>Call by value, Call by reference, Call by address이다.</p>
<h3 id="call-by-value">call by value</h3>
<p>매개변수를 받아 위치를 바꾸는 Swap 메서드를 만들어 보자.</p>
<pre><code class="language-cpp">void Swap(int x, int y) {
    int temp = x;
    x = y;
    y = temp;
}</code></pre>
<p>실행은 Swap(a, b)로 한다
Swap에 int a, b : 1, 3을 넣은 다음 a b를 출력하면 3 1 이 출력될까? 아니다. 
현재의 Swap 메서드는 들어온 값을 복사해 사용한다.
복사된 x와 y가 바뀐 것이기 때문에 
이것이 바로 call by value, 값복사이다.
<img src="https://velog.velcdn.com/images/_chamomile/post/d46f25bb-f0ae-470f-8f04-76b7990983a4/image.png" alt=""></p>
<div style="text-align :center;">(복사기를 표현한 그림)</div>

<h3 id="call-by-reference">call by reference</h3>
<p>그렇다면 Call by reference는 무엇인가??
바로 참조하는 것이다.
참조자 변수 &amp;을 이용해 차이를 알아보자.</p>
<pre><code class="language-cpp">void Chamjo(int&amp; x, int X);</code></pre>
<p>내용이 있다고 치는 이런 메서드가 있다. 
Chamjo(a, b)를 실행해보자.
그러면 x는 a 의 주소를 참조하며, x 의 값을 바꾸면 a 도 같이 바뀐다.
이를 call by reference라고 한다.<img src="https://velog.velcdn.com/images/_chamomile/post/970e57a9-6bbd-450a-875f-0f714dfbdde8/image.png" alt=""></p>
<div style="text-align :center;">(x와 동거중인 a)</div>

<h3 id="call-by-address">call by address</h3>
<p>마지막으로 call by address를 알아보자.
call by address는 말 그대로 주소를 전달하는 것인데
매개변수로 주소를 담고 있는, 포인터 변수를 받아서 그 값을 사용한다.<br>주소를 받는 Swap 메서드를 만들어 보자.
실행은 Swap(&amp;a, &amp;b)로 한다.</p>
<pre><code class="language-cpp">void Swap(int* x, int* y) {
    int temp = x;
    x = y;
    y = temp;
}</code></pre>
<p>그러면 a, b의 주소가 전달되고, 역참조 연산자인 * 를 이용해 a, b 주소에 있는 값을 이용해 x, y의 값을 바꿀 수 있게 되었다.<img src="https://velog.velcdn.com/images/_chamomile/post/db1dc51c-0d24-4295-a227-1e7dd8c4edb5/image.png" alt=""></p>
<div style="text-align :center;">(우편함을 표현한 그림)</div>

<div style="text-align :center;">우편 = 주소, 내용물 = 값</div>



<h3 id="배열은-call-by-">배열은 call by ??</h3>
<p>답부터 말하자면 배열은 call by address이다.
배열의 이름은 주소를 담는 포인터 변수이고, 배열의 특정 인덱스에 접근하는 것은
배열[인덱스] 혹은 (배열의 주소 + 인덱스)를 역참조하여도 가능하다.</p>
<pre><code class="language-cpp">int arr[1]{1,3}
arr[1] == *(arr + 1)</code></pre>
<p><img src="https://velog.velcdn.com/images/_chamomile/post/4a8cfdeb-0757-4483-90fc-5cf74b5415dd/image.png" alt=""></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[c++ 수업 일지]]></title>
            <link>https://velog.io/@_chamomile/c-%EC%88%98%EC%97%85-%EC%9D%BC%EC%A7%80</link>
            <guid>https://velog.io/@_chamomile/c-%EC%88%98%EC%97%85-%EC%9D%BC%EC%A7%80</guid>
            <pubDate>Mon, 11 Mar 2024 10:49:57 GMT</pubDate>
            <description><![CDATA[<h2 id="iostream만-가져왔는데-다른건-왜-써지지">iostream만 가져왔는데 다른건 왜 써지지?</h2>
<p>우선 우리가 쓰는 iostream은 입출력을 도와주는 라이브러리이다.
근데 이상한 점이 있다.
우리가 rand, time같은 함수를 다른 라이브러리 호출 없이 쓸 수 있다는 것이다.
그 이유를 알고 있는가 ? ????
cpp의 iostream 내부에는, stdlib, ctime같은 라이브러리가 존재하기 떄문이다!
<img src="https://velog.velcdn.com/images/_chamomile/post/9a75a4dd-a5d8-4909-8578-29aad4424ed0/image.png" alt="">(이렇게 말이죠)</p>
<h2 id="rand-함수로-난수를-뽑아보자">rand 함수로 난수를 뽑아보자</h2>
<p>난수란 일정한 범위 내에서 아무런 수나 꺼내 온 것이다 
하지만 컴퓨터에게 아무거나 가져와! 라고 하면 컴퓨터는 수행할 수 없다.<img src="https://velog.velcdn.com/images/_chamomile/post/c0acfc13-8d6d-4492-b0ec-32b5fdf8aa00/image.png" alt="">
그래서 rand는 주어진 seed에 맞는 seed 테이블의 숫자를 가져오는데</p>
<p>rand의 seed가 1일 때 rand함수를 n번 실행하면, 41, 6334, 26500, 19169,, .... 가 실행 할 때마다 나온다.</p>
<h3 id="문제점">문제점</h3>
<p>생각해보자, 실행 할 때마다 같은 값이 나오면 사용자는 값을 예측 할 수 있게 된다.
이를 해결하기 위해서는 srand라는 함수로 rand함수의 seed를 바꿀 수 있는데
srand(10230) 이런식으로 숫자를 넣으면 rand함수가 10230 seed 테이블을 가져온다.
하지만 아직 문제가 있다.</p>
<p>seed의 값이 바뀌지 않는다는것</p>
<p>seed를 바꾸려면 무엇을 해야할까??</p>
<h3 id="해결법">해결법</h3>
<p>바로 time()이다, time(0)을 실행하면 약 <del>2n년</del>
1970년 1월 1일 00:00:00부터의 시간을 초로 환산한 현재 시간을 반환한다.
<img src="https://velog.velcdn.com/images/_chamomile/post/033d26c6-97b1-4d2c-a24d-4353e16c223d/image.png" alt=""></p>
<p>이를 이용하면 위의 문제를 해결할 수 있다.</p>
<h2 id="srandtimenull-보다는">srand(time(NULL)) 보다는</h2>
<p>time의 반환값을 보면 int64가 나온다.
srand 함수는 unsigned int를 받는 함수기 때문에
unsigned int(time(NULL))로 써주는게 좋을 것이다</p>
<p>끝</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[0311 자료구조 이론]]></title>
            <link>https://velog.io/@_chamomile/0311-%EC%9E%90%EB%A3%8C%EA%B5%AC%EC%A1%B0-%EC%9D%B4%EB%A1%A0</link>
            <guid>https://velog.io/@_chamomile/0311-%EC%9E%90%EB%A3%8C%EA%B5%AC%EC%A1%B0-%EC%9D%B4%EB%A1%A0</guid>
            <pubDate>Mon, 11 Mar 2024 07:22:18 GMT</pubDate>
            <description><![CDATA[<p>string 클래스의 멤버함수를 정리해보자.</p>
<p>string s가 있을때
s[i]는 i번쩨 원소를 나타낸다
s.at(i) 는 i번쨰 원소를 나타내며, index 범위체크까지 가능하다
s.length(), s.size() 문자열의 길이를 나타낸다.
s.empty는 s가 비었을때 true를 반환한다.</p>
<p>s.insert는 pos, string을 받는다
s의 pos 인덱스에 string을 삽입한다
s = chamo string = mile
s.insert(s.end(), mile);
s는 chamomile이 된다</p>
<p>s.find(s2) s2가 발견되는 인덱스를 반환
s.find(s2, pos) pos위치부터 s2가 발견되는 인덱스를 반환, 없으면 string::npos를 반환</p>
<p>s. push_back(‘ ‘) 문자열 맨 뒤 하나 더하기
s. pop_back() 문자열 맨 뒤 하나 없애기
s. front() 첫번째에 있는것ㄱ을 반환
s.back() 마지막에 있는것을 반환 반환
s.substr(pos, n) s의 pos 위치에서부터 n개의 문자를 반환
clear() 문자열을 비워줌
to_string(정수) int to string
stoi(문자열) string to int
swap(str1, str2) 문자열 2개를 바꿔준다</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[0311 자료구조 문제풀기]]></title>
            <link>https://velog.io/@_chamomile/0311-%EC%9E%90%EB%A3%8C%EA%B5%AC%EC%A1%B0-%EB%AC%B8%EC%A0%9C%ED%92%80%EA%B8%B0</link>
            <guid>https://velog.io/@_chamomile/0311-%EC%9E%90%EB%A3%8C%EA%B5%AC%EC%A1%B0-%EB%AC%B8%EC%A0%9C%ED%92%80%EA%B8%B0</guid>
            <pubDate>Mon, 11 Mar 2024 07:16:46 GMT</pubDate>
            <description><![CDATA[<p>문제 6개를 풀어보자!</p>
<h2 id="문자-위치-ㅏㅊㅈ기">문자 위치 ㅏㅊㅈ기</h2>
<p><img src="https://velog.velcdn.com/images/_chamomile/post/b44f822e-d570-4106-9cd8-6a1256d4b3ea/image.png" alt=""></p>
<pre><code class="language-cpp">#include &lt;iostream&gt;
#include &lt;string&gt;

using namespace std;
int main() {
    string a = &quot;When in Rome, do as the Romans.&quot;;

    cout &lt;&lt; a.find(&quot;Rome&quot;);
}</code></pre>
<h2 id="특정-문자-제거하기">특정 문자 제거하기</h2>
<p><img src="https://velog.velcdn.com/images/_chamomile/post/d2653b7f-727f-46c0-9697-8f602d6ea3cf/image.png" alt=""></p>
<pre><code class="language-cpp">#include &lt;iostream&gt;
#include &lt;string&gt;

using namespace std;
int main() {
    string a;

    getline(cin, a);

    a.erase(a.find(&quot;-&quot;), 1);
    cout &lt;&lt; a;
}</code></pre>
<h2 id="해밍-거리-구하기">해밍 거리 구하기</h2>
<p><img src="https://velog.velcdn.com/images/_chamomile/post/306fa12b-e70c-42b9-87fd-4aec933c8e0c/image.png" alt=""></p>
<pre><code class="language-cpp">#include &lt;iostream&gt;
#include &lt;string&gt;
using namespace std;

int main() {
    string haming1 = &quot;AAAAA21346&quot;;
    string haming2 = &quot;AAAAA123451231234&quot;;
    //삼앟ㅇ연산자
    int shortest = haming1.length() &lt; haming2.length() ? haming1.length() : haming2.length();
    int answer = 0;

    for (int i = 0; i &lt; shortest; i++) {
        if (haming1[i] == haming2[i]) continue;
        else answer++;
    }
    cout &lt;&lt; answer;
}</code></pre>
<h2 id="문자-바꾸기">문자 바꾸기</h2>
<p><img src="https://velog.velcdn.com/images/_chamomile/post/c6187a73-bfe2-45c7-b90c-2e368a7191ec/image.png" alt=""></p>
<pre><code class="language-cpp">#include &lt;iostream&gt;
#include &lt;string&gt;

using namespace std;
int main() {
    string ming2;
    cin &gt;&gt; ming2;

    for (int i = 0; i &lt; ming2.length(); i++) {
        if (ming2[i] == &#39;o&#39;) ming2[i] = &#39;x&#39;;
    }

    cout &lt;&lt; ming2;
}</code></pre>
<h2 id="문자열-바꾸기">문자열 바꾸기</h2>
<p><img src="https://velog.velcdn.com/images/_chamomile/post/08d196ca-024f-412e-b622-613b1dcb0b4c/image.png" alt=""></p>
<pre><code class="language-cpp">#include &lt;iostream&gt;
#include &lt;string&gt;

using namespace std;
int main() {
    string a;
    getline(cin, a);
    int asdf = a.length();
    for (int i = 0; i &lt; asdf; i++) {
        a.push_back(a[0]);
        a.erase(0, 1);
        cout &lt;&lt; a &lt;&lt; endl;
    }
}</code></pre>
<h2 id="무ㅡㄴ자열1">무ㅡㄴ자열*1)</h2>
<p>공백을 포함한 문장 2개를 받아서 공백업ㄹㅅ이 출력하자.
<img src="https://velog.velcdn.com/images/_chamomile/post/898ce354-eb05-4bfd-8b22-d5394c30aa84/image.png" alt=""></p>
<pre><code class="language-cpp">#include &lt;iostream&gt;
#include &lt;string&gt;

using namespace std;
int main() {
    string a;
    string b;

    getline(cin, a);
    getline(cin, b);

    for (char c : a) {
        if (c != &#39; &#39;) cout &lt;&lt; c;
    }
    for (char c : b) {
        if (c != &#39; &#39;) cout &lt;&lt; c;
    }
}</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[240305 수업일지]]></title>
            <link>https://velog.io/@_chamomile/240305-%EC%88%98%EC%97%85%EC%9D%BC%EC%A7%80</link>
            <guid>https://velog.io/@_chamomile/240305-%EC%88%98%EC%97%85%EC%9D%BC%EC%A7%80</guid>
            <pubDate>Tue, 05 Mar 2024 05:44:18 GMT</pubDate>
            <description><![CDATA[<p>자료구조시간에 배우는 cpp.</p>
<p>첫 코드는 </p>
<pre><code class="language-cpp">#include &lt;iostream&gt;
using namespace std;

int main() {
    char arr[100];
    cout &lt;&lt; &quot;what&#39;s your name?\n&quot;;
    cin &gt;&gt; arr;
    cout &lt;&lt; &quot;hi&quot; &lt;&lt; &quot; &quot; &lt;&lt; arr;
}</code></pre>
<p>이였다.</p>
<h3 id="using-namespace-std">using namespace std</h3>
<p>using namespace std를 쓰면 cout cin 같은 std class 안에 있는 애들을 std::cout 같은 식으로 쓰지않게 해준다
그런데 이러면 단점이 다른 클래스의 같은이름을가진 애가 있으면 충돌이날수있는것.
유니티에서 자주 겪는걸 생각해보면 UnityEngine.Random과 System.Random의 경우가 있다.
그래서 using namespace std처럼 큰 틀을 하기보단 
그냥 using std::cout 같이 특정 뭐야 그 이름만 가두는게 좋을 거 같다.</p>
<h3 id="cout">cout</h3>
<p>문자 혹은 문자열을 출력해준다.</p>
<pre><code class="language-cpp">cout &lt;&lt; &quot;cout&quot; &lt;&lt; &#39;c&#39;;</code></pre>
<h3 id="cin">cin</h3>
<p><code>&gt;&gt;</code> 를 통해 문자열을 받아 변수에 저장할 수 있다.
공백을 만나면 중단된다</p>
<pre><code class="language-cpp">char arr[100];
cin &gt;&gt; arr
cout &lt;&lt; arr;</code></pre>
<p>다른걸 좀 생략하긴했지만 이 경우 실행하고 
ㅁㄴㅇㄹ ㅎ를 입력하면 
ㅁㄴㅇㄹ 가 출력된다.</p>
<p>이렇게 정리를하고있었지만 체크 문제가 생겼다. </p>
<h3 id="iostream을-빼면-무슨일이-생길까">iostream을 빼면 무슨일이 생길까</h3>
<p>iostream 라이브러리는 입출력을 하기 위해 필요하다.
뺴면 입출력을 못함</p>
<h3 id="endl의-의미는-무엇일까">endl의 의미는 무엇일까</h3>
<p>endl은 end line을 줄여둔것으로 std 클래스에 포함되어있다.
개행을 해준다. endl
이런식으로 endl
해준다.
또한 \n과 달리 endl은 출력버퍼를 비워준다고 한다
버퍼를 사용하면 입력하는 문자를 버퍼에 저장했다가 버퍼가 가득차거나 개행문자를 입력하면 한번에 전달하고
버퍼를 사용하지 않는 입력은 키보드가 입력할때마다 하나씩 전달한다고 한ㄷ ㅏ
버퍼를 비우는건 버퍼에 있는 문자열을 출력하는것인데
이것을 flush라고도할수잇다.
근데 이제 버퍼를 비우지 않는 출력문을 쓰고 sleep(time)을 하면
time만큼의 시간이 지나고 문자가 출력되면서 프로그램이 종료되는데
버퍼를 비우는 출력문을 쓰면 출력이 되고 나서 time만큼의 시간이 지난다.</p>
<h3 id="이름과-소속을-출력하는-프로그램을-작성해보자">이름과 소속을 출력하는 프로그램을 작성해보자</h3>
<pre><code class="language-cpp">#include &lt;iostream&gt;
using namespace std;

int main() {
    char name[50];
    char sosok[50];

    cout &lt;&lt; &quot;이름과 소속 입력\n&quot;;
    cin &gt;&gt; name;
    cin &gt;&gt; sosok;

    cout &lt;&lt; sosok &lt;&lt; &quot;의 &quot; &lt;&lt; name;
}</code></pre>
<p><img src="https://velog.velcdn.com/images/_chamomile/post/88578456-7543-4689-907a-6e86eac8071c/image.png" alt=""></p>
<h3 id="namespace는-왜필요한가">namespace는 왜필요한가</h3>
<p>std::cout 처럼 써야하는 것을 편하게 쓸 수 있기 때문이 아닐까.
라고 생각했지만
namespace로 묶어서 사용하면 같은 이름의 메서드여도 namespace로 구분할 수 있기 때문이다.</p>
<p>C#에서
A class의 Hello() 메서드와 B class의 Hello() 메서드가 있어도
A.Hello(); 하고 B.Hello(); 해서 따로쓰는거처럼.
오늘은 여기까지.
return 0;</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[240304 수업일지]]></title>
            <link>https://velog.io/@_chamomile/240304-%EC%88%98%EC%97%85%EC%9D%BC%EC%A7%80</link>
            <guid>https://velog.io/@_chamomile/240304-%EC%88%98%EC%97%85%EC%9D%BC%EC%A7%80</guid>
            <pubDate>Mon, 04 Mar 2024 07:39:04 GMT</pubDate>
            <description><![CDATA[<p>오늘은 자료구조 첫 수업을 들었다.
수업을 듣고 두 가지 질문에 대답해보았다.
<img src="https://velog.velcdn.com/images/_chamomile/post/dda66319-2260-4d59-ab45-755e40a31520/image.png" alt=""></p>
<h2 id="c과-c의-차이점이-무엇인가">C#과 C++의 차이점이 무엇인가.</h2>
<p>C#은 메모리 관리를 사용자가 하지 않아도 된다(GC가 해줌)
C++은 메모리 할당을 잘못하면 매번 터질 수 있다.</p>
<p>C#의 컴파일 시간은 C++에 비해 느리다.
그렇기에 퀄리티가 높은 게임들은 보통 c++, 언리얼으로 개발된다.
<img src="https://velog.velcdn.com/images/_chamomile/post/5d5b6d8d-b226-44d4-b345-aa2464c56877/image.png" alt=""></p>
<h2 id="객체지향프로그래밍에-대해서-설명해-보아라">객체지향프로그래밍에 대해서 설명해 보아라.</h2>
<p>객체지향프로그래밍은 Object Or머시기 Programing으로 OOP로 불린다
객체(Object)는 자료와 기능(메서드)를 담고 있는 것으로 생각할 수 있다.
객체지향프로그래밍의 특징으로는 추상화, 다형성, 캡슐화, 정보 은닉 등이 있는데
추상화는 안경 쓴 사람, 모자 쓴 사람 같은 것들을 사람 하나로 묶어버리는 것? 이고
<strong>++ 탈 것으로 묶인 자동차와 오토바이</strong>
다형성은 TakeOff라는 메서드가 있을 때 안경 쓴 사람은 안경을 벗고, 모자 쓴 사람은 모자를 벗을 수 있는 것이다. 같은 이름으로 다른 기능을 할 수 있다는 것?
** ++ 메서드 오버라이딩 등 **
캡슐화는 사실 잘 모르겠다. 
찾아볼것1
정보 은닉은 main 코드에서 볼 때 Hello인 메서드가 안에서는 움직이는 기능을 하는데 이게 가려지는건가 ? 근데 이러면 가독성이 떨어지는게 아닌가? 
찾아볼것2</p>
<p>찾아보고 오니까 캡슐화 안에 정보은닉이 있는거였다. 정보 은닉 당해버림
public, private, protected 같은 접근제어자를 통해 클래스 이름만 보이게 하
는식으로 안에 있는 속성과 기능을 보호할 수 있다. 이상으로 240304 수업일지 끝.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[QTE 개발일지 #4]]></title>
            <link>https://velog.io/@_chamomile/qtedevelog4</link>
            <guid>https://velog.io/@_chamomile/qtedevelog4</guid>
            <pubDate>Sun, 26 Nov 2023 13:39:35 GMT</pubDate>
            <description><![CDATA[<p>기간이 다 되어서 QTE 개발을 마쳤다.
로비와 전투, 클리어와 게임오버 씬으로 구성되어있고, UI는 로비, QTE에만 있다.
<img src="https://velog.velcdn.com/images/_chamomile/post/a2ccfb91-4cc7-4d3f-8525-5066cea03cda/image.png" alt="">
로비 및 설명창(세팅은 자동으로 저장, 로드 된다)
<img src="https://velog.velcdn.com/images/_chamomile/post/be71f3ae-c586-4f57-ad2d-a9b8ac2801d1/image.png" alt="">
만들기로 했던 Space 연타 UI
<img src="https://velog.velcdn.com/images/_chamomile/post/03d8081c-0e05-4026-adac-be8c46432ba7/image.png" alt="">
퍼즈 기능
<img src="https://velog.velcdn.com/images/_chamomile/post/7349a133-0793-4718-b47f-237a904a09e8/image.png" alt="">
게임오버 화면과
<img src="https://velog.velcdn.com/images/_chamomile/post/bfeb559f-0643-4fb4-b1dd-96c975f4d0e7/image.png" alt="">
별건없지만 크레딧이다</p>
<p>뭔가 많이 부족하다. 다음부터는 조금 더 열심히 해봐야 할 것 같다.
에셋 찾는게 정말 귀찮아서 안 찾았더니 게임이 볼 맛이 안 나서 그 점이 아쉽다.
</br>
</br>
</br>
끝</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[QTE 개발일지 #3]]></title>
            <link>https://velog.io/@_chamomile/qtedevelog3</link>
            <guid>https://velog.io/@_chamomile/qtedevelog3</guid>
            <pubDate>Wed, 08 Nov 2023 15:41:26 GMT</pubDate>
            <description><![CDATA[<p><img src="https://velog.velcdn.com/images/_chamomile/post/b40c1f6a-6d17-4633-b779-4796559b7150/image.png" alt=""></p>
<p>벌써 세 번째 개발일지라니
쓸때마다 고민을 참 많이 하는 것 같다.</p>
<p>이번에는 파티클과 체력바를 만들고 코드 구조가 맘에 안들어서 갈아엎었다.</p>
<p> <del>자세한건 깃허브 확인..</del>
<img src="https://velog.velcdn.com/images/_chamomile/post/0405ddba-4c1d-4357-81eb-8e151d7bd27d/image.gif" alt=""></p>
<p><img src="https://velog.velcdn.com/images/_chamomile/post/9c41eebb-ebf8-496f-9ce4-8db61c701c07/image.gif" alt="">    </p>
<p>앞으로 할 것 
GIF에서 보이는 Trail 이어지는 것 고치기
QTE Space 연타 UI 만들기
플레이어가 근거리에서 휘두를 수 있는 무기 추가하기
대쉬, 우클릭 등 쿨타임 표시</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[QTE 개발일지 #2]]></title>
            <link>https://velog.io/@_chamomile/qtedevelog2</link>
            <guid>https://velog.io/@_chamomile/qtedevelog2</guid>
            <pubDate>Fri, 03 Nov 2023 15:35:10 GMT</pubDate>
            <description><![CDATA[<h2 id="이번에-만든-것">이번에 만든 것</h2>
<p><img src="https://velog.velcdn.com/images/_chamomile/post/0ce56ef0-54fc-426c-909b-136cfc7411bc/image.gif" alt="">
흠..
뭔가 뭔가다
내가 원했던건
<img src="https://media.tenor.com/d54jdJzJYTkAAAAd/ranger-quake.gif" alt="">
이런 거야!!</p>
<p>힘을 한번에 주기위해 ForceMode를 Impuls로 바꿔주고, AddForce 전 Velocity를 기억해서 다시 넣어줬다.</p>
<p><img src="https://velog.velcdn.com/images/_chamomile/post/bcbd2316-7017-4c38-b056-d842e720afc8/image.png" alt=""></p>
<p>그리고 수많은 실수와 함께 코드를 고쳤고
(내가 보기엔) 이쁘게 날아가게 되었다.
<img src="https://velog.velcdn.com/images/_chamomile/post/2797d2d4-a347-4155-9b57-1d0be0360e39/image.gif" alt=""></p>
<p>앞으로 할 것
UIToolkit, 다양한 패턴, SFX VFX, +플레이어의 다양한 무기</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[QTE 개발일지 #1]]></title>
            <link>https://velog.io/@_chamomile/qtedevelog</link>
            <guid>https://velog.io/@_chamomile/qtedevelog</guid>
            <pubDate>Thu, 02 Nov 2023 06:51:34 GMT</pubDate>
            <description><![CDATA[<h1 id="개인-프로젝트-qte의-개발일지">개인 프로젝트 QTE의 개발일지</h1>
<p>입니다
</br></p>
<h2 id="만든-것들">만든 것들</h2>
<p>패턴 1
<img src="https://velog.velcdn.com/images/_chamomile/post/9d018f65-f42c-48d2-bedf-aad4f88f824a/image.gif" alt="">
</br></p>
<p>패턴2
<img src="https://velog.velcdn.com/images/_chamomile/post/6ccd1806-099f-4890-adf8-dee951b8277b/image.gif" alt="">
</br></p>
<p>패턴3
<img src="https://velog.velcdn.com/images/_chamomile/post/77f82031-d008-4099-9ea6-a675b25c72a5/image.gif" alt="">
</br></p>
<p>레이저
<img src="https://velog.velcdn.com/images/_chamomile/post/18425de1-0d00-4059-8b64-178829699d52/image.gif" alt="">
</br></p>
<p><del>UI없는</del> QTE (Space 연타)
<img src="https://velog.velcdn.com/images/_chamomile/post/8a8a4352-72e8-4170-af3a-43f0443da603/image.gif" alt=""></p>
<p>플레이어의 위치가 잘 안 보인다고 함 
=&gt; 라이트 추가 + 대쉬 시 intensity값 조정</p>
</br>

<h2 id="앞으로-할-것">앞으로 할 것</h2>
<p>UIToolkit, 다양한 패턴, SFX VFX</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[Hierarchy 커스터마이징!]]></title>
            <link>https://velog.io/@_chamomile/231029clog</link>
            <guid>https://velog.io/@_chamomile/231029clog</guid>
            <pubDate>Mon, 30 Oct 2023 00:12:44 GMT</pubDate>
            <description><![CDATA[<h2 id="개요">개요</h2>
<p>오늘은 Unity Hierarchy 커스텀을 배웠다.
배운 코드를 주석으로 정리하면서 복습하고, 나의 기능을 추가해보자
<img src="https://velog.velcdn.com/images/_chamomile/post/b13d1034-4d27-4643-bf1e-5dff23466cce/image.png" alt="">
Hierarchy 안의 내용물이 많아지면 구분이 힘들어질 수 있다.</p>
<p>그런데...
<br/><br/><br/>
<strong>이렇게!</strong>
<img src="https://velog.velcdn.com/images/_chamomile/post/76cb2d21-bbf6-425b-891d-d4285c3dad29/image.png" alt="">
이번에 배운 것으로 쉬운 구분을 할 수 있다.</p>
<h2 id="코드">코드</h2>
<pre><code class="language-cs">using System.Collections;
using System.Collections.Generic;
using UnityEditor;
using UnityEngine;

public class CustomHierarchy : MonoBehaviour
{
#if UNITY_EDITOR //Unity Editor에서만 돌아가야 함
    private static Dictionary&lt;Object, CustomHierarchy&gt; coloredObject = new Dictionary&lt;Object, CustomHierarchy&gt;();

    static CustomHierarchy() //스크립트 로드 시 한 번만 실행
    {
        EditorApplication.hierarchyWindowItemOnGUI += HandleDraw;
    }

    private static void HandleDraw(int instanceID, Rect selectionRect)
    {
        Object obj = EditorUtility.InstanceIDToObject(instanceID); //Key, instanceID를 참조할 수 있는 obj 생성

        if (obj != null &amp;&amp; coloredObject.ContainsKey(obj)) //null 체크, coloredObject에 obj가 들어있는지 확인
        {
            GameObject gameObj = obj as GameObject; // 해당 Key 값인 Object의 GameObject 저장
            if (gameObj.TryGetComponent&lt;CustomHierarchy&gt;(out CustomHierarchy ch))
            {
                PaintObject(obj, selectionRect, ch);
            }
            else //obj가 CustomHierarchy를 가지고 있지 않음
            {
                coloredObject.Remove(obj);
            }
        }
    }

    private static void PaintObject(Object obj, Rect selectionRect, CustomHierarchy ch)
    {
        Rect bgRect = new Rect(selectionRect.x, selectionRect.y, selectionRect.width + 50 , selectionRect.height); //Prefix를 넣기 위해 selectionRect.width + 50

        if (Selection.activeObject != obj) // obj가 클릭되어 있지 않다면
        {
            EditorGUI.DrawRect(bgRect, ch.backColor);
            string name = $&quot;{ch.prefix} {obj.name}&quot;;

            EditorGUI.LabelField(bgRect, name, new GUIStyle()
            {
                normal = new GUIStyleState { textColor = ch.fontColor },
                fontStyle = FontStyle.Bold
            });
        }
    }

    //커스텀 할 것들
    public string prefix;
    public Color backColor;
    public Color fontColor;

    //에디터 함수
    private void Reset()
    {
        OnValidate();
    }

    private void OnValidate()
    {
        if (coloredObject.ContainsKey(this.gameObject) == false) //coloredObject에 없으면
        {
            coloredObject.Add(this.gameObject, this); //추가
        }
    }
#endif
}</code></pre>
<h2 id="기능-만들어-보기">기능 만들어 보기</h2>
<p>PaintObj 함수 내에 추가한 기능</p>
<pre><code class="language-cs">        if (Selection.activeObject == obj)
        {
            EditorGUI.LabelField(bgRect, &quot;Custom 가능한 오브젝트입니다!&quot;, new GUIStyle()
            {
                normal = new GUIStyleState { textColor = ch.fontColor },
                fontStyle = FontStyle.BoldAndItalic
            });
        }</code></pre>
<p>생긴 문제<img src="https://velog.velcdn.com/images/_chamomile/post/9c4dfe10-5daf-4592-9478-dd56ea965660/image.png" alt="">
원래 있던 이름이 사라지지 않는다</p>
<p>깔끔하게 포기!
하고 만든 것
<img src="https://velog.velcdn.com/images/_chamomile/post/d7aafc09-765f-4851-bc60-1b56bfb39241/image.png" alt=""><img src="https://velog.velcdn.com/images/_chamomile/post/5bff928a-0170-44e8-a6af-41c0643a0fa9/image.png" alt=""></p>
<p>변경사항</p>
<pre><code class="language-cs">//선언
public string objName;

//PaintObject의 if(Selection.activeObject != obj) 안
    string name = $&quot;{ch.prefix} {obj.name}&quot;;
    if (ch.objName != &quot;&quot;) name = $&quot;{ch.prefix} {ch.objName}&quot;;</code></pre>
<h2 id="감사합니다">감사합니다</h2>
<p><img src="https://velog.velcdn.com/images/_chamomile/post/8f337af5-5697-4573-93a4-052aca9ba191/image.gif" alt=""></p>
]]></description>
        </item>
    </channel>
</rss>