<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>Coding Giraffe.</title>
        <link>https://velog.io/</link>
        <description>Coding Giraffe.</description>
        <lastBuildDate>Thu, 18 Aug 2022 14:25:16 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <image>
            <title>Coding Giraffe.</title>
            <url>https://images.velog.io/images/giraffe_/profile/19f637a4-f597-4625-b33b-b635abe546ed/CodingGiraffe.jpg</url>
            <link>https://velog.io/</link>
        </image>
        <copyright>Copyright (C) 2019. Coding Giraffe.. All rights reserved.</copyright>
        <atom:link href="https://v2.velog.io/rss/giraffe_" rel="self" type="application/rss+xml"/>
        <item>
            <title><![CDATA[미디어 쿼리]]></title>
            <link>https://velog.io/@giraffe_/%EB%AF%B8%EB%94%94%EC%96%B4-%EC%BF%BC%EB%A6%AC</link>
            <guid>https://velog.io/@giraffe_/%EB%AF%B8%EB%94%94%EC%96%B4-%EC%BF%BC%EB%A6%AC</guid>
            <pubDate>Thu, 18 Aug 2022 14:25:16 GMT</pubDate>
            <description><![CDATA[<h1 id="미디어-쿼리media-queries">미디어 쿼리(Media Queries)</h1>
<p>미디어 매체(sreen, print 등)에 각각 다른 CSS Style을 적용할 수 있도록 만드는 것 입니다. 즉, 같은 웹 페이지를 환경에따라 최적화하여 제공할 수 있도록합니다.</p>
<h1 id="구문">구문</h1>
<pre><code class="language-css">@media media_queries {CSS Style}</code></pre>
<p>미디어 쿼리 구문이 참이면 CSS Style이 적용되고, 거짓이면 적용되지않습니다.</p>
<pre><code class="language-css">media_query_list
: S* [meida_query [&#39;,&#39; S* media_query]* ]?
;

media_query
: [only | not]? S* Media_Type S* [and S* expression]*
| expression [and S* expression ]*
;

expression
: &#39;(&#39; S* Media_Feature S* [&#39;:&#39; S* expr ]? &#39;)&#39; S*
;</code></pre>
<ul>
<li><p><strong>미디어 타입(Media Type)</strong> : all, print, screen 등이 있으며, 어떤 미디어 타입에 적용할지 선택합니다.
디스플레이가 있는 미디어들은 전부 &#39;screen&#39;에 해당됩니다.</p>
</li>
<li><p><strong>미디어 특성(Media Features)</strong> : width, height, orientation 등이 있으며, 어떤 미디어 특성을 이용하여 적용할지 선택합니다.
&#39;width&#39;는 뷰포트(브라우저)의 너비로, 스크린의 크기가 아닙니다. width 앞에는 &#39;min-(최솟값)&#39; 또는 &#39;max-(최댓값)&#39; prefix가 붙을 수 있습니다.
&#39;orientation&#39;은 미디어의 세로와 가로 모드를 구분하며, width와 height의 값을 비교하여 결정합니다. 세로 모드는 &#39;portrait&#39;, 가로 모드는 &#39;landscape&#39; 키워드와 매칭됩니다.</p>
</li>
<li><p><strong>S*</strong> : 공백을 의미합니다.</p>
</li>
<li><p><strong>not</strong> : 하나의 media query 전체를 부정합니다.</p>
</li>
<li><p><strong>내용?</strong> : ? 앞의 내용이 나오지않거나 한번만 나와야함을 의미합니다.</p>
</li>
<li><p><strong>구문*</strong> : * 앞의 내용이 나오지않거나 여러번 나올 수 있음을 의미합니다.</p>
</li>
<li><p><strong>따옴표(&#39;&#39;)</strong> : 따옴표로 묶인 부분은 반드시 작성되야함을 의미합니다.</p>
</li>
</ul>
<h1 id="뷰포트-사이즈별-스타일-적용">뷰포트 사이즈별 스타일 적용</h1>
<p>&#39;@meida screen&#39;을 이용하여 뷰포트 크기별로 스타일을 적용합니다.</p>
<pre><code>&lt;div&gt;
    &lt;div&gt;현재 디바이스 환경은&lt;/div&gt;
    &lt;span&gt;&lt;/span&gt;
    &lt;div&gt;입니다!&lt;/div&gt;
&lt;/div&gt;</code></pre><pre><code class="language-css">div{
    background-color: white;
    font-size: 30px;
    width: 350px;
    text-align: center;
    margin: auto;
}

span{
    background-color: black;
    font-size: 70px;
    color: white;
}</code></pre>
<p><br><br></p>
<pre><code class="language-css">@media screen and (max-width: 767px){
    body{ background-color: pink; }
    span::after{ content: &quot;모바일&quot;; }
}

@media screen and (min-width: 768px) and (max-width: 1024px){
    body{ background-color: lightgreen; }
    span::after{ content: &quot;태블릿&quot;; }
}

@media screen and (min-width: 1025px){
    body{ background-color: skyblue; }
    span::after{ content: &quot;PC&quot;; }
}</code></pre>
<p>미디어 쿼리는 해당 구문이 참이어야 스타일이 적용됩니다. 따라서 &#39;and&#39;로 연결된 경우 해당 구문이 모두 참이어야 스타일이 적용됩니다.</p>
<blockquote>
<p><img src="https://velog.velcdn.com/images/giraffe_/post/68305413-ca16-41fe-939b-a07abc980610/image.png" alt=""></p>
</blockquote>
<blockquote>
<p><img src="https://velog.velcdn.com/images/giraffe_/post/3ed194eb-da0c-4007-af73-af72e0659596/image.png" alt=""></p>
</blockquote>
<p>구문에 작성된대로 767px까지 해당 스타일이 적용됨을 확인할 수 있습니다.</p>
<blockquote>
<p><img src="https://velog.velcdn.com/images/giraffe_/post/428a8391-6188-4ff1-92ea-dcdcf25db342/image.png" alt=""></p>
</blockquote>
<blockquote>
<p><img src="https://velog.velcdn.com/images/giraffe_/post/a6ebb9e8-a0fb-4283-9e61-bd937dbd7755/image.png" alt=""></p>
</blockquote>
<p>구문에 작성된대로 767px부터 1024px까지 해당 스타일이 적용됨을 확인할 수 있습니다.</p>
<blockquote>
<p><img src="https://velog.velcdn.com/images/giraffe_/post/edbe9a77-d3a4-48e6-b09d-ea854dfe39fd/image.png" alt=""></p>
</blockquote>
<blockquote>
<p><img src="https://velog.velcdn.com/images/giraffe_/post/0a62d56f-988c-4bce-908e-7b7a14ca037b/image.png" alt=""></p>
</blockquote>
<p>구문에 작성된대로 1025px부터 해당 스타일이 적용됨을 확인할 수 있습니다.</p>
<p>위처럼 경우따라 나눠서 미디어 쿼리를 작성할 수도 있지만, 하나의 환경을 중심으로 다른 환경을 지원하는 경우에는 보다 효율적으로 미디어 쿼리를 작성할 수 있습니다.</p>
<br>

<pre><code class="language-css">body{ background-color: pink; }
span::after{ content: &quot;모바일&quot;; }

@media screen and (min-width: 768px) and (max-width: 1024px){
    body{ background-color: lightgreen; }
    span::after{ content: &quot;태블릿&quot;; }
}

@media screen and (min-width: 1025px){
    body{ background-color: skyblue; }
    span::after{ content: &quot;PC&quot;; }
}</code></pre>
<p>위는 &#39;moblie first(모바일 환경 기준)&#39;으로 작성한 미디어 쿼리입니다.
모바일 환경을 기준으로 코드를 작성하고 다른 환경은 미디어 쿼리를 이용하여 다른 스타일을 적용시킵니다.</p>
<blockquote>
<p><img src="https://velog.velcdn.com/images/giraffe_/post/7a9bb3ca-f0f6-4020-be1f-f59bcfd92957/image.png" alt=""></p>
</blockquote>
<blockquote>
<p><img src="https://velog.velcdn.com/images/giraffe_/post/de2f6a00-011b-4adb-903f-9101c5587c06/image.png" alt=""></p>
</blockquote>
<blockquote>
<p><img src="https://velog.velcdn.com/images/giraffe_/post/be25e2bb-daa0-42fd-8b2f-8cbf1d253756/image.png" alt=""></p>
</blockquote>
<blockquote>
<p><img src="https://velog.velcdn.com/images/giraffe_/post/7bba0d60-9bd2-46fb-b2f2-0ab9831b2447/image.png" alt=""></p>
</blockquote>
<blockquote>
<p><img src="https://velog.velcdn.com/images/giraffe_/post/7aec87f0-2f41-4533-ab80-f81e667619b7/image.png" alt=""></p>
</blockquote>
<blockquote>
<p><img src="https://velog.velcdn.com/images/giraffe_/post/89e547f2-1b21-456d-a86f-396afe692621/image.png" alt=""></p>
</blockquote>
<p>결과는 동일한 것을 확인할 수 있습니다.</p>
<p>마찬가지로 다른 환경을 기준으로하여 미디어 쿼리를 작성할 수도 있습니다.</p>
<pre><code class="language-css">body{ background-color: skyblue; }
span::after{ content: &quot;PC&quot;; }

@media screen and (max-width: 767px){
    body{ background-color: pink; }
    span::after{ content: &quot;모바일&quot;; }
}

@media screen and (min-width: 768px) and (max-width: 1024px){
    body{ background-color: lightgreen; }
    span::after{ content: &quot;태블릿&quot;; }
}</code></pre>
<p>PC 환경을 기준으로 미디어 쿼리를 작성하였습니다.</p>
<blockquote>
<p><img src="https://velog.velcdn.com/images/giraffe_/post/0570c22d-3c85-4016-9a4f-ebbfb3f2a90f/image.png" alt=""></p>
</blockquote>
<blockquote>
<p><img src="https://velog.velcdn.com/images/giraffe_/post/04c50591-823f-4109-9996-76f1c72dd13e/image.png" alt=""></p>
</blockquote>
<blockquote>
<p><img src="https://velog.velcdn.com/images/giraffe_/post/da79ae5a-0da9-46f3-820d-8969a5ddea75/image.png" alt=""></p>
</blockquote>
<blockquote>
<p><img src="https://velog.velcdn.com/images/giraffe_/post/e90cadbd-b7e9-4576-96c4-a56260e086bb/image.png" alt=""></p>
</blockquote>
<blockquote>
<p><img src="https://velog.velcdn.com/images/giraffe_/post/669b31f7-4e3f-4a82-a844-0c46b1d620d2/image.png" alt=""></p>
</blockquote>
<blockquote>
<p><img src="https://velog.velcdn.com/images/giraffe_/post/5d3e28fa-ea97-4773-b7d0-13b6ec3d3714/image.png" alt=""></p>
</blockquote>
<p>역시 결과는 동일합니다.</p>
<h1 id="페이지-인쇄시-스타일-적용">페이지 인쇄시 스타일 적용</h1>
<p>&#39;@media print&#39;를 이용하여 페이지를 인쇄할 때 출력물에 스타일을 적용합니다.</p>
<pre><code>&lt;div&gt;W3C에서는 &lt;a href=&quot;https://validator.w3.org/&quot;&gt;&#39;Markup Validation Service&#39;&lt;/a&gt;라는 Markup 언어로 작성된 구문의 유효성을 검사해주는 서비스를 제공합니다.&lt;/div&gt;
&lt;div&gt;또한, &lt;a href=&quot;https://jigsaw.w3.org/css-validator/&quot;&gt;&#39;CSS Validation Service&#39;&lt;/a&gt;라는 CSS로 작성된 구문의 유효성을 검사해주는 서비스도 제공합니다.&lt;/div&gt;</code></pre><pre><code class="language-css">div{
    font-size: 19px;
}</code></pre>
<blockquote>
<p><img src="https://velog.velcdn.com/images/giraffe_/post/711fa9e0-1ea1-4739-8215-ed8b7007726a/image.png" alt=""></p>
</blockquote>
<pre><code class="language-css">@media print{
    a{
        color: black;
        text-decoration: none;
    }
    a::after{
        display: inline;
        content: &quot;(&quot;attr(href)&quot;)&quot;;
    }
}</code></pre>
<blockquote>
<p><img src="https://velog.velcdn.com/images/giraffe_/post/0ffd3051-cc71-4bc1-8e09-ec3a6c5b2493/image.png" alt=""></p>
</blockquote>
<p>인쇄물 출력시에도 그에맞게 스타일을 적용할 수 있습니다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[CSS 속성 - 레이아웃]]></title>
            <link>https://velog.io/@giraffe_/CSS-%EC%86%8D%EC%84%B1-%EB%A0%88%EC%9D%B4%EC%95%84%EC%9B%83</link>
            <guid>https://velog.io/@giraffe_/CSS-%EC%86%8D%EC%84%B1-%EB%A0%88%EC%9D%B4%EC%95%84%EC%9B%83</guid>
            <pubDate>Tue, 16 Aug 2022 14:01:18 GMT</pubDate>
            <description><![CDATA[<h1 id="display">display</h1>
<p>요소의 rendering box 유형을 지정합니다. 기본값은 요소마다 기본으로 가지는 level(inline, block 등)입니다.</p>
<pre><code class="language-css">display: keyword;</code></pre>
<ul>
<li><p><strong>none</strong> : 요소를 렌더링하지않습니다.</p>
</li>
<li><p><strong>inline</strong> : 요소를 inline level처럼 렌더링합니다.</p>
</li>
<li><p><strong>block</strong> : 요소를 block level처럼 렌더링합니다.</p>
</li>
<li><p><strong>inline-block</strong> : block level 성질을 가지는 요소를 inline level 요소처럼 배치하여 렌더링합니다.</p>
</li>
</ul>
<br>
inline level 요소와 block level 요소는 배치 외에도 박스 모델 속성에서 적용되는 부분에 차이를 보입니다. 

<pre><code>&lt;span&gt;inline level&lt;/span&gt;
&lt;div&gt;block level&lt;/div&gt;</code></pre><pre><code class="language-css">span{
    background-color: skyblue;
    width: 100px;
    height: 100px;
    padding: 30px;
    border: 3px solid blue;
    margin: 50px;
}

div{
    background-color: lightgreen;
    width: 100px;
    height: 100px;
    padding: 30px;
    border: 3px solid green;
    margin: 50px;
}</code></pre>
<blockquote>
<p><img src="https://velog.velcdn.com/images/giraffe_/post/d9c017b8-5664-4c22-8380-7984dd0b68f0/image.png" alt=""></p>
</blockquote>
<p><code>&lt;span&gt;</code>과 <code>&lt;div&gt;</code> 요소에 색상값을 제외한 박스 모델 속성을 동일하게 적용했음에도 결과물이 다른 것을 확인할 수 있습니다.</p>
<p><strong>inline level 요소</strong>는 &#39;padding, border&#39; 속성은 적용되는 반면, &#39;width, height&#39; 속성은 적용되지않은 것을 확인할 수 있습니다. 그리고 &#39;margin&#39; 속성은 좌우에만 적용됩니다.</p>
<p><strong>block level 요소</strong>는 모든 박스 모델 속성이 정상적으로 적용됩니다.</p>
<p>display 속성에서 &#39;inline, block&#39;으로 값을 설정하면 위처럼 level에따라 박스모델이 달리 적용되는 것을 확인할 수 있습니다.</p>
<p>&#39;<strong>inline-block 속성</strong>&#39;으로 값을 설정하게되면 <strong>각 요소는 block level 요소처럼 박스 모델 속성이 적용</strong>되지만, 배치는 block level 요소처럼 한 줄을 모두 차지하여 줄마다 배치되는 것이아닌, <strong>inline level 요소처럼 한 줄에 요소들이 배치</strong>됩니다.</p>
<pre><code>&lt;div class=&quot;none&quot;&gt;display: none;&lt;/div&gt;
&lt;div class=&quot;inline&quot;&gt;display: inline;&lt;/div&gt;
&lt;div class=&quot;inline&quot;&gt;display: inline;&lt;/div&gt;
&lt;div class=&quot;block&quot;&gt;display: block;&lt;/div&gt;
&lt;div class=&quot;block&quot;&gt;display: block;&lt;/div&gt;
&lt;div class=&quot;inline-block&quot;&gt;display: inline-block;&lt;/div&gt;
&lt;div class=&quot;inline-block&quot;&gt;display: inline-block;&lt;/div&gt;</code></pre><pre><code class="language-css">div{
    width: 50px;
    height: 50px;
    padding: 20px;
    border: 3px solid currentColor;
    margin: 50px;
}

.none{
    background-color: black;
    display: none;
}

.inline{
    background-color: pink;
    display: inline;
}

.block{
    background-color: skyblue;
    display: block;
}

.inline-block{
    background-color: lightgreen;
    display: inline-block;
}</code></pre>
<blockquote>
<p><img src="https://velog.velcdn.com/images/giraffe_/post/c6a62287-d837-4954-8acf-8ae64d734614/image.png" alt=""></p>
</blockquote>
<h1 id="visibility">visibility</h1>
<p>요소를 화면에 표시할지 여부를 지정합니다.</p>
<pre><code class="language-css">display: keyword;</code></pre>
<ul>
<li><p><strong>visible</strong> : <strong>기본값</strong>으로, 화면에 요소를 표시합니다.</p>
</li>
<li><p><strong>hidden</strong> : 화면에 요소를 표시하지않지만, <strong>공간(박스 모델 영역)은 차지</strong>합니다.</p>
</li>
</ul>
<br>

<pre><code>&lt;div class=&quot;visible&quot;&gt;visiblity: visible;&lt;/div&gt;
&lt;div class=&quot;hidden&quot;&gt;visiblity: hidden;&lt;/div&gt;
&lt;div class=&quot;visible&quot;&gt;visiblity: visible;&lt;/div&gt;</code></pre><pre><code class="language-css">div{
    width: 50px;
    height: 50px;
    padding: 20px;
    border: 3px solid currentColor;
    margin: 50px;
}

.visible{
    background-color: skyblue;
    visibility: visible;
}

.hidden{
    background-color: lightgreen;
}</code></pre>
<blockquote>
<p><img src="https://velog.velcdn.com/images/giraffe_/post/eb0de72f-cba1-42ea-bded-65309229fe06/image.png" alt=""></p>
</blockquote>
<pre><code class="language-css">.hidden{
    visibility: hidden;
}</code></pre>
<blockquote>
<p><img src="https://velog.velcdn.com/images/giraffe_/post/9a19ee0c-ab2b-4571-ab61-6551d1af7a0a/image.png" alt=""></p>
</blockquote>
<p><code>visiblity: hidden;</code>은 요소의 영역은 그대로 유지하고 표시만 되지않습니다.(<strong>렌더링되며 DOM에 존재 O</strong>)</p>
<br>

<pre><code>&lt;div class=&quot;visible&quot;&gt;visiblity: visible;&lt;/div&gt;
&lt;div class=&quot;none&quot;&gt;display: none;&lt;/div&gt;
&lt;div class=&quot;visible&quot;&gt;visiblity: visible;&lt;/div&gt;</code></pre><pre><code class="language-css">div{
    width: 50px;
    height: 50px;
    padding: 20px;
    border: 3px solid currentColor;
    margin: 50px;
}

.visible{
    background-color: skyblue;
    visibility: visible;
}

.none{
    background-color: lightgreen;
    display: none;
}</code></pre>
<blockquote>
<p><img src="https://velog.velcdn.com/images/giraffe_/post/a965d9ff-3664-4f1a-8bd6-c7e2f4ab5020/image.png" alt=""></p>
</blockquote>
<p><code>display: none;</code>은 요소의 영역 자체를 유지하지않고, 표시도 되지않습니다.(<strong>렌더링되지않으며 DOM에 존재 X</strong>)</p>
<h1 id="float">float</h1>
<p>요소를 일반적 흐름에서 벗어나게하여 배치하는 속성입니다.</p>
<pre><code class="language-css">float: keyword;</code></pre>
<ul>
<li><p><strong>none</strong> : <strong>기본값</strong>으로, float을 적용하지않습니다.</p>
</li>
<li><p><strong>left</strong> : 좌측 상단으로 float을 적용합니다.</p>
</li>
<li><p><strong>right</strong> : 우측 상단으로 float을 적용합니다.</p>
</li>
</ul>
<br>

<pre><code>&lt;span class=&quot;left&quot;&gt;float: left;&lt;/span&gt;
&lt;span class=&quot;right&quot;&gt;float: right;&lt;/span&gt;
&lt;p&gt;HyperText Markup Language Cascading Style Sheets HyperText Markup Language Cascading Style Sheets HyperText Markup Language Cascading Style Sheets HyperText Markup Language Cascading Style Sheets HyperText Markup Language Cascading Style Sheets &lt;/p&gt;</code></pre><p><br><br></p>
<pre><code class="language-css">div{
    width: 500px;
    height: 200px;
    border: 3px solid currentColor;
    font-size: 20px;
}

.left{
    float: none;
    background-color: skyblue;
    border: 2px solid blue;
    margin: 10px;
}

.right{
    float: none;
    background-color: lightgreen;
    border: 2px solid green;
    margin: 10px;
}</code></pre>
<blockquote>
<p><img src="https://velog.velcdn.com/images/giraffe_/post/ca0f07cd-864f-4c5d-99b2-681cafdf6c2d/image.png" alt=""></p>
</blockquote>
<p><code>&lt;span&gt;</code>요소들이 inline level 요소의 특성을 띄며 배치되있는 것을 확인할 수 있습니다.</p>
<pre><code class="language-css">div{
    width: 500px;
    height: 200px;
    border: 3px solid currentColor;
    font-size: 20px;
}

.left{
    float: left;
    background-color: skyblue;
    border: 2px solid blue;
    margin: 10px;
}

.right{
    float: right;
    background-color: lightgreen;
    border: 2px solid green;
    margin: 10px;
}</code></pre>
<blockquote>
<p><img src="https://velog.velcdn.com/images/giraffe_/post/f6cf69ce-91d2-438d-82d4-af50d09371f4/image.png" alt=""></p>
</blockquote>
<p><code>&lt;span&gt;</code>요소들에 각각 <code>float: left | right;</code> 속성을 적용시 각각 좌측 상단과 우측 상단으로 배치된 것을 확인할 수 있습니다.
그리고 float된 요소는 inline level 요소의 특성이 아닌, <strong>block level 요소의 특성</strong>을 띄는 것(margin 상하까지 모두 적용)을 확인할 수 있습니다. 이는 실제로 개발자 도구로 확인해도 기존 <code>display: inline;</code>에서 <code>display: block;</code>으로 변경되는 것을 확인할 수 있습니다. 하지만 <strong>display 값이 &#39;inline-table, flex 등&#39;인 경우에는 &#39;block&#39;으로 변경되지않습니다</strong>.
또한 float 적용시 <strong>주변의 텍스트나 인라인 요소가 float된 요소를 감싸는 것</strong>을 확인할 수 있습니다.</p>
<h2 id="clear">clear</h2>
<p>요소를 float의 영향에서 벗어나게합니다. block level의 요소만 적용 가능합니다.</p>
<pre><code class="language-css">clear: keyowrd;</code></pre>
<ul>
<li><p><strong>none</strong> : <strong>기본값</strong>으로, 요소가 float의 영향을 받습니다.</p>
</li>
<li><p><strong>left</strong> : 요소가 left float된 요소의 영향을 받지않습니다. </p>
</li>
<li><p><strong>right</strong> : 요소가 right float된 요소의 영향을 받지않습니다.</p>
</li>
<li><p><strong>both</strong> : 요소가 모든 float된 요소의 영향을 받지않습니다.</p>
</li>
</ul>
<br>

<pre><code>&lt;div class=&quot;container&quot;&gt;
    &lt;div class=&quot;left&quot;&gt;float: left;&lt;/div&gt;
    &lt;div class=&quot;box&quot;&gt;&lt;/div&gt;
&lt;/div&gt;</code></pre><pre><code class="language-css">.container{
    width: 300px;
    height: 300px;
    border: 3px solid black;
}

.left{
    float: left;
    width: 100px;
    height: 100px;
    background-color: skyblue;
    border: 2px solid blue;
}

.box{
    clear: none;
    width: 200px;
    height: 100px;
    border: 3px solid red;
}</code></pre>
<blockquote>
<p><img src="https://velog.velcdn.com/images/giraffe_/post/38d8da4a-e332-45c1-bbae-9d02a2a7c1d5/image.png" alt=""></p>
</blockquote>
<p><code>&lt;div.box&gt;</code>요소가 left float된 요소의 영향을 받고있습니다.</p>
<pre><code class="language-css">.box{
    clear: left;
}</code></pre>
<blockquote>
<p><img src="https://velog.velcdn.com/images/giraffe_/post/979de292-f9ab-40d1-9468-21b0cfc349ee/image.png" alt=""></p>
</blockquote>
<p><code>clear: left;</code>를 선언해줌으로써 <code>&lt;div.box&gt;</code>요소가 left float 된 요소의 영향에서 벗어난 것을 확인할 수 있습니다.</p>
<h1 id="position">position</h1>
<p>요소를 어떻게 배치할지 지정합니다.</p>
<pre><code class="language-css">position: keyword;</code></pre>
<ul>
<li><p><strong>static</strong> : <strong>기본값</strong>으로, normal-flow에 따라 배치되며, offset이 적용되지않습니다.</p>
</li>
<li><p><strong>relative</strong> : normal-flow에 따라 배치되며, 해당 요소의 원래 위치가 offset의 기준점이됩니다. 부모 요소의 position 속성에 영향을 받지않으며, 주변 요소에 영향을 주지않으면서 offset이 적용됩니다.</p>
</li>
<li><p><strong>absolute</strong> : normal-flow를 벗어나 배치되며, 조상요소 중 position 값이 static이 아닌 요소가 offset의 기준점(모든 조상 요소가 해당 사항이 없으면 <code>&lt;body&gt;</code>가 기준점)이됩니다. 해당 요소가 inline level이면 block level로 변경됩니다.</p>
</li>
<li><p><strong>fixed</strong> : normal-flow를 벗어나 배치되며, 뷰포트(브라우저)가 offset의 기준점이됩니다.</p>
</li>
</ul>
<p>(<strong>※ normal-flow</strong> : 블록 레벨 요소가 상하로 배치되고, 인라인 레벨 요소가 좌우로 배치되는 것처럼, 일반적 상황에서 요소가 가진 성질에따라 배치되는 성질입니다.)</p>
<h2 id="offset">offset</h2>
<pre><code>top | bottom | left | right : auto | length;</code></pre><p>속성으로 &#39;top, bottom, left, right&#39;를 가지며, 값은 <strong>기본값</strong>인 &#39;auto&#39;와 길이 단위를 사용하여 지정할 수 있습니다.
기존 박스 모델 속성과 달리, percent(%)로 값 적용시, 상하좌우 모두 가로를 기준으로 적용되는 것이 아닌, <strong>상하는 요소의 height, 좌우는 요소의 width를 기준</strong>으로 적용됩니다.</p>
<h2 id="position-example">position example</h2>
<pre><code>&lt;div class=&quot;container&quot;&gt;
    &lt;div class=&quot;tb&quot;&gt;&lt;/div&gt;
    &lt;div class=&quot;box&quot;&gt;&lt;/div&gt;
    &lt;div class=&quot;tb&quot;&gt;&lt;/div&gt;
&lt;/div&gt;</code></pre><pre><code class="language-css">.tb{
    background-color: lightgreen;
    width: 590x;
    height: 40px;
    border: 5px solid green;
}

.container{
    background-color: skyblue;
    width: 600px;
    height: 300px;
    border: 5px solid blue;
    padding: 10px;
}</code></pre>
<h3 id="static">static</h3>
<pre><code class="language-css">.box{
    position: static;
}</code></pre>
<blockquote>
<p><img src="https://velog.velcdn.com/images/giraffe_/post/6b2c6ad8-d219-44a1-af1f-120fe8073c66/image.png" alt=""></p>
</blockquote>
<pre><code class="language-css">.box{
    position: static;
    top: 50px;
    left: 50px;
}</code></pre>
<blockquote>
<p><img src="https://velog.velcdn.com/images/giraffe_/post/6b2c6ad8-d219-44a1-af1f-120fe8073c66/image.png" alt=""></p>
</blockquote>
<p>static인 경우 offset이 적용되지않습니다.</p>
<h3 id="relative">relative</h3>
<pre><code class="language-css">.box{
    position: relative;
}</code></pre>
<blockquote>
<p><img src="https://velog.velcdn.com/images/giraffe_/post/6b2c6ad8-d219-44a1-af1f-120fe8073c66/image.png" alt=""> </p>
</blockquote>
<p>offset이 적용되지않은 relative는 배치에 변화가 없는 것을 확인할 수 있습니다.</p>
<pre><code class="language-css">
.box{
    position: relative;
    top: 50px;
    left: 50px;
}</code></pre>
<blockquote>
<p><img src="https://velog.velcdn.com/images/giraffe_/post/132d9420-cf86-42d5-9930-c918bec131fe/image.png" alt=""></p>
</blockquote>
<p>주변 요소에 영향을 주지 않으면서 해당 요소의 원래 위치를 기준으로 offset이 적용된 것을 확인할 수 있습니다.</p>
<h3 id="absolute">absolute</h3>
<pre><code class="language-css">.box{
    position: absolute;
}</code></pre>
<blockquote>
<p><img src="https://velog.velcdn.com/images/giraffe_/post/dbac4fe0-6eb0-4c12-80a0-792ba1db5763/image.png" alt=""></p>
</blockquote>
<p>주변 요소에 영향을 주어 아래의 요소가 이동된 것을 확인할 수 있습니다.</p>
<pre><code class="language-css">.box{
    position: absolute;
    top: 50px;
    left: 50px;
}</code></pre>
<blockquote>
<p><img src="https://velog.velcdn.com/images/giraffe_/post/9824a674-d1a1-4609-8368-df7d3fe5400b/image.png" alt=""></p>
</blockquote>
<p>조상 요소 중 position 값이 static 이외인 경우가 없으므로 <code>&lt;body&gt;</code>가 offset의 기준점이된 것을 확인할 수 있습니다.</p>
<pre><code class="language-css">.container{
    position: relative;
}

.box{
    position: absolute;
    top: 100px;
    left: 100px;
}</code></pre>
<blockquote>
<p><img src="https://velog.velcdn.com/images/giraffe_/post/c7dbf8fb-8b2f-4de7-a2b5-5de5c63500e0/image.png" alt=""></p>
</blockquote>
<p>부모 요소인 <code>&lt;div.container&gt;</code>가 postion 값으로 relative를 가지므로, offset의 기준점이 <code>&lt;div.container&gt;</code>가 된 것을 확인할 수 있습니다.</p>
<h3 id="fixed">fixed</h3>
<pre><code class="language-css">.box{
    position: fixed;
}</code></pre>
<blockquote>
<p><img src="https://velog.velcdn.com/images/giraffe_/post/63de178a-b366-4693-a2b0-f2c540f2a7a3/image.png" alt=""></p>
</blockquote>
<pre><code class="language-css">.box{
    position: fixed;
    top: 200px;
    right: 10%;
}</code></pre>
<blockquote>
<p><img src="https://velog.velcdn.com/images/giraffe_/post/b133c772-8575-4270-9f71-648d9b47cca2/image.png" alt="">
<img src="https://velog.velcdn.com/images/giraffe_/post/4bd007d2-83f3-423e-947a-817587ea268a/image.png" alt=""></p>
</blockquote>
<blockquote>
<p><img src="https://velog.velcdn.com/images/giraffe_/post/04a8c9bf-dc0d-49f6-a414-d000b6290156/image.png" alt="">
<img src="https://velog.velcdn.com/images/giraffe_/post/456c4340-22da-4134-a65b-26f40aa80852/image.png" alt=""></p>
</blockquote>
<p>fixed의 경우 뷰포트(브라우저)를 기준으로 offset이 적용되므로, 브라우저의 가로 길이를 조정했을 때, 설정된 offset인 <code>right: 100px;</code>만큼을 유지한 채 고정되어 있는 것을 확인할 수 있습니다. 또한 세로로 스크롤해도 그 위치에 항상 고정되어있습니다.</p>
<h1 id="z-index">z-index</h1>
<p>요소가 겹칠 때 어떤 요소가 위로 올라오게할지 순서를 지정합니다.
postion 값이 static이 아닐 때 사용가능하며, 부모 요소가 z-index 값을 가질 경우, 부모 요소 안에서만 유효합니다.</p>
<pre><code class="language-css">z-index: auto | number;</code></pre>
<p><strong>기본값</strong>은 &#39;auto&#39;로, 선언된 순서대로 높은 값을 가져 위로 올라오게됩니다. 값으로는 <strong>음수를 포함한 단위없는 정수값</strong>을 사용합니다.</p>
<pre><code>&lt;div class=&quot;box1&quot;&gt;&lt;/div&gt;
&lt;div class=&quot;box2&quot;&gt;&lt;/div&gt;
&lt;div class=&quot;box3&quot;&gt;&lt;/div&gt;</code></pre><pre><code class="language-css">[class^=&quot;box&quot;]{
    width: 150px;
    height: 150px;
    position: absolute;
}

.box1{
    background-color: pink;
    border: 5px solid red;
    top: 50px;
    left: 50px;
    z-index: auto;
}

.box2{
    background-color: skyblue;
    border: 5px solid blue;
    top: 100px;
    left: 100px;
    z-index: auto;
}

.box3{
    background-color: lightgreen;
    border: 5px solid green;
    top: 150px;
    left: 150px;
    z-index: auto;
}</code></pre>
<blockquote>
<p><img src="https://velog.velcdn.com/images/giraffe_/post/8b615a06-f4ea-4620-a9ad-44c8703540a0/image.png" alt=""></p>
</blockquote>
<p>기본값인 &#39;auto&#39;의 경우, 선언된 순서대로 위로 올라오는 것을 확인할 수 있습니다.</p>
<pre><code class="language-css">.box1{
    z-index: 3;
}

.box2{
    z-index: 2;
}

.box3{
    z-index: 1;
}</code></pre>
<blockquote>
<p><img src="https://velog.velcdn.com/images/giraffe_/post/1a3e6ff4-0824-4c90-b501-6ba31f02f9ce/image.png" alt=""></p>
</blockquote>
<p>z-index 값이 높은 순서대로 위로 올라오는 것을 확인할 수 있습니다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[CSS 속성 - 폰트, 텍스트, 단어]]></title>
            <link>https://velog.io/@giraffe_/CSS-%EC%86%8D%EC%84%B1-%ED%8F%B0%ED%8A%B8-%ED%85%8D%EC%8A%A4%ED%8A%B8-%EB%8B%A8%EC%96%B4</link>
            <guid>https://velog.io/@giraffe_/CSS-%EC%86%8D%EC%84%B1-%ED%8F%B0%ED%8A%B8-%ED%85%8D%EC%8A%A4%ED%8A%B8-%EB%8B%A8%EC%96%B4</guid>
            <pubDate>Wed, 10 Aug 2022 13:25:46 GMT</pubDate>
            <description><![CDATA[<h1 id="typograhpy-구조">Typograhpy 구조</h1>
<blockquote>
<p><img src="https://velog.velcdn.com/images/giraffe_/post/f62ef5ba-ecf6-481e-9b31-bb11e77cc025/image.png" alt=""></p>
</blockquote>
<p>폰트는 &#39;<strong>소문자 x</strong>&#39;를 기준으로 구조가 구분됩니다.</p>
<ul>
<li><p><strong>Baseline</strong> : 소문자 x의 밑부분을 기준으로 그은 선입니다.</p>
</li>
<li><p><strong>ex</strong> : 소문자 x의 크기입니다.</p>
</li>
<li><p><strong>em</strong> :  폰트의 크기(전체 높이)입니다.(em-box)</p>
</li>
<li><p><strong>Ascender</strong> : ex 영역의 윗부분부터 em-box의 맨 윗부분 사이의 영역입니다.</p>
</li>
<li><p><strong>Descender</strong> : ex 영역의 아랫부분부터 em-box의 맨 아랫부분 사이의 영역입니다.</p>
</li>
</ul>
<h1 id="font-family">font-family</h1>
<pre><code class="language-css">font-family: family-name | generic-family;</code></pre>
<p>글꼴을 지정하는 속성으로, 상속됩니다.</p>
<h2 id="family-name">family-name</h2>
<p>사용할 폰트 이름을 지정합니다. 여러개를 선언할 수 있으며, &#39;<strong>comma(,)</strong>&#39;로 구분하여 선언합니다. 이때 한글 폰트는 &#39;<strong>따옴표(&#39;&#39;)</strong>&#39;로 묶어서 작성해야합니다. 먼저 선언된 것 부터 적용되며, 만약 선언된 폰트를 사용할 수 없다면, 다음에 선언된 폰트가 적용됩니다.</p>
<h2 id="generic-family">generic-family</h2>
<p>family-name에서 선언된 폰트를 모두 사용할 수 없는 경우, 브라우저가 대체할 수 있는 폰트를 지정합니다.
font-family 속성의 맨 마지막에 선언하며, 키워드이므로 따옴표로 묶지않는 것이 원칙입니다.
font-family 속성은 상속되지만, <strong>자식 요소에서 font-family를 다시 선언하면 generic-family도 다시 선언</strong>해주어야합니다.</p>
<p>대표적으로 &#39;<strong>serif, sans-serif</strong>&#39;가 있으며, 이외에 &#39;monospace, cursive, fantasy 등&#39;이 있습니다.
&#39;<strong>serif</strong>&#39;는 &#39;삐침&#39;이라는 뜻으로, &#39;명조체&#39;처럼 <strong>삐침이 있는 폰트</strong>를 의미합니다.
&#39;<strong>sans-serif</strong>&#39;의 &#39;sans&#39;는 프랑스어로 &#39;~이 없이&#39;라는 뜻으로, &#39;돋움체&#39;처럼 <strong>삐침이 없는 폰트</strong>를 의미합니다.</p>
<br>

<pre><code class="language-css">font-family: Helvetica, Dotum, &#39;돋움&#39;, sans-serif;</code></pre>
<p>위와같이 font-family가 선언되었을 때, &#39;<strong>abc 가나다 123</strong>&#39;이라는 문자열이 있다면, &#39;abc&#39;와 &#39;123&#39;은 Helvetica 폰트가 적용되지만, &#39;가나다&#39;는 Helvetica가 한글을 지원하지않기때문에 다음으로 선언된 Dotum 폰트가 적용됩니다.
돋움체를 한글과 영문으로 각각 작성해주는 이유는, 디바이스에서 한글을 지원하지않으면 한글로 작성된 폰트를 적용할 수 없으므로 영문으로 한번 더 작성해주는 것입니다.</p>
<h1 id="line-height">line-height</h1>
<p>&#39;<strong>텍스트 라인의 높이</strong>&#39;를 의미하며, line-height 속성으로 제어되는 영역을 &#39;<strong>line-box</strong>&#39;라고도 합니다.
주로 &#39;<strong>행 간격 제어</strong>&#39; 시 사용되지만, 엄연히 말하면 행 간격과는 다른 개념입니다.
<code>line-box = em-box + 상하_여백</code>입니다. 따라서 행 간격 제어는 폰트 크기인 em-box 부분을 제외한 상하 여백으로 이루지는 것 입니다. 이때 상하 여백은 상황에따라 동등하게 분배되거나 다르게 분배될 수 있으므로, 반드시 확인이 필요합니다.
예를 들어 <code>line-height: 50px; font-size: 30px;</code>인 경우, <code>50px = 30px + 상하_여백</code>이므로, 상하 여백이 각각 10px일 수도 있지만, 각각 5px, 15px처럼 다르게 적용될 수도 있습니다.</p>
<pre><code class="language-css">line-height: normal;
line-height: length;
line-height: number;
line-height: percent;</code></pre>
<ul>
<li><p><strong>normal</strong> : <strong>기본값</strong>으로, 보통 <strong>1.2</strong>의 값을 가지며, 폰트와 브라우저에따라 다른 값을 가집니다.</p>
</li>
<li><p><strong>length</strong> : 길이 단위로 값을 지정합니다.</p>
</li>
<li><p><strong>number</strong> : 단위없이 숫자만 작성하며, font-size의 값을 기준으로 작성한 값을 배율로 적용합니다.</p>
</li>
<li><p><strong>percent</strong> : font-size의 값을 기준으로 작성한 %값을 배율로 적용합니다.</p>
</li>
</ul>
<h1 id="font-size">font-size</h1>
<p>폰트의 크기를 지정하며, 따로 지정하지않으면 &#39;<strong>16px</strong>&#39;로 적용됩니다.</p>
<pre><code class="language-css">font-size: keyword;
font-size: length;
font-size: percent;</code></pre>
<ul>
<li><p><strong>keyword</strong> : 기본값은 &#39;<strong>medium</strong>&#39;이며, <strong>medium을 기준</strong>으로 상대적인 값을 가지는 &#39;xx-small, x-small, small, large, x-large, xx-large&#39;와 <strong>font-size를 기준</strong>으로 상대적인 값을 가지는 &#39;smaller, larger&#39;가 있습니다.</p>
</li>
<li><p><strong>length</strong> : 길이 단위로 값을 지정합니다.</p>
</li>
<li><p><strong>percent</strong> : 부모 요소의 font-size를 기준으로 작성한 %값을 배율로 적용합니다.</p>
</li>
</ul>
<h1 id="font-weight">font-weight</h1>
<p>폰트의 굵기를 지정합니다.</p>
<pre><code class="language-css">font-weight: keyword;
font-weight: number;</code></pre>
<ul>
<li><p><strong>keyword</strong> : 기본값은 &#39;<strong>normal</strong>&#39;이며, &#39;<strong>bold</strong>&#39;는 굵게, &#39;<strong>bolder</strong>&#39;는 부모 요소보다 굵게, &#39;<strong>lighter</strong>&#39;는 부모 요소보다 얇게 적용됩니다.</p>
</li>
<li><p><strong>number</strong> : <strong>100 단위</strong>로 <strong>100~900사이</strong>로 지정합니다.
대표적으로 <strong>400</strong>은 &#39;normal&#39;, <strong>700</strong>은 &#39;bold&#39;와 동일합니다.
폰트에 따라 수치를 지정해도 변화가 없을 수 있으며, &#39;normal, bold&#39;만 지원하는 경우에는 <strong>100~500</strong>은 &#39;normal&#39;, <strong>600~900</strong>은 &#39;bold&#39;로 적용됩니다.</p>
</li>
</ul>
<h1 id="font-style">font-style</h1>
<p>폰트의 스타일을 지정합니다.</p>
<pre><code class="language-css">font-style: keyword;</code></pre>
<ul>
<li><strong>keyword</strong> : 기본값은 &#39;<strong>normal</strong>&#39;이며, &#39;<strong>italic</strong>&#39;은 기울여서 표현합니다.
&#39;<strong>oblique</strong>&#39;도 italic처럼 기울여서 표현하는데, <code>font-style: oblique&lt;각도&gt;;</code>의 형태로 각도를 -90~90도 사이로 직접 지정할 수 있으며, 별도 지정이 없으면 <strong>14도</strong>의 값을 가집니다. 하지만 브라우저에따라 지원하지않을 수도 있습니다.</li>
</ul>
<h1 id="font-variant">font-variant</h1>
<p>폰트의 형태를 변환시키는 속성입니다.</p>
<pre><code class="language-css">font-variant: keyword;</code></pre>
<ul>
<li><strong>keyword</strong> : 기본값은 &#39;<strong>normal</strong>&#39;이며, &#39;<strong>small-caps</strong>&#39;는 소문자를 작은 크기의 대문자로 변환 시켜줍니다.</li>
</ul>
<blockquote>
<p><img src="https://velog.velcdn.com/images/giraffe_/post/72aa516b-367f-427e-9b19-90615ef48e12/image.png" alt=""></p>
</blockquote>
<h1 id="font-face웹-폰트">@font-face(웹 폰트)</h1>
<p>웹에 있는 폰트를 사용자의 PC같은 로컬 환경에 다운로드하여 적용하는 속성입니다.</p>
<pre><code class="language-css">@font-face{
    font-familly: 폰트_이름;
    src: 폰트_경로;
    font-style: 폰트_스타일;
    font-weight: 폰트_굵기;
}</code></pre>
<ul>
<li><p><strong>font-family</strong> : <strong>필수 속성</strong>으로, 폰트의 이름을 지정합니다.</p>
</li>
<li><p><strong>src</strong> : <strong>필수 속성</strong>으로, 폰트의 경로(url)을 지정합니다.</p>
</li>
<li><p><strong>font-style</strong> : <strong>선택 속성</strong>으로, 폰트의 스타일을 지정합니다.</p>
</li>
<li><p><strong>font-weight</strong> : <strong>선택 속성</strong>으로, 폰트의 굵기를 지정합니다.</p>
</li>
</ul>
<h1 id="vertical-align">vertical-align</h1>
<p>요소를 수직으로 어떻게 정렬할지 위치를 지정하며, 블럭 레벨 요소가 아닌, <strong>인라인 레벨 요소에 적용</strong>할 수 있습니다.</p>
<pre><code class="language-css">vertical-align: keyword;
vertical-align: length;
vertical-align: percent;</code></pre>
<ul>
<li><p><strong>keyword</strong> : 기본값은 &#39;<strong>baseline</strong>&#39;이며, &#39;super, sub, top, text-top, middle, bottom, text-bottom&#39;이 있습니다.</p>
</li>
<li><p><strong>length</strong> : 길이 단위를 사용하여 지정하며, 음수를 사용할 수 있습니다.</p>
</li>
<li><p><strong>percent</strong> : line-box 안에서 %값으로 이동하며, 음수를 사용할 수 있습니다.</p>
</li>
</ul>
<h1 id="text-align">text-align</h1>
<p>텍스트의 정렬을 지정하며, 블럭 레벨 요소가 아닌, <strong>인라인 레벨 요소에 적용</strong>할 수 있습니다.</p>
<pre><code class="language-css">text-align: keyword;</code></pre>
<ul>
<li><strong>keyword</strong> : 기본값은 <strong>언어에 따라 달라집니다.</strong> 한국어처럼 문서가 왼쪽에서 오른쪽으로 작성되는 언어(LTR : Left To Right)의 경우 &#39;<strong>left</strong>&#39;가 기본값이며, 아랍어처럼 문서가 오른쪽에서 왼쪽으로 작성되는 언어(RTL : Right To Left)의 경우 &#39;<strong>right</strong>&#39;가 기본값입니다.
&#39;<strong>left</strong>&#39;는 왼쪽 정렬, &#39;<strong>right</strong>&#39;는 오른쪽 정렬, &#39;<strong>center</strong>&#39;는 가운데 정렬, &#39;<strong>justify</strong>&#39;는 양끝 정렬(마지막 줄 제외)입니다.</li>
</ul>
<h1 id="text-indent">text-indent</h1>
<p>텍스트의 첫줄에 들여쓰기와 내어쓰기를 지정합니다.</p>
<pre><code class="language-css">text-align: length;
text-align: percent;</code></pre>
<ul>
<li><p><strong>length</strong> : 길이 단위를 사용하여 지정합니다. <strong>양수</strong>는 들여쓰기, <strong>음수</strong>는 내어쓰기가 적용됩니다.</p>
</li>
<li><p><strong>percnet</strong> : 부모 요소의 width를 기준으로 %값만큼 적용됩니다.</p>
</li>
</ul>
<h1 id="text-decoration">text-decoration</h1>
<p>텍스트에 라인을 어떻게 장식할지 지정합니다.</p>
<pre><code class="language-css">text-decoration-line: 라인_위치;
text-decoration-color: 라인_색상;
text-decoration-style: 라인_종류;</code></pre>
<ul>
<li><p><strong>text-decoration-line</strong> : 기본값은 &#39;<strong>none</strong>&#39;이며, &#39;<strong>underline</strong>&#39;은 밑줄, &#39;<strong>overline</strong>&#39;은 윗줄, &#39;<strong>line-through</strong>&#39;는 중간줄을 생성합니다.</p>
</li>
<li><p><strong>text-decoration-color</strong> : 기본값은 &#39;<strong>currentColor</strong>&#39;이며, 색상을 지정합니다.</p>
</li>
<li><p><strong>text-decoration-style</strong> : 기본값은 &#39;<strong>solid</strong>&#39;이며, &#39;<strong>double</strong>&#39;은 이중선, &#39;<strong>dotted</strong>&#39;는 점선, &#39;<strong>dashed</strong>&#39;는 파선(긴 점선), &#39;<strong>wavy</strong>&#39;는 물결선을 적용합니다.</p>
</li>
</ul>
<h2 id="축약형">축약형</h2>
<pre><code class="language-css">text-decoration: line color style;</code></pre>
<p>각 속성별로 따로 작성하지않고 한번에 <code>text-decoration</code>으로 작성할 수 있습니다.
기본값은 <code>text-decoration: none currentColor solid;</code>입니다.</p>
<blockquote>
<p><img src="https://velog.velcdn.com/images/giraffe_/post/45074b89-f4db-4bb4-bc52-e7195344560e/image.png" alt=""></p>
</blockquote>
<h1 id="단어-관련-속성">단어 관련 속성</h1>
<h2 id="white-space">white-space</h2>
<p>요소 안의 공백 처리 방법을 지정합니다.</p>
<pre><code class="language-css">white-space: keyword;</code></pre>
<ul>
<li><strong>keyword</strong> : 기본값은 &#39;<strong>normal</strong>&#39;입니다.
&#39;<strong>nowrap</strong>&#39;은 공백과 개행을 무시하고, 자동으로 줄바꿈하지않습니다.
&#39;<strong>pre</strong>&#39;는 공백과 개행을 적용하고, 자동으로 줄바꿈하지않습니다.
&#39;<strong>pre-line</strong>&#39;은 공백을 무시하고 개행은 적용하며, 필요시 자동으로 줄바꿈합니다.
&#39;<strong>pre-wrap</strong>&#39;은 공백은 적용하고 개행은 무시하며, 필요시 자동으로 줄바꿈합니다.</li>
</ul>
<h2 id="letter-spacing">letter-spacing</h2>
<p>글자 사이의 간격을 지정합니다.</p>
<pre><code class="language-css">letter-spacing: normal | length;</code></pre>
<p>기본값은 &#39;<strong>normal</strong>&#39;이며, 길이 단위를 사용하여 간격을 조정하고, 음수를 허용합니다.</p>
<h2 id="word-spacing">word-spacing</h2>
<p>단어 사이의 간격을 지정합니다.</p>
<pre><code class="language-css">word-spacing: normal | length;</code></pre>
<p>기본값은 &#39;<strong>normal</strong>&#39;이며, 길이단위를 사용하여 간격을 조정하고, 음수를 허용합니다.</p>
<h2 id="word-break">word-break</h2>
<p>단어가 줄바꿈될 때 어떻게 처리할지 개행점을 지정합니다.
언어가 &#39;<strong>CJK</strong>&#39;인지 아닌지에따라 다르게 적용됩니다.
(<strong>※ CJK</strong> : Chinese, Japanese, Korean 3개국어를 묶어서 지칭하는 단어입니다. 이외의 언어는 &#39;non-CJK&#39;로 지칭합니다.)</p>
<pre><code class="language-css">word-break: keword;</code></pre>
<ul>
<li><p><strong>normal</strong> : <strong>기본값</strong>으로, 개행점은 <strong>CJK</strong>는 음절, <strong>non-CJK</strong>는 공백이나 하이픈(-)입니다.</p>
</li>
<li><p><strong>break-all</strong> : 개행점은 <strong>CJK, non-CJK</strong> 모두 음절입니다.</p>
</li>
<li><p><strong>keep-all</strong> : 개행점은 <strong>CJK</strong>는 공백이나 기호, <strong>non-CJK</strong>는 공백이나 하이픈(-)입니다.</p>
</li>
</ul>
<pre><code>&lt;div&gt;HyperTextMarkupLanguageCascadingStyleSheets&lt;/div&gt;
&lt;div&gt;HyperText Markup Language Cascading Style Sheets&lt;/div&gt;
&lt;div&gt;하이퍼텍스트마크업랭귀지캐스캐이딩스타일시츠&lt;/div&gt;
&lt;div&gt;하이퍼텍스트 마크업 랭귀지 캐스캐이딩 스타일 시츠&lt;/div&gt;</code></pre><pre><code class="language-css">div{
    width: 100px;
    height: 100px;
    margin-bottom: 10px;
    border: 1px solid black;
}</code></pre>
<br>

<pre><code class="language-css">div{
    word-break: normal;
}</code></pre>
<blockquote>
<p><img src="https://velog.velcdn.com/images/giraffe_/post/8fab33bb-c298-4973-ba67-d8536a0372ed/image.png" alt=""></p>
</blockquote>
<br>

<pre><code class="language-css">div{
    word-break: break-all;
}</code></pre>
<blockquote>
<p><img src="https://velog.velcdn.com/images/giraffe_/post/d760c11d-1f3e-4d72-aa4c-f2225053c201/image.png" alt=""></p>
</blockquote>
<br>

<pre><code class="language-css">div{
    word-break: keep-all;
}</code></pre>
<blockquote>
<p><img src="https://velog.velcdn.com/images/giraffe_/post/0297d62e-9fc8-4830-9c6e-b85a3878d53a/image.png" alt=""></p>
</blockquote>
<h2 id="word-wrap">word-wrap</h2>
<p>단어가 요소를 벗어날 때 어떻게 처리할지 지정합니다.</p>
<pre><code class="language-css">word-wrap: keyword;</code></pre>
<ul>
<li><p><strong>normal</strong> : <strong>기본값</strong>으로, 개행점은 <strong>CJK</strong>는 음절, <strong>non-CJK</strong>는 공백이나 하이픈(-)입니다.</p>
</li>
<li><p><strong>break-word</strong> : 개행점은 <strong>CJK, non-CJK</strong> 모두 음절입니다.</p>
</li>
</ul>
<pre><code>&lt;div&gt;HyperTextMarkupLanguageCascadingStyleSheets&lt;/div&gt;
&lt;div&gt;HyperText Markup Language Cascading Style Sheets&lt;/div&gt;
&lt;div&gt;하이퍼텍스트마크업랭귀지캐스캐이딩스타일시츠&lt;/div&gt;
&lt;div&gt;하이퍼텍스트 마크업 랭귀지 캐스캐이딩 스타일 시츠&lt;/div&gt;</code></pre><pre><code class="language-css">div{
    width: 100px;
    height: 100px;
    margin-bottom: 10px;
    border: 1px solid black;
}</code></pre>
<br>

<pre><code class="language-css">div{
    word-wrap: normal;
}</code></pre>
<blockquote>
<p><img src="https://velog.velcdn.com/images/giraffe_/post/75571c46-e922-42ca-a2d8-04cd03250232/image.png" alt=""></p>
</blockquote>
<pre><code class="language-css">div{
    word-wrap: break-word;
}</code></pre>
<blockquote>
<p><img src="https://velog.velcdn.com/images/giraffe_/post/63aba28c-147b-4c01-8a43-075ad379c76a/image.png" alt=""></p>
</blockquote>
]]></description>
        </item>
        <item>
            <title><![CDATA[CSS 속성 - 박스 모델]]></title>
            <link>https://velog.io/@giraffe_/CSS-%EC%86%8D%EC%84%B1-%EB%B0%95%EC%8A%A4-%EB%AA%A8%EB%8D%B8</link>
            <guid>https://velog.io/@giraffe_/CSS-%EC%86%8D%EC%84%B1-%EB%B0%95%EC%8A%A4-%EB%AA%A8%EB%8D%B8</guid>
            <pubDate>Mon, 08 Aug 2022 14:24:40 GMT</pubDate>
            <description><![CDATA[<h1 id="박스-모델box-model">박스 모델(Box Model)</h1>
<p>HTML 문서는 브라우저의 렌더링 엔진에의해 표준 CSS에 따라 요소를 사각형 상자 형태의 &#39;<strong>박스 모델</strong>&#39;로 나타냅니다.</p>
<pre><code>&lt;div&gt;&lt;/div&gt;</code></pre><pre><code class="language-css">div{
    margin: 100px;
    border: 5px solid black;
    padding: 50px;
    width: 100px;
    height: 100px;
}</code></pre>
<blockquote>
<p><img src="https://velog.velcdn.com/images/giraffe_/post/fa91ab47-fac2-41c3-ac70-600d86af0999/image.png" alt=""></p>
</blockquote>
<p>선언된 CSS에 따라 위와 같은 결과물이있을 때, 박스 모델은 아래와 같이 나타납니다.</p>
<blockquote>
<p><img src="https://velog.velcdn.com/images/giraffe_/post/f201d132-5b98-4ae1-b30a-4eb6fbe25375/image.png" alt=""></p>
</blockquote>
<ul>
<li><p><strong>content 영역</strong> : 가장 안쪽 박스에 해당하며, 요소의 내용에 해당하는 영역의 크기를 나타냅니다.</p>
</li>
<li><p><strong>padding 영역</strong> : content 영역과 border 영역 사이의 여백에 해당하는 영역으로, content 영역에 배경, 색 등이 있다면 padding 영역에 걸쳐 표시됩니다.</p>
</li>
<li><p><strong>border 영역</strong> : content 영역과 padding 영역을 감싸는 테두리입니다.</p>
</li>
<li><p><strong>margin 영역</strong> : border 영역의 바깥 부분으로, 다른 요소와 구분할때 쓰이는 여백 영역입니다.</p>
</li>
</ul>
<h1 id="border">border</h1>
<p>테두리로써, 스타일을 지정하는 속성은 세가지가 있습니다.</p>
<pre><code class="language-css">border-width: 두께;
border-style: 종류;
border-color: 색상;</code></pre>
<ul>
<li><p><strong>border-width</strong> : 테두리의 두께를 지정합니다. 길이 단위를 사용하여 지정하거나, &#39;thin, medium, thick&#39; 같은 키워드를 사용하여 지정할 수 있습니다.</p>
</li>
<li><p><strong>border-style</strong> : 테두리의 종류를 지정합니다. 종류는 &#39;none, hidden, dotted, dashed, solid, double 등&#39;이 있습니다.</p>
</li>
<li><p><strong>border-color</strong> : 테두리의 색상을 지정합니다. 여러 색상 표기 형식 중 하나를 선택하여 지정하면됩니다.</p>
</li>
</ul>
<h2 id="축약형">축약형</h2>
<pre><code class="language-css">border: 두께 종류 색상;</code></pre>
<p>상하좌우 테두리의 두께, 종류, 색상을 일괄적으로 지정합니다.</p>
<pre><code>border-top|bottom|left|right: 두께, 종류, 색상;</code></pre><p>테두리의 상|하|좌|우 하나를 선택하여 두께, 종류, 색상을 한번에 선언합니다.</p>
<pre><code class="language-css">border-width: 상하좌우_두께;
border-width: 상하_두께 좌우_두께;
border-width: 상_두께 좌우_두께 하_두께;
border-width: 상_두께 우_두께 하_두께 좌_두께;</code></pre>
<p>border-width 속성에 입력하는 속성값의 갯수에 따라 테두리 위치별로 두께를 다르게 지정합니다.</p>
<p>이러한 축약형은 border-color 속성에서도 동일하게 축약하여 사용할 수 있습니다.</p>
<h1 id="padding">padding</h1>
<pre><code class="language-css">padding: 상하좌우_두께;
padding-top: 상_두께;
padding-right: 우_두께;
padding-bottom: 하_두께;
padding-left: 좌_두께;</code></pre>
<p>padding 영역의 상하좌우 또는 특정 부분을 선택하여 지정할 수 있습니다.
px같은 길이 단위를 사용하여 지정할 수 있으며, &#39;<strong>%</strong>&#39;로 두께를 지정할 때는 <strong>부모 요소의 content 영역 가로 너비(width)</strong>가 기준이됩니다.</p>
<h2 id="축약형-1">축약형</h2>
<pre><code class="language-css">padding: 상하_두께 좌우_두께;
padding: 상_두께 좌우_두께 하_두께;
padding: 상_두께 우_두께 하_두께 좌_두께;</code></pre>
<p>부분마다 다르게 두께를 적용하고자할 때, 위처럼 간단하게 작성할 수 있습니다.</p>
<h1 id="margin">margin</h1>
<p>margin은 속성값에 padding처럼 길이 단위로 구체적 값을 줄 수도있지만, &#39;<strong>%</strong>&#39;도 사용이 가능한데, %로 두께를 지정할 때는 마찬가지로 기준이 <strong>부모 요소의 content 영역 가로 너비(width)</strong>가 됩니다. 또한 &#39;<strong>auto</strong>&#39;라는 브라우저가 자동으로 계산해주는 특수한 속성값도 가집니다. </p>
<pre><code class="language-css">margin: 상하좌우_두께;
margin-top: 상_두께;
margin-right: 우_두께;
margin-bottom: 하_두께;
margin-left: 좌_두께;</code></pre>
<p>padding과 동일하게 선언하여 사용할 수 있습니다.</p>
<pre><code class="language-css">margin: auto;</code></pre>
<p>&#39;<strong>auto</strong>&#39; 속성값은 주로 <strong>가로축 가운데 정렬</strong>에 사용됩니다. 이 속성값을 사용하면 좌우 여백을 직접 입력하지않아도 브라우저가 자동으로 계산해주며, 보통 <code>margin: 0 auto;</code>의 형태로 쓰입니다.</p>
<pre><code>&lt;div class=&quot;parent&quot;&gt;
    &lt;div class=&quot;child&quot;&gt;&lt;/div&gt;
&lt;/div&gt;</code></pre><pre><code class="language-css">.parent{
    width: 500px;
    height: 500px;
    background-color: skyblue;
}

.child{
    width: 300px;
    height: 300px;
    background-color: lightgreen;
    margin: 0 auto;
}</code></pre>
<blockquote>
<p><img src="https://velog.velcdn.com/images/giraffe_/post/0a040679-6eb7-484e-91f4-2b6888da8daf/image.png" alt=""></p>
</blockquote>
<blockquote>
<p><img src="https://velog.velcdn.com/images/giraffe_/post/a32ac542-ddbb-48a0-9fc4-c219ef5b676e/image.png" alt=""></p>
</blockquote>
<p>child class로 선언된 <code>&lt;div&gt;</code>에 좌우 margin 값을 구체적으로 입력하지않았음에도 브라우저가 자동으로 계산하여 좌우 각각 100px의 margin을 적용한 것을 확인할 수 있습니다.</p>
<h2 id="margin-collapse">margin collapse</h2>
<p>서로 다른 요소에서 margin이 선언되어 서로 맞닿을 때, 맞닿는 margin 영역 각각이 별도로 존재하지않고, 두 요소 중 큰 margin 값을 갖는 요소의 margin을 기준으로 중첩되어 적용됩니다.</p>
<pre><code>&lt;div class=&quot;top&quot;&gt;&lt;/div&gt;
&lt;div class=&quot;bottom&quot;&gt;&lt;/div&gt;</code></pre><pre><code class="language-css">.top{
    background-color: skyblue;
    width: 500px;
    height: 100px;
    margin: 100px;
}

.bottom{
    background-color: lightgreen;
    width: 500px;
    height: 100px;
    margin: 50px;
}</code></pre>
<blockquote>
<p><img src="https://velog.velcdn.com/images/giraffe_/post/78b3e0b3-696d-43af-be1a-11665cbe1b56/image.png" alt=""></p>
</blockquote>
<p>개발자 도구로 확인해보면 위의 요소에 적용된 margin 값인 100px에 더해서 아래 요소에 적용된 margin 값인 50px만큼 더 띄워진 형태가 아닌, 맞닿는 margin 영역은 두 값 중 더 큰 값을 기준으로 중첩되어 적용되는 것을 알 수 있습니다.</p>
<p>또한 margin 값은 &#39;<strong>음수(-) 값</strong>&#39;도 적용가능합니다.</p>
<h2 id="축약형-2">축약형</h2>
<pre><code class="language-css">margin: 상하_두께 좌우_두께;
margin: 상_두께 좌우_두께 하_두께;
margin: 상_두께 우_두께 하_두께 좌_두께;</code></pre>
<p>부분마다 다르게 두께를 적용하고자할 때, 위처럼 간단하게 작성할 수 있습니다.</p>
<h1 id="width">width</h1>
<pre><code class="language-css">width: 너비값;</code></pre>
<p>content 영역의 &#39;<strong>너비</strong>&#39;를 지정하는 속성으로, 따로 작성하지않으면 기본값은 &#39;<strong>auto</strong>&#39;입니다. 여기서 auto는 부모 요소와 같은 값을 갖습니다.
길이 단위를 속성값으로 사용할 수 있으며, &#39;%&#39;를 속성값으로 사용시, <strong>부모 요소의 content 영역 너비</strong>를 기준으로 적용됩니다.</p>
<h1 id="height">height</h1>
<pre><code class="language-css">height: 높이값;</code></pre>
<p>content 영역의 &#39;<strong>높이</strong>&#39;를 지정하는 속성으로, 따로 작성하지않으면 기본값은 &#39;<strong>auto</strong>&#39;입니다. 여기서 auto는 부모 요소와 같은 값을 갖습니다.
길이 단위를 속성값으로 사용할 수 있으며, &#39;%&#39;를 속성값으로 사용시, <strong>부모 요소의 content 영역 높이</strong>를 기준으로 적용됩니다.</p>
<h2 id="width--height">width &amp; height</h2>
<pre><code>&lt;div class=&quot;parent&quot;&gt;
    &lt;div class=&quot;child&quot;&gt;&lt;/div&gt;
&lt;/div&gt;</code></pre><pre><code class="language-css">.parent{
    background-color: skyblue;
    width: 500px;
    height: 100px;
}

.child{
    background-color: lightgreen;
    width: 50%;
    height: 200%;
}</code></pre>
<blockquote>
<p><img src="https://velog.velcdn.com/images/giraffe_/post/c143584a-9f5c-4d62-96d4-8791c9ca79a0/image.png" alt=""></p>
</blockquote>
<blockquote>
<p><img src="https://velog.velcdn.com/images/giraffe_/post/a9946b6f-aac5-4b31-ad7a-5966aa693545/image.png" alt=""></p>
</blockquote>
<p>parent class로 선언된 <code>&lt;div&gt;</code>는 작성한대로 너비 500px, 높이 100px을 갖습니다.</p>
<blockquote>
<p><img src="https://velog.velcdn.com/images/giraffe_/post/f7d28b56-36a3-46e2-9842-4eb7ea4ae94d/image.png" alt=""></p>
</blockquote>
<p>child class로 선언된 <code>&lt;div&gt;</code>는 부모 요소의 content 영역을 기준으로 %가 적용되어, 너비는 50%인 250px, 높이는 200%인 200px을 갖습니다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[CSS 속성 - 길이, 색상, 배경]]></title>
            <link>https://velog.io/@giraffe_/CSS-%EC%86%8D%EC%84%B1</link>
            <guid>https://velog.io/@giraffe_/CSS-%EC%86%8D%EC%84%B1</guid>
            <pubDate>Fri, 05 Aug 2022 13:01:40 GMT</pubDate>
            <description><![CDATA[<h1 id="길이-단위">길이 단위</h1>
<p>폰트 크기나 넓이, 높이 등을 지정할 때 여러가지 단위를 사용하여 지정할 수 있습니다.</p>
<h2 id="절대-길이">절대 길이</h2>
<p>길이가 어느 장치에서나 동일하게 보이는 고정 길이입니다.
하지만 같은 장치에서도 해상도나 여러 조건에 따라 다르게 보일 수 있으므로, 완전한 절대 길이라고 할 수는 없습니다.</p>
<ul>
<li><p><strong>px(pixels)</strong> : 1px은 화면에서 하나의 점과 같습니다.
웹 개발 시, 여러 환경에서 디자인을 동일하게 표현하며, 브라우저 호환성 보장에서 유리하므로, 디자인 의도가 많이 반영된 웹 사이트에서 사용이 권장됩니다.</p>
</li>
<li><p><strong>pt(points)</strong> : Windows에서는 9pt=12px, Mac에서는 9pt=9px입니다.
표준 인쇄 단위로, 인쇄물이나 워드프로세서에서 주로 사용됩니다. 따라서 웹에서 인쇄용 문서 스타일 정의 시 유용합니다.</p>
</li>
</ul>
<h2 id="상대-길이">상대 길이</h2>
<p>특정 대상에 대해 상대적인 길이를 가집니다.</p>
<ul>
<li><p><strong>%(percentage)</strong> : 기본 글꼴 크기에 대해 상대적 값을 가집니다.
요소에 정의된 px을 percentage로 조절할 수 있습니다.</p>
</li>
<li><p><strong>em(font size of the element)</strong> : 선언된 폰트의 &#39;<strong>대문자 M</strong>&#39; 너비에 대해 상대적 값을 가집니다.
1em은 현재 폰트 크기, 2em은 현재 폰트 크기의 두배(200%)입니다.
em은 소수점 셋째자리까지 사용 가능합니다.</p>
</li>
<li><p><strong>rem(font size of the root element)</strong> : &#39;<strong>root</strong>&#39;를 기준으로 em을 적용합니다.
&#39;<strong>root</strong>&#39;는 최상위 태그로써, 보통 <code>&lt;html&gt;</code> 태그를 의미합니다.</p>
</li>
<li><p><strong>vw &amp; vh</strong> : &#39;<strong>viewport(브라우저)</strong>&#39;의 사이즈를 기준으로 상대적 값을 가집니다.
&#39;<strong>vw(viewport width)</strong>&#39;는 넓이를 기준으로하여, 1vw는 <strong>width의 1%</strong> 값을 가집니다.
&#39;<strong>vh(viewport height)</strong>&#39;는 높이를 기준으로하여, 1vh는 <strong>height의 1%</strong> 값을 가집니다.</p>
</li>
</ul>
<h1 id="색상-표기">색상 표기</h1>
<p>색상을 지정할 때 여러가지 표기 형식을 사용하여 지정할 수 있습니다.</p>
<h2 id="색상명">색상명</h2>
<pre><code class="language-css">div{
    color: blue;
}</code></pre>
<p>가장 간단한 방법으로, 색상명을 명시적으로 작성하여 색상을 지정합니다.</p>
<h2 id="16진수">16진수</h2>
<pre><code class="language-css">div{
    color: #0000ff;
}</code></pre>
<p>16진수 형식으로 색상 표현시, &#39;<strong>#</strong>&#39;뒤의 6자리에 각각 &#39;<strong>16진수 형식(0<del>9, a</del>f)</strong>&#39;으로 숫자를 기입합니다.
6자리는 다시 2자리씩 끊어서 각각 <strong>R(Red), G(Green), B(Blue)</strong>의 비율을 지정합니다.</p>
<pre><code class="language-css">div{
    color: #RRGGBB;
}</code></pre>
<p><code>#000000</code>은 검정색, <code>#ffffff</code>은 흰색을 표현합니다.</p>
<pre><code>&lt;div class=&quot;black&quot;&gt;&lt;/div&gt;
&lt;div class=&quot;red&quot;&gt;&lt;/div&gt;
&lt;div class=&quot;green&quot;&gt;&lt;/div&gt;
&lt;div class=&quot;blue&quot;&gt;&lt;/div&gt;
&lt;div class=&quot;white&quot;&gt;&lt;/div&gt;</code></pre><pre><code class="language-css">div{
    width: 300px;
    height: 50px;
}

.black { background-color: #000000;}
.red { background-color: #ff0000;}
.green { background-color: #00ff00;}
.blue { background-color: #0000ff;}
.white { background-color: #ffffff;}</code></pre>
<blockquote>
<p><img src="https://velog.velcdn.com/images/giraffe_/post/67ab9ab7-4693-414f-ad46-c8acae18e02b/image.png" alt=""></p>
</blockquote>
<h3 id="축약형">축약형</h3>
<pre><code class="language-css">div{
    color: #RGB;
}</code></pre>
<p>2자리씩 끊었을 때 그 두자리 숫자가 일치하는 경우에는 한번씩만 작성하여, 6자리가 아닌 3자리로 표현할 수 있습니다.</p>
<pre><code>&lt;div class=&quot;black&quot;&gt;&lt;/div&gt;
&lt;div class=&quot;red&quot;&gt;&lt;/div&gt;
&lt;div class=&quot;green&quot;&gt;&lt;/div&gt;
&lt;div class=&quot;blue&quot;&gt;&lt;/div&gt;
&lt;div class=&quot;white&quot;&gt;&lt;/div&gt;</code></pre><pre><code class="language-css">div{
    width: 300px;
    height: 50px;
}

.black { background-color: #000;}
.red { background-color: #f00;}
.green { background-color: #0f0;}
.blue { background-color: #00f;}
.white { background-color: #fff;}</code></pre>
<blockquote>
<p><img src="https://velog.velcdn.com/images/giraffe_/post/67ab9ab7-4693-414f-ad46-c8acae18e02b/image.png" alt=""></p>
</blockquote>
<h2 id="rgb">RGB</h2>
<pre><code class="language-css">div{
    color: rgb(0,0,255);
}</code></pre>
<p>RGB 표기 형식은 &#39;<strong>rgb</strong>&#39; 뒤 괄호 안의 세곳에 각각 R, G, B에 해당하는 값을 0~255 사이로 입력합니다.</p>
<pre><code class="language-css">div{
    color: rgb(r,g,b);
}</code></pre>
<p><code>rgb(0,0,0)</code>은 검정색, <code>rgb(255,255,255)</code>는 흰색을 표현합니다.</p>
<pre><code>&lt;div class=&quot;black&quot;&gt;&lt;/div&gt;
&lt;div class=&quot;red&quot;&gt;&lt;/div&gt;
&lt;div class=&quot;green&quot;&gt;&lt;/div&gt;
&lt;div class=&quot;blue&quot;&gt;&lt;/div&gt;
&lt;div class=&quot;white&quot;&gt;&lt;/div&gt;</code></pre><pre><code class="language-css">div{
    width: 300px;
    height: 50px;
}

.black { background-color: rgb(0,0,0);}
.red { background-color: rgb(255,0,0);}
.green { background-color: rgb(0,255,0);}
.blue { background-color: rgb(0,0,255);}
.white { background-color: rgb(255,255,255);}</code></pre>
<blockquote>
<p><img src="https://velog.velcdn.com/images/giraffe_/post/67ab9ab7-4693-414f-ad46-c8acae18e02b/image.png" alt=""></p>
</blockquote>
<h3 id="rgba">RGBA</h3>
<p>RGB 형식에 &#39;<strong>A(alpha)</strong>&#39; 값을 추가한 형식입니다.
alpha 값은 <strong>투명도</strong>를 지정하며, 0~1 사이의 값을 입력합니다.
0에 가까울수록 투명해지고, 1에 가까울수록 불투명해집니다.</p>
<pre><code>&lt;div class=&quot;black&quot;&gt;&lt;/div&gt;
&lt;div class=&quot;red&quot;&gt;&lt;/div&gt;
&lt;div class=&quot;green&quot;&gt;&lt;/div&gt;
&lt;div class=&quot;blue&quot;&gt;&lt;/div&gt;
&lt;div class=&quot;white&quot;&gt;&lt;/div&gt;</code></pre><pre><code class="language-css">div{
    width: 300px;
    height: 50px;
}

.black { background-color: rgba(0,0,0,0.5);}
.red { background-color: rgba(255,0,0,0.5);}
.green { background-color: rgba(0,255,0,0.5);}
.blue { background-color: rgba(0,0,255,0.5);}
.white { background-color: rgba(255,255,255,0.5);}</code></pre>
<blockquote>
<p><img src="https://velog.velcdn.com/images/giraffe_/post/6e34a45a-b852-499e-96e8-cb1ac9eae308/image.png" alt=""></p>
</blockquote>
<h1 id="배경">배경</h1>
<p>CSS에서 &#39;<strong>background-</strong>&#39;로 시작하는 속성으로 배경에 다양하게 활용할 수 있습니다.</p>
<h2 id="background-color">background-color</h2>
<pre><code>&lt;div&gt;&lt;/div&gt;</code></pre><pre><code class="language-css">div{
    width: 1000px;
    height: 500px;
    background-color: lightgreen;
}</code></pre>
<blockquote>
<p><img src="https://velog.velcdn.com/images/giraffe_/post/456611f5-3292-4b3d-8ac2-20782387f8a8/image.png" alt=""></p>
</blockquote>
<p>속성값에 색상을 입력하면 해당 색상이 적용됩니다.</p>
<h2 id="background-image">background-image</h2>
<pre><code>&lt;div&gt;&lt;/div&gt;</code></pre><pre><code class="language-css">div{
    width: 1000px;
    height: 500px;
    background-image: url(https://www.w3schools.com/cssref/img_tree.gif);
}</code></pre>
<blockquote>
<p><img src="https://velog.velcdn.com/images/giraffe_/post/c0a2ad00-942a-42f5-9dc7-042dc48e0c45/image.png" alt=""></p>
</blockquote>
<p>속성값으로 이미지의 경로를 입력하면 해당 이미지가 표시됩니다.</p>
<h3 id="background-repeat">background-repeat</h3>
<pre><code class="language-css">div{
    width: 1000px;
    height: 500px;
    background-image: url(https://www.w3schools.com/cssref/img_tree.gif);
    background-repeat: no-repeat;
}</code></pre>
<blockquote>
<p><img src="https://velog.velcdn.com/images/giraffe_/post/71c54eaa-f7b0-4fcb-a228-8328b648e88b/image.png" alt=""></p>
</blockquote>
<p>해당 이미지를 어떻게 반복하여 표시할지 지정합니다.</p>
<ul>
<li><p><strong>repeat</strong> : 기본값, 이미지를 반복하여 표시합니다.</p>
</li>
<li><p><strong>no-repeat</strong> : 이미지를 한번만 표시합니다.</p>
</li>
<li><p><strong>repeat-x</strong> : 이미지를 x축으로만 반복하여 표시합니다.</p>
</li>
<li><p><strong>repeat-y</strong> : 이미지를 y축으로만 반복하여 표시합니다.</p>
</li>
</ul>
<h3 id="background-position">background-position</h3>
<pre><code class="language-css">div{
    width: 1000px;
    height: 500px;
    background-image: url(https://www.w3schools.com/cssref/img_tree.gif);
    background-repeat: no-repeat;
    background-position: center top;
}</code></pre>
<blockquote>
<p><img src="https://velog.velcdn.com/images/giraffe_/post/dd820d78-db9d-498a-a36f-f811aa729b36/image.png" alt=""></p>
</blockquote>
<p>이미지를 표시할 위치를 지정합니다.
위치를 명시적으로 지정할 경우 왼쪽에 x축 위치를 지정하는 키워드인, &#39;<strong>left, center, right</strong>&#39;를 작성하고, 오른쪽에 y축 위치를 지정하는 키워드인, &#39;<strong>top, center, bottom</strong>&#39;을 작성합니다.</p>
<p>&#39;px&#39;이나 &#39;%&#39;를 사용하여 지정할 수도 있는데, 이때 위치의 기준은 &#39;<strong>좌측상단</strong>&#39;이됩니다.</p>
<h3 id="background-attachment">background-attachment</h3>
<pre><code class="language-css">div{
    width: 1000px;
    height: 500px;
    background-image: url(https://www.w3schools.com/cssref/img_tree.gif);
    background-attachment: fixed;
}</code></pre>
<p>속성값에 &#39;<strong>fixed</strong>&#39;를 적용하면 스크롤을 내려도 이미지가 고정되어있습니다.
기본값은 &#39;<strong>scroll</strong>&#39;이며, 스크롤을 내리면 이미지가 스크롤에따라 움직입니다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[선택자(selector)]]></title>
            <link>https://velog.io/@giraffe_/%EC%84%A0%ED%83%9D%EC%9E%90selector</link>
            <guid>https://velog.io/@giraffe_/%EC%84%A0%ED%83%9D%EC%9E%90selector</guid>
            <pubDate>Thu, 21 Jul 2022 13:10:06 GMT</pubDate>
            <description><![CDATA[<p>선택자를 다양한 방법으로 지정하여 원하는 HTML 요소에 효과적으로 적용할 수 있습니다.</p>
<h1 id="요소-선택자태그-선택자">요소 선택자(태그 선택자)</h1>
<p>&#39;<strong>요소(태그)</strong>&#39;를 선택자로 사용합니다.</p>
<pre><code>&lt;div&gt;HTML&lt;/div&gt;
&lt;span&gt;CSS&lt;/span&gt;</code></pre><pre><code class="language-css">div{
    font-size: 20px;
    color: blue;
}

span{
    font-size: 20px;
    color: blue;
}</code></pre>
<blockquote>
<p><img src="https://velog.velcdn.com/images/giraffe_/post/cd7fb44d-74a7-4cb7-9855-6755041e38cd/image.png" alt=""></p>
</blockquote>
<p>위처럼 동일한 CSS를 여러 HTML 요소에 적용시, &#39;<strong>그룹화</strong>&#39;하여 한번에 여러 요소에 CSS를 적용시킬 수 있습니다.</p>
<pre><code>&lt;div&gt;HTML&lt;/div&gt;
&lt;span&gt;CSS&lt;/span&gt;</code></pre><pre><code class="language-css">div, span{
    font-size: 20px;
    color: blue;
}</code></pre>
<p>이때 각 요소는 &#39;<strong>,(comma)</strong>&#39;로 구분해줍니다.</p>
<blockquote>
<p><img src="https://velog.velcdn.com/images/giraffe_/post/cd7fb44d-74a7-4cb7-9855-6755041e38cd/image.png" alt=""></p>
</blockquote>
<p>결과는 동일한 것을 확인할 수 있습니다.</p>
<h2 id="전체-선택자">전체 선택자</h2>
<p>모든 요소에 동일한 CSS를 적용하고자할 때 &#39;<strong>*(asterisk)</strong>&#39;를 사용할 수 있습니다.</p>
<pre><code>&lt;div&gt;HTML&lt;/div&gt;
&lt;span&gt;CSS&lt;/span&gt;</code></pre><pre><code class="language-css">*{
    font-size: 20px;
    color: blue;
}</code></pre>
<blockquote>
<p><img src="https://velog.velcdn.com/images/giraffe_/post/cd7fb44d-74a7-4cb7-9855-6755041e38cd/image.png" alt=""></p>
</blockquote>
<p>편리하지만 성능 측면에서 좋지않으므로 사용하지않는 것이 좋습니다.</p>
<h1 id="class-선택자">class 선택자</h1>
<p>HTML의 &#39;<strong>전역 속성(global attribute : 모든 요소에서 사용 가능한 속성)</strong>&#39; 중에서 &#39;<strong>class</strong>&#39; 속성을 이용하여 특정 요소를 선택합니다.
이때 <strong>class 속성의 값은 숫자로 시작하면 안됩니다.</strong></p>
<pre><code>&lt;div&gt;HTML&lt;/div&gt;
&lt;div class=&quot;red&quot;&gt;HTML&lt;/div&gt;
&lt;div class=&quot;blue&quot;&gt;HTML&lt;/div&gt;
&lt;div&gt;CSS&lt;/div&gt;
&lt;div class=&quot;red&quot;&gt;CSS&lt;/div&gt;
&lt;div class=&quot;blue&quot;&gt;CSS&lt;/div&gt;</code></pre><pre><code class="language-css">div{
    font-size: 20px;
}

.red{
    color: red;
}

.blue{
    color: blue;
}</code></pre>
<p>HTML의 class 속성에 값을 지정하고 그 속성 값을 선택자로 사용합니다.
CSS 작성시 class 속성 값 앞에 &#39;<strong>.(dot)</strong>&#39;을 붙여주어야합니다.</p>
<blockquote>
<p><img src="https://velog.velcdn.com/images/giraffe_/post/58db8b79-4f26-450c-a99a-b8f232a747ee/image.png" alt=""></p>
</blockquote>
<p>class 속성은 하나의 요소에 다중으로도 적용할 수 있습니다. 이때 class 속성의 값을 공백으로 구분하여 작성합니다.</p>
<pre><code>&lt;div&gt;HTML&lt;/div&gt;
&lt;div class=&quot;red line&quot;&gt;HTML&lt;/div&gt;
&lt;div class=&quot;blue&quot;&gt;HTML&lt;/div&gt;
&lt;div&gt;CSS&lt;/div&gt;
&lt;div class=&quot;red&quot;&gt;CSS&lt;/div&gt;
&lt;div class=&quot;blue line&quot;&gt;CSS&lt;/div&gt;</code></pre><pre><code class="language-css">div{
    font-size: 20px;
}

.red{
    color: red;
}

.blue{
    color: blue;
}

.line{
    text-decoration: underline;
}</code></pre>
<blockquote>
<p><img src="https://velog.velcdn.com/images/giraffe_/post/5e38b239-2815-43b3-b1e6-efe119bb8b2c/image.png" alt=""></p>
</blockquote>
<h1 id="id-선택자">id 선택자</h1>
<p>class 선택자와 비슷하게 사용가능한 선택자이며, 마찬가지로 <strong>숫자로 시작하면 안됩니다.</strong>
HTML의 전역 속성 중 &#39;<strong>id</strong>&#39; 속성을 사용합니다.
다른점은 CSS 작성시 id 속성 값 앞에는 &#39;.&#39;이아닌, &#39;<strong>#(hash mark)</strong>&#39;를 붙여줘야한다는 것입니다.</p>
<pre><code>&lt;div&gt;HTML&lt;/div&gt;
&lt;div id=&quot;red&quot;&gt;HTML&lt;/div&gt;
&lt;div id=&quot;blue&quot;&gt;HTML&lt;/div&gt;</code></pre><pre><code class="language-css">div{
    font-size: 20px;
}

#red{
    color: red;
}

#blue{
    color: blue;
}</code></pre>
<blockquote>
<p><img src="https://velog.velcdn.com/images/giraffe_/post/eb1a0bfe-8b2f-4194-b411-415225779b7a/image.png" alt=""></p>
</blockquote>
<p>주의할 점은 id 속성은 class 속성처럼 여러 요소에 지정하는 것이 아닌, <strong>하나의 HTML 파일에서 유일하게 한 요소를 식별할 목적</strong>으로 사용되므로, 여러 요소에 지정하여 사용하면 안된다는 것입니다. </p>
<h1 id="속성-선택자">속성 선택자</h1>
<p>HTML의 속성을 선택자로하여 CSS를 적용할 수 있습니다.</p>
<h2 id="속성을-선택자로-사용">속성을 선택자로 사용</h2>
<p>해당 속성을 갖고있는 모든 요소를 선택합니다.</p>
<pre><code>&lt;div class=&quot;red&quot; id=&quot;line&quot;&gt;HTML&lt;/div&gt;
&lt;div class=&quot;red&quot;&gt;CSS&lt;/div&gt;</code></pre><pre><code class="language-css">[id]{
    text-decoration: underline;
}</code></pre>
<blockquote>
<p><img src="https://velog.velcdn.com/images/giraffe_/post/67225a87-6368-4b1e-88db-162e8ed847c3/image.png" alt=""></p>
</blockquote>
<pre><code>&lt;div class=&quot;red&quot; id=&quot;line&quot;&gt;HTML&lt;/div&gt;
&lt;div class=&quot;red&quot;&gt;CSS&lt;/div&gt;</code></pre><pre><code class="language-css">[id]{
    text-decoration: underline;
}

[class]{
    color: red;
}</code></pre>
<blockquote>
<p><img src="https://velog.velcdn.com/images/giraffe_/post/0f46f3af-fe36-416b-96cd-c51be89ad399/image.png" alt=""></p>
</blockquote>
<h2 id="속성과-속성-값을-선택자로-사용">속성과 속성 값을 선택자로 사용</h2>
<p>속성과 속성 값이 정확히 일치하는 요소만 선택합니다.</p>
<pre><code>&lt;div class=&quot;red&quot;&gt;HTML&lt;/div&gt;
&lt;div class=&quot;blue&quot;&gt;CSS&lt;/div&gt;</code></pre><pre><code class="language-css">[class=&quot;red&quot;]{
    color: red;
}</code></pre>
<blockquote>
<p><img src="https://velog.velcdn.com/images/giraffe_/post/70a1215d-bd07-404a-9378-c8d694999b76/image.png" alt=""></p>
</blockquote>
<p>두 요소 모두 class 속성이 있지만, 값이 red인 요소만 선택하기때문에, 값이 blue인 요소는 CSS가 적용되지않습니다.</p>
<h2 id="부분-일치-속성-값을-선택자로-사용">부분 일치 속성 값을 선택자로 사용</h2>
<p>특정 키워드를 사용하여 부분적으로 속성 값이 일치하는 요소만 선택합니다.</p>
<h3 id="carat-키워드">^(carat) 키워드</h3>
<pre><code class="language-css">[class^=&quot;alpha&quot;]{}</code></pre>
<p>class 속성의 값이 &#39;alpha&#39;로 시작하는 요소를 선택합니다.</p>
<pre><code>&lt;div class=&quot;alphabeta&quot;&gt;C&lt;/div&gt;
&lt;div class=&quot;betaalpha&quot;&gt;JAVA&lt;/div&gt;
&lt;div class=&quot;betaalphagamma&quot;&gt;Python&lt;/div&gt;
&lt;div class=&quot;beta alpha gamma&quot;&gt;SQL&lt;/div&gt;</code></pre><pre><code class="language-css">[class^=&quot;alpha&quot;]{
    color: red;
}</code></pre>
<blockquote>
<p><img src="https://velog.velcdn.com/images/giraffe_/post/79ddf4ec-8fd7-42bf-ba15-b4bb80b63db8/image.png" alt=""></p>
</blockquote>
<h3 id="dollar-sign-키워드">$(dollar sign) 키워드</h3>
<pre><code class="language-css">[class$=&quot;alpha&quot;]{}</code></pre>
<p>class 속성의 값이 &#39;alpha&#39;로 끝나는 요소를 선택합니다.</p>
<pre><code>&lt;div class=&quot;alphabeta&quot;&gt;C&lt;/div&gt;
&lt;div class=&quot;betaalpha&quot;&gt;JAVA&lt;/div&gt;
&lt;div class=&quot;betaalphagamma&quot;&gt;Python&lt;/div&gt;
&lt;div class=&quot;beta alpha gamma&quot;&gt;SQL&lt;/div&gt;</code></pre><pre><code class="language-css">[class$=&quot;alpha&quot;]{
    color: red;
}</code></pre>
<blockquote>
<p><img src="https://velog.velcdn.com/images/giraffe_/post/88cd2f6a-c85f-4083-8390-7d1eef65df60/image.png" alt=""></p>
</blockquote>
<h3 id="asterisk-키워드">*(asterisk) 키워드</h3>
<pre><code class="language-css">[class*=&quot;alpha&quot;]{}</code></pre>
<p>class 속성의 값이 &#39;alpha&#39;를 포함하는 요소를 선택합니다.</p>
<pre><code>&lt;div class=&quot;alphabeta&quot;&gt;C&lt;/div&gt;
&lt;div class=&quot;betaalpha&quot;&gt;JAVA&lt;/div&gt;
&lt;div class=&quot;betaalphagamma&quot;&gt;Python&lt;/div&gt;
&lt;div class=&quot;beta alpha gamma&quot;&gt;SQL&lt;/div&gt;</code></pre><pre><code class="language-css">[class*=&quot;alpha&quot;]{
    color: red;
}</code></pre>
<blockquote>
<p><img src="https://velog.velcdn.com/images/giraffe_/post/5f874a45-19c9-442d-82ba-b50b02a30358/image.png" alt=""></p>
</blockquote>
<h3 id="tilde-키워드">~(tilde) 키워드</h3>
<pre><code class="language-css">[class~=&quot;alpha&quot;]{ }</code></pre>
<p>class 속성의 값이 공백으로 구분된 &#39;alpha&#39;를 포함하는 요소를 선택합니다.</p>
<pre><code>&lt;div class=&quot;alphabeta&quot;&gt;C&lt;/div&gt;
&lt;div class=&quot;betaalpha&quot;&gt;JAVA&lt;/div&gt;
&lt;div class=&quot;betaalphagamma&quot;&gt;Python&lt;/div&gt;
&lt;div class=&quot;beta alpha gamma&quot;&gt;SQL&lt;/div&gt;</code></pre><pre><code class="language-css">[class~=&quot;alpha&quot;]{
    color: red;
}</code></pre>
<blockquote>
<p> <img src="https://velog.velcdn.com/images/giraffe_/post/a0c404ac-12ab-45cb-97cb-94cb9be1ae43/image.png" alt=""></p>
</blockquote>
<h1 id="선택자의-조합">선택자의 조합</h1>
<p>선택자는 여러 방법으로 조합하여 더 효과적으로 사용할 수 있습니다.</p>
<h2 id="요소-선택자--class-선택자">요소 선택자 + class 선택자</h2>
<p>선택자에 요소와 class를 조합하여 사용하는 방법입니다.
해당 요소 중에서 지정한 class 속성의 값을 갖고있는 요소를 선택합니다.
선택자 작성시, 요소 선택자 뒤에 class 선택자를 붙여서 작성하면됩니다.</p>
<pre><code>&lt;div class=&quot;red&quot;&gt;HTML&lt;/div&gt;
&lt;span class=&quot;red&quot;&gt;CSS&lt;/span&gt;</code></pre><pre><code class="language-css">div.red{
    color: red;
}</code></pre>
<blockquote>
<p><img src="https://velog.velcdn.com/images/giraffe_/post/a62bdd1f-e027-45f0-8f23-0a85b70cfc19/image.png" alt=""></p>
</blockquote>
<p>div와 span 요소 모두 class 속성의 값으로 red가 지정되어있지만, 선택자를 div 요소 중에서 class 속성 값이 &#39;red&#39;에 해당하는 요소만 적용되게 작성했기때문에 span 요소는 class 속성의 값과 관계없이 스타일이 적용되지않습니다.</p>
<h2 id="다중-class-선택자">다중 class 선택자</h2>
<p>효과를 적용할 요소가 다중 class이면서 해당되는 값을 모두 가지고있을 때만 스타일이 적용됩니다. </p>
<pre><code>&lt;div class=&quot;red line&quot;&gt;HTML&lt;/div&gt;
&lt;div class=&quot;red&quot;&gt;CSS&lt;/div&gt;
&lt;div class=&quot;line&quot;&gt;JS&lt;/div&gt;</code></pre><pre><code class="language-css">.red.line{
    color: red;
    text-decoration: underline;
}</code></pre>
<blockquote>
<p><img src="https://velog.velcdn.com/images/giraffe_/post/a57fcf5b-fd37-415a-8a3f-fb1f695a03b1/image.png" alt=""></p>
</blockquote>
<p>class 선택자 중 값으로 &#39;red&#39;와 &#39;line&#39;을 갖고있는 요소를 대상으로 스타일을 적용하므로, 둘 중 하나만 갖고있는 요소는 효과가 적용되지않습니다.</p>
<h2 id="id-선택자--class-선택자">id 선택자 + class 선택자</h2>
<p>id 선택자에 class 선택자를 조합하여 CSS를 적용합니다.</p>
<pre><code>&lt;div class=&quot;red&quot; id=&quot;line&quot;&gt;HTML&lt;/div&gt;
&lt;div class=&quot;red&quot;&gt;CSS&lt;/div&gt;</code></pre><pre><code class="language-css">#line.red{
    color: red;
    text-decoration: underline;
}</code></pre>
<blockquote>
<p><img src="https://velog.velcdn.com/images/giraffe_/post/1aa1e5d8-ff20-45c6-841e-42733acd7c40/image.png" alt=""></p>
</blockquote>
<p>id 속성의 값과 class 속성의 값을 모두 갖고있는 요소만 효과가 적용된 것을 확인할 수 있습니다.</p>
<p>이외에도 &#39;요소 선택자 + 속성 선택자&#39; 등 선택자들을 다양하게 조합하여 사용할 수 있습니다.</p>
<h1 id="문서-구조-관련-선택자">문서 구조 관련 선택자</h1>
<p>HTML을 구성하는 태그들의 구조를 사용하여 선택자로 활용합니다.</p>
<p>관계에 따라 <strong>부모, 자식, 조상, 자손, 형제</strong> 관계로 나눌 수 있습니다.</p>
<pre><code>&lt;html&gt;
    &lt;head&gt;
        &lt;title&gt;CSS&lt;/title&gt;
    &lt;/head&gt;
    &lt;body&gt;
        &lt;h1&gt;
            &lt;div&gt;&lt;span&gt;문서 구조&lt;/span&gt; 관련 선택자&lt;/div&gt;
        &lt;/h1&gt;
        &lt;p&gt;&lt;span&gt;부모, 자식, 조상, 자손, 형제&lt;/span&gt; 관계를 이용한 선택자입니다.&lt;/p&gt;
    &lt;/body&gt;
&lt;/html&gt;</code></pre><blockquote>
<p><img src="https://velog.velcdn.com/images/giraffe_/post/be34e45d-2bfd-46a6-93bd-9bd6e062210a/image.png" alt=""></p>
</blockquote>
<p>위의 포함 관계를 트리로 구조화하면 아래와 같습니다.</p>
<blockquote>
<p><img src="https://velog.velcdn.com/images/giraffe_/post/9edf9677-ce63-40c2-add7-7e4a31d59b7a/image.png" alt=""></p>
</blockquote>
<h2 id="부모-관계">부모 관계</h2>
<p>어떤 요소를 포함하는 바로 상위 관계 요소로, 어떤 요소의 부모 관계 요소는 단 하나입니다.</p>
<p><code>&lt;head&gt;</code>의 부모 관계 요소는 <code>&lt;html&gt;</code>이며, <code>&lt;div&gt;</code>의 부모 관계 요소는 <code>&lt;h1&gt;</code>입니다.</p>
<h2 id="자식-관계">자식 관계</h2>
<p>부모 관계와 반대되는 관계로, 어떤 요소에 포함되는 바로 하위 관계 요소이며, 부모 관계 요소는 단 하나이지만 자식 관계 요소는 여러개 일 수 있습니다.</p>
<p><code>&lt;haed&gt;</code>와 <code>&lt;body&gt;</code>의 부모 관계 요소는 각각 <code>&lt;html&gt;</code>이지만, <code>&lt;html&gt;</code>의 자식 관계 요소는 <code>&lt;head&gt;</code>와 <code>&lt;body&gt;</code>입니다. <code>&lt;body&gt;</code>의 자식 관계 요소는 <code>&lt;h1&gt;</code>과 <code>&lt;p&gt;</code>입니다.</p>
<p>부모와 자식 관계 요소를 선택할 때는 <code>부모_요소 &gt; 자식_요소</code>의 형태로 사용합니다.</p>
<pre><code class="language-css">div &gt; span{
    text-decoration: underline;
}</code></pre>
<blockquote>
<p><img src="https://velog.velcdn.com/images/giraffe_/post/13d1e264-4ed2-426b-aafd-ec15b94cf190/image.png" alt=""></p>
</blockquote>
<h2 id="조상-관계">조상 관계</h2>
<p>부모 관계의 확장된 관계로, 어떤 요소를 포함하는 모든 상위 관계 요소입니다.</p>
<p><code>&lt;div&gt;</code>의 조상 관계 요소는 <code>&lt;h1&gt;</code>, <code>&lt;body&gt;</code>, <code>&lt;html&gt;</code>입니다.</p>
<h2 id="자손-관계">자손 관계</h2>
<p>조상 관계 요소와 반대되는 관계로, 어떤 요소에 포함되는 모든 하위 관계 요소입니다.</p>
<p><code>&lt;html&gt;</code>의 자손 관계 요소는 <code>&lt;head&gt;</code>, <code>&lt;body&gt;</code>, <code>&lt;h1&gt;</code>, <code>&lt;p&gt;</code>, <code>&lt;div&gt;</code>, <code>&lt;span&gt;</code>, <code>&lt;span&gt;</code>입니다.</p>
<p>조상과 자손 관계 요소를 선택할 때는 <code>조상_요소 자손_요소</code>의 형태로 사용합니다.</p>
<pre><code class="language-css">body span{
    text-decoration: underline;
}</code></pre>
<blockquote>
<p><img src="https://velog.velcdn.com/images/giraffe_/post/6070ba67-a1f7-41a7-b092-b308daecb8a9/image.png" alt=""></p>
</blockquote>
<h2 id="형제-관계">형제 관계</h2>
<p>같은 부모 요소를 가진 관계입니다.</p>
<p><code>&lt;head&gt;</code>과 <code>&lt;body&gt;</code>, <code>&lt;h1&gt;</code>과 <code>&lt;p&gt;</code>는 형제 관계 요소입니다.</p>
<h3 id="인접-형제-관계">인접 형제 관계</h3>
<p>형제 관계에서 어떤 형제 요소 바로 다음에 위치한 요소의 관계입니다.</p>
<p><code>&lt;body&gt;</code>는 <code>&lt;head&gt;</code>의 인접 형제 관계 요소입니다. <code>&lt;head&gt;</code>와 <code>&lt;body&gt;</code>는 형제 관계이지만 <code>&lt;head&gt;</code>는 바로 전에 위치한 형제 관계 요소가 없기때문에 인접 형제 관계 요소가 될 수 없습니다.
마찬가지로 <code>&lt;p&gt;</code>는 <code>&lt;h1&gt;</code>의 인접 형제 관계 요소이지만, <code>&lt;h1&gt;</code>은 인접 형제 관계 요소가 될 수 없습니다.</p>
<p>인접 형제 관계 요소를 선택할 때는 <code>형제_요소 + 인접_형제_요소</code>의 형태로 사용합니다.</p>
<pre><code class="language-css">h1 + p{
    text-decoration: underline;
}</code></pre>
<blockquote>
<p><img src="https://velog.velcdn.com/images/giraffe_/post/aa72397c-01c5-450c-81aa-1ed07b78509d/image.png" alt=""></p>
</blockquote>
<h1 id="가상-선택자pseudo-selector">가상 선택자(pseudo selector)</h1>
<p>첫번째 요소, 마지막 요소 처럼 상황에 따라 유동적으로 적용할 수 있는 <strong>보이지않는 가상의 선택자</strong>입니다.</p>
<h2 id="가상-classpseudo-class">가상 class(pseudo class)</h2>
<p>특정 상황에 적용하여 선택자로 사용하는 클래스입니다.</p>
<pre><code class="language-css">선택자:가상_클래스{
    속성: 값;
}</code></pre>
<h3 id="문서-구조-관련-가상-class">문서 구조 관련 가상 class</h3>
<p>형제 관계에 있는 요소에 적용하여 사용하는 가상 클래스로,
&#39;<strong>first-child</strong>&#39;는 첫번째 요소를, &#39;<strong>last-child</strong>&#39;는 마지막 요소를 선택합니다.</p>
<pre><code>&lt;ul&gt;
    &lt;li&gt;HTML&lt;/li&gt;
    &lt;li&gt;CSS&lt;/li&gt;
    &lt;li&gt;JS&lt;/li&gt;
    &lt;li&gt;C&lt;/li&gt;
    &lt;li&gt;JAVA&lt;/li&gt;
&lt;/ul&gt;</code></pre><pre><code class="language-css">li:first-child{
    text-decoration: underline;
}

li:last-child{
    text-decoration: line-through;
}</code></pre>
<blockquote>
<p><img src="https://velog.velcdn.com/images/giraffe_/post/4cf02fe8-08d3-4780-8022-8d936b8766b0/image.png" alt=""></p>
</blockquote>
<h3 id="링크-관련-가상-class">링크 관련 가상 class</h3>
<p><code>&lt;a&gt;</code> 태그에 적용하여 사용하는 가상 class입니다.</p>
<ul>
<li><p><strong>:link</strong> : 하이퍼링크 중 아직 방문하지않은 앵커</p>
</li>
<li><p><strong>:visited</strong> : 하이퍼링크 중 이미 방문한 앵커</p>
</li>
</ul>
<p><strong>※ 하이퍼링크</strong> : <code>&lt;a&gt;</code> 태그의 속성에 &#39;href&#39; 속성이 적용된 링크 </p>
<pre><code>&lt;a href=&quot;&quot;&gt;하이퍼링크&lt;/a&gt;</code></pre><pre><code class="language-css">a:link{
    color: red;
}

a:visited{
    color: blue;
}</code></pre>
<blockquote>
<p><img src="https://velog.velcdn.com/images/giraffe_/post/3055b8cd-3792-4701-a02b-feb046fc85a9/image.png" alt=""></p>
</blockquote>
<p>:link(미방문 상태) 앵커입니다.</p>
<blockquote>
<p><img src="https://velog.velcdn.com/images/giraffe_/post/361724f6-c148-4ea2-a4f7-97ff55495c99/image.png" alt=""></p>
</blockquote>
<p>:visited(방문 상태) 앵커입니다.</p>
<h3 id="사용자-동작-관련-가상-class">사용자 동작 관련 가상 class</h3>
<p>키보드로 입력하거나 마우스로 클릭하는 등의 사용자 동작에 적용하여 사용하는 가상 class입니다.</p>
<ul>
<li><p><strong>:focus</strong> : 현재 포커스(&#39;tab&#39; 키 등으로 선택)가 위치한 요소</p>
</li>
<li><p><strong>:hover</strong> : 현재 커서가 위치한 요소</p>
</li>
<li><p><strong>:active</strong> : 사용자 입력으로 활성화된 요소</p>
</li>
</ul>
<pre><code>&lt;a href=&quot;&quot;&gt;하이퍼링크&lt;/a&gt;</code></pre><pre><code class="language-css">a:focus{
    font-style: italic;
}

a:hover{
    background-color: skyblue;
}

a:active{
    color: red;
}</code></pre>
<blockquote>
<p><img src="https://velog.velcdn.com/images/giraffe_/post/0c472d77-e251-4f85-9109-261766b113d1/image.png" alt=""></p>
</blockquote>
<p>어떠한 사용자 동작도 입력되지않은 기본 상태입니다.</p>
<blockquote>
<p><img src="https://velog.velcdn.com/images/giraffe_/post/ef1dbf6e-1a58-435b-b0d2-1c383926d4b6/image.png" alt=""></p>
</blockquote>
<p>:focus(포커스를 받고있는 상태) 상태입니다.</p>
<blockquote>
<p><img src="https://velog.velcdn.com/images/giraffe_/post/8eb5010f-cf79-4311-bb2c-a638c5937c44/image.png" alt=""></p>
</blockquote>
<p>:hover(커서가 위치해있는 상태) 상태입니다.</p>
<blockquote>
<p><img src="https://velog.velcdn.com/images/giraffe_/post/20caf83e-a30c-4333-848b-15a624cf40bb/image.png" alt=""></p>
</blockquote>
<p>:active(커서로 클릭된 상태) 상태입니다.</p>
<h2 id="가상-요소pseudo-element">가상 요소(pseudo element)</h2>
<p>정의된 위치에 삽입되는 요소입니다.</p>
<pre><code class="language-css">선택자::가상_요소{
    속성: 값;</code></pre>
<ul>
<li><p><strong>::before</strong> : 해당 요소 바로 앞에 요소 삽입</p>
</li>
<li><p><strong>::after</strong> : 해당 요소 바로 뒤에 요소 삽입</p>
</li>
<li><p><strong>::first-line</strong> : 해당 요소 첫번째 줄에 있는 텍스트를 감싸는 요소 생성(화면 기준)</p>
</li>
<li><p><strong>::first-letter</strong> : 해당 요소 첫번째 문자를 감싸는 요소 생성</p>
</li>
</ul>
<p><strong>※</strong> 가상 클래스처럼 &#39;:(colon)&#39;을 하나만 입력해도되지만, CSS3 부터 가상 클래스와 구분하기위해 &#39;::&#39;처럼 두번 입력하여 사용하기로 약속하였습니다.(브라우저 버전이 낮아 &#39;::&#39;이 지원되지않는 경우는 한번만 입력하여 사용해야합니다.)</p>
<p><strong>※ content 속성</strong> : 가상 요소가 content 속성과 함께 사용되는 경우가 있는데, content 속성은 지정한 텍스트나 이미지 등을 삽입하는 역할을 합니다.</p>
<pre><code>&lt;p&gt;기린은 목이 아주 긴 동물입니다.&lt;br&gt;기린의 뒷발에 차이면 매우 아픕니다.&lt;/p&gt;</code></pre><blockquote>
<p><img src="https://velog.velcdn.com/images/giraffe_/post/d9991a4c-35f2-4aa1-bba3-75c217d4ad76/image.png" alt=""></p>
</blockquote>
<p>위의 HTML에 각각의 가상 요소를 사용하는 CSS를 적용시켜보겠습니다.</p>
<pre><code class="language-css">p::before{
    background-color:skyblue;
    content: &quot;before 가상 요소&quot;;
}</code></pre>
<blockquote>
<p><img src="https://velog.velcdn.com/images/giraffe_/post/5695bbb9-1377-4fcf-b803-a6b42bd76acb/image.png" alt=""></p>
</blockquote>
<p>content 속성으로 지정한 텍스트가 요소의 앞에 삽입된 것을 확인할 수 있습니다.</p>
<pre><code class="language-css">p::after{
    background-color:skyblue;
    content: &quot;after 가상 요소&quot;;
}</code></pre>
<blockquote>
<p><img src="https://velog.velcdn.com/images/giraffe_/post/1ca3a1f2-61df-4d74-b1ab-8ee2cc9f53ef/image.png" alt=""></p>
</blockquote>
<p>content 속성으로 지정한 텍스트가 요소의 뒤에 삽입된 것을 확인할 수 있습니다.</p>
<pre><code class="language-css">p::first-line{
    background-color:skyblue;
}</code></pre>
<blockquote>
<p><img src="https://velog.velcdn.com/images/giraffe_/post/73f2c9da-e64e-4932-bd76-6bd95c799fed/image.png" alt=""></p>
</blockquote>
<p>첫번째 줄을 감싸는 요소가 생성되어 스타일이 적용된 것을 확인할 수 있습니다.</p>
<pre><code class="language-css">p::first-letter{
    background-color:skyblue;
}</code></pre>
<blockquote>
<p><img src="https://velog.velcdn.com/images/giraffe_/post/56b35e69-5f64-4d00-93cd-18f80ffb4146/image.png" alt=""></p>
</blockquote>
<p>첫번째 문자를 감싸는 요소가 생성되어 스타일이 적용된 것을 확인할 수 있습니다.</p>
<h1 id="구체성명시도">구체성(명시도)</h1>
<p><strong>선택자를 얼마나 명시적으로 선언했는지를 수치화하여 값으로 표현한 것</strong>으로, <strong>왼쪽 값부터 우선 순위</strong>를 가지며, 이 <strong>값이 높을수록 적용 우선 순위</strong>를 가집니다.</p>
<p>&#39;<strong>n, n, n, n</strong>&#39;의 형식으로 표현하고, 각 자리는 어떤 선택자를 사용했는지에 따라 값이 결정됩니다.</p>
<p>각 자리별로</p>
<ul>
<li><p><strong>1, 0, 0, 0</strong> : 인라인 스타일</p>
</li>
<li><p><strong>0, 1, 0, 0</strong> : id 선택자</p>
</li>
<li><p><strong>0, 0, 1, 0</strong> : class 선택자, 가상 class 선택자, 속성 선택자</p>
</li>
<li><p><strong>0, 0, 0, 1</strong> : 요소 선택자, 가상 요소 선택자</p>
</li>
<li><p><strong>0, 0, 0, 0</strong> : 전체 선택자</p>
</li>
</ul>
<p>의 값을 가지며, <strong>조합자(&gt;, + 등)는 구체성에 영향을 주지않습니다.</strong></p>
<p>각 케이스 별로 구체성 값을 계산해보겠습니다.</p>
<pre><code class="language-css">p{}</code></pre>
<p>선택자에 요소가 하나이므로, 구체성 값은 &#39;0, 0, 0, 1&#39;입니다.</p>
<pre><code class="language-css">p div{}</code></pre>
<p>선택자에 요소가 두개이므로, 구체성 값은 &#39;0, 0, 0, 2&#39;입니다.</p>
<pre><code class="language-css">.alpha{}</code></pre>
<p>선택자에 class 선택자가 하나이므로, 구체성 값은 &#39;0, 0, 1, 0&#39;입니다.</p>
<pre><code class="language-css">*.alpha{}</code></pre>
<p>선택자에 전체 선택자와 class 선택자가 있지만, 전체 선택자는 &#39;0, 0, 0, 0&#39;의 값을 가지므로, 구체성 값은 &#39;0, 0, 1, 0&#39;입니다.</p>
<pre><code class="language-css">p.alpha div.beta{}</code></pre>
<p>선택자에 요소 선택자가 두개, class 선택자가 두개이므로, 구체성 값은 &#39;0, 0, 2, 2&#39;입니다.</p>
<pre><code class="language-css">#alpha{}</code></pre>
<p>선택자에 id 선택자가 하나이므로, 구체성 값은 &#39;0, 1, 0, 0&#39;입니다.</p>
<pre><code class="language-css">p#alpha{}</code></pre>
<p>선택자에 요소 선택자가 하나, id 선택자가 하나이므로, 구체성 값은 &#39;0, 1, 0, 1&#39;입니다.</p>
<pre><code>&lt;p id=&quot;alpha&quot; style=&quot;color: skyblue&quot;&gt;inlinestyle&lt;/p&gt;</code></pre><pre><code class="language-css">#alpha{ color: green; }</code></pre>
<p>위 처럼 CSS에 id 선택자로 구체성 값 &#39;0, 1, 0, 0&#39;을 가지더라도, HTML에 인라인 스타일로 지정된 속성 값이 더 높은 우선 순위의 구체성 값인 &#39;1, 0, 0, 0&#39;을 가지므로, 인라인 스타일이 적용됩니다.</p>
<h2 id="important">!important</h2>
<pre><code>&lt;p id=&quot;alpha&quot; style=&quot;color: skyblue&quot;&gt;inlinestyle&lt;/p&gt;</code></pre><pre><code class="language-css">#alpha{ color: green !important; }</code></pre>
<p>같은 상황에서 &#39;<strong>!important</strong>&#39; 키워드를 CSS에서 적용시키면, 이 키워드가 붙은 스타일이 <strong>모든 구체성을 무시하고 우선 적용</strong>됩니다.</p>
<h1 id="상속">상속</h1>
<p>문서 구조와 관련된 선택자에서 &#39;부모-자식&#39;같은 관계에서 &#39;<strong>상속</strong>&#39;이 발생하며, 부모에 지정된 스타일을 자식이 물려받는 것을 말합니다.</p>
<pre><code>&lt;div&gt;&lt;span&gt;span 요소&lt;/span&gt;는 div의 자식 요소입니다.&lt;/div&gt;</code></pre><pre><code class="language-css">div { color: blue; }</code></pre>
<blockquote>
<p><img src="https://velog.velcdn.com/images/giraffe_/post/90461db9-9dfb-47f6-833c-d713a650640e/image.png" alt=""></p>
</blockquote>
<p>이처럼 div에 지정된 스타일이 span에도 적용된 것을 확인할 수 있습니다.
하지만 모든 스타일이 상속되는 것은 아닙니다. &#39;margin, padding, background, border&#39; 등의 &#39;<strong>박스 모델</strong>&#39; 관련 속성은 상속되지않습니다.</p>
<h2 id="상속에서-구체성-값">상속에서 구체성 값</h2>
<pre><code>&lt;div&gt;&lt;span&gt;span 요소&lt;/span&gt;는 div의 자식 요소입니다.&lt;/div&gt;</code></pre><pre><code class="language-css">*{ color: red; }

div{ color: blue; }</code></pre>
<blockquote>
<p><img src="https://velog.velcdn.com/images/giraffe_/post/36e3d5fc-75de-4c10-8271-f81df9342c2c/image.png" alt=""></p>
</blockquote>
<p>스타일이 상속되었을 때, 상속받은 요소의 구체성 값은 &#39;0, 0, 0, 0&#39;같은 <strong>값 자체를 갖지않습니다.</strong>
따라서 구체성 값이 &#39;0, 0, 0, 0&#39;인 전체 선택자보다도 낮은 우선 순위를 가지기때문에 span 요소에 전체 선택자로 지정된 스타일인 &#39;color: red;&#39;가 적용되었습니다.</p>
<h1 id="캐스케이딩cascading">캐스케이딩(cascading)</h1>
<p>어떤 요소에 규칙에 따라 단계적으로 스타일이 적용되는 것을 의미하며, 3가지의 규칙이 있습니다.</p>
<h2 id="중요도important와-출처">중요도(!important)와 출처</h2>
<p>&#39;<strong>중요도</strong>&#39;는 &#39;!important&#39; 키워드가 붙은 스타일이 모든 규칙보다 우선 적용되는 것입니다.</p>
<p>&#39;<strong>출처</strong>&#39;는 &#39;제작자&#39;, &#39;사용자&#39;, &#39;사용자 에이전트&#39;로 구분되어 차등 적용됩니다.</p>
<p>우선 순위를 정리하면, 가장 높은 우선 순위부터</p>
<ol>
<li><p>사용자 !important 스타일
(일반 사용자가 작성한 !important 스타일을 본인 브라우저에 적용 시킨 것)</p>
</li>
<li><p>제작자 !important 스타일
(웹 개발자가 작성한 !important 스타일)</p>
</li>
<li><p>제작자 스타일
(웹 개발자가 작성한 CSS 스타일)</p>
</li>
<li><p>사용자 스타일
(일반 사용자가 작성한 CSS 스타일을 본인 브라우저에 적용시킨 것)</p>
</li>
<li><p>사용자 에이전트 스타일
(브라우저 기본 제공 스타일)</p>
</li>
</ol>
<p>순서로 우선 순위를 가집니다.</p>
<p>사용자와 관련된 스타일은 현재 브라우저에서 지원하지않는 부분도많고, 여러 이유로하여 현재는 큰 의미를 갖지않습니다.</p>
<h2 id="구체성">구체성</h2>
<p>구체성 값에따라 더 높은 값을 가진 스타일이 우선 순위를 가집니다.</p>
<h2 id="선언-순서">선언 순서</h2>
<pre><code class="language-css">div{ color: red; }

div{ color: blue; }</code></pre>
<p>위처럼 동일한 선택자를 사용한 스타일이있을 때, 나중에 선언된 스타일이 우선 순위를 가집니다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[CSS 개요]]></title>
            <link>https://velog.io/@giraffe_/CSS-%EA%B0%9C%EC%9A%94</link>
            <guid>https://velog.io/@giraffe_/CSS-%EA%B0%9C%EC%9A%94</guid>
            <pubDate>Tue, 12 Jul 2022 14:52:25 GMT</pubDate>
            <description><![CDATA[<p>※ CSS는 Naver의 &#39;Boostcourse&#39;에서 공부하고있습니다.
<br></p>
<h1 id="css">CSS</h1>
<p>&#39;<strong>CSS(Cascading Style Sheets)</strong>&#39;는 HTML을 <strong>꾸며주는 언어</strong>입니다. HTML은 정보를 담고있는 컨텐츠가되고, CSS는 그 컨텐츠를 디자인하는 역할을합니다. 따라서 HTML이 없다면 CSS는 효용이없다고 할 수 있습니다.</p>
<h1 id="문법">문법</h1>
<pre><code class="language-css">선택자{
    속성1 : 값1;    /* 선언1 */
    속성2 : 값2;    /* 선언2 */

    ...

    속성n : 값n;    /* 선언n */
}</code></pre>
<h2 id="주석comment-tags">주석(comment tags)</h2>
<pre><code class="language-css">/* 주석 */

/*
주석
*/</code></pre>
<p>HTML처럼 CSS에도 주석을 사용할 수 있습니다.</p>
<h2 id="선택자selector">선택자(selector)</h2>
<p>HTML의 어떤 요소를 꾸밀지 선택하는 부분으로, 위 예시처럼 html 태그를 적어 줄 수도있지만, 해당되는 모든 태그에 효과가 적용되기때문에, html 속성 중 &#39;<strong>id</strong>&#39;, &#39;<strong>class</strong>&#39; 같은 속성을 사용해서 특정 요소를 지정하여 효과를 적용시킬 수 있습니다.</p>
<h2 id="속성property">속성(property)</h2>
<p>선택자로 선택한 요소에 어떤 효과를 적용할지 작성합니다.</p>
<h2 id="값value">값(value)</h2>
<p>속성에 구체적인 값을 작성하여 효과를 적용 가능하게합니다.</p>
<h2 id="선언declaration">선언(declaration)</h2>
<p>속성과 값을 묶어 하나의 &#39;<strong>선언</strong>&#39;이라고하며, 선언이 끝나면 끝에 &#39;<strong>세미콜론(;)</strong>&#39;을 붙여서 하나의 선언이 끝났음을 표시하고 그 뒤에 또다른 선언을 사용할 수도 있습니다.
마지막 선언에는 세미콜론을 생략할 수 있지만, 실수를 방지하기위해 붙여주어도 상관이없습니다.</p>
<h2 id="선언부declaration-block">선언부(declaration block)</h2>
<p>선언을 중괄호({, })로 묶고있는 부분을 &#39;<strong>선언부</strong>&#39;라고합니다.</p>
<h2 id="규칙rule-set">규칙(rule set)</h2>
<p>선택자와 선언부를 모두 합쳐 &#39;<strong>규칙</strong>&#39;이라고합니다.
CSS는 여러개의 규칙으로 구성됩니다.</p>
<pre><code class="language-css">선택자 { 선언 }

선택자
{
    선언
}

선택자{
    선언
}</code></pre>
<p>규칙은 위처럼 다양한 형태로 사용할 수 있습니다. 유의할 점은 선언에서는 속성과 값을 개행하여 작성하면 안된다는 것입니다.</p>
<h1 id="css-적용-방식">CSS 적용 방식</h1>
<p>CSS는 여러 방식으로 HTML에 적용시킬 수 있습니다.</p>
<h2 id="inline-방식">Inline 방식</h2>
<p>HTML의 태그에 직접 CSS를 작성하는 방식입니다.</p>
<pre><code>&lt;!DOCTYPE html&gt;
&lt;html lang=&quot;ko&quot;&gt;
    &lt;head&gt;
        &lt;meta charset=&quot;utf-8&quot;&gt;
        &lt;title&gt;CSS&lt;/title&gt;
    &lt;/head&gt;
    &lt;body&gt;
        &lt;div&gt;CSS&lt;/div&gt;
        &lt;div style=&quot;font-size: 20px; color: blue;&quot;&gt;CSS&lt;/div&gt;
    &lt;/body&gt;
&lt;/html&gt;</code></pre><blockquote>
<p><img src="https://velog.velcdn.com/images/giraffe_/post/8b33409e-6deb-4a25-8a4f-269b4501d608/image.png" alt=""></p>
</blockquote>
<p>CSS를 적용할 요소에 매번 따로 지정해줘야하는 번거로움이있고, 확인과 수정이 힘드므로 잘 사용되지않습니다.</p>
<h2 id="internal-방식">Internal 방식</h2>
<p>HTML의 <code>&lt;head&gt;</code> 부분에 <code>&lt;style&gt;</code> 태그를 사용하여 CSS를 작성하는 방식입니다.</p>
<pre><code>&lt;!DOCTYPE html&gt;
&lt;html lang=&quot;ko&quot;&gt;
    &lt;head&gt;
        &lt;meta charset=&quot;utf-8&quot;&gt;
        &lt;title&gt;CSS&lt;/title&gt;
        &lt;style&gt;
            div {font-size : 20px; color : blue; }
        &lt;/style&gt;
    &lt;/head&gt;
    &lt;body&gt;
        &lt;div&gt;CSS&lt;/div&gt;
        &lt;div&gt;CSS&lt;/div&gt;
    &lt;/body&gt;
&lt;/html&gt;</code></pre><blockquote>
<p><img src="https://velog.velcdn.com/images/giraffe_/post/7eafd43e-b2d3-4181-b898-47ac52c8e007/image.png" alt=""></p>
</blockquote>
<p>Inline 방식보다는 유용하지만, 사이트에 존재하는 수많은 페이지에 모두 CSS를 작성해주어야하는 번거로움이있습니다.</p>
<h2 id="external-방식">External 방식</h2>
<p>위의 두가지 방법처럼 HTML 파일 내부에 CSS를 작성하지않고, CSS를 별도의 파일로 분리하여 작성한 후 HTML 파일에 연결시키는 방식입니다.</p>
<pre><code>&lt;!-- HTML 파일 --&gt;

&lt;!DOCTYPE html&gt;
&lt;html lang=&quot;ko&quot;&gt;
    &lt;head&gt;
        &lt;meta charset=&quot;utf-8&quot;&gt;
        &lt;title&gt;CSS&lt;/title&gt;
        &lt;link rel=&quot;stylesheet&quot; href=&quot;./sample.css&quot;&gt;
    &lt;/head&gt;
    &lt;body&gt;
        &lt;div&gt;CSS&lt;/div&gt;
        &lt;div&gt;CSS&lt;/div&gt;
    &lt;/body&gt;
&lt;/html&gt;</code></pre><pre><code class="language-css">/* CSS 파일 */

div{
    font-size: 20px;
    color: blue;
}</code></pre>
<blockquote>
<p><img src="https://velog.velcdn.com/images/giraffe_/post/e780c66d-24e0-4cd7-996a-079a73c3439c/image.png" alt=""></p>
</blockquote>
<p>HTML 파일에 CSS 파일을 연결시킬 때, <code>&lt;link&gt;</code> 태그가 사용됩니다. HTML 파일의 <code>&lt;head&gt;</code> 부분에 작성하며, &#39;<strong>rel</strong>&#39; 속성에 값으로 CSS를 뜻하는 &#39;<strong>stylesheet</strong>&#39;를 작성하고, &#39;<strong>href</strong>&#39; 속성에 CSS 파일의 경로를 입력합니다.
관리도 용이하고, 확인 및 수정도 용이하여 가장 많이 사용되는 방식입니다.</p>
<h2 id="import-방식">@import 방식</h2>
<pre><code class="language-css">@import url(&quot;CSS_파일_경로&quot;);</code></pre>
<p>HTML 파일의 <code>&lt;style&gt;</code> 태그 상단에 선언하거나, CSS 파일 상단에 선언하여 다른 CSS 파일을 연결하는 방식입니다.
HTML 파일에서 <code>&lt;link&gt;</code> 태그를 사용하면 CSS 파일을 병렬로 읽어오는 반면, 이 방식을 사용하면 직렬로 읽어오기때문에 성능 측면에서 좋지않고, 여러 이유로 잘 쓰이지않는 방식입니다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[인덱스(Index)]]></title>
            <link>https://velog.io/@giraffe_/%EC%9D%B8%EB%8D%B1%EC%8A%A4Index</link>
            <guid>https://velog.io/@giraffe_/%EC%9D%B8%EB%8D%B1%EC%8A%A4Index</guid>
            <pubDate>Thu, 07 Jul 2022 13:05:32 GMT</pubDate>
            <description><![CDATA[<p>&#39;<strong>인덱스(Index)</strong>&#39;, 즉 &#39;<strong>색인(索引)</strong>&#39;은 단어 등을 찾기쉽게 어느 곳에 있는지 특정 순서대로 정리해놓은 것 입니다. 인덱스가 있으면 처음부터 쭉 모든 부분을 찾아보는 대신 필요한 부분을 바로 찾을 수 있습니다.
데이터베이스에서 질의문을 사용하여 특정 데이터를 찾을 때, 데이터가 적은 경우에는 상관이없지만, 그 양이 방대하여 매우 많은 데이터에서 일일이 질의문을 만족하는 데이터를 찾을 경우에는 상당히 많은 시간이 필요할 것 입니다. 이런 경우에 인덱스를 활용하면 빠르게 필요한 데이터에 접근할 수 있습니다. 하지만 인덱스도 저장 공간을 차지하기때문에, 과도한 인덱스의 생성은 저장 공간을 불필요하게 차지하고, 성능을 오히려 떨어트릴 수 있습니다.</p>
<h1 id="순서-인덱스ordered-index">순서 인덱스(Ordered Index)</h1>
<p>&#39;<strong>순서 인덱스</strong>&#39;는 &#39;<strong>탐색키(search key : 수퍼키, 후보키 등의 키가 아닌, 파일에서 투플을 찾을 때 이용하는 컬럼)</strong>&#39; 값을 기준으로 정렬된 &#39;<strong>순차 파일(sequential file)</strong>&#39;에서 특정 투플에 &#39;<strong>임의 접근(random access)</strong>&#39;을 가능하게합니다.
순서 인덱스는 &#39;<strong>인덱스 엔트리(index entry)</strong>&#39;를 가지는데, 인덱스 엔트리는 각 투플보다 용량이 작기때문에 탐색시 메모리에서 인덱스 엔트리를 활용하여 더 빠르게 탐색이 가능합니다. 인덱스 엔트리는 <strong>탐색키값과 포인터(Block ID와 Offset으로 구성)</strong>로 구성됩니다.</p>
<p><strong>※ 클러스터형 인덱스(Clustered Index)</strong> : 사전처럼 전체 데이터가 순서대로 저장돼있는 인덱스로, 릴레이션 당 하나만 생성이 가능합니다. 기본키가 지정되었다면 자동으로 생성됩니다.</p>
<p><strong>※ 보조 인덱스(Secondary Index)</strong> : 색인 부분이 따로 존재하는 책처럼 구성된 인덱스로, 릴레이션 당 여러개 생성이 가능합니다.</p>
<p><strong>※ 밀집 인덱스(Dense Index)</strong> : 모든 탐색키가 인덱스 엔트리를 가집니다. 따라서 인덱스 엔트리의 포인터를 따라 전체 탐색을 할 수 있습니다.</p>
<p><strong>※ 희소 인덱스(Sparse Index)</strong> : 일부 탐색키만 인덱스 엔트리를 가집니다. 따라서 인덱스 엔트리의 탐색키값에서 탐색하려는 값보다 작거나 같은 값 중 가장 큰 값을 찾은 후 값이 일치하면 탐색을 종료하고, 일치하지않으면 해당 값에서부터 순차적으로 투플을 읽어 일치하는 투플을 찾습니다.</p>
<p><strong>※ 다단계 인덱스</strong> : 밀집 인덱스와 희소 인덱스의 장점을 이용하여, 투플에 직접 대응되는 밀집 인덱스를 <strong>내부 인덱스</strong>로, 그 내부 인덱스에 대응되는 희소 인덱스를 <strong>외부 인덱스</strong>로 하여 다단계로 인덱스를 형성합니다. 따라서 다단계 인덱스는 2개 이상의 단계로 구성됩니다.</p>
<h1 id="b-트리-인덱스">B+ 트리 인덱스</h1>
<blockquote>
<p><img src="https://velog.velcdn.com/images/giraffe_/post/8e87acd6-0144-46d8-840a-60ac3066c452/image.png" alt="">
<a href="https://ko.wikipedia.org/wiki/B%2B_%ED%8A%B8%EB%A6%AC">출처 : 위키백과 - B+ 트리</a></p>
</blockquote>
<p>&#39;<strong>B+ 트리</strong>&#39;는 &#39;<strong>루트 노드(root node)</strong>&#39;, &#39;<strong>중간 노드(internal node)</strong>&#39;, &#39;<strong>단말 노드(leaf node)</strong>&#39;로 구성됩니다.
루트 노드는 최상위 노드이며, 단말 노드는 모든 탐색키 값이 정렬되어 연결 리스트 형태로 존재하는 &#39;<strong>순차 세트(ordered set)</strong>&#39;로 구성되어있습니다. 중간 노드는 이들을 제외한 그 사이에 위치한 모든 노드들이며, 루트 노드와 중간 노드를 묶어 &#39;<strong>인덱스 세트(index set)</strong>&#39;라고 합니다.</p>
<p>&#39;<strong>B+ 트리 인덱스</strong>&#39;는 이러한 B+ 트리를 활용한 인덱스이며, 상용 DBMS에서 가장 많이 사용되는 인덱스 중 하나입니다.</p>
<h1 id="해시-인덱스hash-index">해시 인덱스(Hash Index)</h1>
<p>&#39;<strong>해시 함수(hash function)</strong>&#39;는 탐색키를 버킷에 &#39;<strong>매핑(mapping)</strong>&#39; 시키는 함수로, 각 <strong>버킷(투플이 저장되는 저장 공간 단위)</strong>&#39;에 거의 동일한 수의 투플을 분배시키는 것이 가장 이상적인 해시 함수입니다.
서로 다른 투플이 같은 버킷에 분배되는 것을 &#39;<strong>충돌(collision)</strong>&#39;이라고하고, 이때 같은 버킷에 분배된 투플을 &#39;<strong>동거자(synonyms)</strong>&#39;라고합니다.
버킷에 빈 공간이 없을 때 충돌이 생기면 &#39;<strong>오버플로우(overflow)</strong>&#39;가 발생하는데, 대안으로 다른 버킷을 따로 지정하거나, 다음 버킷에 저장되게하는 등의 조치가 필요합니다.</p>
<p>&#39;<strong>해시 인덱스</strong>&#39;는 이러한 해시 함수를 활용하여 인덱스 엔트리를 버킷에 저장하는 인덱스입니다.</p>
<h1 id="비트맵-인덱스bitmap-index">비트맵 인덱스(Bitmap Index)</h1>
<p>&#39;<strong>비트맵 인덱스</strong>&#39;는 성별, 성적처럼, 그 범위가 수(數)적으로 넓은 범위를 가지는 값이 아닌, 비교적 좁은 범위의 값을 가져, 중복이 많이 발생하는 컬럼에 효과적으로 사용할 수 있는 인덱스입니다.
예를 들어 성별이 남자인 투플을 대상으로 질의를 한다면, 남자인 투플은 &#39;1&#39;의 비트값을, 여자인 투플은 &#39;0&#39;의 비트값을 지정하는 식으로 &#39;<strong>비트맵</strong>&#39;을 생성하여 효율적으로 탐색할 수 있는 인덱스입니다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[SQL 구문 - DML]]></title>
            <link>https://velog.io/@giraffe_/SQL-%EA%B5%AC%EB%AC%B8-DML</link>
            <guid>https://velog.io/@giraffe_/SQL-%EA%B5%AC%EB%AC%B8-DML</guid>
            <pubDate>Mon, 04 Jul 2022 12:31:59 GMT</pubDate>
            <description><![CDATA[<h1 id="백업-및-복원">백업 및 복원</h1>
<p>DML 구문을 다루기에 앞서, DDL로 정의하고 DML로 조작될 데이터베이스의 데이터들을 백업하고 복원하는 방법을 알아보겠습니다.</p>
<p>데이터는 데이터베이스와 릴레이션 단위로 백업 및 복원할 수 있습니다.
MySQL에 접속한 상태가 아닌, 접속하기 전 프롬프트 창에서 실행해야합니다.</p>
<pre><code>데이터베이스 백업
mysqldump -u 계정명 -p 백업할_데이터베이스명 &gt; 백업_파일명.sql

데이터베이스 복원
mysql -u 계정명 -p 복원할_데이터베이스명 &lt; 백업_파일명.sql

릴레이션 백업
mysqldump -u 계정명 -p 백업할_데이터베이스명 백업할_릴레이션명 &gt; 백업_파일명.sql

릴레이션 복원
mysql -u 계정명 -p 복원할_데이터베이스명 &lt; 백업_파일명.sql</code></pre><blockquote>
<p><img src="https://velog.velcdn.com/images/giraffe_/post/44bfea9d-54ef-4ada-8eb9-75e6ee781c7b/image.png" alt=""></p>
</blockquote>
<blockquote>
<p><img src="https://velog.velcdn.com/images/giraffe_/post/7ca2c40f-a589-4399-b858-b5d0f641e9f0/image.png" alt=""></p>
</blockquote>
<h1 id="insert-문">INSERT 문</h1>
<p>릴레이션(테이블)에 투플을 삽입합니다.
릴레이션 생성시 기술한 컬럼 순서에 맞게 값을 입력해주어야하고, NOT NULL을 사용한 컬럼에는 반드시 값을 입력해주어야합니다.
컬럼을 <strong>문자</strong>나 <strong>날짜 형식</strong>으로 지정한 경우 작은 따옴표를 사용하여 <strong>&#39;값&#39;</strong> 의 형태로 값을 입력합니다.</p>
<pre><code>INSERT INTO 릴레이션명 VALUES (값1, 값2, ..., 값n);

INSERT INTO 릴레이션명 (컬럼1, 컬럼2, ..., 컬럼m) VALUES (값1, 값2, ..., 값m);</code></pre><p>모든 컬럼에 값을 입력하는 경우 위의 형식을, 특정 컬럼에만 값을 입력하려는 경우 아래의 형식을 사용하면됩니다.</p>
<h1 id="delete-문">DELETE 문</h1>
<p>릴레이션에서 투플을 삭제합니다. 컬럼 단위가 아닌 투플 단위의 삭제만 가능합니다.
다른 릴레이션에서 참조하고있는 투플을 삭제하려고 시도하면 미리 정해진 조건에따라 거절될 수 있습니다.</p>
<pre><code>DELETE FROM 릴레이션명 [WHERE 조건];</code></pre><p>만약 WHERE 절을 사용하지않으면 릴레이션의 모든 투플이 삭제되고 <strong>복구할 수 없으므로</strong> WHERE 절과 적절한 조건을 사용하여 원하는 투플만 삭제되도록 해야합니다.</p>
<blockquote>
<p><img src="https://velog.velcdn.com/images/giraffe_/post/e1216518-535f-4275-b4ac-33d20b0611a5/image.jpg" alt=""></p>
</blockquote>
<p>INSERT 문을 사용하여 투플을 삽입한 후, DELETE 문에 WHERE 절에서 id 컬럼에 대한 조건을 기술하여 투플을 삭제하였습니다.</p>
<blockquote>
<p><img src="https://velog.velcdn.com/images/giraffe_/post/a879fa28-c814-4af4-ab59-0ad3f913a571/image.jpg" alt=""></p>
</blockquote>
<p>WHERE 절에 기술하는 조건에따라 원치않는 투플도 삭제될 수 있으므로 조건을 적절하게 기술해야합니다.</p>
<blockquote>
<p><img src="https://velog.velcdn.com/images/giraffe_/post/7a8e7343-8389-4c9b-ae19-dff623a38d55/image.jpg" alt=""></p>
</blockquote>
<p>INSERT 문에서 원하는 컬럼만을 지정하여 값을 입력하면, 입력하지않은 컬럼에대해서는 NULL 값이 삽입되지만, 릴레이션 생성시 DEFAULT 제약조건을 설정하면 기본값이 입력되는 것을 확인할 수 있습니다.</p>
<blockquote>
<p><img src="https://velog.velcdn.com/images/giraffe_/post/0e24e2ff-0f1c-4dd8-910b-6d9bc15b3551/image.jpg" alt=""></p>
</blockquote>
<p>릴레이션 생성시 지정한 AUTO_INCREMENT 제약조건에 따라 값을 따로 입력하지않아도 자동으로 상승하며 저장되는 것을 확인할 수 있습니다.
투플을 삭제해도 값은 이어서 상승합니다.</p>
<blockquote>
<p><img src="https://velog.velcdn.com/images/giraffe_/post/8bd85b08-4200-4ed5-b683-078ac297cbd3/image.jpg" alt=""></p>
</blockquote>
<p>릴레이션에 위처럼 투플을 삽입하였습니다.</p>
<h1 id="update-문">UPDATE 문</h1>
<p>INSERT 문으로 삽입한 투플의 컬럼값을 변경합니다.</p>
<pre><code>UPDATE 릴레이션명
    SET 컬럼1=값1[, 컬럼2=값2, ..., 컬럼n=값n]
    [WHERE 조건];</code></pre><p>DELETE 문과 마찬가지로 WHERE 절을 기술하지않으면 모든 투플에대해서 수정이 이루어지므로 WHERE 절에 적절한 조건을 기술하여 사용해야합니다.</p>
<blockquote>
<p><img src="https://velog.velcdn.com/images/giraffe_/post/704fe874-58a3-48a9-ae6b-df2dfa0017e0/image.png" alt=""></p>
</blockquote>
<blockquote>
<p><img src="https://velog.velcdn.com/images/giraffe_/post/efbd6a56-8c77-4497-a815-ef7090eb105d/image.png" alt=""></p>
</blockquote>
<p>다른 투플의 값도 수정해주었습니다.</p>
<h1 id="select-문">SELECT 문</h1>
<p>릴레이션에서 필요한 데이터를 검색할 때 사용합니다. 위의 예제에서 주로 사용한 SELECT 문인 
<code>SELECT * FROM 릴레이션명;</code>은 가장 단순한 형태로 해당 릴레이션의 모든 투플을 보여주지만, 원하는 데이터만을 선택할 때는 훨씬 복잡한 SELECT 문이 사용됩니다.</p>
<pre><code>|| : OR

SELECT [DISTINCT] * || 컬럼1[, 컬럼2, ..., 컬럼n] FROM [중첩_질의문]릴레이션1
    [CROSS JOIN || INNER JOIN || NATURAL JOIN || LEFT [OUTER] JOIN || RIGHT [OUTER] JOIN
    릴레이션2 ON 조인_조건]
    [WHERE 조건 [중첩_질의문]]
    [GROUP BY 컬럼1, 컬럼2, ..., 컬럼m [HAVING 조건]]
    [ORDER BY 컬럼 ASC || DESC];</code></pre><p>위처럼 다양한 절을 활용하여 수많은 데이터에서 원하는 데이터만을 검색할 수 있습니다.</p>
<h2 id="from-절">FROM 절</h2>
<p>검색할 대상 릴레이션을 기술합니다.</p>
<pre><code>SELECT * || 컬럼1[, 컬럼2, ..., 컬럼n] FROM 릴레이션명;</code></pre><blockquote>
<p><img src="https://velog.velcdn.com/images/giraffe_/post/94e804db-dcc8-4f76-8136-38d9d372211a/image.png" alt=""></p>
</blockquote>
<blockquote>
<p><img src="https://velog.velcdn.com/images/giraffe_/post/4561978c-09e1-4812-b9ab-4b8178105649/image.png" alt=""></p>
</blockquote>
<blockquote>
<p><img src="https://velog.velcdn.com/images/giraffe_/post/c04f2a07-91a6-4a34-b55c-1931a5fce78d/image.png" alt=""></p>
</blockquote>
<p>&#39;<strong>DISTINCT</strong>&#39; 키워드를 사용하면 결과에서 중복되는 값을 제거하여 하나씩만 출력합니다.</p>
<h3 id="제어-흐름-함수">제어 흐름 함수</h3>
<table>
  <thead>
    <tr>
      <th>종류</th>
      <th>기능</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>CASE</td>
      <td>CASE 컬럼의 컬럼값을 WHEN-THEN-ELSE 구조에서 조건과 값으로 출력</td>
    </tr>
    <tr>
      <td>IF(조건, 값1, 값2)</td>
      <td>조건이 참이면 값1, 거짓이면 값2 출력</td>
    </tr>
    <tr>
      <td>IFNULL(값1, 값2)</td>
      <td>값1이 NULL이면 값2 출력, NULL이 아니면 값1 출력</td>
    </tr>
    <tr>
      <td>NULLIF</td>
      <td>값1과 값2가 같으면 NULL 출력, 다르면 값1 출력</td>
    </tr>
  </tbody>
</table>

<pre><code>CASE 컬럼
WHEN 조건1 THEN 값1
...
WHEN 조건n THEN 값n
[ELSE 조건에_맞지않는_경우_값]
END</code></pre><blockquote>
<p><img src="https://velog.velcdn.com/images/giraffe_/post/d0c3828b-0305-4c45-9751-7d0112d038a5/image.png" alt=""></p>
</blockquote>
<blockquote>
<p><img src="https://velog.velcdn.com/images/giraffe_/post/61d01f6d-1f6a-440e-bba5-4072db2ef416/image.png" alt=""></p>
</blockquote>
<blockquote>
<p><img src="https://velog.velcdn.com/images/giraffe_/post/7829bf08-e224-4dc9-9b5f-765fd62de523/image.png" alt=""></p>
</blockquote>
<blockquote>
<p><img src="https://velog.velcdn.com/images/giraffe_/post/8072a6dd-0c29-4f45-9339-bea8acbb8821/image.png" alt=""></p>
</blockquote>
<h2 id="alias-절">ALIAS 절</h2>
<p>&#39;<strong>ALIAS(별칭)</strong>&#39; 절은 릴레이션명이나 컬럼명을 SELECT 문 사용 중 임시로 변경할 때 사용합니다.</p>
<pre><code>SELECT 컬럼1 AS 별칭1[, 컬럼2 AS 별칭2, ..., 컬럼n AS 별칭n]
FROM 릴레이션명 [as 별칭];</code></pre><p>AS 키워드는 생략 가능합니다.</p>
<blockquote>
<p><img src="https://velog.velcdn.com/images/giraffe_/post/f029a077-ca36-43ea-b356-cf37fbb55f5f/image.png" alt=""></p>
</blockquote>
<h2 id="order-by-절">ORDER BY 절</h2>
<p>검색 결과를 오름차순이나 내림차순으로 정렬하여 출력합니다. 생략되있을 경우 기본키 값을 기준으로 오름차순으로 정렬하여 출력합니다.</p>
<pre><code>SELECT * || 컬럼1[, 컬럼2, ..., 컬럼n] FROM 릴레이션명
ORDER BY ASC || DESC;</code></pre><p>ASC는 오름차순(ascending), DESC는 내림차순(descending)으로 결과를 정렬합니다.</p>
<blockquote>
<p><img src="https://velog.velcdn.com/images/giraffe_/post/386afbfa-0f06-48d8-9f75-3bc8e855358a/image.png" alt=""></p>
</blockquote>
<h2 id="limit-절">LIMIT 절</h2>
<p>투플수를 제한하여 출력합니다.
너무많은 투플이 출력되어 일부의 결과만 필요한 경우 등에 사용할 수 있습니다.</p>
<pre><code>SELECT * || 컬럼1[, 컬럼2, ..., 컬럼n] FROM 릴레이션명
LIMIT 출력할_투플_수;</code></pre><blockquote>
<p><img src="https://velog.velcdn.com/images/giraffe_/post/ea6ba555-a6f1-4d0d-8fc4-76a4d1dde60a/image.png" alt=""></p>
</blockquote>
<h2 id="where-절">WHERE 절</h2>
<p>릴레이션에서 특정 조건에 맞는 투플만 검색할 때 사용합니다.</p>
<pre><code>SELECT * || 컬럼1[, 컬럼2, ..., 컬럼n] FROM 릴레이션명
WHERE 조건;</code></pre><blockquote>
<p><img src="https://velog.velcdn.com/images/giraffe_/post/744e47eb-67fd-46f5-b676-2de7353983f5/image.png" alt=""></p>
</blockquote>
<h3 id="is-null--is-not-null">IS NULL / IS NOT NULL</h3>
<p>IS NULL : 컬럼값이 &#39;NULL&#39;인 투플을 검색합니다.</p>
<pre><code>SELECT * || 컬럼1[, 컬럼2, ..., 컬럼n] FROM 릴레이션명
WHERE 컬럼 IS NULL;</code></pre><p>IS NOT NULL : 컬럼값이 &#39;NULL&#39;이 아닌 투플을 검색합니다.</p>
<pre><code>SELECT * || 컬럼1[, 컬럼2, ..., 컬럼n] FROM 릴레이션명
WHERE 컬럼 IS NOT NULL;</code></pre><blockquote>
<p><img src="https://velog.velcdn.com/images/giraffe_/post/3cef07dc-15a4-4725-9c46-5d699fd06c21/image.png" alt=""></p>
</blockquote>
<blockquote>
<p><img src="https://velog.velcdn.com/images/giraffe_/post/23c3ec10-a495-40aa-980e-d9251905af8a/image.png" alt=""></p>
</blockquote>
<p>정확한 키워드가 아닌 &#39;=NULL&#39;, &#39;!=NULL&#39; 등을 사용하면 원하는 결과값을 얻을 수 없습니다.</p>
<h3 id="비교-연산자">비교 연산자</h3>
<table>
  <thead>
    <tr>
      <th>종류</th>
      <th>기능</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>컬럼 = 값</td>
      <td>컬럼값이 값과 일치하는 투플 검색</td>
    </tr>
    <tr>
      <td>컬럼 !=(<>) 값</td>
      <td>컬럼값이 값과 일치하지않는 투플 검색</td>
    </tr>
    <tr>
      <td>컬럼 > 값</td>
      <td>컬럼값이 값보다 큰 투플 검색</td>
    </tr>
    <tr>
      <td>컬럼 < 값</td>
      <td>컬럼값이 값보다 작은 투플 검색</td>
    </tr>
    <tr>
      <td>컬럼 >= 값</td>
      <td>컬럼값이 값보다 크거나 같은 투플 검색</td>
    </tr>
    <tr>
      <td>컬럼 <= 값</td>
      <td>컬럼값이 값보다 작거나 같은 투플 검색</td>
    </tr>
  </tbody>
</table>

<p>비교 연산자는 WHERE 절 내에서 컬럼값과 값을 비교하여 조건에 맞는 투플을 검색할 때 사용됩니다.</p>
<blockquote>
<p><img src="https://velog.velcdn.com/images/giraffe_/post/61b0f1d6-04da-490a-b481-ba44e3e5d3e3/image.png" alt=""></p>
</blockquote>
<h3 id="between-절">BETWEEN 절</h3>
<p>비교 연산자를 사용하는 대신 BETWEEN과 AND를 사용하여 범위에 해당하는 값을 검색할 수 있습니다. 범위는 값들을 포함하는 이상, 이하의 범위를 가집니다.</p>
<pre><code>SELECT * || 컬럼1[, 컬럼2, ..., 컬럼n] FROM 릴레이션명
WHERE 컬럼 BETWEEN 값1 AND 값2;</code></pre><blockquote>
<p><img src="https://velog.velcdn.com/images/giraffe_/post/6094c4db-6d67-4080-833c-9dd663e4e567/image.png" alt=""></p>
</blockquote>
<h3 id="논리-연산자">논리 연산자</h3>
<table>
  <thead>
    <tr>
      <th>종류</th>
      <th>기능</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>NOT(!) 조건</td>
      <td>해당 조건이 아닌 투플을 검색하여 출력</td>
    </tr>
    <tr>
      <td>조건1 AND(&&) 조건2</td>
      <td>조건1과 조건2를 모두 만족하는 투플을 검색하여 출력</td>
    </tr>
    <tr>
      <td>조건1 OR(||) 조건2</td>
      <td>조건1 이나 조건2 중 하나 이상을 만족하는 투플을 검색하여 출력</td>
    </tr>
  </tbody>
</table>

<p>논리 연산자는 WHERE 절 내에서 부울값(참(1), 거짓(0))을 이용하여 결과를 반전시키거나 여러 조건을 이용하여 검색할 때 사용됩니다.</p>
<blockquote>
<p><img src="https://velog.velcdn.com/images/giraffe_/post/ed50bf52-fa6f-409e-863f-d7ebc58a70b5/image.png" alt=""></p>
</blockquote>
<blockquote>
<p><img src="https://velog.velcdn.com/images/giraffe_/post/d019dcbd-7bf4-4527-9aef-2dbab0ce108a/image.png" alt=""></p>
</blockquote>
<blockquote>
<p><img src="https://velog.velcdn.com/images/giraffe_/post/b3dddc4e-377b-4c56-8d71-37bc0efe3dde/image.png" alt=""></p>
</blockquote>
<h3 id="in--not-in-절">IN / NOT IN 절</h3>
<p>논리 연산자를 사용하는 대신 IN이나 NOT IN을 사용하여 기술한 값들 중 일치하거나 일치하지않는 값을 검색할 수 있습니다.</p>
<pre><code>SELECT * || 컬럼1[, 컬럼2, ..., 컬럼n] FROM 릴레이션명
WHERE 컬럼 IN || NOT IN (값1[, 값2, ..., 값n]);</code></pre><blockquote>
<p><img src="https://velog.velcdn.com/images/giraffe_/post/56143084-a2f2-4f37-b54f-7903a5f0a6b5/image.png" alt=""></p>
</blockquote>
<h3 id="like-절">LIKE 절</h3>
<p>비교 연산자(=, !=)를 사용하여 완전히 일치하는 값을 검색하는 대신, LIKE 절에 와일드 카드를 활용하여 <strong>부분적으로 일치하는 값</strong>을 검색할 수 있습니다.</p>
<pre><code>SELECT * || 컬럼1[, 컬럼2, ..., 컬럼n] FROM 릴레이션명
WHERE 컬럼 LIKE 문자와_와일드_카드_조합;</code></pre><blockquote>
<p><img src="https://velog.velcdn.com/images/giraffe_/post/4b089e7d-d3e7-452e-ba9e-c4a6583cd997/image.png" alt=""></p>
</blockquote>
<p><strong>※ 와일드 카드</strong></p>
<table>
  <thead>
    <tr>
      <th>기호</th>
      <th>기능</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>%</td>
      <td>0개 이상의 문자 대체</td>
    </tr>
    <tr>
      <td>_</td>
      <td>한개의 문자 대체</td>
    </tr>
  </tbody>
</table>

<h2 id="함수">함수</h2>
<p>MySQL에서는 다양함 함수를 지원합니다.
SELECT 문과 결합하여 사용할수도있지만, <code>SELECT 함수;</code>의 형태로 사용하면 계산기처럼 단순 계산도 가능합니다.</p>
<h3 id="숫자-관련-함수">숫자 관련 함수</h3>
<table>
    <thead>
        <tr>
            <th>종류</th>
            <th>기능</th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td>ABS(A)</td>
            <td>A의 절댓값 출력</td>
        </tr>
        <tr>
            <td>CEILING(A)</td>
            <td>A보다 큰 정수 중 가장 작은 정수 출력</td>
        </tr>
        <tr>
            <td>FLOOR(A)</td>
            <td>A보다 작은 정수 중 가장 큰 정수 출력</td>
        </tr>
        <tr>
            <td>ROUND(A,B)</td>
            <td>A의 소수점 B자리에서 반올림한 값 출력<br>(0이 소수점 첫째 자리)</td>
        </tr>
        <tr>
            <td>TRUNCATE(A,B)</td>
            <td>A의 소수점 B자리에서 버림한 값 출력<br>(0이 소수점 첫째 자리)</td>
        </tr>
        <tr>
            <td>POWER(A,B)</td>
            <td>A의 B 제곱값 출력</td>
        </tr>
        <tr>
            <td>MOD(A,B)</td>
            <td>A를 B로 나눈 나머지값 출력(모듈로 연산)</td>
        </tr>
    </tbody>
</table>

<blockquote>
<p><img src="https://velog.velcdn.com/images/giraffe_/post/bd3634ed-6bb7-4e29-973a-3e2c488e7e65/image.png" alt=""></p>
</blockquote>
<h3 id="문자-관련-함수">문자 관련 함수</h3>
<table>
    <thead>
        <tr>
            <th>종류</th>
            <th>기능</th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td>ASCII(A)</td>
            <td>문자열 A의 맨 처음 문자 ASCII 코드 값 출력</td>
        </tr>
        <tr>
            <td>CONCAT(A,B,...)</td>
            <td>입력한 문자열을 연결하여 출력</td>
        </tr>
        <tr>
            <td>CHAR_LENGTH(A)</td>
            <td>문자열 A의 길이 출력</td>
        </tr>
        <tr>
            <td>UPPER(A)</td>
            <td>문자열 A를 대문자로 변환하여 출력</td>
        </tr>
        <tr>
            <td>SUBSTRING(A,N)</td>
            <td>문자열 A의 N번째부터 문자열 출력</td>
        </tr>
        <tr>
            <td>INSERT(A,N,M,B)</td>
            <td>문자열 A의 N번째부터 M만큼 문자열 B로 변환하여 출력</td>
        </tr>
        <tr>
            <td>REPLACE(A,B,C)</td>
            <td>문자열 A의 B를 C로 변환하여 출력</td>
        </tr>
        <tr>
            <td>STRCMP(A,B)</td>
            <td>A > B이면 1 출력<br>A = B이면 0 출력<br>A < B이면 -1 출력</td>
        </tr>
    </tbody>
</table>

<blockquote>
<p><img src="https://velog.velcdn.com/images/giraffe_/post/fd873dbc-7b97-429e-a4a6-77c80cfb0631/image.png" alt=""></p>
</blockquote>
<h3 id="날짜-관련-함수">날짜 관련 함수</h3>
<table>
    <thead>
        <tr>
            <th>종류</th>
            <th>기능</th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td>NOW()</td>
            <td>현재 날짜와 시간 출력(질의문 시작 시간 기준)</td>
        </tr>
        <tr>
            <td>CURDATE()</td>
            <td>현재 날짜 출력</td>
        </tr>
        <tr>
            <td>CURTIME()</td>
            <td>현재 시간 출력</td>
        </tr>
        <tr>
            <td>DAYOFWEEK(기준_날짜)</td>
            <td>기준 날짜가 무슨 요일인지 출력(1 : 일요일, 2: 월요일, ..., 7 : 토요일)</td>
        </tr>
        <tr>
            <td>DAYOFYEAR(기준_날짜)</td>
            <td>기준 날짜가 그 해의 몇 번째 날인지 출력</td>
        </tr>
        <tr>
            <td>ADDDATE(기준_날짜, INTERVAL T<br>SECOND||MINUTE||HOUR||DAY||MONTH||YEAR)</td>
            <td>기준 날짜에 T만큼의 초||분||시||일|월||년 더한 값 출력</td>
        </tr>
        <tr>
            <td>SUBDATE(기준_날짜, INTERVAL T<br> SECOND||MINUTE||HOUR||DAY||MONTH||YEAR)</td>
            <td>기준 날짜에 T만큼의 초||분||시||일|월||년 뺀 값 출력</td>
        </tr>
        <tr>
            <td>TIMESTAMPDIFF(SECOND||MINUTE||HOUR||DAY||MONTH||YEAR,<br>기준_날짜1, 기준_날짜2)</td>
            <td>기준 날짜2에서 기준 날짜1을 뺀 값을 초||분||시||일||월||년으로 출력</td>
        </tr>
      <tr>
        <td>SLEEP(T)</td>
        <td>T초만큼 질의문 중단 후 계속 실행</td>
      </tr>
    </tbody>
</table>

<blockquote>
<p><img src="https://velog.velcdn.com/images/giraffe_/post/330d0646-06a0-496f-a662-4f018f074ed0/image.png" alt=""></p>
</blockquote>
<h3 id="집계-관련-함수">집계 관련 함수</h3>
<table>
    <thead>
        <tr>
            <th>종류</th>
            <th>기능</th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td>COUNT(컬럼)</td>
            <td>컬럼에 있는 값들의 갯수 출력</td>
        </tr>
        <tr>
            <td>SUM(컬럼)</td>
            <td>컬럼에 있는 값들의 합 출력(컬럼값이 숫자여야 함)</td>
        </tr>
        <tr>
            <td>AVG(컬럼)</td>
            <td>컬럼에 있는 값들의 평균 출력(컬럼값이 숫자여야 함)</td>
        </tr>
        <tr>
            <td>MAX(컬럼)</td>
            <td>컬럼에 있는 값들 중 최대값 출력</td>
        </tr>
        <tr>
            <td>MIN(컬럼)</td>
            <td>컬럼에 있는 값들 중 최소값 출력</td>
        </tr>
    </tbody>
</table>

<blockquote>
<p><img src="https://velog.velcdn.com/images/giraffe_/post/599d908f-279b-4917-a607-79e2087efad1/image.png" alt=""></p>
</blockquote>
<p><strong>--- 투플 추가 및 수정 ---</strong></p>
<blockquote>
<p><img src="https://velog.velcdn.com/images/giraffe_/post/6ccef384-c9b7-4c51-bbfc-826a354af3ad/image.png" alt=""></p>
</blockquote>
<h2 id="group-by--having-절">GROUP BY ~ HAVING 절</h2>
<p>컬럼의 값이 같은 것끼리 GROUP BY 절로 그룹화하고 HAVING 절에서 조건을 부여합니다.</p>
<pre><code>SELECT 컬럼1[, 컬럼2, ..., 컬럼n][, 함수 활용] FROM 릴레이션명
GROUP BY 컬럼
[HAVING 조건];</code></pre><blockquote>
<p><img src="https://velog.velcdn.com/images/giraffe_/post/1143ac5f-6239-4a5d-99f9-5caf78b40c65/image.png" alt=""></p>
</blockquote>
<blockquote>
<p><img src="https://velog.velcdn.com/images/giraffe_/post/5a196186-b7a4-4f71-a866-0fe38b3d94d4/image.png" alt=""></p>
</blockquote>
<h2 id="중첩-질의문">중첩 질의문</h2>
<p><strong>중첩 질의문</strong>은 SELECT 문 안에 또 다른 SELECT 문을 중첩하여 사용하는 것으로, FROM 절이나 WHERE 절에 사용된 SELECT 문을 <strong>내부 질의문</strong>, 그것을 포함하는 SELECT 문을 <strong>외부 질의문</strong>이라고합니다.
내부 질의문은 &#39;(내부 질의문)&#39;처럼 괄호로 묶어줍니다.</p>
<pre><code>SELECT 컬럼1[, 컬럼2, ..., 컬럼n] FROM (내부 질의문)
[WHERE 조건];

SELECT 컬럼1[, 컬럼2, ..., 컬럼n] FROM 릴레이션명
WHERE [조건] [연산자] (내부 질의문);</code></pre><blockquote>
<p><img src="https://velog.velcdn.com/images/giraffe_/post/2da44592-0acc-4811-aebb-84ee07025aa9/image.png" alt=""></p>
</blockquote>
<p>위의 질의문을 FROM 절의 내부 질의문으로 사용하였습니다.
이때 FROM 절에 위치한 내부 질의문에 속한 데이터를 대상으로하여 외부 질의문을 수행합니다.
FROM 절에 중첩 질의문 사용시, <strong>별칭</strong>을 사용해야합니다.</p>
<blockquote>
<p><img src="https://velog.velcdn.com/images/giraffe_/post/0d0453b6-3580-4ed4-80f7-aad3eefa7ff3/image.png" alt=""></p>
</blockquote>
<p>위의 두 질의문을 각각 외부 질의문, 내부 질의문으로하여 WHERE 절에서 중첩 질의문을 사용하였습니다.</p>
<h3 id="exists--not-exists-절">EXISTS / NOT EXISTS 절</h3>
<p>&#39;<strong>EXISTS / NOT EXISTS 절</strong>&#39;은 IN / NOT IN 절 대신 사용할 수 있으며, 외부 질의문이 실행한 EXISTS / NOT EXISTS 절에서 내부 질의문에 해당 조건에 맞는 투플이 있는지 <strong>참/거짓 값만 반환</strong>하여 확인하므로 IN / NOT IN 절 보다 성능 측면에서 뛰어납니다.</p>
<pre><code>SELECT 컬럼1[, 컬럼2, ..., 컬럼n] FROM 릴레이션명
WHERE [조건] [연산자]
EXISTS||NOT EXISTS (내부 질의문);</code></pre><blockquote>
<p><img src="https://velog.velcdn.com/images/giraffe_/post/744bf687-9d58-441c-8669-f433863fcf42/image.png" alt=""></p>
</blockquote>
<blockquote>
<p><img src="https://velog.velcdn.com/images/giraffe_/post/5036ef76-c9ea-4d9e-b07a-2f40d4128e2b/image.png" alt=""></p>
</blockquote>
<p>같은 결과를 얻기위해 IN / NOT IN 절을 사용하여 질의문을 작성할 수도 있습니다.</p>
<h2 id="join-문">JOIN 문</h2>
<p>두개 이상의 릴레이션에서 연관있는 컬럼(기본키, 외래키 등)을 기준으로 투플을 결합한 릴레이션을 출력합니다.</p>
<p><strong>※ JOIN 시 SELECT 문에서 출력할 컬럼을 기술할 때 여러 컬럼을 기술하는 경우, 안전성과 가독성을 위해 별칭을 사용하여 각 릴레이션의 컬럼을 기술하는 것이 권장됩니다.</strong></p>
<h3 id="cross-join">CROSS JOIN</h3>
<p>투플을 결합할 때 특정 조건없이 모든 조합으로 결합합니다.
이는 결합 가능한 모든 조합을 보여주는 &#39;<strong>카티션 프로덕트 연산</strong>&#39;과 동일합니다.
따라서 의미없는 조합의 투플을 포함하여 생성됩니다.</p>
<pre><code>SELECT * || 컬럼1[, 컬럼2, ..., 컬럼n]
FROM 릴레이션명1 CROSS JOIN 릴레이션명2 [, CROSS JOIN ... 릴레이션명n]
[WHERE 조건];</code></pre><blockquote>
<p><img src="https://velog.velcdn.com/images/giraffe_/post/96c8acf2-d075-4156-9bc7-e89e2fdba39e/image.png" alt=""></p>
</blockquote>
<h3 id="inner-joinequi-join">INNER JOIN(EQUI JOIN)</h3>
<p>크로스 조인에서 의미없는 조합의 투플을 제거하여, 의미있는 조합의 투플만 생성하기위해 &#39;<strong>INNER JOIN</strong>&#39;을 사용합니다. 이는 릴레이션 간의 &#39;<strong>교집합 연산</strong>&#39;과 동일하며, 이를 위해 결합하는 릴레이션 간에 공통적으로 존재하는 일치 조건을 <strong>ON 절</strong>에 기술하여 결합합니다.
INNER JOIN은 대표적인 JOIN으로 INNER JOIN 대신 INNER 키워드를 생략하고 <strong>JOIN</strong>만 기술하여도 INNER JOIN이 실행됩니다.</p>
<pre><code>SELECT * || 컬럼1[, 컬럼2, ..., 컬럼n]
FROM 릴레이션명1 [INNER] JOIN 릴레이션명2 ON 조인_조건1
[, [INNER] JOIN ... 릴레이션명n ON 조인_조건m]
[WHERE 조건];</code></pre><blockquote>
<p><img src="https://velog.velcdn.com/images/giraffe_/post/bb100ad3-0749-462f-a64e-60deee88d108/image.png" alt=""></p>
</blockquote>
<h3 id="natural-join">NATURAL JOIN</h3>
<p>INNER JOIN 시 결합하는 릴레이션 간에 같은 이름의 컬럼이있을때 &#39;<strong>NATURAL JOIN</strong>&#39;을 이용하면, 같은 컬럼명을 가진 컬럼의 컬럼값을 기준으로 자동으로 INNER JOIN을 실행하며, ON 절에 조인 조건을 따로 기술할 필요가 없습니다.</p>
<pre><code>SELECT * || 컬럼1[, 컬럼2, ..., 컬럼n]
FROM 릴레이션명1 NATURAL JOIN 릴레이션명2
[WHERE 조건];</code></pre><blockquote>
<p><img src="https://velog.velcdn.com/images/giraffe_/post/e7a03a64-acfb-4bee-b5a0-d30c6e77b880/image.png" alt=""></p>
</blockquote>
<p>ON 절에 따로 조인 조건을 기술하지않았음에도 INNER JOIN과 같은 결과가 나온 것을 확인할 수 있습니다.
(※ NATURAL JOIN을 위해 &#39;order_list&#39; 릴레이션의 &#39;customer_id&#39; 컬럼을 잠시 &#39;id&#39;로 수정한 후 진행하였습니다.)</p>
<h3 id="outer-join">OUTER JOIN</h3>
<p>INNER JOIN과 NATURAL JOIN은 유용하게 사용할 수 있지만 조인 조건에 부합하지않는 투플은 제외하고 출력합니다.
&#39;<strong>OUTER JOIN</strong>&#39;은 조인 조건에 부합하지않는 투플까지도 출력하기위해 사용되며, 기준이되는 릴레이션에 따라 종류가 나뉩니다.
(각 JOIN에서 &#39;OUTER&#39; 키워드는 생략 가능합니다.)</p>
<pre><code>SELECT * || 컬럼1[, 컬럼2, ..., 컬럼n]
FROM 릴레이션명1 LEFT||RIGHT [OUTER] JOIN 릴레이션명2 ON 조인_조건
[WHERE 조건];</code></pre><h4 id="left-outer-join">LEFT [OUTER] JOIN</h4>
<p>왼쪽에 기술된 릴레이션의 모든 투플이 반영되어 출력됩니다.
오른쪽에 기술된 릴레이션의 투플은 조건에 부합하는 투플은 정상적으로 값이 출력되고, 그렇지않은 투플은 컬럼값이 &#39;NULL&#39;로 대체되어 출력됩니다.</p>
<blockquote>
<p><img src="https://velog.velcdn.com/images/giraffe_/post/7592648b-9cf9-407c-9da3-e7ab7e7fff32/image.jpg" alt=""></p>
</blockquote>
<blockquote>
<p><img src="https://velog.velcdn.com/images/giraffe_/post/9ac64827-e4f5-491d-8464-4e51dc2d6a35/image.png" alt=""></p>
</blockquote>
<p>INNER JOIN으로 출력되지않던 투플도 출력된 것을 확인할 수 있습니다.</p>
<h4 id="right-outer-join">RIGHT [OUTER] JOIN</h4>
<p>오른쪽에 기술된 릴레이션의 모든 투플이 반영되어 출력됩니다.
왼쪽에 기술된 릴레이션의 투플은 조건에 부합하는 투플은 정상적으로 값이 출력되고, 그렇지않은 투플은 컬럼값이 &#39;NULL&#39;로 대체되어 출력됩니다.</p>
<blockquote>
<p><img src="https://velog.velcdn.com/images/giraffe_/post/9c8ae2e5-8b33-4622-b0d3-977aec851157/image.jpg" alt=""></p>
</blockquote>
<blockquote>
<p><img src="https://velog.velcdn.com/images/giraffe_/post/c8da1834-a38f-40a4-b86d-f268970aaaa3/image.png" alt=""></p>
</blockquote>
<h4 id="full-outer-join">FULL [OUTER] JOIN</h4>
<p>양쪽에 기술된 릴레이션의 모든 투플이 반영되어 출력됩니다.
조건에 부합하는 투플은 정상적으로 값이 출력되고, 그렇지않은 투플은 컬럼값이 &#39;NULL&#39;로 대체되어 출력됩니다.
MySQL에서는 FULL OUTER JOIN 연산을 지원하지않으므로, LEFT OUTER JOIN과 RIGHT OUTER JOIN에 &#39;<strong>UNION ALL</strong>&#39; 연산을 사용하여 같은 효과를 얻을 수 있습니다.</p>
<blockquote>
<p><img src="https://velog.velcdn.com/images/giraffe_/post/197f2d4c-2715-4a8a-9c9f-389a05d775e4/image.png" alt=""></p>
</blockquote>
<p><strong>※ UNION / UNION ALL</strong></p>
<p>합집합 연산의 역할을 하며, 다수의 SELECT 문을 하나로 통합합니다.
UNION은 중복을 제거하고 결과를 출력하며, UNION ALL은 중복을 허용하여 결과를 출력합니다.</p>
<pre><code>SELECT * || 컬럼1[, 컬럼2, ..., 컬럼n] FROM 릴레이션명1
[WHERE 조건]
UNION / UNION ALL
SELECT * || 컬럼1[, 컬럼2, ..., 컬럼n] FROM 릴레이션명2
[WHERE 조건]</code></pre><blockquote>
<p><img src="https://velog.velcdn.com/images/giraffe_/post/d2259d41-7c05-451f-957b-19ae8b4ded2b/image.png" alt=""></p>
</blockquote>
<h3 id="self-join">SELF JOIN</h3>
<p>같은 릴레이션을 JOIN하며, 같은 릴레이션을 JOIN하기때문에 반드시 <strong>별칭</strong>을 사용하여 컬럼을 구분해주어야합니다.
주로 <strong>재귀 관계</strong>에 있는 릴레이션에 사용합니다.</p>
<pre><code>SELECT 별칭1.컬럼1[, ... 별칭1.컬럼n], 별칭2.컬럼1[, ... 별칭2.컬럼m]
FROM 릴레이션명1 AS 별칭1 INNER||OUTER JOIN 릴레이션2 AS 별칭2
ON 조인_조건
[WHERE 조건];</code></pre><h2 id="검색-결과-파일에-저장">검색 결과 파일에 저장</h2>
<p>SELECT 문을 사용하여 검색한 값을 파일에 저장할 수 있습니다.</p>
<pre><code>SELECT 문
INTO OUTFILE 파일경로
FROM 릴레이션명;</code></pre><blockquote>
<p><img src="https://velog.velcdn.com/images/giraffe_/post/0ec7bc1e-01df-4e82-9b2a-f9e50b32cef4/image.png" alt=""></p>
</blockquote>
<blockquote>
<p><img src="https://velog.velcdn.com/images/giraffe_/post/78b111ec-1994-48dc-b02d-52cf36587eff/image.png" alt=""></p>
</blockquote>
<h1 id="view">View</h1>
<p>&#39;<strong>View</strong>&#39;는 데이터베이스에 존재하는 원본 릴레이션을 기반으로 생성된 &#39;<strong>가상 릴레이션</strong>&#39;입니다. 따라서 View는 물리적으로 저장되지않고, 물리적인 삽입, 수정, 삭제는 원본 릴레이션에서 실행됩니다.
이러한 특성때문에 View에 투플을 삽입할 때는 제약이있습니다.
JOIN을 통해 생성된 View는 두개 이상의 릴레이션에 데이터가 삽입되므로 오류가 발생하고, &#39;NOT NULL&#39;같은 옵션이 사용된 컬럼이 View 정의 시 포함되지않은 경우 데이터를 삽입하려고하면 오류가 발생합니다.</p>
<p>View는 릴레이션에서 선택한 부분을 기반으로 생성되므로, 원본 릴레이션에는 접근하지 못하게하면서 필요한 부분은 보여줄 수 있습니다. 그리고 복잡한 질의문으로 다양한 View를 구성하고 필요시에는 간단하게 View를 통해 검색하여 사용할 수 있습니다.</p>
<h2 id="create-view">CREATE VIEW</h2>
<p>SELECT 문을 사용하여 View를 정의하고 생성합니다.</p>
<pre><code>CREATE VIEW View명
AS (SELECT 문)
[WITH CHECK OPTION];</code></pre><blockquote>
<p><img src="https://velog.velcdn.com/images/giraffe_/post/1aeee08a-68a4-4a9b-a858-b8eea9683de5/image.png" alt=""></p>
</blockquote>
<blockquote>
<p><img src="https://velog.velcdn.com/images/giraffe_/post/66361fcd-8362-4f5c-aa95-d82908da4f1b/image.png" alt=""></p>
</blockquote>
<p><strong>※ WITH CHECK OPTION</strong> : View 생성시 기술한 제약조건에 위배되는 투플 삽입 시도시 오류가 발생합니다.
즉, View에 삽입한 투플이 View 안에 포함되지않으면 오류가 발생합니다.</p>
<blockquote>
<p><img src="https://velog.velcdn.com/images/giraffe_/post/7a8944d5-4179-41f8-b2b0-cfc77ba1b54c/image.png" alt=""></p>
</blockquote>
<p>&#39;MEMBER&#39; 릴레이션을 기반으로 생성한 &#39;MEMBER_U30&#39; View는 &#39;<strong>WITH CHECK OPTION</strong>&#39;이 사용되었고, AGE가 30 이하인 투플만 포함합니다. 따라서 AGE가 27인 &#39;DELTA&#39;는 View에 정상적으로 삽입되었지만, AGE가 33인 &#39;ECO&#39;는 삽입이 거부되고 오류 메시지가 출력되었습니다.</p>
<blockquote>
<p><img src="https://velog.velcdn.com/images/giraffe_/post/0a99c20c-52c6-47ec-96b9-4ce240fd771b/image.png" alt=""></p>
</blockquote>
<p>View에 투플 삽입시 실제로 저장되는 곳은 View의 기반이되는 원본 릴레이션입니다.</p>
<blockquote>
<p><img src="https://velog.velcdn.com/images/giraffe_/post/230eee3d-49f9-468c-9083-cc5951eadc76/image.png" alt=""></p>
</blockquote>
<p>원본 릴레이션이 삭제되면 View도 사용할 수 없습니다.</p>
<h2 id="alter-view">ALTER VIEW</h2>
<p>SELECT 문을 사용하여 생성된 View를 수정합니다.</p>
<pre><code>ALTER VIEW View명
AS (SELECT 문);</code></pre><blockquote>
<p><img src="https://velog.velcdn.com/images/giraffe_/post/43b44fad-3665-42bc-9095-49c05ae337e0/image.png" alt=""></p>
</blockquote>
<h2 id="drop-view">DROP VIEW</h2>
<p>생성된 View를 삭제합니다.</p>
<pre><code>DROP VIEW View명 [CASCADE || RESTRICT];</code></pre><p>만약 삭제할 View를 이용해 생성된 또다른 View가 있을 때 &#39;<strong>CASCADE</strong>&#39;와 &#39;<strong>RESTRICT</strong>&#39; 키워드를 사용할 수 있습니다.
CASCADE 키워드는 다른 View를 계속 유지하며,
RESTRICT 키워드는 다른 View를 같이 삭제합니다.</p>
<blockquote>
<p><img src="https://velog.velcdn.com/images/giraffe_/post/1157530f-475c-4ab8-a037-d7f97676a2d3/image.png" alt=""></p>
</blockquote>
]]></description>
        </item>
        <item>
            <title><![CDATA[SQL 구문 - DDL]]></title>
            <link>https://velog.io/@giraffe_/SQLStructured-Query-Language-%EA%B5%AC%EB%AC%B8</link>
            <guid>https://velog.io/@giraffe_/SQLStructured-Query-Language-%EA%B5%AC%EB%AC%B8</guid>
            <pubDate>Mon, 27 Jun 2022 11:42:21 GMT</pubDate>
            <description><![CDATA[<p>&#39;<strong>SQL(Structrued Query Language)</strong>&#39;은 관계형 데이터베이스 관리 시스템(RDBMS)에서 데이터를 관리하기위해 쓰이는 &#39;<strong>비절차적 언어</strong>&#39;로 절차없이 사용자가 원하는 것만을 기술합니다.</p>
<p><strong>※ 이 글에서는 MySQL의 SQL 문법을 기준으로 작성합니다.
([내용] 부분은 옵션으로, 반드시 기술해야하는 부분은 아닙니다.)</strong></p>
<h1 id="create-문">CREATE 문</h1>
<h2 id="create-databaseschema">CREATE DATABASE(SCHEMA)</h2>
<p>DDL 문으로 생성 가능한 개체 중 가장 상위 단계인 데이터베이스(스키마)를 생성합니다.</p>
<pre><code>CREATE DATABASE(SCHEMA) 데이터베이스(스키마)명;</code></pre><blockquote>
<p><img src="https://velog.velcdn.com/images/giraffe_/post/0e8ef1b4-ace4-4d34-8434-0292be1d89fe/image.jpg" alt=""></p>
</blockquote>
<p>데이터베이스(스키마)를 생성한 후 <code>USE 데이터베이스(스키마)명;</code> 문을 사용하여 데이터베이스에 진입할 수 있습니다.</p>
<blockquote>
<p><img src="https://velog.velcdn.com/images/giraffe_/post/796cbbf0-fdff-46ed-9da6-c28b33f37502/image.jpg" alt=""></p>
</blockquote>
<p><code>SHOW TABLES;</code> 문으로 현재 데이터베이스에 존재하는 릴레이션(테이블) 목록을 조회할 수 있습니다.
아직은 릴레이션이 없는 상태이므로 릴레이션을 생성해주어야합니다.</p>
<h2 id="create-table">CREATE TABLE</h2>
<p>자료를 실질적으로 저장하는 구조인 릴레이션(테이블)을 생성합니다.</p>
<pre><code>CREATE TABLE 릴레이션명 (
    컬럼1 데이터_타입 [제약조건],
    컬럼2 데이터_타입 [제약조건],

    ...

    컬럼n 데이터_타입 [제약조건],
    [PRIMARY KEY 기본키로_지정할_컬럼],
    [그외 UNIQUE, FOREIGN KEY 등의 조건]
)[CHARSET=&#39;인코딩_형식&#39;];</code></pre><blockquote>
<p><img src="https://velog.velcdn.com/images/giraffe_/post/d6198941-35fd-4f3d-b507-a2c1597f4197/image.jpg" alt=""></p>
</blockquote>
<p>릴레이션 생성 후 릴레이션 목록을 조회 해보면 릴레이션이 생성된 것을 확인할 수 있습니다.</p>
<blockquote>
<p><img src="https://velog.velcdn.com/images/giraffe_/post/5e4a3fd7-3f63-4674-863f-48a760029144/image.jpg" alt=""></p>
</blockquote>
<p><code>SHOW CREATE TABLE 릴레이션명;</code> 문을 사용하면 해당 릴레이션이 어떻게 정의되었는지 확인할 수 있습니다.</p>
<p><code>DESC 릴레이션명;</code> 문을 사용하면 릴레이션에 어떤 컬럼들이 있고 어떤 데이터 타입을 사용하고있는지 등을 확인할 수 있습니다.</p>
<blockquote>
<p><img src="https://velog.velcdn.com/images/giraffe_/post/21c18b8c-cf5c-44b5-bc2a-b6a19919dc54/image.jpg" alt=""></p>
</blockquote>
<p><strong>※ 데이터 타입</strong></p>
<table>
  <caption>정수</caption>
    <tr>
      <th>표기</th>
      <th>범위</th>
    </tr>
      <tr>
      <td>TINYINT</td>
      <td>1byte, -128 ~ 127</td>
    </tr>
      <tr>
      <td>SMALLINT</td>
      <td>2byte, -32,768 ~ 32,767</td>
    </tr>
      <tr>
      <td>MEDIUMINT</td>
      <td>3byte, -8,388,608 ~ 8,388,607</td>
    </tr>
      <tr>
      <td>INT</td>
      <td>4byte, -2,147,483,648 ~ 2,147,483,647</td>
    </tr>
      <tr>
      <td>BIGINT</td>
      <td>8byte, -9,223,372,036,854,775,808 ~ 9,223,372,036,854,775,807</td>
    </tr>
</table>
제약 조건에 'UNSGINED' 추가시, 동일 byte에서 음수는 표현할 수 없습니다.
<br>
<br>
<table>
  <caption>부동 소수</caption>
  <tr>
    <th>표기</th>
    <th>범위</th>
  </tr>
  <tr>
      <td>FLOAT</td>
    <td>4byte 크기의 부동 소수점 형식 유리수</td>
  </tr>
</table>
<br>
<table>
  <caption>문자</caption>
  <tr>
    <th>표기</th>
    <th>범위</th>
  </tr>
  <tr>
      <td>CHAR(n)</td>
    <td>길이 n의 고정 문자열</td>
  </tr>
  <tr>
      <td>VARCHAR(n)</td>
    <td>길이 n 이하의 가변 문자열</td>
  </tr>
</table>
VARCHAR 타입 사용시, 지정한 길이에서 실제 저장된 문자열과 문자열의 길이가 함께 저장되고 남은 공간은 줄어듭니다.
<br>
<br>
<table>
  <caption>날짜/시간</caption>
  <tr>
    <th>표기</th>
    <th>형식</th>
    <th>범위</th>
  </tr>
  <tr>
      <td>DATE</td>
    <td>YYYY-MM-DD</td>
    <td>3byte, 1000-01-01 ~ 9999-12-31</td>
  </tr>
  <tr>
      <td>YEAR</td>
    <td>YYYY</td>
    <td>1byte</td>
  </tr>
  <tr>
      <td>TIME</td>
    <td>hh:mm:ss</td>
    <td>3byte</td>
  </tr>
  <tr>
      <td>DATETIME</td>
    <td>YYYY-MM-DD hh:mm:ss</td>
    <td>8byte, 1000-01-01 00:00:00 ~ 9999-12-31 23:59:59</td>
  </tr>
  <tr>
      <td>TIMESTAMP</td>
    <td>YYYY-MM-DD hh:mm:ss</td>
    <td>4byte, 1970-01-01 00:00:01 ~ 2038-01-09 03:14:07</td>
  </tr>
</table>

<p>DATETIME의 경우 시간대가 일정하게 유지되지만, TIMESTAMP의 경우 타임존에 따라 시간이 달라지므로 의도치않은 시간값이 저장될 수 있습니다. 따라서 DATETIME이 권장됩니다.</p>
<p><strong>※ 제약조건</strong></p>
<ul>
<li><p>NOT NULL : 해당 컬럼에 반드시 어떤 값이 저장되어야합니다.
<code>NOT NULL</code></p>
</li>
<li><p>DEFAULT : 해당 컬럼에 어떤 값도 입력되지않으면 지정한 값이 자동으로 입력됩니다.
<code>DEFAULT 값</code></p>
</li>
<li><p>CHECK : 데이터 무결성 유지를 위해 조건에 맞는 값만 입력 가능합니다.
<code>CHECK 조건</code></p>
</li>
<li><p>AUTO_INCREMENT : 데이터 입력시 어떤 값도 입력되지않으면 1부터 시작하여 데이터 추가시마다 자동으로 1씩 증가된 값이 저장됩니다. INT 타입이 사용되며, 숫자를 직접 지정할 수도 있습니다.
<code>AUTO_INCREMENT</code></p>
</li>
<li><p>PRIMARY KEY : 기본키를 지정합니다. 기본키로 지정할 컬럼을 하나 이상 선택해야하며, 해당 컬럼값은 서로 중복되지않는 값(UNIQUE)을 가져야하고, NULL 값을 가질 수 없습니다.
<code>PRIMARY KEY(컬럼)</code></p>
</li>
<li><p>UNIQUE : 해당 컬럼에 위치한 값들은 서로 중복되지않는 값(UNIQUE)을 가져야합니다.
<code>UNIQUE 컬럼</code></p>
</li>
<li><p>FOREIGN KEY : 특정 릴레이션의 컬럼을 참조하는 외래키를 지정합니다.
<code>FOREIGN KEY 참조받을_컬럼 REFERENCES 참조할_릴레이션(참조할_컬럼)</code></p>
</li>
<li><p>CHARSET : 인코딩 방식을 지정합니다.
<code>CHARSET=&#39;인코딩_방식&#39;</code></p>
</li>
</ul>
<h1 id="alter-문">ALTER 문</h1>
<h2 id="alter-table">ALTER TABLE</h2>
<p>CREATE TABLE 문으로 생성한 릴레이션의 정보를 수정합니다.</p>
<pre><code>ALTER TABLE 릴레이션명
    [ADD COLUMN 컬럼 데이터_타입],
    [DROP COLUMN 컬럼],
    [CHANGE COLUMN 수정전_컬럼 수정후_컬럼 변경할_데이터_타입],
    [MODIFY COLUMN 컬럼 변경할_데이터_타입]
    [ALTER COLUMN 컬럼 SET DEFAULT 값];</code></pre><blockquote>
<p><img src="https://velog.velcdn.com/images/giraffe_/post/1158009c-d5ca-4f9f-b07f-925e99b47b25/image.png" alt=""></p>
</blockquote>
<p>ADD COLUMN 절을 사용하면 릴레이션에 새로운 컬럼을 추가할 수 있습니다.</p>
<blockquote>
<p><img src="https://velog.velcdn.com/images/giraffe_/post/9bb7c180-da1f-4f88-bcaf-29a59f0ed852/image.png" alt=""></p>
</blockquote>
<p>MODIFY COLUMN 절을 사용하면 데이터 타입을 다른 데이터 타입으로 변경할 수 있습니다.</p>
<blockquote>
<p><img src="https://velog.velcdn.com/images/giraffe_/post/11e16d31-a5ab-48f9-8b99-1915fbe39ed2/image.png" alt=""></p>
</blockquote>
<p>CHANGE COLUMN 절을 사용하면 컬럼의 이름을 변경할 수 있고, 데이터 타입을 추가하면 데이터 타입까지도 변경 가능합니다.</p>
<blockquote>
<p><img src="https://velog.velcdn.com/images/giraffe_/post/b28dc7d2-dd5e-4f1f-9101-869ba0387be1/image.png" alt=""></p>
</blockquote>
<p>ALTER COLUMN과 SET DEFAULT 절을 사용하면 DEFAULT 값을 변경할 수 있습니다.</p>
<blockquote>
<p><img src="https://velog.velcdn.com/images/giraffe_/post/6b641f77-2076-4f3e-a930-0ab97d95889f/image.png" alt=""></p>
</blockquote>
<p>DROP COLUMN 절을 사용하면 컬럼을 삭제할 수 있습니다.</p>
<h1 id="drop-문">DROP 문</h1>
<h2 id="drop-databaseschema">DROP DATABASE(SCHEMA)</h2>
<p>데이터베이스(스키마)를 삭제합니다.</p>
<pre><code>DROP DATABASE 데이터베이스명;</code></pre><h2 id="drop-table">DROP TABLE</h2>
<p>릴레이션을 삭제합니다.</p>
<pre><code>DROP TABLE 릴레이션명;</code></pre><blockquote>
<p><img src="https://velog.velcdn.com/images/giraffe_/post/e9676166-4363-45ef-9189-aea5285690d2/image.jpg" alt=""></p>
</blockquote>
]]></description>
        </item>
        <item>
            <title><![CDATA[관계형 데이터베이스(RDB) 개요]]></title>
            <link>https://velog.io/@giraffe_/%EA%B4%80%EA%B3%84%ED%98%95-%EB%8D%B0%EC%9D%B4%ED%84%B0%EB%B2%A0%EC%9D%B4%EC%8A%A4</link>
            <guid>https://velog.io/@giraffe_/%EA%B4%80%EA%B3%84%ED%98%95-%EB%8D%B0%EC%9D%B4%ED%84%B0%EB%B2%A0%EC%9D%B4%EC%8A%A4</guid>
            <pubDate>Tue, 21 Jun 2022 14:36:31 GMT</pubDate>
            <description><![CDATA[<p>&#39;<strong>관계형 데이터베이스(RDB:Relational Database)</strong>&#39;는 릴레이션(테이블), 컬럼 등으로 관계를 정의하는 &#39;<strong>관계형 모델</strong>&#39;에 기초하여 데이터를 다루는 데이터베이스입니다.</p>
<h1 id="구조">구조</h1>
<p><strong>행(row)</strong>과 <strong>열(column)</strong>의 2차원으로 데이터를 표현하는 &#39;<strong>릴레이션(Relation, =테이블(table))</strong>&#39;에 데이터가 저장됩니다.</p>
<blockquote>
<p><img src="https://velog.velcdn.com/images/giraffe_/post/48cde1b9-87dc-49bd-ab8b-b6e724a210c3/image.png" alt="릴레이션 예시"></p>
</blockquote>
<p>위의 릴레이션은 &#39;select&#39;라는 SQL 구문을 사용하여 데이터를 검색한 결과로, 릴레이션의 이름은 &#39;customer&#39;이며, 파일처리 시스템의 &#39;<strong>파일(file)</strong>&#39;에 대응됩니다.</p>
<p>최상단에 &#39;id, name, local, grade, credit&#39;으로 이루어진 행을 &#39;<strong>릴레이션 스키마(relation schema)</strong>&#39;라 부르고, 릴레이션 스키마는 각 컬럼과 컬럼의 순서, 도메인 그리고 릴레이션의 이름을 포함합니다.
릴레이션 스키마의 id, name 같은 컬럼값을 각각 &#39;<strong>컬럼 이름</strong>&#39;이라고 합니다.</p>
<p>컬럼(열)은 컬럼에 위치한 값들을 뜻하고,&#39;<strong>속성(attribute), 필드(feild)</strong>&#39;라고도 부르며, 파일 처리 시스템의 &#39;<strong>필드(feild)</strong>&#39;에 대응됩니다.</p>
<p>릴레이션 스키마 아래에 위치한 데이터들의 행은 각각 &#39;<strong>투플(tuple), 개체 인스턴스(entity instance), 레코드(record)</strong>&#39;라고도 부르며, 파일 처리 시스템의 &#39;<strong>레코드(record)</strong>&#39;에 대응됩니다.</p>
<p>&#39;<strong>도메인(domain)</strong>&#39;은 해당 속성의 <strong>입력 가능한 값의 범위</strong>로, &#39;<strong>데이터 타입</strong>&#39;으로 정의되며, 각 속성에 적합한 데이터 타입을 사용해야합니다.
&#39;credit&#39; 컬럼의 도메인은 &#39;int&#39;가 사용되었습니다.</p>
<p>&#39;<strong>차수(degree)</strong>&#39;는 릴레이션에서 <strong>컬럼의 수</strong>를 뜻하며, 모든 릴레이션은 &#39;1 이상&#39;의 차수를 갖습니다.</p>
<p>&#39;<strong>카디널리티(cardinality)</strong>&#39;는 릴레이션의 &#39;<strong>투플 갯수</strong>&#39;를 뜻합니다. 아직 투플이 입력되지않은 릴레이션의 경우 카디널리티는 &#39;0&#39;이되며, 위의 릴레이션에서 카디널리티는 &#39;5&#39;가 됩니다.</p>
<h2 id="릴레이션의-특징">릴레이션의 특징</h2>
<ul>
<li>릴레이션 내의 컬럼의 이름은 서로 달라야합니다.</li>
<li>컬럼은 다중 값을 가질 수 없으므로, 여러개의 값을 가지는 경우 서로 나누어 저장해야합니다.(원자성 : 컬럼은 여러 의미를 갖는 값으로 분해가 불가능해야함)</li>
<li>컬럼은 해당 도메인에 맞는 값을 가져야합니다.</li>
<li>컬럼은 순서의 구분이 없으므로, 순서가 바뀌어도 스키마는 동일합니다.(컬럼의 무순서성)</li>
<li>릴레이션에서 투플의 순서는 구분하지않습니다.(투플의 무순서성)</li>
<li>릴레이션에서 투플은 중복될 수 없으며, 하나의 키 값으로 하나의 투플을 유일하게 구분합니다.(투플의 유일성)</li>
</ul>
<h1 id="키key">키(key)</h1>
<p>&#39;<strong>키(key)</strong>&#39;는 릴레이션에서 투플을 유일하게 구분할 수 있게하는 컬럼입니다.
릴레이션에서 키 컬럼의 값은 서로  다른 값을 가져야하며(유일성), 유일성 유지를 위해 최소한의 컬럼으로 구성(최소성)해야합니다.</p>
<h2 id="수퍼키super-key">수퍼키(Super Key)</h2>
<p>&#39;<strong>투플을 유일하게 식별할 수 있는 컬럼 집합</strong>&#39;입니다. 하나 이상의 컬럼으로 구성되며, 유일성에 따라 수퍼키에 속하는 컬럼값은 투플마다 달라야합니다.</p>
<p>위의 릴레이션에서 수퍼키는
(id), (name), (local),
(id, name), (id, local), (id, grade), (id, credit), (name, local), ...,
(id, name, local), (id, name, grade), ...,
(id, name, local, grade), (id, name, local, credit), ...,
(id, name, local, grade, credit)
처럼 각 투플을 유일하게 구분할 수 있는 컬럼의 집합입니다.</p>
<h2 id="후보키candidate-key">후보키(Candidate Key)</h2>
<p>&#39;<strong>수퍼키 중에서 최소성을 만족하는 키</strong>&#39;로, 후술 할 기본키의 후보가 되며, 투플이 추가 및 수정되어도 유지되야합니다.</p>
<p>위의 릴레이션에서 후보키는
(id) 등이 될 수 있습니다.(id는 &#39;NULL&#39;값을 가질 수 없고, 수정되지않으며, 중복될 수 없다고 가정)
(name), (local) 같은 경우 현재는 후보키로서의 역할이 가능하지만, 투플이 추가 및 수정되었을 때 동일한 값을 가지는 투플이 생기면 후보키로서의 역할이 불가능해집니다.
(id, name)같은 조합의 경우 수퍼키는 가능하지만, 이미 (id)가 후보키로서 유일하게 투플을 식별 가능하기때문에 최소성을 만족하지 못하는 조합이되어 후보키는 될 수 없습니다.</p>
<h2 id="기본키pkprimary-key">기본키(PK:Primary Key)</h2>
<p>&#39;<strong>후보키 중 하나를 선정하여 기본키로 지정</strong>&#39;합니다. 만약 후보키가 하나라면 그 후보키가 기본키가됩니다.
&#39;NULL&#39;값을 가져서는 안되며, 값이 수정되지 않아야하고, 유일성과 최소성을 만족하는 후보키입니다.</p>
<p>따라서 위의 릴레이션에서는 (id)가 기본키로 가장 적합합니다.</p>
<h2 id="대체키alternate-key">대체키(Alternate Key)</h2>
<p>&#39;<strong>기본키로 지정되지않은 후보키</strong>&#39;입니다.</p>
<blockquote>
<p><img src="https://velog.velcdn.com/images/giraffe_/post/338db704-959b-4d85-ab44-a7e28f3432a1/image.png" alt="키 포함 관계"></p>
</blockquote>
<h2 id="외래키fkforeign-key">외래키(FK:Foreign Key)</h2>
<p>&#39;<strong>다른 릴레이션의 기본키를 참조하는 컬럼(컬럼의 집합)</strong>&#39;으로, &#39;<strong>릴레이션 간의 관계(Relation)</strong>&#39;를 표현합니다.
다른 릴레이션의 기본키를 참조하므로, 동일한 도메인을 가져야합니다. 기본적으로 외래키는 다른 릴레이션의 기본키와 일치해야하지만, NULL 값을 가질 수도 있으며(NULL 값을 가지는 경우 해당 투플이 다른 릴레이션의 어떤 투플과도 연관성이 없음), 중복도 허용합니다.</p>
<ul>
<li>부모 릴레이션 : 참조 제공함(기본키)</li>
<li>자식 릴레이션 : 참조 제공받음(외래키)</li>
</ul>
<h2 id="대리키surrogate-key인조키artificial-key">대리키(Surrogate Key)/인조키(Artificial Key)</h2>
<p>시리얼 넘버처럼 &#39;<strong>가상의 컬럼을 만들어 기본키로 사용</strong>&#39;하는 키 입니다.
대리키/인조키는 기본키가 유출되면 안되거나, 기본키가 여러 컬럼으로 구성되어 복잡한 경우, 적절한 기본키가 없을 때 사용되며, DBMS가 임의로 생성하기때문에 직관적으로 알기 어렵습니다.</p>
<h1 id="제약조건constraints">제약조건(Constraints)</h1>
<p><strong>데이터베이스 내의 데이터의 정확성 유지를 위해 특정 조건을 만족</strong>해야 하는 것으로, 릴레이션 내의 모든 투플들이 이 조건을 만족해야합니다.</p>
<p><strong>※ 데이터 무결성</strong>
<strong>데이터베이스에 저장된 데이터가 일관성과 정확성을 유지</strong>해야하는 것으로, 투플이 삽입, 삭제, 수정될 때 제약 조건을 준수해야합니다.</p>
<h2 id="도메인-무결성-제약조건domain-intergrity-constraints">도메인 무결성 제약조건(Domain Intergrity Constraints)</h2>
<p>&#39;<strong>영역 제약조건</strong>&#39;이라고도 하며, <strong>릴레이션의 투플은 각 컬럼의 도메인을 만족</strong>해야하고, <strong>원자성</strong>을 만족해야합니다.
SQL 문에서 데이터 형식(type), NULL/NOT NULL, Default, Check 등을 사용하여 제약합니다.</p>
<h2 id="개체-무결성-제약조건entity-integrity-constraints">개체 무결성 제약조건(Entity Integrity Constraints)</h2>
<p>&#39;<strong>기본키 제약조건(Primary Key Constraints)</strong>&#39;이라고도 하며, <strong>값의 중복이 있어서는 안되고, 기본키 값으로 NULL 값을 사용하면 안된다</strong>는 것입니다.</p>
<h2 id="참조-무결성-제약조건referential-integrity-constraints">참조 무결성 제약조건(Referential Integrity Constraints)</h2>
<p>&#39;<strong>외래키 제약조건(Foreign Key Constraints)</strong>&#39;이라고도 하며, <strong>릴레이션 간의 참조 관계를 정의</strong>합니다.
자식 릴레이션의 값은 부모 릴레이션의 도메인에 맞는 값을 가져야하고, 자식 릴레이션에서 제공받고있는 값을 부모 릴레이션에서 삭제하거나 수정하면 안됩니다.</p>
<h2 id="고유성-제약조건unique-constraint">고유성 제약조건(Unique Constraint)</h2>
<p>&#39;<strong>키 제약조건(Key Constraints)</strong>&#39;이라고도 하며, <strong>각 투플들의 구분을 위해 기본키가 아닌 컬럼의 값들이 중복되어서는 안됩</strong>니다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[데이터베이스(Database) 개요]]></title>
            <link>https://velog.io/@giraffe_/%EB%8D%B0%EC%9D%B4%ED%84%B0%EB%B2%A0%EC%9D%B4%EC%8A%A4Database-%EA%B0%9C%EC%9A%94</link>
            <guid>https://velog.io/@giraffe_/%EB%8D%B0%EC%9D%B4%ED%84%B0%EB%B2%A0%EC%9D%B4%EC%8A%A4Database-%EA%B0%9C%EC%9A%94</guid>
            <pubDate>Wed, 15 Jun 2022 13:42:15 GMT</pubDate>
            <description><![CDATA[<h1 id="파일-처리-시스템file-processing-system">파일 처리 시스템(File Processing System)</h1>
<p>&#39;<strong>파일 처리 시스템</strong>&#39;은 &#39;<strong>운영체제(OS)</strong>&#39;의 지원으로 파일을 사용하여 데이터를 저장하고 관리하는 시스템입니다.
전통적으로 사용되오던 방식이지만 파일을 사용하여 데이터를 관리하므로 프로그램에서 데이터를 사용할 때 몇가지 문제점이 발생합니다.</p>
<h2 id="데이터-종속">데이터 종속</h2>
<p>파일 처리 시스템에서 어떠한 작업을 처리하기위해 프로그램을 개발하면 그 프로그램에 종속된 파일이 생깁니다. 이때 처리되는 데이터가 그 프로그램에 종속되면 데이터의 공유가 어렵고, 데이터 구조가 변경됐을 때 그 데이터를 프로그램에서 사용하기위해서 결국 프로그램을 수정해야되기때문에 큰 비용이 발생합니다.</p>
<h2 id="데이터-중복">데이터 중복</h2>
<p>파일 처리 시스템으로 데이터를 처리하다보면 프로그램에서 작성된 내용에따라 데이터의 경로나 정보를 공유하지 못하는 상황이 발생하므로 비슷하거나 같은 내용의 데이터임에도 각각 따로 저장해야되는 경우가 생깁니다. 이로인해 동일한 데이터가 여러 파일에 중복되어 저장된다면 데이터 간의 불일치가 생기거나, 같은 수준의 보안을 유지해야함에도 보안 유지가 어려워집니다. 그리고 중복 저장된 데이터들로 인해 추가적인 저장공간이 필요해지고 데이터가 수정될 때도 해당 데이터가 포함된 모든 파일에대해 수정이 이루어져야하므로 큰 비용이 발생합니다.
나아가서 이러한 사항들이 정확히 유지되지 못했을 때는 결국 <strong>데이터의 무결성이 훼손</strong>됩니다.</p>
<h1 id="데이터베이스database">데이터베이스(Database)</h1>
<p>&#39;<strong>데이터베이스</strong>&#39;는 여러 사용자가 공유하여 사용하기위해 통합하여 관리되는 데이터의 집합입니다.
데이터베이스는 같은 데이터를 중복하여 저장하지않는 통합된 자료이며, 여러 사용자가 공유하여 사용하는 만큼 각 사용자는 같은 데이터라도 각자의 목적에 따라 다르게 사용가능합니다.</p>
<h1 id="데이터베이스-관리-시스템dbmsdatabase-management-system">데이터베이스 관리 시스템(DBMS:Database Management System)</h1>
<p>파일 처리 시스템의 데이터 종속과 데이터 중복 해결을 위해 제시된 소프트웨어로, 데이터베이스에 필요한 데이터들을 통합하여 저장하고 관리하며, 프로그램 대신 데이터를 데이터베이스에 삽입, 삭제, 수정 및 검색하는 작업을 수행합니다.
&#39;<strong>데이터베이스 관리 시스템(DBMS)</strong>&#39;은 데이터의 사용과 관리가 분리되어 프로그램과 데이터의 독립성을 가집니다.</p>
<p>흔히 접할 수 있는 DBMS의 종류로는 Oracle, MySQL, MariaDB 등이 있습니다.</p>
<h2 id="데이터베이스-언어">데이터베이스 언어</h2>
<p>데이터베이스 관리 시스템(DBMS)은 데이터베이스의 사용 및 관리를 위해 언어 형태의 인터페이스를 제공합니다.</p>
<h3 id="데이터-정의-언어ddldata-definition-language">데이터 정의 언어(DDL:Data Definition Language)</h3>
<p>데이터 정의 기능(물리적 저장 구조, 데이터의 원시 수준 특징)을 수행하기때문에 데이터베이스 사용자에게는 감춰져있으며, 데이터에대한 상세 조건을 기술합니다.
데이터 정의 언어 명령의 결과는 시스템 카탈로그(=데이터 사전 : 특수한 형태의 테이블로 메타데이터를 저장하며 데이터베이스 관리 시스템만 사용 및 수정 가능)에서 관리합니다.</p>
<p>데이터베이스(스키마(schema)), 테이블을 정의합니다.</p>
<h3 id="데이터-조작-언어dmldata-manipulation-language">데이터 조작 언어(DML:Data Manipulation Language)</h3>
<p>데이터 정의 언어로 구조화 시킨 데이터에 사용자가 데이터(레코드)를 삽입, 수정, 삭제 및 검색하는 기능을 제공합니다.</p>
<h3 id="데이터-제어-언어dcldata-control-language">데이터 제어 언어(DCL:Data Control Language)</h3>
<p>DBMS의 동작과 접근에 대한 권한을 관리할 때 사용되며, 주로 &#39;<strong>데이터베이스 관리자(DBA:Database Administrator)</strong>&#39;가 사용합니다.</p>
<h1 id="데이터베이스-시스템database-system">데이터베이스 시스템(Database System)</h1>
<p>데이터베이스 관리 시스템(DBMS)을 사용하여 데이터베이스를 사용 및 관리하고, 사용자가 사용할 수 있는 애플리케이션이 포함된 시스템으로, 데이터를 가진 서버와 데이터를 요청하는 클라이언트의 서버-클라이언트 구조로 구성됩니다.
데이터베이스(DB), 베이터베이스 관리 시스템(DBMS), 데이터 모델(데이터가 저장되는 방식)으로 구성됩니다.</p>
<p><strong>※ 값, 메타데이터, 데이터, 정보</strong></p>
<ul>
<li>값 : 특정 기준에 따른 정량적 수치</li>
<li>메타데이터 : 값에 의미를 부여하는 수식항목(값이 갖는 의미)</li>
<li>데이터 : 값과 메타데이터의 묶음</li>
<li>정보 : 의미를 가질 수 있는 가공된 데이터</li>
</ul>
<p>ex) 2022년 6월 15일 최고기온은 22도이다.
값 : 2022년 6월 15일, 22
메타데이터 : 최고기온
데이터 : 2022년 6월 15일 최고기온 22도
정보 : 2020년대 6월 15일 평균 최고기온은 22도이다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[메모리 동적 할당]]></title>
            <link>https://velog.io/@giraffe_/%EB%A9%94%EB%AA%A8%EB%A6%AC-%EB%8F%99%EC%A0%81-%ED%95%A0%EB%8B%B9</link>
            <guid>https://velog.io/@giraffe_/%EB%A9%94%EB%AA%A8%EB%A6%AC-%EB%8F%99%EC%A0%81-%ED%95%A0%EB%8B%B9</guid>
            <pubDate>Fri, 18 Mar 2022 15:10:22 GMT</pubDate>
            <description><![CDATA[<p>우리가 흔히 사용하는 데스크탑을 구성하는 부품을 보면, 메인보드(마더보드), CPU, 주기억장치(DRAM), 보조기억장치(SSD, 하드디스크(HDD)), 그래픽카드(GPU) 등의 하드웨어로 구성돼있습니다.
컴퓨터에서 프로그램은 보조기억장치에 저장돼있다가 주기억장치에 적재된 후 CPU의 연산 장치가 실행합니다. 기억공간은 주기억장치의 기억공간을 의미합니다.</p>
<p>기억공간은 세가지 영역으로 나눌 수 있는데, 변수에 따라 기억공간에서 할당되는 영역이 다릅니다.</p>
<html>
    <table style="width: 100%; font-size: 15px; text-align: center;">
      <thead>
        <tr>
          <th style="width: 30%;">영역</th>
          <th>설명</th>
        </tr>
      </thead>
      <tbody>
        <tr>
          <td>데이터(data) 영역</td>
          <td>전역변수, 정적변수 저장 / 프로그램 시작시 할당되고 종료시 소멸</td>
        </tr>
        <tr>
          <td>힙(heap) 영역</td>
          <td>사용자가 임의로 할당 및 소멸 시키는 영역<br>
                / 자유 기억공간이라고하며, 실행되면서 크기가 변하여 '메모리 동적 할당'에 사용 
          </td>
        </tr>
        <tr>
          <td>스택(stack) 영역</td>
          <td>지역변수, 매개변수 저장 / 함수 호출시 할당되고 종료시 소멸</td>
        </tr>
      </tbody>
    </table>
</html>

<blockquote>
<div align="center"><img src="https://images.velog.io/images/giraffe_/post/68ec7051-52bd-47cd-8ff9-da28d40463ad/image.png" width="50%"></div>
</blockquote>
<p>프로그램이 실행되기위해서는 주기억장치의 기억공간을 할당받아야합니다. C에서 변수를 선언하는 것은 기억공간을 확보하는 것을 의미합니다.</p>
<p>프로그램에서 기억공간을 확보하는 방법은 크게 &#39;<strong>메모리 정적 할당</strong>&#39;과 &#39;<strong>메모리 동적 할당</strong>&#39; 두가지가 있습니다.</p>
<h1 id="메모리-정적-할당">메모리 정적 할당</h1>
<p>&#39;<strong>메모리 정적 할당(memory static allocation)</strong>&#39;은 프로그램 실행 전에 프로그램 작성 단계에서 필요한 기억공간의 크기를 미리 할당하는 것 입니다. 기억공간의 크기를 미리 결정하므로 변수와 배열 선언이 해당됩니다.</p>
<pre><code class="language-c">void memory_static_allocation(){
    int a = 1;
    int array[3] = {1,2,3};
}</code></pre>
<p>위의 예시에서 함수 호출시 int형 변수 &#39;a&#39;는 지역변수이므로 스택 영역에 4byte 만큼의 크기로 할당되고 1이 저장됩니다. 마찬가지로 int형 자료 3개를 갖는 배열 &#39;array&#39;는 스택 영역에 12byte 만큼의 크기로 할당되고 각각 1,2,3이 저장됩니다. 그리고 호출 종료시 스택영역에서 사라집니다.</p>
<pre><code class="language-c">int main(){
    char name[20];

    printf(&quot;이름 : &quot;);
    scanf(&quot;%s&quot;, name);

    printf(&quot;입력한 이름 : %s&quot;, name);
}</code></pre>
<p>만약 위처럼 이름을 입력받아 출력하는 프로그램이 있다면, 사람마다 이름의 글자수가 다를 수 있으므로 여유있는 크기로 배열의 크기를 할당해 주어야합니다. 이는 곧 기억공간의 낭비로 이어질 수 있습니다.</p>
<pre><code class="language-c">int main(){
    int size;
    char name[size];

    printf(&quot;이름 글자 수 : &quot;);
    scanf(&quot;%d&quot;, &amp;size);

    printf(&quot;이름 : &quot;);
    scanf(&quot;%s&quot;, name);

    printf(&quot;입력한 이름 : %s&quot;, name);
}</code></pre>
<p>따라서 기억공간의 낭비를 위해 이름의 글자수와 이름을 모두 사용자가 입력하게하여 기억공간의 낭비를 줄이려고 위처럼 프로그램을 작성하게되면, 에러가 발생합니다. C에서는 배열의 크기가 상수로 선언되어야하기때문입니다.</p>
<p>이러한 문제를 해결하기위해 &#39;메모리 동적 할당&#39;이 사용됩니다.</p>
<h1 id="메모리-동적-할당">메모리 동적 할당</h1>
<p>&#39;<strong>메모리 동적 할당(memory dynamic allocation)</strong>&#39;은 프로그램 실행 중에 사용자에 의해 입력되는 자료를 활용하여 힙 영역에 알맞은 크기만큼의 기억공간을 할당할 수 있습니다. 이는 곧 메모리 정적 할당에서 발생했던 기억공간의 낭비를 해결할 수 있습니다.
메모리 동적 할당은 특정 함수를 사용하여 이루어지는데, 그 함수를 사용할 때, 컴퓨터가 사용하지 않는 기억공간을 찾아 할당한 후, 그 위치에대한 포인터를 리턴하는 과정에서 시간이 낭비되므로 프로그램의 실행이 늦어지는 결과를 유발합니다. 따라서 꼭 필요한 상황에서만 사용하는 것이 좋습니다.</p>
<blockquote>
<p>※ 메모리 동적 할당에 사용되는 함수들을 사용하기 위해서는 <code>#include &lt;stdlib.h&gt;</code>로 &#39;stdlib&#39; 헤더파일을 include 해주어야합니다.</p>
</blockquote>
<h2 id="malloc-함수">malloc() 함수</h2>
<p>&#39;<strong>malloc() 함수</strong>&#39;는 <strong>allocate memory block</strong>으로, <strong>힙 영역에 기억공간을 byte 단위로 동적 할당</strong>합니다.</p>
<p><code>void* malloc(size_t size);</code>의 형태로 사용하며, size 만큼의 byte 단위로 기억공간을 힙 영역에 할당하고, 기억공간의 시작 주소를 리턴합니다.
만약 기억공간 부족 등 으로 할당에 실패시, null 포인터를 리턴하며, null 포인터는 선행 처리시 &#39;0&#39;으로 바껴, 상수값 0과 같습니다.
malloc()은 void*를 리턴하므로 다른 모든 타입으로 형변환이 가능합니다.
malloc()은 할당된 기억공간을 초기화하지는 않습니다.</p>
<blockquote>
<p>※ size_t : <code>typedef unsigned int size_t;</code>
typedef로 unsigned int를 size_t로 재정의 한 것 입니다.
하지만 엄밀히 말하면 unsigned int와는 차이가 있습니다.</p>
</blockquote>
<h2 id="free-함수">free() 함수</h2>
<p>힙 영역에 할당되면 프로그램 종료시 OS에 의해 기억공간이 해제되지만, 프로그램 종료시까지는 유지되기때문에 기억공간이 낭비되고, 프로그램의 실행 속도가 저하될 우려가 있습니다. 나아가서는 기억공간은 한정적이기 때문에 계속 할당해주다보면 기억공간이 부족할 수 있습니다. 따라서 &#39;<strong>free() 함수</strong>&#39;를 사용하여 <strong>사용이 끝났거나 낭비되고 있는 기억공간을 반납</strong>해주어야합니다.</p>
<p><code>void free(void *p);</code>의 형태로 사용하며, 해당 포인터의 기억공간을 반납하여 해제합니다.</p>
<h2 id="calloc-함수">calloc() 함수</h2>
<p>&#39;<strong>calloc() 함수</strong>&#39;는 &#39;<strong>allocate and and clear memory block</strong>&#39;으로, malloc() 함수처럼 동적으로 힙 영역에 기억공간을 할당한 후, <strong>해당 기억공간을 0으로 초기화</strong>합니다.</p>
<p><code>void* calloc(int n, int size);</code>의 형태로 사용하며, malloc() 함수와 달리 size의 크기를 갖는 기억공간 n개를 할당하고, 실패시 마찬가지로 null 포인터를 리턴합니다.</p>
<h2 id="realloc-함수">realloc() 함수</h2>
<p>&#39;<strong>realloc() 함수</strong>&#39;는 &#39;<strong>resize memory block</strong>&#39;으로, 이미 할당된 기억공간의 크기를 변경해줍니다.</p>
<p><code>void* realloc(void *p, int size);</code>의 형태로 사용하며, 포인터 p가 가리키는 기억공간의 크기를 size의 크기로 변경하고, 재할당된 기억공간의 포인터를 리턴합니다.
이때 변경하려는 size가 원래 크기보다 큰 경우, 원래 기억공간의 뒤쪽에 그만큼의 공간이 비어있다면 그 위치에서 크기만 늘리지만, 비어있지않다면 그만큼의 여유가 있는 기억공간으로 이동해 재할당하고, 원래 내용을 그대로 복사합니다.</p>
<h1 id="기억공간-관리-함수">기억공간 관리 함수</h1>
<p>메모리 동적 할당 함수를 사용하여 기억공간을 할당한 후 &#39;<strong>기억공간 관리 함수</strong>&#39;를 사용하여 해당 기억공간에 있는 자료를 활용할 수 있습니다.</p>
<blockquote>
<p>※ 기억공간 관리와 관련된 함수를 사용하기위해서는 <code>#include &lt;mem.h&gt;</code>로 &#39;mem&#39; 헤더파일을 inlcude 해줘야합니다.</p>
</blockquote>
<h2 id="memcmp-함수">memcmp() 함수</h2>
<p>&#39;<strong>memcmp 함수</strong>&#39;는 &#39;<strong>compare memory blocks</strong>&#39;로, 기억공간의 자료를 주어진 크기만큼 비교하여 같은지 여부를 판별합니다.</p>
<p><code>int memcmp(const void *s1, const void *s2, size_t n);</code>의 형태로 사용하며, s1과 s2가 가리키는 기억공간의 내용을 n byte 만큼 비교하여 s1&gt;s2 일 경우 양수를, s1=s2 일 경우 0을, s1&lt;s2 일 경우 음수를 리턴합니다.(이때 각 문자의 ASCII 코드값을 사용하여 비교합니다.)</p>
<blockquote>
<p>※ memcmp() 함수 vs strncmp() 함수 : strncmp() 함수는 중간에 NULL 문자가 있으면 종료되기때문에 그 뒤의 내용이 다르더라도 같다고 판별하지만, memcmp() 함수는 끝까지 비교하기때문에 정확한 판별이 가능합니다.</p>
</blockquote>
<pre><code class="language-c">#include &lt;stdio.h&gt;
#include &lt;string.h&gt;
#include &lt;mem.h&gt;

int main(){
    char *p1 = &quot;abc\0d&quot;;
    char *p2 = &quot;abc\0e&quot;;

    int a = strncmp(p1, p2, 5);
    int b = memcmp(p1, p2, 5);

    printf(&quot;%d\n&quot;, a);
    printf(&quot;%d\n&quot;, b);
}</code></pre>
<pre><code>0
-1</code></pre><h2 id="memcpy-함수">memcpy() 함수</h2>
<p>&#39;<strong>memcpy() 함수</strong>&#39;는 &#39;<strong>copy memory block</strong>&#39;으로, 기억공간의 자료를 다른 기억공간으로 복사합니다.</p>
<p><code>void* memcpy(void *dest, const void *src, size_t n);</code>의 형태로 사용하며, src(source)에 있는 대상 자료를 dest(destination)로 n byte 만큼 복사하고 dest의 값을 리턴합니다.</p>
<h2 id="memset-함수">memset() 함수</h2>
<p>&#39;<strong>memset() 함수</strong>&#39;는 &#39;<strong>initialize memory block</strong>&#39;으로, 기억공간을 지정한 문자로 채웁니다.</p>
<p><code>void* memset(void *s, int c, size_t n);</code>의 형태로 사용하며, s가 가리키는 기억공간을 c의 값으로 n byte만큼 채우고 s의 값을 리턴합니다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[파일 처리 함수]]></title>
            <link>https://velog.io/@giraffe_/%ED%8C%8C%EC%9D%BC-%EC%B2%98%EB%A6%AC-%ED%95%A8%EC%88%98</link>
            <guid>https://velog.io/@giraffe_/%ED%8C%8C%EC%9D%BC-%EC%B2%98%EB%A6%AC-%ED%95%A8%EC%88%98</guid>
            <pubDate>Mon, 07 Mar 2022 13:44:57 GMT</pubDate>
            <description><![CDATA[<p>표준 입출력 함수(printf(), scanf(), ...)는 키보드와 모니터를 통해 자료를 입출력합니다.
하지만 &#39;<strong>파일 처리 함수</strong>&#39;는 ssd, 하드디스크, USB 메모리같은 보조 기억장치의 파일(file)에 OS(운영체제)를 통해 자료를 읽고 쓰게됩니다.
파일은 &#39;<strong>텍스트 파일(text file)</strong>&#39;과 &#39;<strong>2진 파일(binary file)</strong>&#39; 두가지가 있습니다.
텍스트 파일은 문자로 구성된 파일이며, 2진 파일은 텍스트 파일을 포함해 모든 종류의 자료를 다루는 파일입니다. 2진 파일은 컴파일되어 있으므로 기계어에 가까워 내용의 이해 및 인쇄가 불가능합니다.
C에서는 이러한 파일들과 <strong>컴퓨터에 연결된 장치들까지도 모두 파일로 처리</strong>합니다.</p>
<h1 id="파일-입출력">파일 입출력</h1>
<p>&#39;<strong>파일 입출력</strong>&#39;은 파일에 대한 입력과 출력을 의미합니다.
&#39;<strong>파일에 대한 입력</strong>&#39;은 보조 기억장치의 파일에 있는 자료를 기억공간에 읽어오는 것 입니다.
&#39;<strong>파일에 대한 출력</strong>&#39;은 기억공간에 있는 자료를 보조 기억장치의 파일에 읽어오는 것 입니다.
이때 파일 입출력 함수를 사용하는데, 모든 파일 입출력 함수는 파일의 위치를 가리키는 &#39;<strong>파일 포인터</strong>&#39;를 사용합니다. 그리고 파일 입출력 시 기억공간과 보조 기억장치 사이에 존재하는 &#39;<strong>버퍼(buffer)</strong>&#39;라는 임시 기억공간을 활용합니다. 버퍼를 사용하는 이유는 기억공간으로 활용되는 주 기억장치와 보조 기억장치 간에 속도 차이때문에 처리시간이 많이 소요되므로, 버퍼의 크기만큼 자료를 일단 채운 뒤, CPU에서 이를 한꺼번에 처리하여 출력해 처리시간을 최소화 시키기 위함입니다.</p>
<h1 id="파일-포인터를-이용한-파일-입출력">파일 포인터를 이용한 파일 입출력</h1>
<p>프로그램과 입출력 장치(키보드, 모니터) 간에 자료의 입출력을 위해서는 &#39;<strong>스트림(stream)</strong>&#39;이라고하는 논리적인 통로가 필요합니다.</p>
<blockquote>
<p><strong>표준 입출력과 스트림</strong>
    - 프로그램 &lt;-&gt; 표준 입력(키보드) : &#39;입력 스트림&#39;이 존재하여 표준 입력함수(scanf() 등)을 이용하여 자료의 입력이 가능합니다.
    - 프로그램 &lt;-&gt; 표준 출력(모니터) : &#39;출력 스트림&#39;이 존재하여 표준 출력함수(printf() 등)을 이용하여 자료의 출력이 가능합니다.
※ 표준 입출력 시, OS가 자동으로 프로그램이 시작할 때 표준 입출력 장치와의 스트림을 생성하고, 프로그램 종료시 자동으로 스트림을 소멸시킵니다.</p>
</blockquote>
<p>파일 입출력 시에도 프로그램과 파일을 연결하는 스트림이 있어야합니다. 그러나 표준 입출력시와 달리, 파일 입출력 시에는 이를 위한 스트림을 수동으로 프로그램을 통해 생성 및 소멸 시켜주어야합니다.</p>
<h2 id="파일-입출력-과정">파일 입출력 과정</h2>
<blockquote>
<p>파일을 엽니다.(스트림 생성) -&gt; 입출력을 수행합니다. -&gt; 파일을 닫습니다.(스트림 소멸)</p>
</blockquote>
<p>스트림의 생성(파일 열 때)에는 &#39;<strong>fopen()</strong>&#39; 함수가 사용되고, 소멸(파일 닫을 때)에는 &#39;<strong>fclose()</strong>&#39; 함수가 사용됩니다.
파일과 프로그램의 통로 역할을 하는 스트림에는 &#39;<strong>파일 포인터</strong>&#39;가 사용됩니다.</p>
<h3 id="파일-처리-함수">파일 처리 함수</h3>
<p>파일 포인터를 사용하여 파일에 입출력을 수행하는 함수로, &#39;stdio.h&#39; 헤더파일에 원형이 선언되어있습니다.</p>
<table style="font-size: 15px; width: 100%; text-align:center;">
  <thead>
    <tr>
      <th style="width: 30%;">
        함수
      </th>
      <th>
        기능
      </th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>
        fopen()
      </td>
      <td>
        파일을 지정한 모드로 엽니다.
      </td>
    </tr>
    <tr>
      <td>
        fclose()
      </td>
      <td>
        파일을 닫습니다.
      </td>
    </tr>
    <tr>
      <td>
        fgetc(), getc()
      </td>
      <td>
        파일로부터 한 문자를 읽습니다.
      </td>
    </tr>
    <tr>
      <td>
        fputc(), putc()
      </td>
      <td>
        파일에 한 문자를 씁니다.
      </td>
    </tr>
    <tr>
      <td>
        fgets()
      </td>
      <td>
        파일로부터 문자열을 읽습니다.
      </td>
    </tr>
    <tr>
      <td>
        fputs()
      </td>
      <td>
        파일에 문자열을 씁니다.
      </td>
    </tr>
    <tr>
      <td>
        fscanf()
      </td>
      <td>
        파일로부터 정해진 형식에 따라 읽습니다.
      </td>
    </tr>
    <tr>
      <td>
        fprintf()
      </td>
      <td>
        파일에 정해진 형식에 따라 씁니다.
      </td>
    </tr>
    <tr>
      <td>
        fread()
      </td>
      <td>
        파일로부터 정해진 크기의 자료를 정해진 갯수만큼 읽습니다.
      </td>
    </tr>
    <tr>
      <td>
        fwrite()
      </td>
      <td>
        파일에 정해진 크기의 자료를 정해진 갯수만큼 씁니다.
      </td>
    </tr>
    <tr>
      <td>
        fseek()
      </td>
      <td>
        파일에서 입출력 위치를 이동합니다.
      </td>
    </tr>
    <tr>
      <td>
        feof()
      </td>
      <td>
        파일의 끝인지를 확인합니다.
      </td>
    </tr>
    <tr>
      <td>
        ferror()
      </td>
      <td>
        파일의 입출력 시 에러 발생 유무를 확인합니다.
      </td>
    </tr>
  </tbody>
</table>

<p>파일 처리 함수를 사용하여 만들어지는 파일은 그 파일을 구성하는 방법에 따라 &#39;<strong>순차 파일(sequential file)</strong>&#39;과 &#39;<strong>랜덤 파일(random file)</strong>&#39;로 나뉩니다.
<strong>순차 파일</strong>은 파일의 처음부터 자료를 차례대로 읽고 기록하는 파일이며,
<strong>랜덤 파일</strong>은 파일의 임의 위치에서 자료를 읽고 기록하는 파일입니다.</p>
<h3 id="파일-포인터를-활용한-파일-편집">파일 포인터를 활용한 파일 편집</h3>
<pre><code class="language-c">FILE *fp; // 파일 포인터 fp 선언

fp = fopen(&quot;파일명&quot;, &quot;파일 사용 모드&quot;); //fp가 파일을 가리키게하고 파일을 지정한 모드로 엽니다.

...

&quot;파일 처리 함수를 활용한 명령문&quot;

...

fclose(fp); //버퍼를 비우고 fp가 가리키는 파일을 닫습니다.</code></pre>
<ul>
<li><p><strong>파일 포인터 선언</strong> : &#39;<strong>FILE</strong>&#39;형은 구조체로 되어있으며, 파일 내의 위치정보와 파일의 끝에 관한 정보를 갖고있습니다. FILE형으로 선언된 파일 포인터는 버퍼의 어떤 부분을 가리킵니다. 이때 파일 포인터는 동시에 여러개 선언도 가능하며, 각각의 버퍼를 갖습니다.</p>
</li>
<li><p><strong>파일 열기</strong> : &#39;<strong>fopen()</strong>&#39; 함수를 사용하며, 정상적으로 입출력 가능한 상태면 지정된 파일의 파일 포인터 시작 주소값을 리턴하고, 비정상적으로 입출력 불가능한 상태면 NULL 에러값을 리턴합니다. 
&#39;<strong>파일명</strong>&#39;에는 파일의 경로를 적어줍니다.
&#39;<strong>파일 사용 모드</strong>&#39;는 자료의 입출력 방식을 의미합니다.</p>
</li>
</ul>
<table style="width: 100%; text-align: center; font-size: 15px;">
    <thead>
        <tr>
            <th style="width: 20%;">파일 사용 모드</th>
            <th style="width: 30%;">기능</th>
            <th style="width: 25%;">파일이 있을 때</th>
            <th style="width: 25%;">파일이 없을 때</th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td>r(read)</td>
            <td>파일 읽기</td>
            <td>정상 처리</td>
            <td>NULL값 리턴</td>
        </tr>
        <tr>
            <td>r+</td>
            <td>파일 읽기, 쓰기, 추가</td>
            <td>정상 처리</td>
            <td>NULL값 리턴</td>
        </tr>
        <tr>
            <td>w(write)</td>
            <td>파일 쓰기, 추가</td>
            <td>이전 내용 덮어씀</td>
            <td>새 파일 생성</td>
        </tr>
        <tr>
            <td>w+</td>
            <td>파일 읽기, 쓰기, 추가</td>
            <td>이전 내용 삭제</td>
            <td>새 파일 생성</td>
        </tr>
        <tr>
            <td>a(append)</td>
            <td>파일 추가</td>
            <td>이전 내용 뒤에 추가</td>
            <td>새 파일 생성</td>
        </tr>
        <tr>
            <td>a+</td>
            <td>파일 읽기, 추가</td>
            <td>이전 내용 뒤에 추가</td>
            <td>새 파일 생성</td>
        </tr>
    </tbody>
</table>

<blockquote>
<p><strong>텍스트(text) 모드와 2진(binary) 모드</strong>
(파일 사용 모드 뒤에 t 또는 b를 붙여서 사용(t는 생략 가능))</p>
</blockquote>
<ul>
<li>텍스트 모드(t) : 프로그램에서 파일로 자료를 입출력할 때 변환이 일어나는 입출력 모드</li>
<li>2진 모드(b) : 프로그램에서 파일로 자료를 입출력할 때 아무런 변환이 일어나지 않는 입출력 모드</li>
</ul>
<p>fopen() 함수는 파일을 열 수 없을 때 NULL값을 리턴하여 에러가 생기는 경우가 있으므로, 에러가 생길 때를 대비하여 에러 메시지를 띄우고 프로그램을 종료시키는 코드를 함께 작성해야합니다.</p>
<pre><code class="language-c">FILE *fp;

if((fp=fopen(&quot;파일명&quot;, &quot;파일 사용 모드&quot;)) == NULL){
    fputs(&quot;파일을 찾을 수 없습니다.&quot;, fp);
    eixt(1);    //프로그램을 강제 종료시키며, 정상 종료는 &#39;0&#39;, 비정상 종료는 &#39;0 이외의 값&#39;을 넣어줍니다.
    }</code></pre>
<ul>
<li><strong>파일 닫기</strong> : &#39;<strong>fclose()</strong>&#39;함수를 사용합니다. 스트림을 닫고 버퍼를 비우며, 쓰기 모드일 경우 파일 끝에 파일의 끝을 나타내는 &#39;<strong>EOF(End of FILE)</strong>&#39;를 표시해 완전한 파일로 만듭니다.</li>
</ul>
<h1 id="파일-처리-방식">파일 처리 방식</h1>
<p>파일은 정보의 집합입니다. 파일은 논리적으로 &#39;<strong>레코드(record)</strong>&#39; 단위로 이루어지며, 레코드는 다시 &#39;<strong>필드(field)</strong>&#39;로 구성됩니다.
학교에 학생기록부가 있다면, 학생 기록부는 파일, 그 안에 학생 한명에 해당하는 종이는 레코드,  그 종이에 학생의 이름, 번호 등의 항목은 필드에 해당합니다.
즉, <strong>필드가 모여서 레코드, 레코드가 모여서 파일을 구성</strong>합니다.</p>
<h2 id="순차-파일-처리">순차 파일 처리</h2>
<p>파일의 입출력 처리에 사용되는 논리적인 기본단위는 레코드입니다. 그런데 자료 특성상 레코드의 길이가 일정하지 않은 경우가 있는데, 이런 파일을 &#39;<strong>순차 파일</strong>&#39;이라고 합니다.
따라서 순차 파일의 경우 일정하지않은 레코드를 구분해 줄 필요가 있습니다. 이떄 구분 기호로 &#39;<strong>CR(Carriage Return)</strong>&#39;과 &#39;<strong>LF(Line Feed)</strong>&#39;를 합쳐서 사용합니다. 따라서 <strong>순차 파일 처리시 레코드를 파일에 쓸 때 개행 기호(\n)는 CR/LF로 바꿔 기록하고, 읽을 때는 CR/LF를 개행 기호로 바꿔</strong>서 읽습니다.
이러한 변환 과정을 거치는 파일 모드가 &#39;<strong>텍스트 모드</strong>&#39;이며, <strong>텍스트 모드로 파일 열고 기록할 때는 반드시 개행 문자를 레코드와 레코드 사이에 작성</strong>해주어야합니다. 읽을 때는 CR/LF까지 한번에 읽는 것이 좋습니다.
결론적으로, <strong>순차 파일은 순차적으로 기록되고, 순차적으로 읽히는 파일</strong>입니다.</p>
<h3 id="순차-파일-쓰기">순차 파일 쓰기</h3>
<ul>
<li><p><strong>putc()</strong> : <code>putc(문자 변수, 파일 포인터 변수);</code> 형식으로 사용합니다.
호출에 성공하면 &#39;출력된 문자&#39;를 리턴하며, 실패시 &#39;EOF(-1)&#39;을 리턴합니다.</p>
</li>
<li><p><strong>fputs()</strong> : <code>fputs(문자열 변수, 파일 포인터 변수);</code> 형식으로 사용합니다.
문자열을 출력하므로 개행 문자를 넣어 레코드 사이를 구분해주어야합니다.
호출에 성공하면 &#39;음이 아닌 값&#39;을 리턴하며, 실패시 &#39;EOF(-1)&#39;을 리턴합니다.</p>
</li>
<li><p><strong>fprintf()</strong> : <code>fprintf(파일 포인터 변수, &quot;출력 형식&quot;, 변수);</code> 형식으로 사용합니다.
호출에 성공하면 &#39;출력된 문자 수&#39;를 리턴하며, 실패시 &#39;음수&#39;를 리턴합니다.</p>
</li>
</ul>
<h3 id="순차-파일-읽기">순차 파일 읽기</h3>
<ul>
<li><p><strong>getc()</strong> : <code>getc(파일 포인터 변수);</code> 형식으로 사용합니다.
파일 포인터로부터 &#39;한 문자&#39;를 읽어오며, 한 문자를 읽어오면 파일 포인터가 자동으로 1 증가하여 다음 문자를 가리킵니다. 파일의 끝을 만나거나 에러 발생시 &#39;EOF(-1)&#39;을 리턴합니다.</p>
</li>
<li><p><strong>fgets()</strong> : <code>fgets(문자열 변수, 문자열 길이+1, 파일 포인터 변수);</code> 형식으로 사용합니다.
파일에 저장된 문자열 자료를 읽을 때 사용하며, 읽어 낼 문자열의 길이를 반드시 적어야합니다. 저장된 문자열에서 끝을 알리는 CR/LF는 개행 문자(\n)로 변환되어 출력되고 마지막에 &#39;\0&#39;이 추가됩니다. 파일의 끝을 만나거나 에러 발생시 &#39;NULL&#39;을 리턴합니다.</p>
</li>
<li><p><strong>fscanf()</strong> : <code>fscanf(파일 포인터 변수, &quot;입력 형식&quot;, 변수);</code> 형식으로 사용합니다.
파일의 끝을 만나거나 에러 발생시 &#39;EOF(-1)&#39;을 리턴하지만, 일반적으로 fscanf() 함수에서 파일의 끝을 구분할때는 &#39;<strong>feof(파일 포인터 변수) 함수</strong>&#39;를 함께 사용합니다, feof() 함수는 파일의 끝을 만나면 &#39;0이 아닌 값&#39;을 리턴합니다.</p>
</li>
</ul>
<h3 id="순차-파일--추가">순차 파일  추가</h3>
<p>파일 사용 모드를 추가 모드로 바꾼 뒤, 쓰기 함수를 사용하면 파일 끝에 레코드를 추가할 수 있습니다. 추가 모드에서는 해당 파일이 없어도 그 파일명으로 파일을 새로 생성하므로 파일이 없어도 상관 없습니다.</p>
<h2 id="랜덤-파일-처리">랜덤 파일 처리</h2>
<p>순차 파일은 순차적(파일의 처음이나 끝을 이용)으로 처리하지만, 랜덤 파일은 파일의 임의 위치에서 자료를 편집할 수 있습니다. 순차 파일은 레코드 길이가 일정하지 않기때문에 CR/LF로 구분했지만, 랜덤 파일은 각 레코드의 길이가 일정하므로 레코드 구분이 필요 없습니다.
랜덤 파일은 가변 길이가 아닌 고정 길이 레코드를 갖고있으므로 순차적으로 레코드를 차곡차곡 채우지 못해 공간을 비효율 적으로 사용하게되지만, 레코드의 검색이 빠르고 효율적으로 가능합니다.</p>
<h3 id="랜덤-파일-열기">랜덤 파일 열기</h3>
<p>원칙적으로 랜덤 파일을 입출력하기 위해서는 순차 파일과 달리 레코드 구분을 위해 CR/LF가 필요 없으므로 변환 작업을 하지않는 2진 모드를 사용합니다.
2진 파일은 텍스트 파일보다 적은 기억공간을 차지하지만, 특정 프로그램에서는 그 파일을 읽어 들일 수 없습니다. 오로지 2진 파일에 접근할 수 있도록 작성된 프로그램만 읽고 쓸 수 있습니다.
2진 모드는 레코드 길이를 사용자가 결정하므로 레코드 길이가 일정하여 길이를 알고 있으므로 파일 포인터의 위치를 마음대로 옮기면서 입출력을 수행할 수 있습니다.</p>
<h3 id="랜덤-파일-생성">랜덤 파일 생성</h3>
<p><code>fwrite(포인터형 자료 저장 변수, 레코드 길이, 레코드 갯수, 파일 포인터 변수);</code>의 형태로 사용합니다.
fwrite() 함수는 텍스트 파일을 저장할 때도 사용하지만, 주로 랜덤 파일 처리 시 사용합니다. fputs() 함수처럼 사용 가능하며, 다른 점은 2진 모드로 파일을 열 때 NULL 값을 사용 가능한 것 입니다.(텍스트 모드에서는 NULL 값을 읽거나 쓸 수 없지만, 2진 모드에서는 가능합니다.)</p>
<h3 id="랜덤-파일-읽기">랜덤 파일 읽기</h3>
<p><code>fread(포인터형 읽을 자료 변수, 레코드 길이, 레코드 갯수, 파일 포인터);</code>의 형태로 사용합니다.
fread() 함수는 읽기에 성공하면 &#39;읽은 레코드 수&#39;를 리턴하며, 실패하거나 파일의 끝을 만나면 &#39;다른 값&#39;을 리턴합니다.</p>
<h3 id="랜덤-파일-위치-제어">랜덤 파일 위치 제어</h3>
<ul>
<li><strong>fseek()</strong> : <code>fseek(파일 포인터 변수, 이동할 상대 위치, 기준 위치 지정 값);</code>의 형태로 사용합니다.
fseek() 함수는 랜덤 파일의 특정 위치에서 입출력 가능합니다. 이동할 위치는 상대 위치 개념을 사용합니다.</li>
</ul>
<table style="width: 100%; font-size:15px; text-align: center;">
  <thead>
    <tr>
      <th style="width: 40%;">
        기준 위치 지정 값
      </th>
      <th>
        기능
      </th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>
        SEEK_SET(== 0)
      </td>
      <td>
        파일의 시작 위치로 지정
      </td>
    </tr>
    <tr>
      <td>
        SEEK_CUR(== 1)
      </td>
      <td>
        현재 파일 포인터의 위치로 지정
      </td>
    </tr>
    <tr>
      <td>
        SEEK_END(== 2)
      </td>
      <td>
        파일의 끝 위치로 지정
      </td>
    </tr>
  </tbody>
</table>

<p>이동할 상대 위치는 byte 단위이며, +값은 순방향, -값은 역방향으로 이동합니다.</p>
<ul>
<li><strong>ftell()</strong> : <code>ftell(파일 포인터 변수);</code>의 형태로 사용하며, 현재 파일 포인터 변수가 위치한 곳이 파일의 처음부터 몇바이트 떨어진 곳인지 알려줍니다.</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[구조체와 공용체]]></title>
            <link>https://velog.io/@giraffe_/%EA%B5%AC%EC%A1%B0%EC%B2%B4%EC%99%80-%EA%B3%B5%EC%9A%A9%EC%B2%B4</link>
            <guid>https://velog.io/@giraffe_/%EA%B5%AC%EC%A1%B0%EC%B2%B4%EC%99%80-%EA%B3%B5%EC%9A%A9%EC%B2%B4</guid>
            <pubDate>Sun, 06 Mar 2022 13:37:05 GMT</pubDate>
            <description><![CDATA[<h1 id="구조체">구조체</h1>
<p>&#39;<strong>구조체(structure)</strong>&#39;는 서로 다른 자료형을 갖는 자료들을 하나의 자료형으로 정의하여 사용하는 자료형입니다. 배열은 같은 자료형만 모아서 사용할 수 있지만 구조체는 서로 다른 자료형을 모아서 사용할 수 있고, 사용자가 필요에 따라 정의하여 사용하므로 더 폭넓게 사용 가능합니다.</p>
<pre><code class="language-c">struct 구조체명{
    멤버_자료형 멤버명;
    멤버_자료형 멤버명;

    ...
};</code></pre>
<p>구조체는 위와같은 형식으로 선언하고 아래와같이 사용 가능합니다.</p>
<pre><code class="language-c">#include &lt;stdio.h&gt;

struct student{                    //struct로 student라는 구조체명 선언
    char *name;                    //char 포인터 형식의 name이라는 멤버 정의
    char *gender;                //char 포인터 형식의 gender라는 멤버 정의
    unsigned short number;        //unsigned short 형식의 number라는 멤버 정의
};

int main(){
    struct student giraffe;        //giraffe라는 student 구조체 변수 선언

    giraffe.name = &quot;giraffe&quot;;    //giraffe라는 student 구조체 변수의 name 멤버에 자료값 입력
    giraffe.gender = &quot;male&quot;;    //giraffe라는 student 구조체 변수의 gender 멤버에 자료값 입력
    giraffe.number = 1;            //giraffe라는 student 구조체 변수의 number 멤버에 자료값 입력

    printf(&quot;student name    : %s\n&quot;, giraffe.name);
    printf(&quot;student gender  : %s\n&quot;, giraffe.gender);
    printf(&quot;student number  : %u\n&quot;, giraffe.number);
}</code></pre>
<pre><code>student name    : giraffe
student gender  : male
student number  : 1</code></pre><p>위와 같은 구조체 정의로 student라는 새로운 자료형을 정의하여 사용하였습니다.</p>
<p>구조체 변수 선언 부분에서 <code>struct student giraffe;</code> 형식 외에도
<code>struct 구조체명 변수명, 배열명[배열크기], *포인터 변수명;</code>의 형식으로도 선언이 가능하고, 여러개를 나열하여 한번에 선언도 가능합니다.</p>
<p><code>struct student giraffe, zibra;</code>로 두 구조체 변수를 정의하고 멤버값들을 넣어 준 후,
<code>zibra = giraffe;</code> 처럼 배정 연산을 사용하여 각 멤버에 대응하는 값들을 복사해 줄 수도있습니다.</p>
<p>구조체는 다른 자료형처럼 선언과 동시에 초기화가 가능합니다.
<code>struct student giraffe = {&quot;giraffe&quot;, &quot;male&quot;, 1};</code></p>
<p>구조체 멤버를 사용하기위해 멤버에 접근하는 것을 &#39;구조체 멤버를 참조한다&#39;라고 합니다.
참조 방법은 <code>구조체명.멤버명</code>으로 접근하여 자료값을 대입하거나 꺼낼 수 있습니다.</p>
<h2 id="구조체-포인터">구조체 포인터</h2>
<p>구조체 포인터는 구조체 선언시 구조체 변수명 앞에 *를 붙여서 선언할 수 있습니다. 구조체 포인터도 포인터이므로 주소값을 갖습니다.</p>
<pre><code class="language-c">#include &lt;stdio.h&gt;

struct student{
    char *name;
    char *gender;
    unsigned short number;
};

int main(){
    struct student giraffe, *p;
    p = &amp;giraffe;

    (*p).name = &quot;giraffe&quot;;        //.(도트) 연산자의 우선 순위가 더 높으므로 괄호로 *p를 묶어줌
    (*p).gender = &quot;male&quot;;
    (*p).number = 1;

    printf(&quot;student name    : %s\n&quot;, giraffe.name);
    printf(&quot;student gender  : %s\n&quot;, giraffe.gender);
    printf(&quot;student number  : %d\n&quot;, giraffe.number);
    printf(&quot;\n&quot;);

    p-&gt;name = &quot;Giraffe&quot;;        //구조체 포인터로 멤버 접근시 -&gt;(포인터 연산자)로 접근 가능
    p-&gt;gender = &quot;Male&quot;;
    p-&gt;number = 2;

    printf(&quot;student name    : %s\n&quot;, giraffe.name);
    printf(&quot;student gender  : %s\n&quot;, giraffe.gender);
    printf(&quot;student number  : %d\n&quot;, giraffe.number);
}</code></pre>
<pre><code>student name    : giraffe
student gender  : male
student number  : 1

student name    : Giraffe
student gender  : Male
student number  : 2</code></pre><p>구조체 포인터도 앞서 보았던 포인터처럼 사용하여 유용하게 활용할 수 있습니다.</p>
<h2 id="함수와-구조체">함수와 구조체</h2>
<p>함수를 사용할 때 매개변수로 구조체가 사용가능합니다.</p>
<h3 id="구조체를-함수의-매개변수로-사용">구조체를 함수의 매개변수로 사용</h3>
<p>구조체를 함수의 매개변수로 사용하는 것은 일반 변수를 매개변수로 사용하는 방법과 같습니다. 하지만 함수에 넘겨줄 때 구조체를 통째로 복사하기때문에 편리하지만 시간이 많이 걸리고, 기억공간이 낭비될 수 있습니다.</p>
<pre><code class="language-c">#include &lt;stdio.h&gt;

struct student{
    char *name;
    char *gender;
    unsigned short number;
};

struct student print_info(struct student target);
int main(){
    struct student giraffe;

    giraffe.name = &quot;giraffe&quot;;
    giraffe.gender = &quot;male&quot;;
    giraffe.number = 1;

    print_info(giraffe);
}

struct student print_info(struct student target){        //struct student 자체가 int처럼 일종의 자료형
    printf(&quot;=====Student Information=====\n&quot;);
    printf(&quot;student name    : %s\n&quot;, target.name);
    printf(&quot;student gender  : %s\n&quot;, target.gender);
    printf(&quot;student number  : %d\n&quot;, target.number);
}</code></pre>
<pre><code>=====Student Information=====
student name    : giraffe
student gender  : male
student number  : 1</code></pre><h3 id="구조체-포인터를-함수의-매개변수로-사용">구조체 포인터를 함수의 매개변수로 사용</h3>
<p>구조체 자체를 함수의 매개변수로 사용할 때의 단점 때문에 포인터를 통해 주소값을 넘겨주는 것이 더 효율적입니다.</p>
<pre><code class="language-c">#include &lt;stdio.h&gt;

struct student{
    char *name;
    char *gender;
    unsigned short number;
};

struct student print_info(struct student *target);
int main(){
    struct student giraffe;

    giraffe.name = &quot;giraffe&quot;;
    giraffe.gender = &quot;male&quot;;
    giraffe.number = 1;

    print_info(&amp;giraffe);
}

struct student print_info(struct student *target){
    printf(&quot;=====Student Information=====\n&quot;);
    printf(&quot;student name    : %s\n&quot;, target-&gt;name);
    printf(&quot;student gender  : %s\n&quot;, target-&gt;gender);
    printf(&quot;student number  : %d\n&quot;, target-&gt;number);
}</code></pre>
<pre><code>=====Student Information=====
student name    : giraffe
student gender  : male
student number  : 1</code></pre><h1 id="typedef">typedef</h1>
<p>&#39;<strong>typedef(type definitioin)</strong>&#39;은 이미 존재하는 자료형에 새로운 이름을 붙여주는 키워드입니다.</p>
<p><code>typedef 기존_자료형_이름 새로운_자료형_이름</code>의 형식으로 사용합니다.
<code>typedef unsigned int INT;</code>라고 선언하면 unsigned int라고 선언하지않고 INT라고 변수를 선언해도 unsigned int형으로 선언된 것과 동일하게 사용 가능합니다.</p>
<pre><code class="language-c">#include &lt;stdio.h&gt;

struct student{
    char *name;
    char *gender;
    unsigned short number;
};
typedef struct student Student;

Student print_info(Student *target);
int main(){
    Student giraffe;

    giraffe.name = &quot;giraffe&quot;;
    giraffe.gender = &quot;male&quot;;
    giraffe.number = 1;

    print_info(&amp;giraffe);
}

Student print_info(Student *target){
    printf(&quot;=====Student Information=====\n&quot;);
    printf(&quot;student name    : %s\n&quot;, target-&gt;name);
    printf(&quot;student gender  : %s\n&quot;, target-&gt;gender);
    printf(&quot;student number  : %d\n&quot;, target-&gt;number);
}</code></pre>
<pre><code>=====Student Information=====
student name    : giraffe
student gender  : male
student number  : 1</code></pre><p>위의 예시처럼 구조체에도 사용이 가능하며, struct student처럼 길게 적지않고 새로 정의한 이름으로 간편하게 사용할 수 있는 장점이 있습니다.</p>
<pre><code class="language-c">typedef struct student{
    char *name;
    char *gender;
    unsigned short number;
}Student;</code></pre>
<p>구조체 정의 후 따로 <code>typedef struct student Student;</code> 처럼 작성하지않고 구조체 정의시 위 처럼 바로 새로운 이름으로 정의할 수도 있습니다.</p>
<pre><code class="language-c">typedef struct{
    char *name;
    char *gender;
    unsigned short number;
}Student;</code></pre>
<p>그리고 더 간단하게 위처럼 작성할 수도 있습니다.</p>
<h1 id="공용체">공용체</h1>
<p>&#39;<strong>공용체(union)</strong>&#39;는 동일한 기억공간에 여러 자료형을 저장할 때 사용합니다. 주로 선택적으로 다른 자료형의 값을 가질 때 기억공간을 절약하기위해 사용합니다.</p>
<p>공용체의 사용방법은 구조체와 키워드만 다르고 대부분 동일합니다.</p>
<p>예를 들어 송금 시 우리나라 사람에게 보낸다면 우리나라의 원 단위는 정수형이므로 int형을 사용하면 되지만, 미국 사람에게 보낸다면 미국의 달러는 소수점까지 사용하므로 float형을 사용해야합니다. 이때 기억공간의 절약을 위해 택 1을 할 수 있는 이러한 상황에 사용하면 유용합니다.</p>
<pre><code class="language-c">#include &lt;stdio.h&gt;

typedef union{
    int won;
    float dollar;
}SendMoney;

int main(){
    char country;
    SendMoney money;

    printf(&quot;어느 나라로 돈을 송금하시겠습니까?(한국 : K, 미국 : A) : &quot;);
    scanf(&quot;%c&quot;, &amp;country);

    if(country == &#39;K&#39;){
        printf(&quot;금액을 입력하세요. : &quot;);
        scanf(&quot;%d&quot;, &amp;money.won);
        printf(&quot;%d원을 송금하였습니다.&quot;, money.won);
    }
    else if(country == &#39;A&#39;){
        printf(&quot;금액을 입력하세요. : &quot;);
        scanf(&quot;%f&quot;, &amp;money.dollar);
        printf(&quot;%7.2f달러를 송금하였습니다.&quot;, money.dollar);
    }
    else{
        printf(&quot;잘못 입력하셨습니다. 다시 시도해주세요.&quot;);
        return 1;
    }
    return 0;
}</code></pre>
<pre><code>어느 나라로 돈을 송금하시겠습니까?(한국 : K, 미국 : A) : K
금액을 입력하세요. : 500
500원을 송금하였습니다.

어느 나라로 돈을 송금하시겠습니까?(한국 : K, 미국 : A) : A
금액을 입력하세요. : 433.7
433.70달러를 송금하였습니다.

어느 나라로 돈을 송금하시겠습니까?(한국 : K, 미국 : A) : U
잘못 입력하셨습니다. 다시 시도해주세요.</code></pre><p>위의 예시는 송금하는 나라에 따라 int형이 필요한지, float형이 필요한지 나뉘기때문에 기억공간의 효율적 사용을 위해 공용체를 사용는게 좋습니다.</p>
<pre><code class="language-c">#include &lt;stdio.h&gt;

typedef union
{
    char c;
    int i;
    long l;
    float f;
    double d;
} UNION;

int main(){
    UNION Union;

    int c, i, l, f, d, u;

    c = sizeof(char);
    i = sizeof(int);
    l = sizeof(long);
    f = sizeof(float);
    d = sizeof(double);
    u = sizeof(Union);

    printf(&quot;sizeof char : %d\n&quot;, c);
    printf(&quot;sizeof int : %d\n&quot;, i);
    printf(&quot;sizeof long : %d\n&quot;, l);
    printf(&quot;sizeof float : %d\n&quot;, f);
    printf(&quot;sizeof double : %d\n&quot;, d);
    printf(&quot;sizeof union : %d\n&quot;, u);
}</code></pre>
<pre><code>sizeof char : 1
sizeof int : 4
sizeof long : 4
sizeof float : 4
sizeof double : 8
sizeof union : 8</code></pre><p>공용체는 가장 큰 기억공간을 갖는 멤버의 기억공간 크기를 갖습니다.
따라서 위의 예시에서는 가장 큰 기억공간을 갖는 멤버인 double형에 따라 8byte가 할당된 것을 알 수 있습니다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[call by value & reference]]></title>
            <link>https://velog.io/@giraffe_/call-by-value-reference</link>
            <guid>https://velog.io/@giraffe_/call-by-value-reference</guid>
            <pubDate>Sun, 06 Mar 2022 09:55:57 GMT</pubDate>
            <description><![CDATA[<p>다른 블럭에 함수를 정의하고 사용하여 값을 주고 받을 때, C에서는 기본적으로 지역 변수로 선언된 변수의 값은 서로 다른 블럭에서 사용할 수 없기때문에 기대한 결과값과 실제 결과값이 다르게 나올 수 있습니다. 이런 상황을 위해 매개변수 간 자료 전달 방법에 대해 알 필요가 있습니다.</p>
<h1 id="call-by-value">call by value</h1>
<p>&#39;<strong>call by value(값에 의한 호출)</strong>&#39;는 함수를 호출하여 인자를 매개변수로 넘겨줄 때 값을 복사하여 넘겨줍니다. </p>
<pre><code class="language-c">#include &lt;stdio.h&gt;

void swap(int x, int y);
int main(){
    int x = 1, y = 2;

    printf(&quot;원래 값\n&quot;);
    printf(&quot;x = %d, y = %d\n&quot;, x, y);

    swap(x, y);

    printf(&quot;\n&quot;);
    printf(&quot;바꾼 값\n&quot;);
    printf(&quot;x = %d, y = %d\n&quot;, x, y);
}

//매개변수로 받은 두 값을 서로 교환
void swap(int x, int y){
    int tmp;

    tmp = x;
    x = y;
    y = tmp;
}</code></pre>
<pre><code>원래 값     
x = 1, y = 2

바꾼 값     
x = 1, y = 2</code></pre><p>swap() 함수는 매개변수로 받은 두 인자 값을 서로 교환할 목적으로 작성했지만 실행 결과는 교환이 되지 않은 것을 확인할 수 있습니다.
C에서 기본으로 사용되는 이 방식은 복사하여 인자를 넘겨주면 서로 별개의 변수가 되므로, 넘겨주는 순간 더이상 관련이 없어지기때문입니다.
물론 swap() 함수의 반환 자료형을 void가 아닌 int로 바꿔 return문을 이용하면 값의 반환이 가능하지만, 하나의 값 밖에 반환할 수 없기때문에 사실상 불가능합니다.</p>
<h1 id="call-by-reference">call by reference</h1>
<p>&#39;<strong>call by reference(참조에 의한 호출)</strong>&#39;는 함수를 호출하여 인자의 주소값을 매개변수로 넘겨줍니다.</p>
<blockquote>
<p>정확히 얘기하자면 C에서는 공식적으로 call by reference를 지원하지않는다고합니다. 따라서 이 예시의 방법은 주소값을 복사하여 넘겨주므로 call by reference가 아닌 &#39;<strong>call by address</strong>&#39;로 보는 것이 맞다고 합니다.</p>
</blockquote>
<pre><code class="language-c">#include &lt;stdio.h&gt;

void swap(int *x, int *y);
int main(){
    int x = 1, y = 2;

    printf(&quot;원래 값\n&quot;);
    printf(&quot;x = %d, y = %d\n&quot;, x, y);

    swap(&amp;x, &amp;y);

    printf(&quot;\n&quot;);
    printf(&quot;바꾼 값\n&quot;);
    printf(&quot;x = %d, y = %d\n&quot;, x, y);
}

//매개변수로 받은 두 값을 서로 교환
void swap(int *x, int *y){
    int tmp;

    tmp = *x;
    *x = *y;
    *y = tmp;
}</code></pre>
<pre><code>원래 값
x = 1, y = 2

바꾼 값
x = 2, y = 1</code></pre><p>자료 값이 아닌 인자의 주소값을 (복사하여) 넘겨주었습니다. 따라서 swap() 함수에서도 기억공간의 주소에 접근함으로써 해당 주소에있는 자료값을 얻을 수 있으므로, 포인터를 사용하여 두 기억공간에 있는 자료값을 서로 교환해주었습니다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[포인터]]></title>
            <link>https://velog.io/@giraffe_/%ED%8F%AC%EC%9D%B8%ED%84%B0</link>
            <guid>https://velog.io/@giraffe_/%ED%8F%AC%EC%9D%B8%ED%84%B0</guid>
            <pubDate>Sun, 06 Mar 2022 09:08:36 GMT</pubDate>
            <description><![CDATA[<h1 id="포인터-개요">포인터 개요</h1>
<p>&#39;<strong>포인터(pointer)</strong>&#39;는 변수의 일종이지만, 다른 변수와는 조금 다릅니다. 포인터는 특정한 값을 가지는게 아니라, 어떤 데이터가 저장된 &#39;<strong>기억공간의 주소(번지)</strong>&#39;를 값으로 가집니다.</p>
<pre><code class="language-c">int i = 100;
int *p = &amp;i;</code></pre>
<p>정수형 변수 i가 차지하는 기억공간이 있고, 모든 기억공간에는 주소가 존재하며, 그 주소를 값으로 가지는 변수가 포인터 변수이고, 선언시 앞에 &#39;<strong>***&#39;를 붙여 선언합니다. 그리고 그 주소(포인터 값)를 표현하기위해 &#39;</strong>주소 연산자(&amp;)**&#39;를 사용합니다.</p>
<blockquote>
<div align="center"><img src="https://images.velog.io/images/giraffe_/post/699d266f-f190-4a39-8068-05efe533ac20/image.png" width="50%"></div>
</blockquote>
<h1 id="포인터-변수의-선언과-참조">포인터 변수의 선언과 참조</h1>
<pre><code class="language-c">int i = 100;
int *p = &amp;i;                //포인터 변수 p를 선언하고 i의 주소값을 대입합니다.

printf(&quot; i = %d\n&quot;,  i);    //i의 값 100
printf(&quot;*p = %d\n&quot;, *p);    //포인터 변수 p가 가리키는 주소(&amp;i)에 있는 내용(자료값(*p))
printf(&quot;\n&quot;);
printf(&quot;&amp;i = %d\n&quot;, &amp;i);    //i의 주소값(&amp;i)
printf(&quot; p = %d\n&quot;,  p);    //포인터 변수 p의 값(i의 주소값(&amp;i))
printf(&quot;\n&quot;);
printf(&quot;&amp;p = %d\n&quot;, &amp;p);    //p의 주소값(&amp;p)</code></pre>
<pre><code> i = 100
*p = 100

&amp;i = 0xAC
 p = 0xAC

&amp;p = 0xB1</code></pre><p>일반 변수는 선언시 <code>int i = 100;</code>의 형태로 선언합니다.
포인터 변수는 선언시 <code>int *p = &amp;i;</code>의 형태로 선언합니다.</p>
<p>정수형 변수 i는 기억공간을 가집니다.
해당 기억공간은 i가 갖고있는 정수형 값 100을 가집니다.
모든 기억공간은 주소가 있고, 정수형 변수 i의 주소값(&amp;i)은 0xAC입니다.</p>
<p>포인터 변수 p는  기억공간을 가집니다.
해당 기억공간은 p가 가리키는 i의 주소값(&amp;i) 0xAC를 가집니다.
모든 기억공간은 주소가 있고, 포인터 변수 p의 주소값(&amp;p)은 0xB1입니다.</p>
<p>이때 포인터 변수 p가 가리키는 주소에 있는 내용(자료값)은 &#39;<strong>*p</strong>&#39;로 알 수 있습니다.
이렇게 어떤 포인터 변수가 가리키는 내용(자료값)을 읽거나 값을 대입하는 것을 &#39;<strong>포인터 변수를 참조(reference)한다</strong>&#39;라고 합니다.</p>
<pre><code class="language-c">int a =10, b, *p;
p = &amp;a;
b = *p;

printf(&quot;a = %d, b = %d, *p = %d&quot;, a, b, *p);</code></pre>
<pre><code>a = 10, b = 10, *p = 10</code></pre><h1 id="void형-포인터">void형 포인터</h1>
<p>포인터는 선언시 자료형을 명시해 주어야합니다. 하지만 컴파일시 자료형을 결정하지 못하고 프로그램 실행시 자료형이 결정되는 경우에 &#39;<strong>void형 포인터</strong>&#39;를 사용합니다.
<code>void *포인터명;</code>의 형태로 선언하며 void형 포인터는 어떤 형태의 포인터라도 모두 저장할 수 있지만, 어떠한 자료형을 가지는 기억공간의 주소를 넘겨주는지 알려주기위해 명시적 형변환으로 자료형을 알려주어야합니다.</p>
<pre><code class="language-c">int a = 10;
char c = &#39;b&#39;;
void *p = NULL; //void형 포인터 p를 선언하고 아무것도 카리키지않게 NULL로 초기화

p = (int*)&amp;a;
printf(&quot;*p = %d\n&quot;, *(int*)p);

p = (char*)&amp;c;
printf(&quot;*p = %c\n&quot;, *(char*)p);</code></pre>
<pre><code>*p = 10
*p = b</code></pre><h1 id="포인터-연산">포인터 연산</h1>
<p>기억공간은 byte 단위로 이루어집니다. 자료형에 따라 가지는 기억공간의 용량이 다르며 대표적으로 char형은 1byte, int형은 4byte, double형은 8byte를 가집니다.</p>
<pre><code>char *p 의 주소가 100 번지일때
char *(p+1) 의 주소는 100+(1*1)이 되어 101번지가 됩니다.


int *p 의 주소가 100 번지일때
int *(p+1) 의 주소는 100+(1*4)이 되어 104번지가 됩니다.

double *p 의 주소가 100 번지일때
double *(p+1) 의 주소는 100+(1*8)이 되어 108번지가 됩니다.</code></pre><p>위처럼 포인터 변수에 +, -, ++, --의 연산자를 사용하는 연산을 &#39;<strong>포인터 연산</strong>&#39;이라고합니다.
(포인터 연산을 사용하여 계산된 숫자)*(자료형 byte 크기) 만큼의 주소를 이동합니다.</p>
<pre><code>주의해야 할 점은
*(p+1)은 (p번지+1) 번지의 내용을 가리키고,
*p+1은 p번지의 내용에 1을 더한 값을 가리킨다
는 것 입니다.</code></pre><h1 id="포인터와-배열">포인터와 배열</h1>
<h2 id="char형-포인터">char형 포인터</h2>
<p>앞서 말한 것 처럼, C에서는 문자열이라는 자료형을 제공하지않기에, char형 포인터를 사용하여 문자열을 표현할 수 있습니다.</p>
<blockquote>
<div align="center"><img src="https://images.velog.io/images/giraffe_/post/cc01921d-7644-480d-854d-d192ee9db8c9/image.png" width="50%"></div>
</blockquote>
<pre><code class="language-c">char *cp = &quot;hello&quot;;                                //char형 포인터 cp를 선언하고 문자열 hello를 대입합니다.

for(int i=0; *(cp+i) != &#39;\0&#39;; i++){                //cp가 1byte씩 커질때 NULL이 아닌 내용이 있으면 루프를 계속 돕니다.
    printf(&quot;*(cp+%d) : %c\n&quot;, i, *(cp+i));
}</code></pre>
<pre><code>*(cp+0) : h
*(cp+1) : e
*(cp+2) : l
*(cp+3) : l
*(cp+4) : o</code></pre><p>cp를 char형 포인터로 선언하고, cp의 값은 문자열이 시작하는 주소가 됩니다.
그리고 cp는 char형 포인터이므로, *cp의 값은 문자열의 첫번째 문자인 &#39;h&#39;입니다.</p>
<h2 id="포인터와-배열의-관계">포인터와 배열의 관계</h2>
<p>앞서 배열은 &#39;동일한 자료형을 갖는 자료를 연속으로 기억공간에 나열한 것&#39;이라고 했습니다.
위의 예시를 참고하여 배열과 포인터로 문자열을 사용하는 것을 비교해보면</p>
<p><code>char s[3] = &quot;hi&quot;;</code> : char형 자료를 연속으로 기억공간에 나열한 배열
<code>char *s = &quot;hi&quot;;</code>    : char형 자료를 연속으로 기억공간에 나열한 포인터</p>
<p>즉, 위의 두가지는 작성 방식의 차이이지 비슷한 성질을 가짐을 알 수 있습니다.</p>
<p>배열은 선언시 배열명 자체가 배열의 시작 주소를 갖는다는 특징이 있습니다.</p>
<pre><code class="language-c">int i, array[5] = {1,2,3,4,5};</code></pre>
<p>즉, array 자체는 int형 포인터고, 값은 array의 시작주소, 즉, array[0]의 주소와 같습니다.
따라서 다른 원소들의 주소도 <code>array+i == &amp;array[i]</code>로 표현 가능합니다.
값을 얻고싶다면 <code>*(array+i) == array[i]</code>로 사용할 수 있습니다.</p>
<p>따라서 배열과 포인터는 서로 변환하여 표현할 수 있습니다.</p>
<pre><code class="language-c">char s[6] = &quot;hello&quot;;

for(int i=0; i&lt;5; i++){
    printf(&quot;s[%d] : %c\n&quot;, i, s[i]);
}
printf(&quot;\n&quot;);

for(int i=0; i&lt;5; i++){
    printf(&quot;*(s+%d) : %c\n&quot;, i, *(s+i));
}
</code></pre>
<pre><code>s[0] : h
s[1] : e
s[2] : l
s[3] : l
s[4] : o

*(s+0) : h
*(s+1) : e
*(s+2) : l
*(s+3) : l
*(s+4) : o</code></pre><h2 id="포인터-배열">포인터 배열</h2>
<p>&#39;<strong>포인터 배열</strong>&#39;은 포인터들을 배열로 나타낸 것 입니다. 동일한 자료형의 포인터가 여러개 사용될 때 이를 배열로 나타낸 것 입니다. 따라서 포인터 배열은 2차원 배열과 유사하지만, 각 포인터의 연속된 원소 수가 다르다면, 포인터 배열은 기억공간 절약 효과를 얻을 수 있습니다.</p>
<pre><code class="language-c">char *fruit[3];

fruit[0] = &quot;apple&quot;;
fruit[1] = &quot;banana&quot;;
fruit[2] = &quot;melon&quot;;</code></pre>
<p>fruit[0]의 시작 주소가 100번지라면
fruit[1]의 시작 주소는 106번지
fruit[2]의 시작 주소는 113번지가 됩니다.</p>
<p><code>100번지</code>
<code>a</code> <code>p</code> <code>p</code> <code>l</code> <code>e</code> <code>\0</code></p>
<p><code>106번지</code>
<code>b</code> <code>a</code> <code>n</code> <code>a</code> <code>n</code> <code>a</code> <code>\0</code></p>
<p><code>113번지</code>
<code>m</code> <code>e</code> <code>l</code> <code>o</code> <code>n</code> <code>\0</code></p>
<p>하지만 2차원 배열을 사용하면 제일 긴 문자열에 맞추어 기억공간을 일괄적으로 할당해야합니다.</p>
<pre><code class="language-c">char fruit[3][7] = {&quot;apple&quot;, &quot;banana&quot;, &quot;melon&quot;};</code></pre>
<p>fruit[0]의 시작 주소가 100번지라면
fruit[1]의 시작 주소는 107번지
fruit[2]의 시작 주소는 114번지가 됩니다.</p>
<p><code>100번지</code>
<code>a</code> <code>p</code> <code>p</code> <code>l</code> <code>e</code> <code>\0</code> <code>[]</code></p>
<p><code>107번지</code>
<code>b</code> <code>a</code> <code>n</code> <code>a</code> <code>n</code> <code>a</code> <code>\0</code></p>
<p><code>114번지</code>
<code>m</code> <code>e</code> <code>l</code> <code>o</code> <code>n</code> <code>\0</code> <code>[]</code></p>
<p>(※ <code>[]</code>는 빈칸입니다.)</p>
<p>제일 긴 문자열인 banana에 맞추어 7바이트씩 할당해주어야하고, apple과 melon은 6바이트가 필요함에도 7바이트씩 할당 받았기때문에 각각 1byte라는 기억공간의 낭비가 발생합니다.</p>
<h1 id="이중-포인터">이중 포인터</h1>
<p>&#39;<strong>이중 포인터(pointer to pointer)</strong>&#39;는 포인터 변수에 다시 포인터를 할당합니다.
<code>자료형 **포인터명;</code>의 형태로 사용합니다. 이중 포인터가 가리키는 곳에는 또 포인터가 있으므로 주소값이 들어있습니다. 그리고 다시 그 포인터가 가리키는 주소를 찾아가 마침내 자료를 참조하게됩니다.</p>
<pre><code class="language-c">int i = 100, *p, **pp;

p = &amp;i;
pp = &amp;p;

printf(&quot;i = %d&quot;, **pp);</code></pre>
<pre><code>i = 100</code></pre>]]></description>
        </item>
        <item>
            <title><![CDATA[배열]]></title>
            <link>https://velog.io/@giraffe_/%EB%B0%B0%EC%97%B4</link>
            <guid>https://velog.io/@giraffe_/%EB%B0%B0%EC%97%B4</guid>
            <pubDate>Sat, 05 Mar 2022 11:58:01 GMT</pubDate>
            <description><![CDATA[<p>&#39;<strong>배열(array)</strong>&#39;은 동일한 자료형을 갖는 자료를 연속으로 기억공간에 나열한 것 입니다.</p>
<h1 id="1차원-배열">1차원 배열</h1>
<h2 id="배열의-선언">배열의 선언</h2>
<p><code>자료형 배열명[원소수];</code>의 형태로 사용하며, 배열의 각각의 자료를 원소라고합니다. 대괄호로 나타낸 부분은 첨자라고하며 첨자의 개수에따라 하나면 &#39;1차원 배열&#39;, 두개면 &#39;2차원 배열&#39;, ...로 구분합니다. 그리고 첨자를 이용해 배열의 원소를 하나씩 사용할 수 있는데, 첨자에 숫자를 넣어서 사용할 수 있으며, 숫자는 0부터 시작합니다. 즉, 배열의 첫번째 원소는 &#39;배열명[0]&#39;이 되며 마지막 원소는 &#39;배열명[배열크기-1]&#39;이 되는 것 입니다.
예를 들어 <code>int member_number[1000];</code>이라는 배열은 배열명은 &#39;member_number&#39;, 자료의 자료형은 int, 원소의 수는 &#39;1000&#39;인 1차원 배열입니다. 첫번쨰 원소의 호출은 &#39;member_number[0]&#39;을 통해 가능하며, 마지막 원소의 호출은 &#39;member_number[999]&#39;를 통해 가능합니다.</p>
<h2 id="배열의-초기화">배열의 초기화</h2>
<h3 id="배열-선언-후-초기화">배열 선언 후 초기화</h3>
<pre><code class="language-c">int array[3];    //배열 크기 : 3

array[0] = 1;    //배열의 첫번째 원소
array[1] = 2;    //배열의 두번째 원소
array[2] = 3;    //배열의 세번째(마지막) 원소</code></pre>
<h3 id="배열-선언-시-초기화">배열 선언 시 초기화</h3>
<pre><code class="language-c">int array[3] = {1,2,3};        //배열 선언과 동시에 초기값 할당
int array[] = {1,2,3};        //배열 크기 생략시 원소의 수에따라 자동으로 크기를 지정합니다.
int array[3] = {1,2,};        //배열 크기보다 적은 수의 원소를 입력하면, 처음부터 순서대로 할당 후, 나머지는 0으로 초기화합니다.
int array[3] = {0};            //배열의 모든 원소의 초기값을 0으로 할당합니다.
int array[3] = {1,2,3,4};    //선언한 배열의 크기를 초과하므로 에러가 발생합니다.
int array[3] = {1,,3};        //끝 이외의 원소 자리에 공백을 두면 에러가 발생합니다.</code></pre>
<h2 id="배열의-사용">배열의 사용</h2>
<pre><code class="language-c">int array[5] = {1,2,3,4,5};

printf(&quot;%d\n&quot;, array[2]);

for(int i=0; i&lt;5; i++){
    printf(&quot;%d &quot;, array[i]);
}</code></pre>
<pre><code>3
1 2 3 4 5</code></pre><h1 id="다차원-배열">다차원 배열</h1>
<p>2차원 이상의 배열을 &#39;<strong>다차원 배열(multidimensional array)</strong>&#39;이라고 합니다.</p>
<h2 id="2차원-배열">2차원 배열</h2>
<p><code>자료형 배열명[행 수][열 수];</code>의 형태로, &#39;(행 수)x(열 수)&#39;개의 원소를 가집니다.</p>
<pre><code class="language-c">int array[2][3] = {1,2,3,4,5,6};
int array[2][3] = {{1,2,3},{4,5,6}};
int array[2][3] = {{1,2,3},
                   {4,5,6}};</code></pre>
<p>위와 같은 형태로 초기화가 가능합니다.</p>
<pre><code class="language-c">int array[2][3] = {1,2,3,4,5,6};

for(int i=0; i&lt;2; i++){
    for(int j=0; j&lt;3; j++){
        printf(&quot;%d &quot;, array[i][j]);
    }
    printf(&quot;\n&quot;);
}

printf(&quot;%d\n&quot;, array[0][2]);
printf(&quot;%d\n&quot;, array[1][2]);</code></pre>
<pre><code>1 2 3
4 5 6
3
6</code></pre><h2 id="3차원-배열">3차원 배열</h2>
<p><code>자료형 배열명[면 수][행 수][열 수];</code>의 형태로, &#39;(면 수)x(행 수)x(열 수)&#39;개의 원소를 가집니다.</p>
<pre><code class="language-c">int array[2][2][3] = {{{1,2,3},{4,5,6}},
                     {{7,8,9},{10,11,12}}};</code></pre>
<p>위와 같은 형태로 초기화가 가능하며, 2차원 배열처럼 다른 형태로도 초기화가 가능합니다.</p>
<pre><code class="language-c">int array[2][2][3] = {{{1,2,3},{4,5,6}}, {{7,8,9},{10,11,12}}};

for(int i=0; i&lt;2; i++){
    for(int j=0; j&lt;2; j++){
        for(int k=0; k&lt;3; k++){
            printf(&quot;%d &quot;, array[i][j][k]);
        }
        printf(&quot;\n&quot;);
    }
    printf(&quot;\n&quot;);
}

printf(&quot;%d\n&quot;, array[0][0][2]);
printf(&quot;%d\n&quot;, array[0][1][2]);
printf(&quot;%d\n&quot;, array[1][0][2]);
printf(&quot;%d\n&quot;, array[1][1][2]);</code></pre>
<pre><code>1 2 3 
4 5 6

7 8 9
10 11 12 

3
6
9
12</code></pre><h1 id="char형-배열과-문자열">char형 배열과 문자열</h1>
<p>C에서는 따로 문자열(string)이라는 자료형이 없으므로 &#39;char형 배열&#39;이나 &#39;포인터&#39;를 사용해야합니다.
char형 배열은 문자열로 사용시 <code>char 배열명[문자열 길이+1];</code>의 형태로 사용합니다. 문자열 길이보다 1이 크게 할당하는 이유는 배열의 마지막 원소로 &#39;null 문자(\0)&#39;를 사용하여 문자열의 끝을 나타내기 때문입니다.
아래처럼 선언하고 초기화할 수 있으며, 문자열은 큰따옴표(&quot;&quot;)로 묶어줍니다.</p>
<pre><code class="language-c">char name[12] = &quot;hello world&quot;;
char name[] = &quot;hello world&quot;;
char name[12] = {&#39;h&#39;,&#39;e&#39;,&#39;l&#39;,&#39;l&#39;,&#39;o&#39;,&#39; &#39;,&#39;w&#39;,&#39;o&#39;,&#39;r&#39;,&#39;l&#39;,&#39;d&#39;,&#39;\0&#39;};
char name[] = {&#39;h&#39;,&#39;e&#39;,&#39;l&#39;,&#39;l&#39;,&#39;o&#39;,&#39; &#39;,&#39;w&#39;,&#39;o&#39;,&#39;r&#39;,&#39;l&#39;,&#39;d&#39;,&#39;\0&#39;};</code></pre>
<pre><code class="language-c">char name[12] = &quot;hello world&quot;;

printf(&quot;%s\n&quot;, name);

for(int i=0; i&lt;12; i++){
    printf(&quot;%c&quot;, name[i]);
}
printf(&quot;\n&quot;);

char Name[12] = {&#39;h&#39;,&#39;e&#39;,&#39;l&#39;,&#39;l&#39;,&#39;o&#39;,&#39; &#39;,&#39;w&#39;,&#39;o&#39;,&#39;r&#39;,&#39;l&#39;,&#39;d&#39;,&#39;\0&#39;};

printf(&quot;%s\n&quot;, Name);

for(int i=0; i&lt;12; i++){
    printf(&quot;%c&quot;, Name[i]);
}</code></pre>
<pre><code>hello world
hello world
hello world
hello world</code></pre>]]></description>
        </item>
        <item>
            <title><![CDATA[함수]]></title>
            <link>https://velog.io/@giraffe_/%ED%95%A8%EC%88%98</link>
            <guid>https://velog.io/@giraffe_/%ED%95%A8%EC%88%98</guid>
            <pubDate>Sat, 05 Mar 2022 10:30:28 GMT</pubDate>
            <description><![CDATA[<p>&#39;<strong>함수</strong>&#39;는 특정한 기능을 수행하도록 설계된 독립적인 프로그램입니다. C 프로그램은 이런 함수들로 구성되고, 이 함수들이 정해진 실행 순서에 따라 실행됩니다. C 프로그램은 전체의 실행 내용을 몇개의 모듈(module)로 분류하고 각각의 모듈에 해당하는 실행 내용을 기술한 함수를 작성하여 실행 순서에따라 그 함수들을 차례로 호출 및 실행합니다. 이렇게 모듈 단위로 함수를 작성하면 &#39;수정이 용이&#39;해지고, &#39;유지 관리가 쉬워&#39;지며, &#39;함수를 재사용함으로써 코드 중복을 최소화&#39;합니다.</p>
<blockquote>
<p>모듈(module) : 프로그램의 일부분을 의미하며, 하나의 함수나 여러 함수와 변수들의 집합입니다. 하나의 파일도 모듈이 될 수 있습니다. 이러한 모듈은 특정 기능을 가지고 나누어진 하나의 독립적인 프로그램 코드의 단위입니다.</p>
</blockquote>
<h1 id="표준-함수">표준 함수</h1>
<p>&#39;<strong>표준 함수</strong>&#39;는 C에서 자체적으로 제공하는 함수이며, &#39;<strong>표준 라이브러리</strong>&#39;라는 이름으로 제공됩니다. 앞서 사용했던 printf() 함수는 &#39;표준 입출력 함수&#39;이며, 이 외에도 수학 연산 관련 기능이있는 &#39;수학 함수&#39; 등 수많은 표준 함수가 존재합니다.
표준 함수를 사용하려면 그 표준 함수의 양식에 해당하는 &quot;<strong>함수 원형(prototype)</strong>&#39;과 &#39;<strong>실체</strong>&#39;를 알아야합니다. C에서 함수원형은 &#39;<strong>헤더 파일</strong>&#39;에 정의되어있고, 실체는 &#39;<strong>라이브러리 파일</strong>&#39;에 수록되어있습니다. 예를 들어 printf() 함수의 원형은 <code>int printf(const char *format, ...);</code>로, &#39;stdio.h&#39;라는 헤더 파일에 선언되어있고, 실체는 &#39;링킹(linking)&#39; 과정에서 라이브러리 파일에서 읽어와서 프로그램에 연결시켜줍니다. 따라서 해당 함수를 사용하기위해서는 함수 원형이 선언되어있는 헤더 파일을 &#39;#include&#39;를 통해 전처리기가 처리할 수 있게끔 해주어야합니다.</p>
<h1 id="사용자-정의-함수">사용자 정의 함수</h1>
<p>printf()처럼 C 자체에서 사용하는 표준 함수 외에도 사용자가 필요에 따라서 코드의 중복을 막거나, 전체 길이가 길어지는 것을 막기위해 짧은 길이로 나누어 사용하기위해 &#39;<strong>사용자 정의 함수</strong>&#39;를 사용할 수 있습니다.</p>
<h2 id="함수의-정의">함수의 정의</h2>
<p>함수가 수행할 작업을 작성해놓은 코드를 &#39;<strong>함수의 정의</strong>&#39;라고 합니다.</p>
<pre><code class="language-c">반환_자료형 함수명(자료형 매개변수1, 자료형 매개변수2, ...)  //함수 헤더
{                                                      //함수 시작
    함수 내용
}                                                      //함수 끝
</code></pre>
<h3 id="함수-헤더">함수 헤더</h3>
<h4 id="반환-자료형return-type">반환 자료형(return type)</h4>
<ul>
<li>함수에서 계산된 결과 값을 호출한 함수에 되돌려줄 때 사용할 자료형입니다.</li>
<li>C에서 사용 가능한 모든 자료형을 사용할 수 있습니다.</li>
<li>생략 가능하며, 생략시 int로 취급합니다.</li>
<li>반환값이 없다면 &#39;void&#39;형으로 선언합니다.
ex) <code>void print_hello(int count){...}</code></li>
</ul>
<h4 id="함수명">함수명</h4>
<ul>
<li><a href="https://velog.io/@giraffe_/C-%EA%B0%9C%EC%9A%94#%EB%AA%85%EC%B9%AD"><em>명칭 작성 규칙</em></a> 에 맞게 작성해야하며, 의미있는 이름으로 짓습니다.</li>
</ul>
<h4 id="자료형과-매개변수">자료형과 매개변수</h4>
<ul>
<li>자료형은 매개변수의 자료형입니다.</li>
<li>매개변수는 호출한 함수에서 해당 함수에 자료를 넘겨줄 때 사용합니다.</li>
<li>함수 내용 작성시 매개변수를 해당 함수의 변수처럼 사용합니다.</li>
<li>매개변수가 여러개이면 콤마로 구분합니다.</li>
<li>매개변수가 없으면 괄호에 void를 적어주거나 생략합니다.</li>
</ul>
<h3 id="함수-내용">함수 내용</h3>
<p>함수가 수행할 명령문을 작성해줍니다.</p>
<pre><code class="language-c">int main(){            //int형을 반환하며 함수명은 &#39;main&#39;이고 매개변수가 없으므로 &#39;void&#39;를 작성해주거나, 이처럼 생략 가능합니다. 
    명령문;

    ...

    명령문n;

    return 0;        //main 함수의 반환형이 int이므로 &#39;return&#39;을 사용하여 정수를 반환합니다.
}</code></pre>
<p>위는 일반적인 &#39;main&#39; 함수의 형태입니다.
&#39;return&#39; 부분에서 &#39;0&#39;을 반환해주었는데, 반환값이 이처럼 0인 경우 시스템은 프로그램이 에러없이 정상 종료되었다고 판단합니다. 다른 함수와 달리 <strong>main 함수의 종료는 프로그램의 종료</strong>이며, <strong>main 함수의 반환값은 시스템으로 전달</strong>됩니다.</p>
<blockquote>
<p>return : return문은 함수값을 반환할 때 사용합니다. 함수안에서 여러번 작성할 수도 있지만 한번이라도 return문이 실행되면 해당 함수는 종료됩니다. 반환값은 수식을 사용할 수도있으며, 함수의 반환형이 void라면 <code>return;</code>으로 적어줍니다.</p>
</blockquote>
<h2 id="함수의-원형-선언과-사용">함수의 원형 선언과 사용</h2>
<pre><code class="language-c">#include &lt;stdio.h&gt;

int sum(int x, int y){    //함수 정의
    int s;
    s = x+y;

    return s;
}

int main(){
    int a=1, b=10, c;
    c = sum(a, b);        //함수 호출
    printf(&quot;%d&quot;, c);

    return 0;
}</code></pre>
<pre><code class="language-c">#include &lt;stdio.h&gt;

int sum(int x, int y);    //함수 원형(prototype) 선언

int main(){
    int a=1, b=10, c;
    c = sum(a, b);        //함수 호출
    printf(&quot;%d&quot;, c);

    return 0;
}

int sum(int x, int y){ //함수 정의
    int s;
    s = x+y;

    return s;
}</code></pre>
<p>위의 두가지 예시는 같은 동작을 하는 프로그램입니다. 하지만 위의 예시에는 따로 prototype을 선언하지않습니다.</p>
<p>C는 컴파일러가 위에서 아래로 내려오면서 코드를 읽는데, 위의 예시는 사용자 정의 함수가 main함수 위에 있기때문에 컴파일할 때 문제가 없습니다. 하지만 아래 예시는 사용자 정의 함수가 main함수 보다 아래에 있기 때문에 main 함수 안에서 사용자 정의 함수를 호출했을 때 컴파일러가 그 함수를 읽은 적이 없기 때문에 오류가 나게됩니다. 이는 함수도 변수처럼 사용 전에 미리 선언되어야 하기때문입니다. 따라서 사용자 정의 함수가 main 함수보다 아래에 있다면 아래 예시처럼 <strong>함수 원형(prototype)을 main 함수 전에 선언</strong>해주어야합니다.</p>
<h1 id="지역-변수와-전역-변수">지역 변수와 전역 변수</h1>
<ul>
<li><p>지역 변수(local variable) : 선언된 블럭이나 함수 안에서만 사용 가능합니다.</p>
</li>
<li><p>전역 변수(global variable) : 함수 밖이나 외부 파일에서 선언되어 프로그램 전체에서 사용 가능합니다.</p>
</li>
</ul>
<p>만약 같은 범위에서 전역 변수와 지역 변수의 이름이 같다면 지역 변수가 사용됩니다.</p>
<h1 id="기억-클래스">기억 클래스</h1>
<p>&#39;<strong>기억 클래스(storage class)</strong>&#39;는 변수를 기억공간의 특정 영역에 할당하는 방법입니다. C의 모든 변수는 자료형과 기억 클래스를 갖는데, 기억 클래스는 변수가 어디 사용될 것인지(사용 가능한 범위), 언제까지 존재할 것인지(life time)와 초기화 방법을 결정합니다.
형식은 <code>기억_클래스_예약어 자료형 변수명;</code>으로 평소 변수를 선언하던 형식에서 앞쪽에 &#39;기억 클래스 예약어&#39;만 붙여주면됩니다.</p>
<h2 id="자동-변수">자동 변수</h2>
<p>&#39;<strong>자동(auto) 변수</strong>&#39;는 보통 함수 실행시 만들어지고 종료시 기억공간에서 제거됩니다. 예약어는 &#39;<strong>auto</strong>&#39;이며 생략 가능합니다. 사용가능한 범위는 해당 블럭이나 함수 안이고, 기억공간 중 &#39;<strong>스택(stack)</strong>&#39;에 할당됩니다. &#39;<strong>지역(local) 변수</strong>&#39;가 해당되며, 자동 변수는 항상 쓰레기값을 가지므로 반드시 초기화가 필요합니다.</p>
<blockquote>
<p>쓰레기값(garbage value) : 의미없는 값을 의미합니다. 정적 변수같은 몇몇 경우를 제외하고 C에서는 변수 선언시 초기화를 따로 하지않으면 7212268(방금 쓰레기값을 확인해서 실제로 나온 값 입니다.) 등의 의미없는 아무런 값을 해당 변수에 할당합니다. 이는 특정 값을 할당하여 발생하는 시간 손실을 최소화하기위한 것 입니다.</p>
</blockquote>
<h2 id="정적-변수">정적 변수</h2>
<p>&#39;<strong>정적(static) 변수</strong>&#39;는 기억공간을 프로그램 종료시까지 계속 유지하며, 예약어는 &#39;<strong>static</strong>&#39;입니다. 정적인 기억공간을 할당받는데, 이는 stack같은 임시 기억공간이 아닌 일반적인 기억공간을 의미합니다. 따라서 함수 종료나 블럭 밖에서도 값이 계속 유지되며, 모든 &#39;<strong>전역(global) 변수</strong>&#39;가 이에 포함됩니다. 정적 변수는 자동 변수와 달리 컴파일할 때 한번 기억공간을 할당하고 초기값(특별한 지정이 없으면 0)을 부여합니다.
정적 변수는 전역 변수의 특징을 가지면서 선언된 지역에서만 접근이 가능하며, 변수값은 프로그램 실행 중 계속 유지되고, 전역 변수와 달리 &#39;extern&#39;으로 다른 파일에서 참조 불가합니다.</p>
<pre><code class="language-c">#include &lt;stdio.h&gt;

static int g;                    //전역 변수 g

void increase();

int main(){
    for(int i=0; i&lt;5; i++){
        increase();
    }
}

void increase(){
    static int s;                //정적 변수 s
    auto int a=0;                //자동 변수 a

    g++, s++, a++;

    printf(&quot;static g : %d, static s : %d, auto a : %d\n&quot;, g, s, a);
}</code></pre>
<pre><code>static g : 1, static s : 1, auto a : 1
static g : 2, static s : 2, auto a : 1
static g : 3, static s : 3, auto a : 1
static g : 4, static s : 4, auto a : 1
static g : 5, static s : 5, auto a : 1</code></pre><h2 id="외부-변수">외부 변수</h2>
<p>&#39;<strong>외부 변수</strong>&#39;는 함수 밖에서 선언되어 프로그램 종료시까지 값이 유지되며 초기값은 &#39;0&#39;입니다. 예약어는 &#39;<strong>extern</strong>&#39;을 사용하며, 외부 변수는 다른 파일에서 선언된 변수의 값을 참조할 수 있습니다. 정적 변수와 마찬가지로 기억공간은 일반 기억공간을 할당 받으며, 컴파일 시 초기화됩니다.</p>
<h2 id="레지스터-변수">레지스터 변수</h2>
<p>&#39;<strong>레지스터(register) 변수</strong>&#39;는 CPU 안의 레지스터에 자료를 저장할 때 사용합니다. 레지스터 변수를 사용하는 이유는 실행 속도 향상을 위해서인데, 레지스터의 속도가 기억장치보다 빠르기 때문입니다. 자동 변수와 동일한 속성을 가지며, 예약어는 &#39;<strong>register</strong>&#39;이고, 전역 변수로는 선언할 수 없습니다. 레지스터의 용량을 넘는 크기의 자료형으로는 사용할 수 없고, 기억공간에 저장되는 것이 아니므로 포인터로 활용할 수 없습니다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[반복 제어문과 기타 제어문]]></title>
            <link>https://velog.io/@giraffe_/%EB%B0%98%EB%B3%B5-%EC%A0%9C%EC%96%B4%EB%AC%B8%EA%B3%BC-%EA%B8%B0%ED%83%80-%EC%A0%9C%EC%96%B4%EB%AC%B8</link>
            <guid>https://velog.io/@giraffe_/%EB%B0%98%EB%B3%B5-%EC%A0%9C%EC%96%B4%EB%AC%B8%EA%B3%BC-%EA%B8%B0%ED%83%80-%EC%A0%9C%EC%96%B4%EB%AC%B8</guid>
            <pubDate>Thu, 03 Mar 2022 14:47:28 GMT</pubDate>
            <description><![CDATA[<h1 id="반복-제어문">반복 제어문</h1>
<p>&#39;<strong>반복 제어문</strong>&#39;은 지정된 명령문을 조건이 참인 동안 반복하여 계속 수행하는 제어문입니다.</p>
<h2 id="for문">for문</h2>
<p>&#39;<strong>for문</strong>&#39;은 반복 횟수가 정해져있는 경우에 사용합니다.</p>
<pre><code class="language-c">for(초기식; 조건식; 증감식){
    명령문;
}</code></pre>
<ul>
<li>&#39;<strong>초기식</strong>&#39;은 최초 for문 실행시 한번만 수행되며, 카운트하기위해 조건식에 사용될 변수의 값을 초기화합니다. </li>
<li>&#39;<strong>조건식</strong>&#39;은 매 루프마다 확인하면서 조건이 참이면 명령문을 수행하고, 거짓이면 for문을 종료하여 중괄호 밖으로 빠져나옵니다.</li>
<li>&#39;<strong>증감식</strong>&#39;은 초기식의 변수 값을 증가시키거나 감소시키는 용도로 사용합니다.</li>
</ul>
<blockquote>
<div align="center"><img src="https://images.velog.io/images/giraffe_/post/0af8ac32-f81e-44c6-a1d5-f551511247e1/image.png" width="50%"></div>
</blockquote>
<pre><code class="language-c">int i;
for(i=1; i&lt;=5; i++){
    printf(&quot;i의 값 : %d\n&quot;, i);
}</code></pre>
<pre><code>i의 값 : 1
i의 값 : 2
i의 값 : 3
i의 값 : 4
i의 값 : 5</code></pre><p>위의 예시를 보면 for문 최초 실행시 한번 수행되는 초기식에서 i의 값을 1로 초기화합니다.
그리고 조건식의 조건과 비교해서 i는 현재 1로, 5보다 작거나 같으므로 참이되어 for문의 명령문을 실행해서 printf()에 의해 &#39;i의 값 : 1&#39;이 출력됩니다.
그리고 증감값 계산식에 의해 i는 1 증가하므로 2가됩니다.
그리고 조건식의 조건과 비교해서 i는 현재 2로, 5보다 작거나 같으므로 참이되어 for문의 명령문</p>
<p>...</p>
<p>을 실행해서 printf()에 의해 &#39;i의 값 : 5&#39;가 출력됩니다.
그리고 증감값 계산식에 의해 i는 1 증가하므로 6이됩니다.
그리고 조건식의 조건과 비교해서 i는 현재 6으로, &#39;5보다 작거나 같지않으므로&#39; 거짓이되어 for문을 빠져나온 뒤 다음 명령문을 다시 순차적으로 수행합니다.</p>
<p>이렇게 반복 구조(loop)는 같은 명령문을 계속 수행합니다. 다만 영원히 반복할 수는 없기에 for문에서는 조건식과 증감식을 이용하여 종료조건을 주게되며, 조건을 충족시 종료되어 루프를 빠져나가는 것 입니다.</p>
<p>for문은 위처럼 기본 형태 외에도 다양한 형태로 사용이 가능합니다.</p>
<ul>
<li><p>초기식과 증감식 복수로 존재
: i와 j를 함께 초기화하고 증감식에서 i와 j에 각각 증감 조건을 줍니다.</p>
<pre><code class="language-c">for(i=1, j=1; i&lt;=10; i*=2, j+=3){...}</code></pre>
</li>
<li><p>조건식 생략
: 종료 조건을 조건식에서 부여하지않고 증감 조건만을 준 뒤, for문의 명령문에서 if문 등을 사용하여 종료 조건을 부여합니다.</p>
<pre><code class="language-c">for(i=1; ; i+=5){ //(세미콜론은 절대 생략하면 안됩니다.)
  if(i&lt;100) printf(&quot;아직 i의 값이 100보다 작습니다.\n&quot;);
  else break;
}</code></pre>
</li>
<li><p>증감식 생략
: 증감 조건을 증감식에서 부여하지않고 명령문에서 부여합니다.</p>
<pre><code class="language-c">for(i=1; i&lt;=1000;){
  ...

  i &lt;&lt;= 2;

  ...
}</code></pre>
</li>
<li><p>초기식, 조건식, 증감식 모두 생략
: 무한 루프로, 명령문에서 별다른 조건을 주어 빠져나가지않는 한, 무한 반복합니다.</p>
<pre><code class="language-c">for(;;){...}</code></pre>
</li>
</ul>
<p>for문은 if문과 마찬가지로 중첩하여 사용이 가능합니다.</p>
<pre><code class="language-c">for(int i=1; i&lt;=11; i++){
    for(int j=1; j&lt;=11-i; j++){
        printf(&quot; &quot;);
    }
    for(int k=1; k&lt;=i*2-1; k++){
        printf(&quot;*&quot;);
    }
    printf(&quot;\n&quot;);
}
for(int i=10; i&gt;=1; i--){
    for(int j=1; j&lt;=11-i; j++){
        printf(&quot; &quot;);
    }
    for(int k=1; k&lt;=i*2-1; k++){
        printf(&quot;*&quot;);
    }
    printf(&quot;\n&quot;);
}</code></pre>
<pre><code>          *
         ***
        *****
       *******
      *********
     ***********
    *************
   ***************
  *****************
 *******************
*********************
 *******************
  *****************
   ***************
    *************
     ***********
      *********
       *******
        *****
         ***
          *</code></pre><h2 id="while문">while문</h2>
<p>&#39;<strong>while문</strong>&#39;은 조건식이 참이면 계속 명령문을 반복해서 수행합니다. 조건식이 거짓이면 명령문을 수행하지않습니다.</p>
<pre><code class="language-c">while(조건식){
    명령문;
}</code></pre>
<blockquote>
<div align="center"><img src="https://images.velog.io/images/giraffe_/post/2bf7b350-391e-4971-ae7f-07c6cd6285e0/image.png" width="50%"></div>
</blockquote>
<p>while문은 초기식과 증감식이 그 자체에 명시되어있지않으므로 while문 전에 외부나, 내부의 명령문 부분에서 따로 조건을 주어야합니다.
앞서 for문에서 식이 생략된 경우 for문의 명령문에서 따로 조건을 주었던 것과 비슷합니다.</p>
<pre><code class="language-c">int i=1;                            //초기식
while(i&lt;=5){                        //조건식
    printf(&quot;i의 값 : %d\n&quot;, i);
    i++;                            //증감식
}</code></pre>
<pre><code>i의 값 : 1
i의 값 : 2
i의 값 : 3
i의 값 : 4
i의 값 : 5</code></pre><p>위의 예시처럼 초기식, 조건식, 증감식을 각각 사용해주면됩니다.
그리고 while문도 if문, for문처럼 중첩하여 사용이 가능합니다.</p>
<p>while문은 조건식이 참이면 루프가 구성됩니다. 그리고 참인 값은 0을 제외한 값이므로, 조건식에 0이 아닌값이 오게된다면 while문은 무한 루프가 구성됩니다. 따라서 의도적으로 무한 루프를 구성하였다면, 명령문에 break문, goto문 등을 사용하면 빠져나갈 수 있습니다.</p>
<h2 id="dowhile문">do~while문</h2>
<p>for문과 while문은 조건식을 먼저 검사한 뒤 참일때만 명령문을 실행하지만, &#39;<strong>do~while문</strong>&#39;은 먼저 명령문을 실행한 뒤 조건문을 검사하여 계속 반복할지를 결정합니다. 즉, <strong>적어도 한번은 명령문을 실행</strong>하게됩니다.</p>
<pre><code class="language-c">do{
    명령문;
}
while(조건식);        //반드시 세미콜론을 붙여야합니다.</code></pre>
<blockquote>
<div align="center"><img src="https://images.velog.io/images/giraffe_/post/25319e2e-909b-4394-8611-4097db14ef13/image.png" width="50%"></div>
</blockquote>
<pre><code class="language-c">do{
    printf(&quot;명령문 실행\n&quot;);
}
while(0);</code></pre>
<pre><code>명령문 실행</code></pre><p>위의 예시처럼 명령문을 무조건 한번은 수행하기 때문에 명령문이 한번은 실행되었지만 그 뒤에 while문의 조건식이 거짓이므로 더이상 반복되지않습니다.</p>
<pre><code class="language-c">do{
    printf(&quot;명령문 실행\n&quot;);
}
while(1);</code></pre>
<pre><code>명령문 실행
명령문 실행
명령문 실행
명령문 실행
명령문 실행
명령문 실행
명령문 실행

...</code></pre><p>하지만 위의 예시처럼 while문의 조건식이 참이라면 계속 반복하여 명령문을 실행하는데 위와 같은 경우, 따로 종료조건 없이 조건식이 1로 참이므로 무한 반복하게됩니다.</p>
<h1 id="기타-제어문">기타 제어문</h1>
<p>앞서 살펴본 선택 제어문과 반복 제어문 외에도 프로그램을 제어할 수 있는 제어문이 존재합니다.</p>
<h2 id="break문">break문</h2>
<p>&#39;<strong>break문</strong>&#39;은 루프 등에서 강제로 빠져나올 때 사용합니다.
단, 중첩된 루프 등에 속해있다면 모든 중첩에서 빠져나오는 것이 아닌, 현재 위치한 블럭에서만 빠져나옵니다.</p>
<pre><code class="language-c">for(int i=1; i&lt;=5; i++){
    for(int j=1; j&lt;=1000; j++){
        break;
        printf(&quot;j의 값 : %d\n&quot;, j);
    }
    printf(&quot;i의 값 : %d\n&quot;, i);
}</code></pre>
<pre><code>i의 값 : 1
i의 값 : 2
i의 값 : 3
i의 값 : 4
i의 값 : 5</code></pre><p>위의 예시는 for문이 중첩되어있고, i로 초기화된 루프의 명령문은 정상 실행되지만, j로 초기화된 루프의 명령문은 명령문 시작부에 break문으로 해당 블럭을 빠져나가게 되므로 break문 뒤의 명령문은 실행되지않습니다.</p>
<h2 id="continue문">continue문</h2>
<p>&#39;<strong>continue문</strong>&#39;은 루프 실행 중 주로 if문과 함께 사용하여 특정 조건을 만족시 <strong>해당 루프의 처음으로 돌아가 다시 반복</strong>합니다.</p>
<pre><code class="language-c">for(int i=1; i&lt;=10; i++){
    if(i%2==0){
        continue;
    }
    printf(&quot;%d\n&quot;, i);
}</code></pre>
<pre><code>1
3
5
7
9</code></pre><p>위의 예시는 for문을 수행하는데 명령문 처음에 if문의 조건에서 i를 2로 나눈 나머지가 0이면, 즉 짝수이면 continue문이 실행되어 continue문의 다음 부분은 실행되지않고 루프의 처음으로 돌아가 처음부터 다시 수행합니다. 따라서 짝수는 출력되지않고 if문의 조건에서 거짓이되는 홀수만 출력합니다.</p>
]]></description>
        </item>
    </channel>
</rss>