<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>alextep_tree.log</title>
        <link>https://velog.io/</link>
        <description>Full-Stack Developer</description>
        <lastBuildDate>Fri, 31 Mar 2023 05:36:21 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <image>
            <title>alextep_tree.log</title>
            <url>https://velog.velcdn.com/images/alextep_tree/profile/92d15443-28f7-4599-bc72-7ddab8e446e4/image.png</url>
            <link>https://velog.io/</link>
        </image>
        <copyright>Copyright (C) 2019. alextep_tree.log. All rights reserved.</copyright>
        <atom:link href="https://v2.velog.io/rss/alextep_tree" rel="self" type="application/rss+xml"/>
        <item>
            <title><![CDATA[백준 - 1158 요세푸스 문제]]></title>
            <link>https://velog.io/@alextep_tree/%EB%B0%B1%EC%A4%80-1158-%EC%9A%94%EC%84%B8%ED%91%B8%EC%8A%A4-%EB%AC%B8%EC%A0%9C</link>
            <guid>https://velog.io/@alextep_tree/%EB%B0%B1%EC%A4%80-1158-%EC%9A%94%EC%84%B8%ED%91%B8%EC%8A%A4-%EB%AC%B8%EC%A0%9C</guid>
            <pubDate>Fri, 31 Mar 2023 05:36:21 GMT</pubDate>
            <description><![CDATA[<p><img src="https://velog.velcdn.com/images/alextep_tree/post/04872b22-fc10-428b-96b3-d440c14420ac/image.png" alt=""></p>
<h1 id="요약">요약</h1>
<ol>
<li>1번부터 n명이 순서대로 원을 이루며 앉음</li>
<li>자연수 k가 주어지고 순서대로 k번째 사람을 제거함</li>
<li>모두 제거될때 까지 2번은 반복됨</li>
<li>n,k가 주어지면 제거되는 순서대로 출력</li>
</ol>
<h1 id="아이디어">아이디어</h1>
<ol>
<li>n명을 배치해야함</li>
<li>어디에? <ol>
<li>배열 x(인덱스 중간의 삭제가 힘듦)</li>
<li>스택 x(한쪽에서만 삽입과 제거가능)</li>
<li>큐 o (원형을 아래의 그림처럼 전단의 제거를 후단의 삽입으로 생각가능)
<img src="https://velog.velcdn.com/images/alextep_tree/post/638d4ad8-2d4a-48ef-a398-aea2e15431e1/image.jpeg" alt=""></li>
</ol>
</li>
<li>큰 틀을 모델링<ol>
<li>전체큐 입력받음</li>
<li>전단부터 k번째의 수가 출력되고 제거되어야함 </li>
<li>k-1번 (삽입 + 제거) → 출력 + 제거</li>
<li>queue가 empty가 될때까지 위의 과정을 반복</li>
</ol>
</li>
</ol>
<h1 id="코드작성">코드작성</h1>
<pre><code>#include &lt;queue&gt;
#include &lt;iostream&gt;
using namespace std;

int main()
{
queue &lt;int&gt; q;//queue 선언
int n,k;
cin&gt;&gt;n;
cin&gt;&gt;k;
for(int i=1;i&lt;=n;i++){
    q.push(i);
}//queue 입력
cout&lt;&lt;&quot;&lt;&quot;;
while(!q.empty()){

    for(int i=0;i&lt;k-1;i++){
    q.push(q.front());
    q.pop();
    }//k-1번째까지 삽입 + 삭제 반복

    cout&lt;&lt;q.front();//k번째 출력
    q.pop();//k번째 삭제

    if(q.empty()){
        break;
    }//,를 위한 예외처리
    cout&lt;&lt;&quot;, &quot;; 
}
cout&lt;&lt;&quot;&gt;&quot;;
return 0;
}</code></pre>]]></description>
        </item>
        <item>
            <title><![CDATA[백준 - 2161 카드1]]></title>
            <link>https://velog.io/@alextep_tree/%EB%B0%B1%EC%A4%80-2161-%EC%B9%B4%EB%93%9C1</link>
            <guid>https://velog.io/@alextep_tree/%EB%B0%B1%EC%A4%80-2161-%EC%B9%B4%EB%93%9C1</guid>
            <pubDate>Fri, 31 Mar 2023 05:00:16 GMT</pubDate>
            <description><![CDATA[<h1 id="백준---2161-카드1">백준 - 2161 카드1</h1>
<p><img src="https://velog.velcdn.com/images/alextep_tree/post/4410934c-b998-41bb-b690-6a2461c68c06/image.png" alt=""></p>
<h1 id="요약">요약</h1>
<ol>
<li>N을 입력받아 카드 N개를 1번카드가 제일위에 N번카드가 제일 아래인 순서대로 배열</li>
<li>위 순서대로 진행함<ol>
<li>맨 위의 카드를 버림</li>
<li>그아래 카드를 맨 아래의 카드밑으로 옮김</li>
</ol>
</li>
<li>이와 같이 진행했을때, 버린 카드를 순서대로 출력하시오.</li>
</ol>
<h1 id="아이디어">아이디어</h1>
<ol>
<li>N개의 배열을 저장할 자료구조를 골라야함.<ol>
<li>배열 : 배열을 N개 생성후 배열에 넣었다면, 인덱스의 제거와 이동이 잦음 → 적합하지 x</li>
<li>스택 : 삽입과 제거연산이 모드 최상위 노드 한쪽에서만 이뤄짐 → 양 사이드로 제거 삽입이 일어나는 위의 문제에는 적합하지 x</li>
<li>큐 : 제거(Dequeu)는 전단, 삽입(Enqueue)은 후단에서 수행됨 → 적합</li>
</ol>
</li>
<li>큰 틀을 모델링<ol>
<li>큐전체를 입력받음</li>
<li>전단을 출력 → 전단을 제거 → 전단을 삽입(후단으로) → 전단을 제거</li>
<li>queue가 empty가 될때까지 위를 반복함</li>
</ol>
</li>
</ol>
<h1 id="코드작성">코드작성</h1>
<pre><code>#include &lt;iostream&gt;
#include &lt;queue&gt;

using namespace std;
queue &lt;int&gt; q;//queue 선언
int main()
{
    int n;
    cin&gt;&gt;n;
    for(int i=1; i&lt;=n;i++){
        q.push(i);//queue에 1부터 n까지 숫자 삽입
    }
    while(!q.empty()){
        cout&lt;&lt;q.front();//전단 출력
        q.pop();//전단 팝
        q.push(q.front());//전담을 후단으로 삽입
        q.pop();//전단팝

        if(q.empty()){
            break;
        }//space를 위한 예외처리
        else{cout&lt;&lt;&quot; &quot;;}
    }
return 0;
}</code></pre>]]></description>
        </item>
        <item>
            <title><![CDATA[변수]]></title>
            <link>https://velog.io/@alextep_tree/%EB%B3%80%EC%88%98</link>
            <guid>https://velog.io/@alextep_tree/%EB%B3%80%EC%88%98</guid>
            <pubDate>Fri, 10 Mar 2023 05:42:01 GMT</pubDate>
            <description><![CDATA[<blockquote>
<p>Notion link : <a href="https://melon-taker-d3e.notion.site/3-1-90e463fb742f4326a8388aa75030a64c">https://melon-taker-d3e.notion.site/3-1-90e463fb742f4326a8388aa75030a64c</a></p>
</blockquote>
<h1 id="변수-선언">변수 선언</h1>
<ul>
<li>l-value, r-value</li>
</ul>
<h1 id="정수-데이터-타입">정수 데이터 타입</h1>
<ul>
<li>Range of data types</li>
</ul>
<table>
<thead>
<tr>
<th>자료형</th>
<th>범위</th>
</tr>
</thead>
<tbody><tr>
<td>bool</td>
<td>true 또는 false</td>
</tr>
<tr>
<td>char</td>
<td>-128 ~ 127</td>
</tr>
<tr>
<td>short</td>
<td>-32,768 ~ 32,767</td>
</tr>
<tr>
<td>int</td>
<td>-2,147,483,648 ~ 2,147,483,647</td>
</tr>
<tr>
<td>long long</td>
<td>-9,223,372,036,854,775,808 ~ 9,223,372,036,854,775,807</td>
</tr>
<tr>
<td>float</td>
<td>1.2 x 10^-38 ~ 3.4 x 10^38</td>
</tr>
<tr>
<td>double</td>
<td>2.2 x 10^-308 ~ 1.8 x 10^308</td>
</tr>
</tbody></table>
<ul>
<li>컴파일러는 처리를 위해 0에서 127 사이 (ASCII 코드)의 정수로 문자를 변환합니다. ch1 = &#39;A&#39;이면 값 65가 ch1에 저장됩니다. 출력 형식은 변환 문자 (%d, %c)에 의해 결정됩니다.</li>
</ul>
<h1 id="sizeof-연산자">sizeof 연산자</h1>
<p><code>sizeof</code> 연산자는 변수 또는 데이터 유형의 크기를 바이트 단위로 결정하는 데 사용됩니다. 이는 <code>int</code>, <code>double</code>, <code>float</code>, <code>char</code>와 같은 기본 데이터 유형뿐만 아니라 구조체와 클래스와 같은 사용자 정의 데이터 유형과 함께 사용할 수 있습니다.</p>
<p>다음 예제 코드는 구조체와 <code>sizeof</code> 연산자를 사용하여 구조체의 크기와 멤버 변수의 크기를 계산합니다.</p>
<pre><code>#include &lt;stdio.h&gt;

struct person {
    char name[50];
    int age;
    float height;
};

int main() {
    struct person p1;
    printf(&quot;The size of the person struct is %d bytes\\\\\\\\n&quot;, sizeof(struct person));
    printf(&quot;The size of the name member variable is %d bytes\\\\\\\\n&quot;, sizeof(p1.name));
    printf(&quot;The size of the age member variable is %d bytes\\\\\\\\n&quot;, sizeof(p1.age));
    printf(&quot;The size of the height member variable is %d bytes\\\\\\\\n&quot;, sizeof(p1.height));
    return 0;
}
</code></pre><p>위 코드를 실행하면 다음 출력이 표시됩니다.</p>
<pre><code>The size of the person struct is 58 bytes
The size of the name member variable is 50 bytes
The size of the age member variable is 4 bytes
The size of the height member variable is 4 bytes
</code></pre><p>위 코드에서 <code>person</code> 구조체는 58 바이트 크기이며 <code>name</code> 멤버 변수는 50 바이트이며 <code>age</code> 및 <code>height</code> 멤버 변수는 각각 4 바이트 크기입니다.</p>
<p><code>sizeof</code> 연산자의 구문은 다음과 같습니다.</p>
<pre><code>sizeof(type);
</code></pre><p>여기서 <code>type</code>은 유효한 데이터 유형 또는 변수가 될 수 있습니다.</p>
<p>예를 들어 정수 변수의 크기를 바이트 단위로 찾으려면 다음 문을 사용할 수 있습니다.</p>
<pre><code>printf(&quot;The size of an integer variable is %d bytes&quot;, sizeof(int));
</code></pre><p>이는 대부분의 현대적인 시스템에서 정수 변수의 크기를 일반적으로 4 바이트로 출력합니다.</p>
<p><code>sizeof</code> 연산자는 부호 없는 정수형 <code>size_t</code>의 값으로 반환됨에 유의하세요.</p>
<p><code>size_t</code> 유형은 부호 없는 정수를 저장하는 데 사용되는 데이터 유형입니다. 이는 <code>sizeof</code> 연산자와 같은 목적으로 사용됩니다. <code>size_t</code>는 시스템에 따라 크기가 다르며 일반적으로 <code>unsigned int</code>와 동등합니다. 데이터 유형의 크기가 양수인 경우에 사용하기 적합합니다.</p>
<h1 id="unsigned-integer-datatype">Unsigned integer datatype</h1>
<ul>
<li>한정된 데이터 크기에서 양수만 저장하면 두배넓게 사용가능 → unsigned를 사용</li>
</ul>
<pre><code class="language-c">#include &lt;stdio.h&gt;

int main() {
    unsigned int a = 4294967295;
    int b = -1;
    printf(&quot;unsigned a = %u, signed b = %d\\\\n&quot;, a, b);
    printf(&quot;unsigned a = %d, signed b = %d\\\\n&quot;, a, b);
    return 0;
}
</code></pre>
<p>Output:</p>
<pre><code class="language-c">unsigned a = 4294967295, signed b = -1
unsigned a = -1, signed b = -1
</code></pre>
<p>이 코드는 <code>unsigned int</code>와 <code>int</code> 자료형을 사용하여 변수 <code>a</code>와 <code>b</code>를 선언합니다. <code>a</code>에는 <code>4294967295</code>를 할당하고, <code>b</code>에는 <code>-1</code>을 할당합니다. 첫 번째 <code>printf</code> 문은 <code>a</code>와 <code>b</code>를 <code>%u</code>와 <code>%d</code> 변환 문자와 함께 출력합니다. 두 번째 <code>printf</code> 문은 <code>a</code>와 <code>b</code>를 둘 다 <code>%d</code> 변환 문자와 함께 출력하고 있습니다.</p>
<p><code>%u</code>를 사용하여 unsigned int 변수를 출력할 때는 부호 없는 값으로 출력됩니다. 이는 <code>%d</code>를 사용하여 출력할 때와는 달리 값의 부호가 없기 때문입니다. 따라서 첫 번째 <code>printf</code> 문은 <code>a</code>의 값을 올바르게 출력합니다. 그러나 <code>b</code>는 부호 있는 변수이므로 <code>-1</code>을 출력합니다.</p>
<p>두 번째 <code>printf</code> 문에서 <code>%d</code> 변환 문자를 사용하여 <code>a</code>를 출력하면, 부호있는 int 변수로 간주되어 값이 부호화됩니다. <code>a</code>의 값이 <code>4294967295</code>이므로 이것은 부호화 된 int 값의 최대 값 <code>2147483647</code>보다 큽니다. 이는 정수 오버플로우를 일으키고, 이것이 부호화된 값 <code>-1</code>로 해석되어 출력된 이유입니다.</p>
<h1 id="실수-자료형">실수 자료형</h1>
<ul>
<li>데이터 구현방법이 정수와 다름</li>
<li>float, double, long double 로 구별</li>
</ul>
<table>
<thead>
<tr>
<th>자료형</th>
<th>크기 (byte)</th>
</tr>
</thead>
<tbody><tr>
<td>float</td>
<td>4</td>
</tr>
<tr>
<td>double</td>
<td>8</td>
</tr>
<tr>
<td>long double</td>
<td>16</td>
</tr>
</tbody></table>
<p>다음은 유효숫자를 파악하는 코드입니다.</p>
<pre><code>#include &lt;stdio.h&gt;

int main() {
    float f = 12345.67890123456789;
    double d = 12345.67890123456789;

    printf(&quot;float 유효숫자: %.20f\\n&quot;, f);
    printf(&quot;double 유효숫자: %.20lf\\n&quot;, d);

    return 0;
}
</code></pre><p>출력값:</p>
<pre><code>float 유효숫자: 12345.67871093750000000
double 유효숫자: 12345.67890123456789000
</code></pre><p>초기값과 출력값이 다른 이유는 float과 double이 표현할 수 있는 범위와 정밀도가 다르기 때문입니다. float은 4바이트(32비트)이며, double은 8바이트(64비트)입니다. float은 약 7자리의 유효숫자를 가지며, double은 약 16자리의 유효숫자를 가집니다. 따라서 float에서는 12345.67890123456789라는 값을 정확하게 표현할 수 없으므로 근사치인 12345.67871093750000000으로 출력됩니다. 반면 double은 12345.67890123456789라는 값을 정확하게 표현할 수 있으므로, 초기값과 출력값이 같습니다..</p>
<p>IEEE 754 부동소수점 방식으로 표현했을 경우, 23자리까지 유효 비트이며, 2의 23승은 10의 7승과 유사하기 때문에 십진수 경우 7자리까지 유효 숫자입니다.</p>
<pre><code>#include &lt;stdio.h&gt;

int main() {
    double d = 0.1;

    printf(&quot;double 저장값: %.20lf\\n&quot;, d);

    return 0;
}
</code></pre><p>위 코드를 실행하면 다음과 같은 출력이 나타납니다.</p>
<pre><code>double 저장값: 0.10000000000000000555
</code></pre><p>float과 double 부동소수점 방식으로 12345.67890123456789을 표현하면 다음과 같습니다.</p>
<table>
<thead>
<tr>
<th>자료형</th>
<th>부호비트</th>
<th>지수비트</th>
<th>가수비트</th>
</tr>
</thead>
<tbody><tr>
<td>float</td>
<td>0</td>
<td>10000011</td>
<td>00111100000011010001110</td>
</tr>
<tr>
<td>double</td>
<td>0</td>
<td>10000000010</td>
<td>0011110000001101000111001011000111110101110000100111</td>
</tr>
<tr>
<td>- 그래서 정수형을 기본으로 사용 실수형은 필요한 경우만 사용</td>
<td></td>
<td></td>
<td></td>
</tr>
<tr>
<td>- 실수형에서 유효숫자가 많은 double형을 기본으로 사용</td>
<td></td>
<td></td>
<td></td>
</tr>
<tr>
<td>- 그러나 유효숫자 내의 수도 2진수 변환시 무한소수로 변환되면 오차 발생</td>
<td></td>
<td></td>
<td></td>
</tr>
</tbody></table>
<h1 id="문자열-저장">문자열 저장</h1>
<ul>
<li>문자열은 char형을 배열형태로 만들어 저장</li>
</ul>
<pre><code class="language-c">char 배열명[문자열길이+1]=문자열;</code></pre>
<ul>
<li><p>문자열을 저장할 때는 배열의 마지막에 null 문자(<code>\\0</code>)를 추가해야 합니다. 이는 문자열의 끝을 표시하는 특별한 문자입니다. null 문자를 빠뜨리면 문자열을 처리하는 함수가 제대로 동작하지 않을 수 있습니다.</p>
<p>  예를 들어, 다음 코드에서는 문자열 <code>str</code>을 출력할 때 null 문자를 빠뜨렸기 때문에 예상치 못한 결과를 출력합니다.</p>
<pre><code class="language-c">  #include &lt;stdio.h&gt;

  int main() {
      char str[5] = &quot;hello&quot;;
      printf(&quot;%s&quot;, str);
      return 0;
  }
</code></pre>
<p>  출력값:</p>
<pre><code class="language-c">  hellorv▒
</code></pre>
<p>  위 코드에서 <code>str</code> 배열의 크기는 5이므로, 문자열 &quot;hello&quot;와 null 문자(<code>\0</code>)를 모두 저장할 수 있는 크기입니다. 그러나 null 문자(<code>\0</code>)를 생략하고 문자열을 출력하면 예상치 못한 결과가 출력됩니다.</p>
<p>  따라서 문자열을 저장할 때는 null 문자(<code>\0</code>)를 반드시 추가해야 합니다.</p>
<pre><code>  char str[6] = &quot;hello&quot;;
</code></pre><p>  위 코드에서는 문자열 &quot;hello&quot;와 null 문자(<code>\\0</code>)를 모두 저장할 수 있도록 배열의 크기를 6으로 지정하였습니다.</p>
</li>
<li><p>char 배열에 문자열 저장하고 출력</p>
</li>
</ul>
<pre><code>#include &lt;stdio.h&gt;

int main() {
    char str[6] = &quot;hello&quot;;
    printf(&quot;%s&quot;, str);
    return 0;
}
</code></pre><p>Output:</p>
<pre><code>hello
</code></pre><h1 id="문자열에-새로운-문자-저장">문자열에 새로운 문자 저장</h1>
<p>C 언어에서 새로운 문자열을 배열에 저장하는 방법은 <code>memcpy()</code>와 <code>strcpy()</code> 함수를 사용하는 것입니다.</p>
<h2 id="memcpy"><code>memcpy()</code></h2>
<p><code>memcpy()</code> 함수는 메모리 영역을 복사하는 데 사용됩니다. 아래 예시는 <code>memcpy()</code> 함수를 사용하여 문자열을 배열에 복사하는 코드입니다.</p>
<pre><code>#include &lt;stdio.h&gt;
#include &lt;string.h&gt;

int main() {
    char src[] = &quot;Hello, world!&quot;;
    char dest[20];

    memcpy(dest, src, strlen(src) + 1);

    printf(&quot;src: %s\\\\\\\\\\\\\\\\n&quot;, src);
    printf(&quot;dest: %s\\\\\\\\\\\\\\\\n&quot;, dest);

    return 0;
}
</code></pre><p><code>src</code> 배열에 문자열 &quot;Hello, world!&quot;를 저장하고, <code>dest</code> 배열에 <code>src</code> 배열의 내용을 <code>memcpy()</code> 함수를 사용하여 복사합니다. <code>strlen()</code> 함수는 문자열의 길이를 반환하며, <code>+ 1</code>은 NULL 문자를 포함하기 위한 것입니다.</p>
<h2 id="strcpy"><code>strcpy()</code></h2>
<p><code>strcpy()</code> 함수는 문자열을 복사하는 데 사용됩니다. 아래 예시는 <code>strcpy()</code> 함수를 사용하여 문자열을 배열에 복사하는 코드입니다.</p>
<pre><code>#include &lt;stdio.h&gt;
#include &lt;string.h&gt;

int main() {
    char src[] = &quot;Hello, world!&quot;;
    char dest[20];

    strcpy(dest, src);

    printf(&quot;src: %s\\\\\\\\\\\\\\\\n&quot;, src);
    printf(&quot;dest: %s\\\\\\\\\\\\\\\\n&quot;, dest);

    return 0;
}
</code></pre><p><code>src</code> 배열에 문자열 &quot;Hello, world!&quot;를 저장하고, <code>dest</code> 배열에 <code>src</code> 배열의 내용을 <code>strcpy()</code> 함수를 사용하여 복사합니다.</p>
<h2 id="결과-비교">결과 비교</h2>
<p><code>memcpy()</code>와 <code>strcpy()</code> 함수 모두 <code>src</code> 배열의 내용을 <code>dest</code> 배열에 복사합니다. 하지만 둘의 차이점은 NULL 문자 처리에 있습니다. <code>memcpy()</code> 함수는 NULL 문자를 복사하지 않습니다. 따라서 복사된 문자열이 정확한 문자열인지 확인하려면 NULL 문자를 수동으로 추가해야 합니다. 반면 <code>strcpy()</code> 함수는 NULL 문자를 복사하므로 추가 작업이 필요하지 않습니다.</p>
<p>문자열을 저장할 때 null 문자(<code>\\\\\\\\0</code>)를 생략하면 문자열을 처리하는 함수가 제대로 동작하지 않을 수 있습니다. 예를 들어, 다음 코드에서는 문자열 <code>str</code>을 출력할 때 null 문자를 빠뜨렸기 때문에 예상치 못한 결과를 출력합니다.</p>
<pre><code>#include &lt;stdio.h&gt;

int main() {
    char str[5] = &quot;hello&quot;;
    printf(&quot;%s&quot;, str);
    return 0;
}
</code></pre><p>출력값:</p>
<pre><code>hellorv▒
</code></pre><p><code>str</code> 배열의 크기는 5이므로, 문자열 &quot;hello&quot;와 null 문자(<code>\\0</code>)를 모두 저장할 수 있는 크기입니다. 그러나 null 문자(<code>\\0</code>)를 생략하고 문자열을 출력하면 예상치 못한 결과가 출력됩니다. 따라서 문자열을 저장할 때는 null 문자(<code>\\0</code>)를 반드시 추가해야 합니다.</p>
<h1 id="const를-사용한-변수">const를 사용한 변수</h1>
<ul>
<li><p><code>const</code> 키워드를 사용하여 상수를 선언할 수 있습니다. 상수는 한 번 정해지면 값을 변경할 수 없습니다.</p>
<pre><code>  const int a = 100;
</code></pre></li>
<li><p><code>const</code> 키워드를 사용하여 변수를 선언하면, 해당 변수는 읽기 전용이 됩니다. 따라서 값을 변경하려고 하면 컴파일러가 오류를 발생시킵니다.</p>
<pre><code>  const int a = 100;
  a = 200; // 컴파일 오류 발생
</code></pre></li>
<li><p><code>const</code> 키워드를 사용하여 함수 매개변수를 선언하면, 해당 매개변수에 전달되는 값이 변경되지 않도록 보장할 수 있습니다.</p>
<pre><code>  void print(const char* str) {
      printf(&quot;%s&quot;, str);
  }

  int main() {
      char* s = &quot;hello&quot;;
      print(s);
      return 0;
  }
</code></pre></li>
</ul>
<ul>
<li><p>const 변수를 초기화하는 방법에는 두 가지가 있습니다.</p>
<ol>
<li><p>첫번째 방법은 변수를 선언하면서 값을 할당하는 것입니다.</p>
<pre><code>const int a = 100;
</code></pre></li>
<li><p>두 번째 방법은 변수를 선언하고, 나중에 값을 할당하는 것입니다. 이때는 <code>const</code> 키워드 앞에 <code>extern</code> 키워드를 사용하여 선언합니다.</p>
<pre><code>// const.h
extern const int a;

// const.c
#include &quot;const.h&quot;
const int a = 100;

// main.c
#include &quot;const.h&quot;
int main() {
 printf(&quot;%d&quot;, a);
 return 0;
}
</code></pre><p><code>const</code> 키워드를 사용하면, 변수의 값을 변경할 수 없다는 것을 명시적으로 나타낼 수 있습니다. 이는 코드의 가독성을 높이고, 프로그램의 안정성을 높입니다.</p>
<p>다음은 <code>const</code> 변수를 사용하여 간단한 소스 코드 예시입니다. 변수 <code>a</code>를 <code>const</code>로 선언하고, <code>a</code> 값을 출력하는 코드입니다.</p>
<pre><code>#include &lt;stdio.h&gt;

int main() {
 const int a = 100;
 printf(&quot;%d&quot;, a);
 return 0;
}
</code></pre><p>출력 결과:</p>
<pre><code>100
</code></pre></li>
</ol>
</li>
</ul>
<h1 id="예약어와-식별자">예약어와 식별자</h1>
<ul>
<li>예약어 : 컴파일러와 사용방법이 약속된 단어</li>
<li>식별자 : 필요에 따라 만들어 사용하는 단어</li>
</ul>
<p>정수형과 실수형 데이터형의 종류, 크기, 값의 저장 범위, 출력 및 변환 문자에 대한 표입니다.</p>
<table>
<thead>
<tr>
<th>데이터형</th>
<th>종류</th>
<th>크기 (바이트)</th>
<th>값의 저장 범위</th>
<th>변환문자</th>
</tr>
</thead>
<tbody><tr>
<td>char</td>
<td>부호 있는 정수형</td>
<td>1</td>
<td>-128 ~ 127</td>
<td>%c %d</td>
</tr>
<tr>
<td>unsigned char</td>
<td>부호 없는 정수형</td>
<td>1</td>
<td>0 ~ 255</td>
<td>%u</td>
</tr>
<tr>
<td>short</td>
<td>부호 있는 정수형</td>
<td>2</td>
<td>-32,768 ~ 32,767</td>
<td>%d</td>
</tr>
<tr>
<td>unsigned short</td>
<td>부호 없는 정수형</td>
<td>2</td>
<td>0 ~ 65,535</td>
<td>%u</td>
</tr>
<tr>
<td>int</td>
<td>부호 있는 정수형</td>
<td>4</td>
<td>-2,147,483,648 ~ 2,147,483,647</td>
<td>%d</td>
</tr>
<tr>
<td>unsigned int</td>
<td>부호 없는 정수형</td>
<td>4</td>
<td>0 ~ 4,294,967,295</td>
<td>%u</td>
</tr>
<tr>
<td>long</td>
<td>부호 있는 정수형</td>
<td>4</td>
<td>-2,147,483,648 ~ 2,147,483,647</td>
<td>%ld</td>
</tr>
<tr>
<td>unsigned long</td>
<td>부호 없는 정수형</td>
<td>4</td>
<td>0 ~ 4,294,967,295</td>
<td>%lu</td>
</tr>
<tr>
<td>long long</td>
<td>부호 있는 정수형</td>
<td>8</td>
<td>-9,223,372,036,854,775,808 ~ 9,223,372,036,854,775,807</td>
<td>%lld</td>
</tr>
<tr>
<td>unsigned long long</td>
<td>부호 없는 정수형</td>
<td>8</td>
<td>0 ~ 18,446,744,073,709,551,615</td>
<td>%llu</td>
</tr>
<tr>
<td>float</td>
<td>실수형</td>
<td>4</td>
<td>1.2E-38 ~ 3.4E+38</td>
<td>%f</td>
</tr>
<tr>
<td>double</td>
<td>실수형</td>
<td>8</td>
<td>2.2E-308 ~ 1.8E+308</td>
<td>%lf</td>
</tr>
<tr>
<td>long double</td>
<td>실수형</td>
<td>12</td>
<td>3.4E-4932 ~ 1.1E+4932</td>
<td>%Lf</td>
</tr>
</tbody></table>
]]></description>
        </item>
        <item>
            <title><![CDATA[상수와 데이터 출력]]></title>
            <link>https://velog.io/@alextep_tree/%EC%83%81%EC%88%98%EC%99%80-%EB%8D%B0%EC%9D%B4%ED%84%B0-%EC%B6%9C%EB%A0%A5</link>
            <guid>https://velog.io/@alextep_tree/%EC%83%81%EC%88%98%EC%99%80-%EB%8D%B0%EC%9D%B4%ED%84%B0-%EC%B6%9C%EB%A0%A5</guid>
            <pubDate>Fri, 10 Mar 2023 03:35:10 GMT</pubDate>
            <description><![CDATA[<blockquote>
<p>Notion link : <a href="https://melon-taker-d3e.notion.site/2-f04a9eaa69fe4e64b4ae6436992e6607">https://melon-taker-d3e.notion.site/2-f04a9eaa69fe4e64b4ae6436992e6607</a></p>
</blockquote>
<blockquote>
</blockquote>
<ul>
<li>printf: 형식화된 출력</li>
<li>stdio.h: 표준 입력 출력</li>
<li>제어 문자: 문자는 아니지만 출력 방법에 영향을 미침<ul>
<li>\n: 새 줄</li>
<li>\t: 탭 (8 공백)</li>
<li>\b: 백스페이스</li>
<li>\r: 캐리지 리턴 (처음으로 이동)</li>
<li>\a: 경고음</li>
</ul>
</li>
<li>정수와 부동 소수점 출력<ul>
<li>정수: %d (10진수)</li>
<li>부동 소수점: %lf (긴 실수)<ul>
<li>.1lf는 소수점 첫 자리까지 출력</li>
</ul>
</li>
</ul>
</li>
</ul>
<h1 id="상수와-데이터-출력">상수와 데이터 출력</h1>
<ul>
<li>부동 소수점 상수는 정규화된 표기법으로 표현됨
(부동 소수점 상수의 정규화된 표기법 예: 3.14e-2)
%le 변환 문자 사용</li>
</ul>
<h1 id="문자와-문자열-상수의-표기">문자와 문자열 상수의 표기</h1>
<ul>
<li>작은 따옴표와 큰 따옴표 사용</li>
</ul>
<h1 id="상수-컴파일-후-비트-표현">상수 컴파일 후 비트 표현</h1>
<ul>
<li>10+20;을 입력하면 한 문자로 저장됩니다. 1,0,+,2,0,; 즉, 모든 문자는 문자열로 처리됩니다. 연산자는 컴파일 후에만 명령으로 처리됩니다.</li>
</ul>
<ul>
<li>문자 상수를 컴파일하면 이진 ASCII 코드로 변환됩니다.</li>
</ul>
<h1 id="컴파일된-정수-상수의-비트-표현">컴파일된 정수 상수의 비트 표현</h1>
<ul>
<li>양수의 변환<ul>
<li>숫자의 이진 표현을 그대로 사용합니다.</li>
</ul>
</li>
<li>음수의 변환<ul>
<li>2의 보수 방법을 사용합니다.</li>
<li>먼저 절대 값의 이진 표현을 나타냅니다.</li>
<li>각 비트를 반전한 다음 1을 더합니다.</li>
<li>주어진 숫자에 대해 결과 값을 이진으로 변환하고 첫 번째 비트를 부호 비트로 사용합니다.</li>
<li>예를 들어, -6.5는 6.5를 이진으로 나타내고 각 비트를 반전하고 1을 더하면 1101.1이 됩니다. 이를 다시 이진으로 변환하면 -6.5의 결과 값은 1010.1이 됩니다.</li>
</ul>
</li>
</ul>
<blockquote>
<p>   💡 뺄셈에 2의 보수를 사용하는 이유
       음수를 나타내기 위해 2의 보수를 사용하는 이유는 뺄셈 연산을 덧셈 연산으로 변환하기 위해서입니다. 예를 들어, 5-3은 5+(-3)으로 나타낼 수 있습니다. 이 경우, 2의 보수로 나타낸 -3은 11111101입니다. 이를 5에 더하면 1010이 되어 10진수로는 2와 같습니다. 이는 뺄셈을 수행하지 않고 덧셈 연산만으로 양수와 음수 간의 연산을 처리할 수 있다는 것을 의미합니다.</p>
</blockquote>
<h1 id="컴파일된-부동-소수점-상수의-비트-표현">컴파일된 부동 소수점 상수의 비트 표현</h1>
<ul>
<li>IEEE 754 표준 (단정밀도, 배정밀도, 쿼드 포맷)을 따릅니다.</li>
</ul>
<blockquote>
</blockquote>
<p>  💡 <strong>부동 소수점 구조</strong>
 9.6875는 이제 -1001.1011(2)입니다. 그러나 아직 끝나지 않았습니다. -1001.1011(2)를 그대로 저장하면 고정 소수점이 됩니다. 이는 부호 비트를 음수로, 정수 부분을 1001로, 소수 부분을 1011로 저장해야 합니다. 따라서 실수를 나타내는 지수를 사용하여 정규화 프로세스를 거칩니다.</p>
<blockquote>
<p>정규화하면 1001.1011(2)는 -1.0011011×2³이 됩니다. 정규화는 정수 부분을 1로 맞추고 소수점을 적절하게 조정하는 것을 의미합니다. 여기서 지수는 2³이며 일반적으로 3의 지수를 나타냅니다. 이제 실수를 부동 소수점 수로 간단히 표현할 수 있습니다. 정규화 후 소수 부분의 유효 숫자는 &quot;유효숫자&quot;라고 합니다.
9.6875 → -1001.1011(2) → -1.0011011×2³ → [부호 비트 음수, 지수 3, 유효숫자 0011011]
부동 소수점 형식은 미리 결정된 비트 수 (32Bit 또는 64Bit)를 적절하게 분배하여 부호 비트, 지수, 유효숫자를 할당하기 위한 규칙과 약속입니다. 가장 일반적으로 사용되는 표준은 보통 IEEE754이며, 이 글도 IEEE754를 기반으로 설명합니다. 이 글의 목적은 IEEE754를 설명하는 것이 아닙니다. 주요 목적은 부동 소수점의 표현 방법과 그 문제점을 검토하는 것입니다. 대표적인 IEEE754 표준을 기반으로 설명할 것입니다. 일반적으로 C/C++와 Java는 부동 소수점 유형으로 float (32Bit)와 double (64Bit)을 제공합니다. 물론 double은 더 크기 때문에 더 나은 정밀도와 더 넓은 범위의 표현을 제공하므로 가능하다면 double을 사용해야 합니다. 그러나 이 글의 목적은 구조와 원리를 설명하는 것이므로 편의상 float을 기준으로 설명할 것입니다.
float: [ 부호 비트 1Bit | 지수 8Bit | 유효숫자 23Bit ] = 총 32Bit
double: [ 부호 비트 1Bit | 지수 11Bit | 유효숫자 52Bit ] = 총 64Bit
이제 유효숫자를 설명하고, 그 다음에 부호 비트를 설명하고, 가장 어려운 부분인 지수를 설명해 보겠습니다! 부호 비트는 매우 간단합니다. 양수이면 0이고 음수이면 1입니다. 지수를 설명하기 전에 유효숫자를 설명해 보겠습니다! 이미 변환된 유효숫자를 왼쪽에서부터 채우기만 하면 됩니다. 물론 나머지 부분은 모두 0입니다. 이해하기 가장 어려운 부분은 지수입니다. 일반적으로 부동 소수점에서 사용되는 지수는 2-127~2-128입니다. 지수는 8비트로 127부터 128까지 256단계를 나타내야 합니다. 정수를 나타낼 때와 마찬가지로 2의 보수 방법을 사용하여 표현할 수 있을 것 같지만 그렇지 않습니다. 모든 0으로 채워진 [0000,0000]는 -127을 나타내고, 1이 증가하는 [0000,0001]은 -126을 나타내고, 이와 같이 반복하면 모든 1로 채워진 [1111,1111]은 128을 나타냅니다. 이 방법을 바이어스 표현이라고 하며, 이 구조가 선택된 이유에 대해 궁금할 수 있습니다. 순수한 0을 나타내기 위해서입니다. 일반적으로 모든 변수를 기본 값으로 설정하는 방법은 변수가 차지하는 모든 메모리 비트를 0으로 설정하는 것입니다. float의 모든 비트를 0으로 채우는 것으로 생각해 보십시오. 2의 보수 방법을 사용하여 지수를 표현하면 1.00000...00000×20=1이 됩니다. 즉, 부동 소수점에서 모든 비트를 0으로 채우면 기본 값이 1이 되어 문제가 됩니다. 이를 나타내기 위해 바이어스 표현이 사용됩니다. 이에 대한 의문이 생길 수 있지만 나중에 자세히 설명될 것입니다.
이제 실제로 -9.6875를 float으로 표현해 보겠습니다! [부호 비트 음수, 지수 3, 유효숫자 0011011]으로 정규화하고 1차 기준으로 -127을 취하면 130차 기준이 됩니다. 즉, 이진으로 130을 표현하면 [1000,0010]이 됩니다. 이제 비트 배열로 이동해 보겠습니다!<img src="https://dataonair.or.kr/publishing/img/knowledge/column_img_1534.jpg" alt="https://dataonair.or.kr/publishing/img/knowledge/column_img_1534.jpg">
실제로 이를 확인해 보겠습니다! C/C++는 이진을 직접 표현할 수 없지만 16진수 표기법으로 비트 배열을 표현할 수 있습니다. 4비트마다 하나의 16비트 숫자로 변경하면 [0xC11B,0000]으로 표현됩니다.</p>
</blockquote>
]]></description>
        </item>
        <item>
            <title><![CDATA[C 시작 ]]></title>
            <link>https://velog.io/@alextep_tree/1.C-%EC%8B%9C%EC%9E%91%ED%95%98%EA%B8%B0</link>
            <guid>https://velog.io/@alextep_tree/1.C-%EC%8B%9C%EC%9E%91%ED%95%98%EA%B8%B0</guid>
            <pubDate>Fri, 10 Mar 2023 03:14:28 GMT</pubDate>
            <description><![CDATA[<blockquote>
<p>Notion link : <a href="https://melon-taker-d3e.notion.site/1-9076ce3903e647e6a8691d8b261d31c2">https://melon-taker-d3e.notion.site/1-9076ce3903e647e6a8691d8b261d31c2</a></p>
</blockquote>
<h2 id="요약">요약</h2>
<ul>
<li>프로그램: 작업 순서 나열</li>
<li>C 언어는 UNIX에서 사용하도록 만들어졌습니다.</li>
<li>컴파일: 소스 코드를 기계 코드로 변환하는 과정</li>
<li>컴파일의 3 단계: 전처리 → 컴파일 → 링킹</li>
</ul>
<p><img src="https://velog.velcdn.com/images/alextep_tree/post/531533cb-a217-4d02-b6d0-4a262a407620/image.png" alt=""></p>
<h2 id="전처리-컴파일-링킹">전처리, 컴파일, 링킹</h2>
<p>C 코드를 실행하려면 소스 코드를 기계 코드로 변환해야 합니다. 이를 위해 전처리, 컴파일 및 링킹 단계를 거쳐야 합니다.</p>
<h3 id="전처리">전처리</h3>
<p>전처리 단계에서는 소스 코드의 일부를 다른 코드로 대체하고 전처리기 지시문(#으로 시작하는 문장)이 처리됩니다. 전처리기 지시문은 상수 또는 매크로를 정의하는 &#39;#define&#39; 형식으로 사용됩니다. 또한 &#39;#include&#39; 지시문을 사용하여 다른 헤더 파일을 가져올 수 있습니다.</p>
<pre><code>#include&lt;stdio.h&gt;
#define MAX 100
</code></pre><p>위의 예에서는 stdio.h 헤더 파일을 가져오고 MAX를 전처리 단계에서 100으로 정의합니다.</p>
<h3 id="컴파일">컴파일</h3>
<p>컴파일러는 전처리된 코드를 어셈블리 코드로 변환합니다. 어셈블리 코드는 기계 코드로 직접 실행할 수 없지만 기계 코드로 변환하기 충분히 가깝습니다.</p>
<pre><code>int main()
{
    printf(&quot;Hello, World!&quot;);
    return 0;
}
</code></pre><p>위의 예에서 컴파일러는 이 코드를 어셈블리 코드로 변환합니다.</p>
<pre><code>    .file   &quot;hello.c&quot;
    .section    .rodata
.LC0:
    .string &quot;Hello, World!&quot;
    .text
    .globl  main
    .type   main, @function
main:
.LFB0:
    .cfi_startproc
    leaq    .LC0(%rip), %rdi
    movl    $0, %eax
    call    printf@PLT
    movl    $0, %eax
    leave
    ret
</code></pre><h3 id="오브젝트-파일">오브젝트 파일</h3>
<p>컴파일러가 소스 코드를 어셈블리 코드로 변환한 후, 어셈블러는 이를 오브젝트 파일로 변환합니다. 오브젝트 파일은 어셈블리 코드를 기계 코드로 변환하기 위해 사용되는 중간 파일입니다. 오브젝트 파일은 링커와 결합하여 여러 개의 오브젝트 파일을 결합하여 실행 파일을 만드는 데 사용됩니다.</p>
<h3 id="링킹">링킹</h3>
<p>링킹 단계에서 컴파일러는 오브젝트 파일과 라이브러리 파일을 링크하여 실행 파일을 만듭니다. 오브젝트 파일은 컴파일러에서 생성된 어셈블리 코드를 포함하는 이진 파일입니다. 오브젝트 파일은 링커와 결합하여 여러 개의 오브젝트 파일을 결합하여 실행 가능한 파일을 만드는 데 사용됩니다. 링킹 프로세스에서 함수 또는 변수를 서로 연결하여 하나의 실행 파일을 만듭니다.</p>
<p>예를 들어, 다음 코드가 있다면:</p>
<pre><code>#include &lt;stdio.h&gt;
int main()
{
    printf(&quot;Hello, World!&quot;);
    return 0;
}
</code></pre><p>이 코드를 컴파일하고 링크하면 실행 파일이 생성됩니다. 이 실행 파일을 실행하면 &quot;Hello, World!&quot;가 출력됩니다.</p>
<h2 id="c-언어의-탄생">C 언어의 탄생</h2>
<ul>
<li>Dennis Ritchie는 Ken Thompson이 UNIX 시스템에서 사용하기 위해 만든 B 언어를 개발했습니다.</li>
<li>장점<ul>
<li>시스템 프로그래밍(하드웨어 제어)이 가능합니다.</li>
<li>이식 가능한 프로그램을 만들 수 있습니다.</li>
<li>함수를 사용하여 개별적인 프로그래밍이 가능합니다.</li>
</ul>
</li>
</ul>
]]></description>
        </item>
    </channel>
</rss>