<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>woo_hyun_1.log</title>
        <link>https://velog.io/</link>
        <description>조급함보다는 꾸준하게</description>
        <lastBuildDate>Sat, 14 Jan 2023 16:49:08 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <image>
            <title>woo_hyun_1.log</title>
            <url>https://velog.velcdn.com/images/woo_hyun_1/profile/ef1036aa-0625-40fb-9a8c-ed80d8cb211d/image.jpeg</url>
            <link>https://velog.io/</link>
        </image>
        <copyright>Copyright (C) 2019. woo_hyun_1.log. All rights reserved.</copyright>
        <atom:link href="https://v2.velog.io/rss/woo_hyun_1" rel="self" type="application/rss+xml"/>
        <item>
            <title><![CDATA[2023 / 01 / 14 기록]]></title>
            <link>https://velog.io/@woo_hyun_1/2023-01-14-%EA%B8%B0%EB%A1%9D</link>
            <guid>https://velog.io/@woo_hyun_1/2023-01-14-%EA%B8%B0%EB%A1%9D</guid>
            <pubDate>Sat, 14 Jan 2023 16:49:08 GMT</pubDate>
            <description><![CDATA[<p>이번 3학년 2학기에 파란학기, 알고리즘 스터디, Javascript 스터디 진행, React와 ReactNative를 사용한 안드로이드 앱개발 등 많은 팀프로젝트 및 스터디에 참여할 수 있었던 값진 시간이었다. </p>
<p>하지만 학기가 끝나고 방학기간동안 인턴생활과 개발공부를 병행하다보니 시간분배에 대한 어려움을 겪었고, 공부를 하는 방향에 대한 의구심이 들었다.</p>
<p>그래서 평소에 개발에 대해 이야기를 자주 주고받던 친구에게 고민상담을 하면서 개발자로서 내 자신을 돌아보는 시간을 가졌다.</p>
<p>그래서 오늘 나누었던 친구와의 이야기 및 여러 Velog 글들을 보며 앞으로 내가 어떻게 공부에 임할지에 대한 목표와 개선점들을 적어보기로 하였다.</p>
<ol>
<li>나만의 강점과 색을 드러낼 수 있는 차별화된 개발자가 되자.(누구나 시간만 있다면 짤 수 있는 개발이 아니라, 다른 사람들이 대체할 수 없는 코드를 짜는 개발자가 되는 것)</li>
<li>항상 새로운 기술을 습득할 때는 사용하는 이유와 등장 배경, 내부 동작 원리들을 직접 몸소 느껴보면서 이해하자.</li>
<li>모르는 부분이나 기능이 생기면 구글링에서 멈추지말고 공식 문서를 보는 습관을 들이자.</li>
<li>항상 기록하는 습관을 들이자.</li>
<li>무엇이든 두려워하지 말고 일단 부딪혀보자.</li>
<li>생각에서 멈추지 말고 실천하는 사람이 되자.</li>
<li>여러 커뮤니티를 통해 다른 개발자들의 마인드와 성장과정을 배우자.</li>
<li>새로운 내용을 배울 때마다 정리하는 습관을 들이자.</li>
<li>여러가지를 모두 잘하겠다는 생각보다는 한 두가지를 하더라도 확실하게 배우자.</li>
<li>현재에 머무르고 안주하는 사람이 아니라 매번 자신을 돌아보고 성장하는 사람이 되자.</li>
</ol>
<p>늦게 개발을 시작한 만큼 내 자신을 인정하고 점차적으로 내 자신을 성장시켜보고자 한다.</p>
<p>위 내용들을 토대로 이번 한 해의 구체적인 목표는 크게 다음과 같다.</p>
<blockquote>
<ul>
<li>React와 Javascript에 대해 깊이있게 공부하기</li>
</ul>
</blockquote>
<ul>
<li>알고리즘 및 CS 관련 책 정독하기</li>
<li>코딩테스트 문제 주기적으로 풀기</li>
<li>티스토리 및 Velog에 꾸준하게 기록 남기기</li>
<li>꾸준하게 배우려고 노력하고 어떤 일이든 느슨해지지 말기</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[Recoil : 리액트 상태 관리 라이브러리]]></title>
            <link>https://velog.io/@woo_hyun_1/Recoil-%EB%A6%AC%EC%95%A1%ED%8A%B8-%EC%83%81%ED%83%9C-%EA%B4%80%EB%A6%AC-%EB%9D%BC%EC%9D%B4%EB%B8%8C%EB%9F%AC%EB%A6%AC</link>
            <guid>https://velog.io/@woo_hyun_1/Recoil-%EB%A6%AC%EC%95%A1%ED%8A%B8-%EC%83%81%ED%83%9C-%EA%B4%80%EB%A6%AC-%EB%9D%BC%EC%9D%B4%EB%B8%8C%EB%9F%AC%EB%A6%AC</guid>
            <pubDate>Tue, 08 Nov 2022 15:05:29 GMT</pubDate>
            <description><![CDATA[<h1 id="global-state-선언">Global state 선언</h1>
<pre><code class="language-js">import { atom } from &#39;recoil&#39;;

export default atom&lt;string | undefined&gt;({
  key: &#39;QuizDifficulty&#39;,
  default: undefined,
});
</code></pre>
<p>atom은 key와 default를 property로 가지고 있는 객체를 파라미터로 받는 함수이다.</p>
<p>key값에는 &quot;고유한 값&quot;이 들어가야 한다 ! (atom으로 만들 global state에 대해서 제각각 다른 고유 값을 가지고 있어야 함, key가 같다면 같은 state값으로 인식)</p>
<h1 id="컴포넌트-내에서-활용">컴포넌트 내에서 활용</h1>
<pre><code class="language-js">import { QuizDifficultyState } from &#39;src/state&#39;;
import { useRecoilState } from &#39;recoil&#39;;

const QuizDifficulty = () =&gt; {
  const [quizDifficulty, setQuizDifficulty] = useRecoilState(
    QuizDifficultyState,
  );
};</code></pre>
<p>useRecoilState라는 Hook을 사용하면 컴포넌트 내에서 global state를 활용할 수 있다.
useRecoilState의 파라미터로는 위에서 선언한 atom을 넣어준다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[노마드코더 카카오톡 클론코딩 7일차]]></title>
            <link>https://velog.io/@woo_hyun_1/%EB%85%B8%EB%A7%88%EB%93%9C%EC%BD%94%EB%8D%94-%EC%B9%B4%EC%B9%B4%EC%98%A4%ED%86%A1-%ED%81%B4%EB%A1%A0%EC%BD%94%EB%94%A9-7%EC%9D%BC%EC%B0%A8</link>
            <guid>https://velog.io/@woo_hyun_1/%EB%85%B8%EB%A7%88%EB%93%9C%EC%BD%94%EB%8D%94-%EC%B9%B4%EC%B9%B4%EC%98%A4%ED%86%A1-%ED%81%B4%EB%A1%A0%EC%BD%94%EB%94%A9-7%EC%9D%BC%EC%B0%A8</guid>
            <pubDate>Mon, 11 Jul 2022 04:27:10 GMT</pubDate>
            <description><![CDATA[<h1 id="states">States</h1>
<p>1) active : 대상을 클릭하고 있는 상태
2) hover : 마우스가 대상 위에 있을 때의 상태
3) focus : active와 비슷하다고 생각될 수 있는데, 키보드로 선택되었을때를 말한다 !
4) visited : 링크에만 적용된다. 그 링크에 방문했다면 그 안에 스타일이 적용이 된다.
5) focus-within : focuse된 자식을 가진 부모 엘리먼트의 상태를 말한다
즉, 위의 예시에서 form은 그 자식들인 input이 focuse가 되면 form의 모습을 바꾼다는 것이다</p>
<p>state들을 다른 엘리먼트와 연계해서 사용할 수도 있다</p>
<p>1) 부모의 state에 따라 조정</p>
<pre><code class="language-html">form:hover input {
background-color: slateblue;
}</code></pre>
<p>즉, form이 hover일경우 input의 백그라운드 컬러가 바뀌게된다.</p>
<p>부모의 state에 따라 자식의 state를 조정할 수 있다.</p>
<p>2) 부모와 자식의 state에 따라 조정</p>
<pre><code class="language-html">form:hover input:focus {
background-color: teal;
}</code></pre>
<p>form이 hover이면서 input이 focus된 경우에 백그라운드 컬러가 바뀌게 된다.</p>
<hr>
<h1 id="transition">Transition</h1>
<p>transition은 <u>다른 상태로의 변화</u>를 보여줌</p>
<ul>
<li>transition: (속성) (시간) (커브종류)</li>
</ul>
<blockquote>
<ol>
<li>state가 없는 요소에 붙어야 함. 
ex) a:hover{...}에 작성되면 안됨. a{...}안에 작성해야함.</li>
<li>transition은 변화를 보여주는 속성이기 때문에 변화시키고자 하는 요소를 꼭 반응속성 요소에 포함시켜야 함. 
a {...transition: color 5s each-in-out}을 넣어서 색변화를 잡고 싶다면 a:hover {color : black}처럼 a:hover 속성에 color 속성을 추가시켜야 함.</li>
</ol>
</blockquote>
<p>transition 은 상태에 따라 바뀌는 요소가 있을때 사용한다.</p>
<p>상태변화의 종류 : hover, active, focus, focus-within...</p>
<ul>
<li>ease-in function : 브라우저에게 변화하는 방법을 알려주는 역할</li>
<li>linear - 시작부터 끝까지 일정한 속도</li>
<li>ease-in - 시작과 끝이 빠름</li>
<li>ease-out - 시작과 끝이 느림</li>
<li>ease-in-out - 시작이 빠르고 끝이 느림</li>
<li>cubic-bezier(x, y, z, k)로 직접 설정할수도 있음 (<a href="https://matthewlein.com/tools/ceaser">https://matthewlein.com/tools/ceaser</a>)</li>
</ul>
<p>transition : all ~ : 변화 요소를 한번에 다룬다.</p>
<ul>
<li>transition을 특정한 요소에 다른 속도로 주고 싶으면 ,(쉼표)를 통해 따로 따로 transition을 줄 수 있다.</li>
</ul>
<p>ex)transition : color 1s ease-in-out, border-radius 2s ease-out;</p>
<p>transition은 root(기본 요소)에 들어가야 변화하고 되돌아오는 과정을 거친다.(state에 존재하면 X)</p>
<hr>
<h1 id="transformation">Transformation</h1>
<p>transformation: 말 그대로 한 요소를 변형시킬 수 있음.</p>
<p>border-radius에 50%를 주면 원이 됨.</p>
<blockquote>
<p>rotateX/Y/Z(각도deg) : 해당 요소를 3d상에서 각 축에 따라 회전
scale(숫자) : 해당 요소를 숫자배만큼 크기를 조정
translateX/Y/Z : 해당 요소를 3d상에서 각 축으로 이동</p>
</blockquote>
<ul>
<li>transformation은 한 요소를 transform(변형)시킬 수 있다.</li>
<li>border-radius에 50%를 준다면 원이 된다.</li>
<li>translate은 transformation을 적용 시키긴 하지만, 다른 형제(sibling)을 변화시키진 않는다.
→ transformation은 box element를 변형시키지 않는다.
→ margin, padding이 적용되지 않는다. 일종의 3D transformation이기 때문이다.
→ margin, padding을 위해서 translateX, translateY를 사용하지 않는다.</li>
<li>transform과 transition을 조합하면 더 역동적인 애니메이션을 만들 수 있다.</li>
<li>CSS 3D는 GPU로 돌아가므로, 3D 작업을 할 수 있다.</li>
</ul>
<hr>
<h1 id="animation">Animation</h1>
<p>@keyframes 이름{} 으로 만든 후 안에 어디서부터 어디까지 애니메이션을 만들지 선택.</p>
<pre><code class="language-html">&lt;style&gt;
    @keyframes superSexyCoinFlip {
        from {
          transform: rotateX(0);
        }
        to {
          transform: rotateX(360deg);
        }
      }
&lt;/style&gt;</code></pre>
<p>from{} to{} 사용.</p>
<blockquote>
<p>사용방법 : 애니메이션을 사용하고 싶은 요소 안에 <u>animation: (애니메이션 이름) (시간) (ease-in funtion) (infinite 여부)</u></p>
</blockquote>
<pre><code class="language-html">img {
  animation: superSexyCoinFlip 3s ease-in-out infinite;
}</code></pre>
<ul>
<li><p>infinite 추가시 무한으로 반복</p>
</li>
<li><p>from to 말고, 1,2,3,4,5...10 혹은 0% 25% 50% 75% 100% 같이 여러 단계로 나뉘어 애니매이션을 만들 수 있다.</p>
</li>
<li><p>다른 property들도 애니매이션으로 만들 수 있다. 꼭 transform만 써야하는 건 아니지만, transform을 쓰는걸 권한다. 일부 property는 애니매이션이 잘 안되기 때문이다.</p>
</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[노마드코더 카카오톡 클론코딩 6일차]]></title>
            <link>https://velog.io/@woo_hyun_1/%EB%85%B8%EB%A7%88%EB%93%9C%EC%BD%94%EB%8D%94-%EC%B9%B4%EC%B9%B4%EC%98%A4%ED%86%A1-%ED%81%B4%EB%A1%A0%EC%BD%94%EB%94%A9-6%EC%9D%BC%EC%B0%A8</link>
            <guid>https://velog.io/@woo_hyun_1/%EB%85%B8%EB%A7%88%EB%93%9C%EC%BD%94%EB%8D%94-%EC%B9%B4%EC%B9%B4%EC%98%A4%ED%86%A1-%ED%81%B4%EB%A1%A0%EC%BD%94%EB%94%A9-6%EC%9D%BC%EC%B0%A8</guid>
            <pubDate>Sun, 10 Jul 2022 10:01:24 GMT</pubDate>
            <description><![CDATA[<h1 id="fixed">Fixed</h1>
<p>position fixed를 이용하면 스크롤해도 항상 제자리에 머무른다.</p>
<p>처음 만들어진 자리에 고정 되어있다. 하지만 top, left, right, bottom 중 하나만 수정해도 서로 다른 레이어에 위치하게되어 원래 위치가 무시된다.</p>
<p>positon fixed를 이용하면 가장 위의 레이어에 위치하게 된다.</p>
<hr>
<h1 id="relative-absolute">Relative Absolute</h1>
<blockquote>
<ol>
<li>position: static (default) - 박스를 처음 위치한 곳에 두는 것</li>
<li>position: fixed - 처음에 위치한 자리에서 화면의 스크롤에 상관없이 고정되는 것, top,bottom, left, right 속성을 줘서 고정된 위치 이동시킬 수 있음. 단 이동이 되면 가장 위의 새 레이어에 놓이게됨</li>
<li>position : relative - 박스가 처음 위치한 곳을 기준으로 이동,
top,bottom, left, right 속성을 주면 첫 위치를 기준으로 이동됨</li>
<li>position : absolute - 가장 가까운 부모 엘리먼트에 position:relative를 추가한다면, 그 부모 기준으로 top,bottom,left,right이동하고/ 아닐시엔 body 기준으로 이동된다 </li>
</ol>
<p>-&gt; absolute, relative 가장 중요</p>
</blockquote>
<hr>
<h1 id="pseudo-selectors-1">Pseudo Selectors 1</h1>
<p>pseudo selectors: 좀 더 세부적으로 element를 선택해주는 것.</p>
<blockquote>
<p>현재 알고 있는 세가지 element 선택방법</p>
</blockquote>
<ol>
<li>tag {}</li>
<li>.class {}</li>
<li>#id {} </li>
</ol>
<h2 id="pseudo-selector--first-childlast-childnth-child">pseudo selector(: + first-child/last-child/nth-child)</h2>
<p>: 먼저 여러개의 div를 만들고, 맨 밑에 있는 div만 배경색을 다르게 하고 싶으면 div: last-child {background-color: red} 이런 식으로 씀. last child는 리스트에 있는 div들 중 마지막에 있는 것을 의미. first-child도 있음.</p>
<p>: 여러개의 span을 만들고, 원하는 span에만 배경색 집어넣는다고 했을 때도 사용가능. nth-child라고 쓰고 바로 뒤 괄호 안에 적용되길 원하는 span의 순서를 쓰는 것. nth-child(2), nth-child(4)...</p>
<p>: 여러개 span의 배경색이 번갈아서 나타나길 원할 때는 nth-child로 숫자를 다 쓰는게 아니라 nth-child(even) 이라고 쓰면 짝수번 째의 span에만 적용. 반대인 odd(홀수)도 가능.</p>
<p>: 2n이라고 쓰면 even이랑 똑같이 적용. 2n+1은 odd랑 똑같이 적용. n을 사용하는게 아주 유용함. 
ex) 5n, n+5, 3n+1 등.</p>
<p>id나 class를 따로 만드는것보다 이렇게 지정하는게 훨씬 좋은 방법이다.
왜냐하면 css에서만 선택을 하면 되므로 html코드를 고칠 필요가 없기 때문이다 !</p>
<hr>
<h1 id="combinators">Combinators</h1>
<blockquote>
<ol>
<li>parentselector childrenselector {property...}
=&gt; 부모 선택자 안의 모든 해당 자식 선택자를 선택하는 방법 ex) div span{}</li>
<li>parentselector &gt; childrenselector {...}
=&gt; 부모 선택자의 바로 밑의 자식 선택자를 선택하는 방법 ex) div &gt; span{}</li>
<li>parentselector + brotherselector
=&gt; 부모 선택자의 다음에 있는 형제 선택자를 선택하는 방법 ex) div + span{}</li>
</ol>
</blockquote>
<hr>
<h1 id="pseudo-selectors-2">Pseudo selectors 2</h1>
<h2 id="attribute-selectors속성-선택자">Attribute selectors(속성 선택자)</h2>
<p>tag[attribute = &quot;value&quot;] : 속성의 값이 &quot;value&quot;인 모든 tag 적용
tag[attribute ~= &quot;value&quot;] : 앞뒤에 공백이 있는 상태에서 &quot;value&quot; 값을 포함한 모든 tag 적용
tag[attribute *= &quot;value&quot;] : 앞뒤 공백 상관없이 &quot;value&quot; 값을 포함한 모든 tag 적용</p>
<p>tag: required {} required 속성을 가지고 있는 모든 tag 적용</p>
<p>tag: optional {} required 속성이 없는, 즉 optional 속성을 가지는 모든 tag 적용</p>
<pre><code class="language-html">&lt;!DOCTYPE html&gt;
&lt;html lang=&quot;kr&quot;&gt;
  &lt;head&gt;
    &lt;meta charset=&quot;utf-8&quot; /&gt;
    &lt;style&gt;
      body {
        height: 1000vh;
        margin: 50px;
      }
      div {
        width: 500px;
        height: 500px;
        background-color: wheat;
        position: relative;
      }
      #green2 {
        position: fixed;
        background-color: teal;
        opacity: 0.2;
      }
      #different {
        background-color: wheat;
      }
      .green {
        background-color: teal;
        position: absolute;
        top: 0px;
        left: 0px;
        height: 100px;
        width: 100px;
      }
      span {
        background-color: yellowgreen;
        padding: 5px;
        border-radius: 10px;
      }
      p span {
        color: white;
      }
      p ~ span {
        text-decoration: underline;
      }
      input {
        border: 1px solid slateblue;
      }
      input:required {
        border: 1px solid tomato;
      }
      input[placeholder~=&quot;Name&quot;] {
        background-color: brown;
      }
    &lt;/style&gt;
  &lt;/head&gt;
  &lt;body&gt;
    &lt;div&gt;
      &lt;span&gt;hello&lt;/span&gt;
      &lt;p&gt;I&#39;m Woohyun King &lt;span&gt;inside&lt;/span&gt;&lt;/p&gt;
      &lt;address&gt;hi&lt;/address&gt;
      &lt;span&gt;hello&lt;/span&gt;
      &lt;form&gt;
        &lt;input type=&quot;text&quot; placeholder=&quot;First Name&quot; /&gt;
        &lt;input type=&quot;text&quot; placeholder=&quot;Second Name&quot; /&gt;
        &lt;input type=&quot;password&quot; required placeholder=&quot;password&quot; /&gt;
      &lt;/form&gt;
    &lt;/div&gt;
  &lt;/body&gt;
&lt;/html&gt;</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[노마드코더 카카오톡 클론코딩 5일차]]></title>
            <link>https://velog.io/@woo_hyun_1/%EB%85%B8%EB%A7%88%EB%93%9C%EC%BD%94%EB%8D%94-%EC%B9%B4%EC%B9%B4%EC%98%A4%ED%86%A1-%ED%81%B4%EB%A1%A0%EC%BD%94%EB%94%A9-5%EC%9D%BC%EC%B0%A8</link>
            <guid>https://velog.io/@woo_hyun_1/%EB%85%B8%EB%A7%88%EB%93%9C%EC%BD%94%EB%8D%94-%EC%B9%B4%EC%B9%B4%EC%98%A4%ED%86%A1-%ED%81%B4%EB%A1%A0%EC%BD%94%EB%94%A9-5%EC%9D%BC%EC%B0%A8</guid>
            <pubDate>Sat, 09 Jul 2022 13:01:32 GMT</pubDate>
            <description><![CDATA[<ul>
<li>padding은 margin과 반대 개념이다.</li>
<li>padding은 box의 경계로부터 &#39;안쪽&#39;에 있는 공간이다.</li>
<li>값의 개수에 따라 적용되는 방향은 margin과 동일하다.</li>
<li>여러 div를 생성했을 때 &#39;id&#39;를 이용하여 div들을 구분할 수 있고, 각각 다른 속성을 적용시킬 수 있다.</li>
<li>CSS로 first div에 속성을 적용 시킬 땐, #first {}</li>
<li>이는 body, span 등에서도 마찬가지다.</li>
<li>CSS 코드의 id명은 HTML 코드에서 썼던 id명과 같아야 한다.</li>
</ul>
<hr>
<p> border: 말 그대로 box의 경계</p>
<ul>
<li>border 종류는 많은데 다 못생겨서 거의 한 종류의 border만 씀</li>
<li>border : 굵기(line-width)/종류(style)/색상(color)</li>
<li>style 종류는 solid가 실선, dashed가 점선</li>
<li>inline과 block 모두 적용됨</li>
</ul>
<p>모든 요소에 border 주고 싶으면 특수문자 별을 이용. 별은 전체를 뜻함.</p>
<pre><code class="language-html">&lt;!DOCTYPE html&gt;
&lt;html lang=&quot;kr&quot;&gt;
  &lt;head&gt;
    &lt;title&gt;The Woohyun Times&lt;/title&gt;
    &lt;!--&lt;link href=&quot;style.css&quot; rel=&quot;stylesheet&quot; /&gt; --&gt;
    &lt;!--external CSS--&gt;
    &lt;style&gt;
      /*inline CSS*/
      * {
        border: 2px solid black;
      }
      html {
        background-color: tomato;
      }
      body {
        margin: 20px;
        padding: 20px;
        background-color: aqua;
      }
      h1 {
        font-size: 50px;
        color: yellowgreen;
      }
      div {
        padding: 20px;
        border: 2px solid black;
      }
      span {
        background-color: aquamarine;
        border-style: dotted;
      }
      a {
        background-color: blueviolet;
      }
      p {
        background-color: blue;
      }
      #first {
        background-color: red;
        width: 150px;
        height: 150px;
      }
      #second {
        background-color: orange;
        width: 100px;
        height: 100px;
      }
      #third {
        background-color: yellow;
        width: 50px;
        height: 50px;
      }
      /*margin : box의 border(경계)의 바깥에 있는 공간*/
      /**/
    &lt;/style&gt;
  &lt;/head&gt;

  &lt;body&gt;
    &lt;div id=&quot;first&quot;&gt;
      &lt;div id=&quot;second&quot;&gt;
        &lt;div id=&quot;third&quot;&gt;&lt;span&gt;hello&lt;/span&gt;&lt;/div&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/body&gt;
&lt;/html&gt;</code></pre>
<hr>
<ul>
<li>span은 inline이기 때문에 높이와 너비를 가질 수 없으며, 그래서 위, 아래에 margin을 가질 수 없다.</li>
<li>하지만 padding은 사방에 가질 수 있다.</li>
<li>이와 같은 상황에 margin을 위, 아래에 적용하고 싶다면, inline 요소를 block으로 바꿔줘야 한다.</li>
<li>온점(.)은 class명이라는 뜻.</li>
<li>#tomato는 id=&quot;tomato&quot;/.tomato는 class=&quot;tomato&quot; 라는 의미</li>
<li>id명과 다르게 class명은 유일할 필요가 없다. 여러 요소들이 여러 개의 클래스를 동시에 쓸 수 있다.</li>
<li>class 속에는 btn과 tomato를 연이어 넣어 각각 다른 class 속성을 동시에 부여할 수도 있다.</li>
</ul>
<hr>
<p>block은 옆에 아무것도 올 수 없음</p>
<p>ㅡ&gt; inline : width, height가 무시돼서 무언가 추가하지 않는 이상 아무것도 안보임
ㅡ&gt; inline-block : 위 문제를 해결할 수 있어서 좋긴 한데, 반응형 디자인이 지원되지 않음(각 기기마다 만족하는 최적값을 일일히 찾아야 함
예 :10.5 ,10.4 ,10.3, ...... 10.01, ......10.08, 10.05,..10.05!)</p>
<p>ㅡ&gt; 이 문제를 해결할 수 있는게 &quot;flex&quot;</p>
<hr>
<p>inline block의 문제점을 해결하기 위해 &quot;flexbox&quot;를 생각해냈다.</p>
<p>flexbox 사용 규칙</p>
<ol>
<li>자식 엘리먼트에는 어떤 것도 적지 말아야 함.
자식 엘리먼트를 움직이게 하려면 부모 엘리먼트를 flex container로 만들어야 한다.</li>
<li>align-items : cross axis(교차축)에서 작용</li>
<li>justify-content : main axis(주축)에서 작용
flex-container가 height를 가지고 있지 않으면 align-items를 사용하더라도 위치가 바뀌지 않음.</li>
</ol>
<p>vh = viewport height</p>
<hr>
<ul>
<li>justify-content나 align-items의 default를 변경하기 위해선, &#39;flex-direction&#39;을 수정하면 된다.</li>
<li>flex-direction에는 두 가지 속성, column과 row가 있다.</li>
<li>display를 flex로 했을 때 default는 row이다. 따라서 flex-direction: column;을 주면 주축과 교차축이 반전된다.</li>
<li>원하는만큼 flex 부모-자식 엘리먼트를 만들어낼 수 있다.</li>
<li>flex-wrap: nowrap;을 통해 wrapping이 일어나지 않게 할 수 있다.</li>
<li>flexbox는 width값을 초기 사이즈로만 여기고, 모든 엘리먼트를 같은 줄에 있게 하기 위해 width를 바꾸기도 한다.</li>
<li>flex-direction: column-reverse; 밑에서 시작해서 위로 올라가게 한다.(마찬가지로 row-reverse도 있다.)</li>
<li>flex-wrap: wrap-reverse; 또한 있는데, 브라우저를 줄일 때, 엘리먼트가 겹쳐지는 위치가 역전된다.<pre><code class="language-html">&lt;!DOCTYPE html&gt;
&lt;html lang=&quot;kr&quot;&gt;
&lt;head&gt;
  &lt;meta charset=&quot;utf-8&quot; /&gt;
  &lt;style&gt;
    div {
      display: flex;
      justify-content: center;
      align-items: center;
      width: 50px;
      height: 50px;
      background-color: blueviolet;
    }
    body {
      height: 100vh;
      margin: 20px;
      display: flex;
      /*flex-direction: column;*/
      justify-content: space-evenly;
      align-items: center;
      flex-wrap: nowrap;
    }
    span {
      background-color: teal;
    }
    .btn {
      padding: 5px 10px;
      border-radius: 5px;
    }
    .tomato {
      background-color: tomato;
      color: white;
    }
    .teal {
      background-color: teal;
    }
  &lt;/style&gt;
&lt;/head&gt;
&lt;body&gt;
  &lt;span class=&quot;teal btn&quot;&gt;hello&lt;/span&gt;
  &lt;span class=&quot;tomato btn&quot;&gt;hello&lt;/span&gt;
  &lt;span class=&quot;teal btn&quot;&gt;hello&lt;/span&gt;
  &lt;span class=&quot;tomato btn&quot;&gt;hello&lt;/span&gt;
  &lt;span class=&quot;teal btn&quot;&gt;hello&lt;/span&gt;
  &lt;span class=&quot;tomato btn&quot;&gt;hello&lt;/span&gt;
  &lt;span class=&quot;teal btn&quot;&gt;hello&lt;/span&gt;
  &lt;div&gt;1&lt;/div&gt;
  &lt;div&gt;2&lt;/div&gt;
  &lt;div&gt;3&lt;/div&gt;
&lt;/body&gt;
&lt;/html&gt;</code></pre>
</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[노마드코더 카카오톡 클론코딩 4일차]]></title>
            <link>https://velog.io/@woo_hyun_1/%EB%85%B8%EB%A7%88%EB%93%9C%EC%BD%94%EB%8D%94-%EC%B9%B4%EC%B9%B4%EC%98%A4%ED%86%A1-%ED%81%B4%EB%A1%A0%EC%BD%94%EB%94%A9-4%EC%9D%BC%EC%B0%A8</link>
            <guid>https://velog.io/@woo_hyun_1/%EB%85%B8%EB%A7%88%EB%93%9C%EC%BD%94%EB%8D%94-%EC%B9%B4%EC%B9%B4%EC%98%A4%ED%86%A1-%ED%81%B4%EB%A1%A0%EC%BD%94%EB%94%A9-4%EC%9D%BC%EC%B0%A8</guid>
            <pubDate>Fri, 08 Jul 2022 11:16:07 GMT</pubDate>
            <description><![CDATA[<h2 id="스타일-언어-css-배우기">스타일 언어 css 배우기</h2>
<p>css를 html 페이지에 추가하는 두가지 방법</p>
<ul>
<li><ol>
<li>같은 html 파일에 html코드와 css코드를 놓는 방법
: head 파트에 &lt; style &gt; 태그를 사용해서 그 사이에 css 코드 입력하기<pre><code class="language-html">&lt;sytle&gt;&lt;/style&gt;</code></pre>
</li>
</ol>
</li>
<li><ol start="2">
<li>css와 html을 분리하는 방법(추천)
: css 파일(styles.css)을 만들어서 link 태그로 파일 연결하기(link 태그를 열고 href로 styles.css 값 주고 rel 속성으로 css 파일과 html 도큐먼트의 관계인 stylesheet 명시)<pre><code class="language-html">&lt;link herf=&quot;styles.css&quot; rel=&quot;stylesheet&quot;&gt;</code></pre>
: 따로 분리해서 만들면 여러 html 파일에 적용할 수 있어서 좋음</li>
</ol>
</li>
</ul>
<h2 id="css-코드-작성-세가지-규칙">css 코드 작성 세가지 규칙</h2>
<ul>
<li>html 코드를 가리키는 것을 selector 이라고 함. 그리고 selector의 텍스트 크기, 폰트 종류, 색상 등을 속성이라고 하는데 이것들을 {중괄호}를 사용해서 묶음.</li>
</ul>
<ol>
<li>selector을 사용해서 html의 어떤 태그를 가리킴</li>
<li>중괄호 열고 속성 적기</li>
<li>값 쓰기</li>
</ol>
<p>#html 태그 중에 h1 태그에 css 적용하기</p>
<ol>
<li>먼저 태그 이름이랑 동일하게 selector인 h1을 적고</li>
<li>중괄호 열고</li>
<li>속성 이름과 : 을 쓴 다음 Value를 줌</li>
<li>그리고 세미콜론;으로 닫아주면 한 줄 작성 완료</li>
</ol>
<ul>
<li>color, font-size(속성이름에는 띄어쓰기, _ , / 사용X), text-decoration
: 속성에 맞는 값 써주기</li>
</ul>
<hr>
<p>CSS는 Cascading Style Sheets. 
이때 C가 의미하는 cascading은 폭포같은, 계속되는, 연속되는 이라는 의미.</p>
<p>브라우저가 CSS코드를 읽을 때 위에 있는 코드부터 차례차례로 읽힘. 
즉, 마지막에 있는 코드가 가장 마지막에 적용됨.
-&gt; <u>코드의 순서가 결과에 영향 미침</u></p>
<hr>
<p>어떤 웹사이트든 거의 모든 요소들이 box로 이루어져 있음.</p>
<p>p,header, address와 같은 <strong>&quot;block(box)&quot;</strong>를 만들면 그 옆에 다른 요소가 올 수 없음.</p>
<p>span이나 link와 같은 <strong>&quot;inline&quot;</strong>은 바로 옆에 다른 요소들이 올 수 있음(가로로 쭉 적어짐)</p>
<p>div는 box고 span, link(a), code는 박스가 아님</p>
<blockquote>
<p>옆에 다른 요소 못 오는거 = block
다른 요소 올 수 있는 거 = inline(in the same line)</p>
</blockquote>
<p>inline에는 아주 작은 글이나 링크, 그림 등등이 속함. inline에 해당하는 것들은 많이 없음.</p>
<p>따라서 block이 아닌 inline 종류를 기억하는게 훨씬 편함. ex) span, a, img</p>
<hr>
<p>block을 inline으로 바꾸고 inline을 block으로 바꾸는 것이 가능한데, 그렇게 하는 것을 &#39;display&#39;속성이라고 한다.</p>
<p>기본적으로 span의 display 속성은 inline인데 이걸 display:block 으로 설정하면 block으로 변경됨.</p>
<p>다음으로 만들어둔 div의 display:lnline으로 속성을 inline으로 변경하면 div가 사라짐(div에 아무 컨텐츠도 없을 때).</p>
<p><u>Why? inline 요소는 높이와 너비를 가질 수 없음. block은 높이와 너비가 있음.</u></p>
<p>브라우저가 자동으로 적용하는 디자인 요소들이 많음.</p>
<blockquote>
<p>Block이 가지는 중요한 세 가지 요소</p>
</blockquote>
<ol>
<li>margin: box의 경계 바깥에 있는 공간</li>
</ol>
<ul>
<li>브라우저는 자동으로 8px만큼 margin을 주는게 디폴트값으로 설정돼있음.</li>
<li>margin 값을 0으로 주면 공간이 없어짐</li>
<li>margin-left, bottom, right 등 사방으로 다 값 줄 수 있음</li>
</ul>
<ol start="2">
<li>padding</li>
<li>border</li>
</ol>
<ul>
<li><p>인자의 개수에 따른 margin의 적용범위
1 value: 상하좌우
2 value: 수직(상/하), 수평(좌/우)
4 value: 상 우 하 좌 (시계방향)</p>
</li>
<li><p>collapsing margin(마진상쇄)
두 box의 border가 겹칠때 일어난다.
수직으로만 발생한다.
=&gt; padding 속성을 사용하여 해결할 수 있다.</p>
</li>
</ul>
<pre><code class="language-html">&lt;!DOCTYPE html&gt;
&lt;html land=&quot;kr&quot;&gt;
  &lt;head&gt;
    &lt;title&gt;The Woohyun Times&lt;/title&gt;
    &lt;!--&lt;link href=&quot;style.css&quot; rel=&quot;stylesheet&quot; /&gt; --&gt;
    &lt;!--external CSS--&gt;
    &lt;style&gt;
      /*inline CSS*/
      html {
        background-color: tomato;
      }
      body {
        background-color: beige;
        margin: 30px 50px 30px 50px;
      }
      h1 {
        font-size: 50px;
        color: yellowgreen;
      }
      div {
        margin: 50px 30px 50px 30px;
        height: 150px;
        width: 150px;
        background-color: whitesmoke;
      }
      span {
        background-color: aquamarine;
      }
      a {
        background-color: blueviolet;
      }
      p {
        background-color: blue;
      }
      /*margin : box의 border(경계)의 바깥에 있는 공간*/
      /**/
    &lt;/style&gt;
  &lt;/head&gt;

  &lt;body&gt;
    &lt;div&gt;&lt;/div&gt;
  &lt;/body&gt;
&lt;/html&gt;</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[노마드코더 카카오톡 클론코딩 3일차]]></title>
            <link>https://velog.io/@woo_hyun_1/%EB%85%B8%EB%A7%88%EB%93%9C%EC%BD%94%EB%8D%94-%EC%B9%B4%EC%B9%B4%EC%98%A4%ED%86%A1-%ED%81%B4%EB%A1%A0%EC%BD%94%EB%94%A9-3%EC%9D%BC%EC%B0%A8</link>
            <guid>https://velog.io/@woo_hyun_1/%EB%85%B8%EB%A7%88%EB%93%9C%EC%BD%94%EB%8D%94-%EC%B9%B4%EC%B9%B4%EC%98%A4%ED%86%A1-%ED%81%B4%EB%A1%A0%EC%BD%94%EB%94%A9-3%EC%9D%BC%EC%B0%A8</guid>
            <pubDate>Thu, 07 Jul 2022 14:49:32 GMT</pubDate>
            <description><![CDATA[<p>img tag : 인터넷의 이미지 뿐만 아니라 로컬의 이미지도 표시 가능. html 파일과 같이 있거나 혹은 다른 경로에 있다면 path notation 으로 파일 위치를 표시해주어야 함.</p>
<p>html 파일은 정해진 작성 형식과 문법이 있음.</p>
<p><strong>&lt; !DOCTYPE html &gt;</strong>로 현재 파일이 text파일이 아닌 html 파일이라는 것을 알려준다 !</p>
<p>html 문서는 크게 head와 body 두 부분으로 나누어진다.</p>
<blockquote>
<p>head : 웹사이트의 환경 설정, html 문서의 configuration 을 주로 설정함, html 문서에 대한 meta 정보들 ex)title tag</p>
</blockquote>
<blockquote>
<p>body : 웹사이트에서 contents 를 보여주는 부분, 브라우저 상에서 시각적으로 보여주는 요소는 body에 작성하여야 함</p>
</blockquote>
<p>meta는 부가적인 정보라는 뜻을 가지는 self closing tag 이며 meta 태그는 두개의 attribute(content/name)를 갖고 있다.</p>
<p>head 태그에 있는 것들은 보이지 않음</p>
<p><strong>&lt; meta charset=&quot;utf-8&quot; &gt;</strong> : 매우 중요. 브라우저에게 text를 어떻게 그려달라는지 말해줌.</p>
<p>한글이나 다른 특수문자가 있는 언어를 입력 할 때 브라우저가 그 문자들을 이해 못 할 때가 있다.</p>
<p>그래서 이 charset 메타 태그가 없으면 글자가 사이트에서 깨져보일 것이다. 꼭 잊지말고 기입하자.</p>
<p><strong>&lt; html lang=&quot;kr&quot; &gt;</strong> : html의 attribute lang(구글,네이버,bing 같은 검색엔진들에 도움을 준다, 우리 사이트에서 사용되는 언어가 무엇인지 말해주는 것이다. 주된 언어가 한국어인지 영어인지 검색엔진에게 알려주는 것이다.)</p>
<p>이 head 내의 작업들은 사이트의 정보를 브라우저에게 알려주는 용도인것이다. 최대한 명확하게 우리의 웹사이트가 무엇인지 브라우저에게 알려주는 것이다.(검색엔진이 이해 할 수 있게 정리해서 말해주는 것이다.)</p>
<p>head태그에 있는것 : 보이지않는 태그들로 사이트 설정을 하는 것. 브라우저에게 사이트가 어떻게 보여지는지, 구글이 어떻게 사이트를 바라보는지 이 모든게 head태그에 속해있다.</p>
<p>meta property=&quot;og:image&quot; 태그의 이미지는 카카오톡으로 공유될때 보여지는 이미지다.</p>
<hr>
<ul>
<li><p>html, css, javascript 관련 정보 검색할 때 마지막 부분에 ‘mdn’ 붙이기</p>
</li>
<li><p>mdn : Mozilla developer Network (firefox만든 회사에서 제공하는 web관련 정보 제공 사이트)</p>
</li>
<li><p>w3shool 사용은 지양함.</p>
</li>
<li><p>태그는 암기하지 말고 구글링 후 사용</p>
</li>
<li><p>ctrl + d : 태그이름 (시작, 끝) 동시에 수정</p>
</li>
</ul>
<hr>
<ol>
<li>&lt; form &gt; tag</li>
</ol>
<ul>
<li>form tag 안에 form의 양식을 만들어 줘야 함</li>
<li>양식 중에 제일 중요한 태그는 input tag(self-closing tag)</li>
<li>input은 type에 따라 동작 방식이 달라짐
: type=&quot;color&quot; 은 색 고를 수 있음
: type=&quot;password&quot; 비밀번호 칠 수 있음
: type=&quot;submit&quot; 전송 버튼 생김, 지금은 누르면 form이 어디로 보낼지 모르기 때문에 사이트가 새로고침됨
: type의 기본값은 text임
: type=&quot;file&quot; 파일 업로드 가능 (type이 file 인 경우에만 사용 가능한 accept라는 속성은 특정 파일의 유형들만 선택 가능하도록 만드는 기능, accept=&quot;.jpg, .pdf&quot; 이렇게 작성, 이미지면 다 괜찮으면 &quot;image/*&quot; 이렇게 뒤에 /* 붙임)</li>
<li>placeholder는 input이 가지는 또다른 attribute</li>
<li>value라는 속성으로 submit에 적혀지는 글자를 다른 걸로 바꿀 수 있음</li>
<li>disabled 속성 입력하면 해당 칸이나 버튼 작동 안되게 해줌</li>
<li>required 속성 입력하면 해당 칸 작성 안하면 안넘어감</li>
<li>minlength 최소 입력해야하는 글자 수 설정</li>
</ul>
<ol start="2">
<li>기본적인 html 구문</li>
</ol>
<ul>
<li>tagname -&gt; attrname=&quot;attrvalue&quot; -&gt; content I want -&gt; /tagname
: attrvalue를 넣어줄 때는 attribute 값이 많을 때, 값이 true나 false만 있을 때는 그냥 attrname만 적어도 무방함(required 같이)</li>
</ul>
<hr>
<ol>
<li>form을 더 괜찮게 만들기 위한 label 태그</li>
</ol>
<ul>
<li>label tag에는 question을 추가 가능</li>
<li>label은 input과 함께여야 작동됨. 같이 사용하는 방법은 label 태그에는 for이라는 속성을 적고 input 태그에는 id라는 속성을 적는데 두 속성의 값이 동일해야 함. profile photo라는 콘텐츠를 클릭하면 for과 같은 값을 가진 id를 들고있는 input을 작동시킴.</li>
</ul>
<ol start="2">
<li>type 유형</li>
</ol>
<ul>
<li>email, url 같은 값 넣으면 원하는 유형의 정보만 받을 수 있게 해줌</li>
<li>range는 범위 선택할 수 있음</li>
<li>date는 날짜 선택, 숫자만 입력 가능</li>
</ul>
<ol start="3">
<li>ID</li>
</ol>
<ul>
<li>body 안에 어떤 태그에도 id 속성 입력 가능. 왜냐하면 id는 unique identifier이기 때문.</li>
<li>태그 하나당 하나의 id만 가질 수 있고 그 값은 고유해야 함.</li>
<li>html은 뼈대. 나중에 css로 특정 스타일을 적용할 수 있는 이유는 id가 있기 때문. 나중에 css에서 &quot;website라는 id를 가진 input을 파란색으로 해줘&quot; 라고 입력해야 함. 따라서 id 값을 다른 태그에서 공유하면 안됨.</li>
</ul>
<hr>
<p>어떤 태그는 의미가 있고 어떤 태그는 의미가 없음.</p>
<ol>
<li>사용은 하지만 의미는 없는 태그</li>
</ol>
<ul>
<li><p>div tag(division): 분할, 구분, 경계선. 태그가 일자로 써지는걸 원치 않을 때 div를 사용하면 위아래로 배치됨. 구분하고 싶은 태그 영역을 div 태그로 감싸주기. div 태그의 기능은 있지만 document에서는 아무런 값이 없는 box.</p>
</li>
<li><p>span tag: p와 달리 짧은 텍스트 쓸 때 사용</p>
</li>
</ul>
<ol start="2">
<li>div를 대체할 수 있는 semantic tag (문서를 보기만해도 그 의미를 짐작할 수 있는 것)</li>
</ol>
<ul>
<li><p>header tag: head랑 헷갈리지 않기. div태그와 같은 박스 역할을 하지만 div와는 달리 header 태그는 안에 뭔가 적으면 그냥 읽기만 해도 이게 페이지의 헤더부분인지 바로 알 수 있음.</p>
</li>
<li><p>main tag: div에 id=&quot;main&quot; 이라고 작성해도 되지만, 더 알아보기 쉽게 main 태그를 사용해서 웹사이트의 메인 부분인것 나타냄</p>
</li>
<li><p>footer tag: 웹사이트의 꼬리말을 나타냄</p>
</li>
</ul>
<p><u>semantic tag 모두 div로 대체할 수 있지만 코드 이해하는데 오래걸림.</u> 
따라서 코드를 짤 때 &#39;semantic html&#39;로 작성하려고 노력해야 함.</p>
<hr>
<ul>
<li>visul studio code는 코드 작성이 잘못되면 빨간색으로 나타내준다.</li>
<li>atrribute 값은 항상 &quot;&quot; 큰 따옴표 안에 작성한다.</li>
<li>모든 태그는 id라는 arrtribute를 가질 수 있다.ex) image, paragraph. header, link...</li>
<li>반대로 src(source)라는 attribute는 모든 태그가 가질 수 있지 않다.</li>
<li>코드 자체에 의미가 부여된 semantic 태그를 잊지 말자.ex) header, navigation, footer...</li>
<li>semantic 태그로 코드를 작성 하는 것은 매우 중요하다. 작성된 코드들이 훨씬 더 보기 좋고, 좋은
프로그래머가 되기 위해서는 필수 사항이다.</li>
<li>header, main, footer, navigation, hgroup 등 &lt;&gt;속 태그들은 전부 container이다. 전부 div 태그로 대체 할 수 있다.</li>
<li>div 태그는 가장 통용적인 container이다. 대체가 가능하지만, 코드만 보고 어떤 의미인지 파악하기 위해서 semantic 태그를 쓰는 것이다.</li>
<li>모든 태그를 암기 할 필요는 없다. 필요할 때마다 문서를 찾아 적용하면 된다.</li>
</ul>
<pre><code class="language-html">&lt;!DOCTYPE html&gt;
&lt;!--브라우저에게 text파일이 아닌 html문서라는 것을 알려주는 코드--&gt;
&lt;html lang=&quot;kr&quot;&gt;
  &lt;!--html 코드--&gt;
  &lt;head&gt;
    &lt;!--웹 사이트 구조의 첫 번째 파트 : 웹사이트의 환경(웹사이트의 부가적인 정보), 즉 외부적으로 보여지지 않는 설정--&gt;
    &lt;link
      rel=&quot;shortcut icon&quot;
      sizes=&quot;16x16 32x32 64x64&quot;
      href=&quot;https://nomadcoders.co/m.svg&quot;
    /&gt;

    &lt;title&gt;Home - My first website&lt;/title&gt;

    &lt;meta charset=&quot;utf-8&quot; /&gt;
    &lt;!--브라우저에게 text를 어떻게 그려달라는지 말해줌--&gt;

    &lt;!--meta : 부가적인 정보를 나타내는 self closing tag--&gt;
    &lt;meta name=&quot;description&quot; content=&quot;This is my website&quot; /&gt;
    &lt;!--meta의 두 가지 attribute : name/content--&gt;
    &lt;!--description은 구글이 검색할 때 찾는 태그 --&gt;
    &lt;style&gt;
      h1 {
        color: blanchedalmond;
        text-decoration: underline;
        font-style: italic;
        font-weight: 800;
        font-size: 50px;
        /*css속성 이름에는 띄어쓰기, _, /사용 금지 */
      }
    &lt;/style&gt;
  &lt;/head&gt;

  &lt;body&gt;
    &lt;!--웹 사이트 구조의 두 번째 파트 : 외부에 보여지는 Content 설정--&gt;

    &lt;h1&gt;Hello, I&#39;m Woohyun King !&lt;/h1&gt;
    &lt;a href=&quot;https://www.instagram.com/woo_h.king/?hl=ko&quot;&gt;Go to my instagram&lt;/a&gt;
    &lt;img src=&quot;img/me.jpg&quot; /&gt;
    &lt;p&gt;I&#39;m a &lt;mark&gt;Ajou University&lt;/mark&gt; student.&lt;/p&gt;
    &lt;cite&gt;My major is computer engineering.&lt;/cite&gt;
    &lt;pre&gt;My age is 24.&lt;/pre&gt;
    &lt;p&gt;I live in &lt;strong&gt;Dongtan&lt;/strong&gt;.&lt;/p&gt;
    &lt;p&gt;My puppy&#39;s name is &lt;sub&gt;BBoDDo&lt;/sub&gt;.&lt;/p&gt;
    &lt;p&gt;2&lt;sup&gt;5&lt;/sup&gt;is 32.&lt;/p&gt;

    &lt;form&gt;
      &lt;div&gt;
        &lt;label for=&quot;first-name&quot;&gt;First Name&lt;/label&gt;
        &lt;input id=&quot;first-name&quot; required placeholder=&quot;Name&quot; type=&quot;text&quot; /&gt;
      &lt;/div&gt;

      &lt;div&gt;
        &lt;label for=&quot;last-name&quot;&gt;Last Name&lt;/label&gt;
        &lt;input id=&quot;last-name&quot; required placeholder=&quot;Last Name&quot; type=&quot;text&quot; /&gt;
      &lt;/div&gt;

      &lt;div&gt;
        &lt;label for=&quot;user-name&quot;&gt;User Name&lt;/label&gt;
        &lt;input
          id=&quot;user-name&quot;
          required
          disabled
          placeholder=&quot;User Name&quot;
          type=&quot;text&quot;
        /&gt;
      &lt;/div&gt;

      &lt;div&gt;
        &lt;label for=&quot;password&quot;&gt;Password&lt;/label&gt;
        &lt;input
          id=&quot;password&quot;
          required
          placeholder=&quot;Password&quot;
          minlength=&quot;8&quot;
          type=&quot;password&quot;
        /&gt;
      &lt;/div&gt;

      &lt;div&gt;
        &lt;input type=&quot;submit&quot; value=&quot;Create Account&quot; /&gt;
      &lt;/div&gt;

      &lt;div&gt;
        &lt;label for=&quot;profile&quot;&gt;Profile Photo&lt;/label&gt;
        &lt;input id=&quot;profile&quot; type=&quot;file&quot; accept=&quot;image/*&quot; /&gt;
      &lt;/div&gt;

      &lt;div&gt;
        &lt;label for=&quot;website&quot;&gt;Website&lt;/label&gt;
        &lt;input id=&quot;website&quot; required placeholder=&quot;url&quot; type=&quot;url&quot; /&gt;
      &lt;/div&gt;

      &lt;div&gt;
        &lt;label for=&quot;email&quot;&gt;Email&lt;/label&gt;
        &lt;input id=&quot;email&quot; required placeholder=&quot;email&quot; type=&quot;email&quot; /&gt;
      &lt;/div&gt;

      &lt;div&gt;
        &lt;input type=&quot;range&quot; /&gt;
      &lt;/div&gt;
      &lt;div&gt;
        &lt;input type=&quot;date&quot; /&gt;
      &lt;/div&gt;
      &lt;!--input : form 양식중에서 가장 중요한 self closing tag--&gt;
      &lt;!--id는 body안에 있는 어떠한 tag에도 넣을 수 있는 attribute, 고유 식별자--&gt;

      &lt;header&gt;
        &lt;h1&gt;Hello&lt;/h1&gt;
      &lt;/header&gt;
      &lt;main&gt;
        &lt;p&gt;Nice to meet you&lt;/p&gt;
      &lt;/main&gt;
      &lt;footer&gt;&amp;copy; 2022 N.C&lt;/footer&gt;
    &lt;/form&gt;
  &lt;/body&gt;
&lt;/html&gt;</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[노마드코더 카카오톡 클론코딩 2일차]]></title>
            <link>https://velog.io/@woo_hyun_1/%EB%85%B8%EB%A7%88%EB%93%9C%EC%BD%94%EB%8D%94-%EC%B9%B4%EC%B9%B4%EC%98%A4%ED%86%A1-%ED%81%B4%EB%A1%A0%EC%BD%94%EB%94%A9-2%EC%9D%BC%EC%B0%A8</link>
            <guid>https://velog.io/@woo_hyun_1/%EB%85%B8%EB%A7%88%EB%93%9C%EC%BD%94%EB%8D%94-%EC%B9%B4%EC%B9%B4%EC%98%A4%ED%86%A1-%ED%81%B4%EB%A1%A0%EC%BD%94%EB%94%A9-2%EC%9D%BC%EC%B0%A8</guid>
            <pubDate>Tue, 05 Jul 2022 15:26:37 GMT</pubDate>
            <description><![CDATA[<ul>
<li>HTML의 목적 : 브라우저에게 무엇이 무엇인지 알려주는 것. 이건 링크야, 이건 제목이야, 이건 이미지야 등...</li>
<li>&#39;여기부터 여기까지가 무엇이다&#39; → 이걸 말해주는걸 <strong>HTML Tag</strong>라고 함. 이 두 태그 사이에 넣는 내용이 무언가가 되는 것이다.</li>
<li>HTML에서는 tag를 텍스트로 넣는다. 실제로 tag가 어떤 의미를 하는지 생각해보자.(물건에 붙어서 이게 뭔지 말해준다.)</li>
<li>/이 있다면 tag가 끝났다는 뜻. tag를 닫지 않으면 제대로 작동하지 않는다.</li>
</ul>
<pre><code class="language-html">&lt;!-- HTML의 목적 : 브라우저에게 어떤 컨텐츠가 있는지 알려줌 --&gt;
&lt;!-- h1~h6 : header number, 제목 --&gt;
&lt;h1&gt;Hello this is my website!&lt;/h1&gt;
&lt;h2&gt;Hello this is my website!&lt;/h2&gt;
&lt;h3&gt;Hello this is my website!&lt;/h3&gt;
&lt;h4&gt;Hello this is my website!&lt;/h4&gt;
&lt;h5&gt;Hello this is my website!&lt;/h5&gt;
&lt;h6&gt;Hello this is my website!&lt;/h6&gt;

&lt;!-- ul : unordered list, li : list item(목록 요소), ol : ordered list --&gt;
&lt;ol&gt;
  &lt;li&gt;beer&lt;/li&gt;
  &lt;li&gt;soju&lt;/li&gt;
  &lt;li&gt;meat&lt;/li&gt;
  &lt;li&gt;milk&lt;/li&gt;
&lt;/ol&gt;

&lt;!-- attributes(속성) : tag에 추가하는 부가적인 정보--&gt;
&lt;!-- a : anchor(닻), href : http reference/hyperlink reference--&gt;
&lt;!-- target=&quot;_blank&quot; : 새로운 탭에서 링크 열기--&gt;
&lt;!-- img 태그 : self-closing tag(자체 닫기 태그)중 하나,이미지--&gt;
&lt;!-- src : source(소스)--&gt;
&lt;a href=&quot;http://www.google.com&quot; target=&quot;_blank&quot;&gt;Go to google&lt;/a&gt;
&lt;img
  src=&quot;https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcTo2x09km7b35RzvH8yg_tXzVkSi_jXJnmOWA&amp;usqp=CAU&quot;
/&gt;</code></pre>
<blockquote>
<p>header number tag 1~6 ( 제목 )
h1 ~ h6 까지 있다.</p>
</blockquote>
<ul>
<li>제대로 된 위치에 제대로 된 tag를 쓰면 브라우저가 이해하고 표시한다.</li>
<li>모든 tag를 전부 기억하고 암기할 필요는 없다. 아주 많은 tag가 있고 그냥 작동원리를 이해하면 된다.</li>
</ul>
<blockquote>
<ol>
<li>orderded list = 순서가 있는 리스트</li>
<li>unordered list = 순서가 없는 리스트 (ul)</li>
<li>리스트 안에 사용할 수 있는 태그 = list item (li)</li>
</ol>
</blockquote>
<blockquote>
<p>a = anchor를 뜻함 (link를 떠올리면 됨, 추가적인 정보가 필요함) + href(hypertext reference)</p>
</blockquote>
<ul>
<li>tag에 추가하는 부가정보를 attributes(속성)라고 한다.</li>
<li>한 tag 안에 2개 이상의 attributes를 동시에 사용할 수 있다.</li>
<li>속성 &#39;href&#39;는 오직 &#39;a&#39;tag에만 붙일 수 있다.</li>
<li>속성 &#39;target&#39; : 기본값은 _self로, _blank 입력 시 새 탭에서 링크가 열림</li>
</ul>
<blockquote>
<p>img = image를 뜻함, self-closing tag(자체 닫기 태그) + src(source, 사진의 주소)</p>
</blockquote>
<ul>
<li>&#39;src&#39;는 오직 &#39;img&#39; tag에서만 작동한다.</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[노마드코더 JS 1,2일차]]></title>
            <link>https://velog.io/@woo_hyun_1/%EB%85%B8%EB%A7%88%EB%93%9C%EC%BD%94%EB%8D%94-JS-12%EC%9D%BC%EC%B0%A8</link>
            <guid>https://velog.io/@woo_hyun_1/%EB%85%B8%EB%A7%88%EB%93%9C%EC%BD%94%EB%8D%94-JS-12%EC%9D%BC%EC%B0%A8</guid>
            <pubDate>Tue, 05 Jul 2022 13:42:53 GMT</pubDate>
            <description><![CDATA[<h2 id="js에-관하여">JS에 관하여</h2>
<p>Vanilla JS는 다른 라이브러리를 사용하지 않고 순수 JavaScript를 뜻하는 것.</p>
<p>자바 스크립트는 모든 브라우저에 내장되어있고 프론트엔드 개발자가 사용할수 있는 유일한 프로그래밍 언어이다.</p>
<p>브라우저는 html을 열고, html은 css와 js를 가져오는 것.(css나 js는 브라우저에서 연다고 실행X, html 을 브라우저에 열어서 그 안에서 실행)</p>
<h2 id="data-type데이터-타입의-종류">Data Type(데이터 타입의 종류)</h2>
<h3 id="정수실수문자열">정수/실수/문자열</h3>
<ol>
<li>Number
1) 정수(Integer) // 1, 2, 3, 4 ...
2) 소수(Float) // 1.555, 2.545345 ...</li>
</ol>
<ul>
<li>Number타입은 서로 연산기호를 이용하여 계산할 수 있다.</li>
</ul>
<ol start="2">
<li>String
: 처음부터 끝까지 문자(Text)로 구성되어 있다는 의미</li>
</ol>
<p>console.log(); 라는 함수를 통해서 콘솔창에 무언가를 출력할 수 있음.</p>
<p>number형은 따옴표없이 입력해도 인식해서 알아서 출력해주고 string은 앞뒤로 &quot;큰따옴표&quot; 혹은 &#39;작은따옴표&#39;로 같은 따옴표를 써서 묶어줘야 한다.</p>
<h3 id="booleannullundefined">Boolean/null/undefined</h3>
<p>data type 에는 숫자 , 문자 말고도 boolean 값으로 true와 false가 있다.</p>
<p>또 다른 값으로는 null, undefined가 있다.</p>
<ol>
<li>null: 값이 정의되긴 했지만 값이 없음을 의도적으로 알리기 위해 채워진 값이다.</li>
<li>undefined: let something; 처럼 변수에 값을 지정하지 않아 메모리 상에 변수는 선언되었지만 값이 정의되지 않은 것이다.</li>
</ol>
<h2 id="변수란">변수란?</h2>
<p>variable은 값을 저장하거나 유지하는 역할을 한다</p>
<ol>
<li>const : constant(상수) 바뀌지 않는 값, 값을 업데이트 할 수 없음.</li>
<li>let : 생성할 때 사용, 생성 후에 값을 바꿀 수 있음. 새로운 것(변수)을 생성할 때만 앞에 let을 붙여주고 한번 생성된 변수는 let 없이 &#39;변수명 = 값&#39; 으로 업데이트가 가능.</li>
<li>var - 어디서든 변경할 수 있음. 실수로 값을 업데이트해도 알아차릴 수 없는 단점. (구버전)<blockquote>
<p>★ always use const, sometimes let, never var ★
let - 재선언 금지, 재할당 가능
const - 재선언 금지, 재할당 금지
var - 재선언 가능, 재할당 가능</p>
</blockquote>
</li>
</ol>
<p>[variable naming example] ( 관례같은것.. )
javascript : veryLongVariableName ( camelCase )
python : very_long_variable_name ( snake_Case )</p>
<h2 id="array배열">Array(배열)</h2>
<p>//배열생성
const days_of_week = [&quot;Mon&quot;, &quot;Tue&quot;, &quot;Wed&quot;, &quot;Thu&quot;, &quot;Fri&quot;, &quot;Sat&quot;, &quot;Sun&quot;]</p>
<p>//배열접근방법. 첫번째 인덱스는 0임.
console.log(days_of_week[0]); //Mon출력
console.log(days_of_week[1]); //Tue출력
console.log(days_of_week[6]); //Sun출력</p>
<p>//배열 값 변경
days_of_week[0] = &quot;월요일&quot; //Mon을 월요일로 변경
console.log(days_of_week[0] = &quot;월&quot;); //출력과 동시에 변경 가능</p>
<p>javascript 에서의 배열에는 자료형(Data type)이 달라도 하나의 배열에 저장할 수 있다.</p>
<p>시작과 끝에 [ ]를 쓰고 쉼표(,)로 구분을 해준다.</p>
<p>array를 이용해 값들을 list로 저장한다.</p>
<p>array 안의 데이터에 접근할 때는 name[0]처럼 접근한다. 첫 번째가 0부터 시작한다.</p>
<p>push() 함수를 이용해서 배열의 마지막에 값을 추가할 수 있다. ex) name.push(“sun”)</p>
<h2 id="object객체">Object(객체)</h2>
<p>설명이 필요하지 않은 데이터 리스트들은 array로,
설명이 필요한 정보가 담긴 데이터 리스트들은 object로 선언.</p>
<p>object는 property를 가진 데이터를 저장해주며, { } 를 사용한다.</p>
<p>게임 캐릭터의 속성을 지정할 때 변수명을
const playerName = &quot;woohyun&quot;;
const playerPoints = 100;
const playerFat = true; 으로 지정하면 한 그룹으로 모아서 인식하기 힘들고</p>
<p>const player = [&quot;woohyun&quot;, 100, true]; 로 지정하면 어떤 속성의 값인지 알 수 없다.
(왜냐면 list는 같은 속성의 나열만 취급하기 때문이다.)</p>
<p>다른 속성의 리스트를 만들기 위해서는 0bject를 만들어야 하는데 이때 [] 대신 {} 사용.</p>
<pre><code class="language-python">const player = {
    name: &quot;woohyun&quot;,
    points:100,
    fat:true
};</code></pre>
<p>console.log(player); &gt;&gt; {name:&quot;woohyun&quot;, points:100, fat:true}</p>
<p>property를 불러오는 방법은 2가지가 있다.</p>
<p>1) console.log(player.fat); &gt;&gt; true
2) console.log(player[&quot;fat&quot;]); &gt;&gt; true</p>
<p>** const는 let과 다르게 update가 안되지만 리스트의 경우 전체를 변경하는 게 아니라 속성값을 수정/추가하는 경우에는 update 가 가능하다. (property를 바꾸는 것은 가능하지만 선언된 object를 바꾸는 것은 불가능)</p>
<p>예) player=false; &gt;&gt; error
player.fat=false; &gt;&gt; success</p>
<p>그리고 property를 추가 할 수도 있다.</p>
<p>player.koreanName = &quot;킹우현&quot;;</p>
<p>--&gt; {name:&quot;woohyun&quot;, points:100, fat:true, koreaName: &quot;킹우현&quot;}</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[노마드코더 카카오톡 클론코딩 1일차]]></title>
            <link>https://velog.io/@woo_hyun_1/%EB%85%B8%EB%A7%88%EB%93%9C%EC%BD%94%EB%8D%94-%EC%BD%94%EC%BD%94%EC%95%84%ED%86%A1-%ED%81%B4%EB%A1%A0%EC%BD%94%EB%94%A9-1%EC%9D%BC%EC%B0%A8</link>
            <guid>https://velog.io/@woo_hyun_1/%EB%85%B8%EB%A7%88%EB%93%9C%EC%BD%94%EB%8D%94-%EC%BD%94%EC%BD%94%EC%95%84%ED%86%A1-%ED%81%B4%EB%A1%A0%EC%BD%94%EB%94%A9-1%EC%9D%BC%EC%B0%A8</guid>
            <pubDate>Mon, 04 Jul 2022 02:47:42 GMT</pubDate>
            <description><![CDATA[<h1 id="웹페이지를-구성하는-3가지-언어--html--css--javascript">웹페이지를 구성하는 3가지 언어 : HTML &amp; CSS &amp; JavaScript</h1>
<blockquote>
<p>HTML - 뼈대, 골격(Skeleton)
CSS - 근육, 피부(Muscle)
JavaScript - 뼈대와 근육을 움직이는 뇌의 역할(Brain)</p>
</blockquote>
<p>HTML은 콘텐츠가 무엇인지에 초점, browser 에게 어떤 content가 있는지를 알려줌(Markup language)
<em>ex) title, link, image, paragraph, date… etc</em></p>
<p>CSS는 콘텐츠에 어떻게 보이는지에 초점, browser에게 content들이 어떻게 보여야하는지 알려줌(디자인과 스타일을 위한 Design Language)</p>
<p>JavsScript는 이 콘텐츠와 사용자와의 상호작용에 초점, website를 똑똑하게 동적으로 만들어주는 것(웹사이트를 Interactive하게 만들어주는 Programming Language)</p>
<p>위의 3가지 언어 중 프로그래밍 언어는 &#39;Javascript&#39; 뿐이다 !</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[자료구조] 스택 응용 - 괄호 검사]]></title>
            <link>https://velog.io/@woo_hyun_1/%EC%9E%90%EB%A3%8C%EA%B5%AC%EC%A1%B0-%EC%8A%A4%ED%83%9D-%EC%9D%91%EC%9A%A9-%EA%B4%84%ED%98%B8-%EA%B2%80%EC%82%AC</link>
            <guid>https://velog.io/@woo_hyun_1/%EC%9E%90%EB%A3%8C%EA%B5%AC%EC%A1%B0-%EC%8A%A4%ED%83%9D-%EC%9D%91%EC%9A%A9-%EA%B4%84%ED%98%B8-%EA%B2%80%EC%82%AC</guid>
            <pubDate>Tue, 08 Mar 2022 05:35:54 GMT</pubDate>
            <description><![CDATA[<p>프로그램에서는 여러 가지 타입의 괄호들이 같은 타입으로 쌍으로 존재하여야 한다.</p>
<p>프로그램에서는 대괄호[], 중괄호{}, 소괄호() 등이 사용되는데 괄호의 검사 조건은 다음의 3가지 이다.</p>
<blockquote>
<ol>
<li>왼쪽과 오른쪽의 괄호의 개수가 같아야 한다.</li>
<li>같은 타입의 괄호에서 왼쪽 괄호는 오른쪽 괄호보다 먼저 나와야 한다.</li>
<li>서로 다른 타입의 왼쪽 괄호와 오른쪽 괄호 쌍은 서로를 교차하면 안 된다.</li>
</ol>
</blockquote>
<p>이러한 괄호 사용의 오류를 검사하는 데 스택을 사용할 수 있다.</p>
<p>위의 괄호들을 자세히 살펴보면 가장 가까운 거리에 있는 괄호들끼리 서로 쌍을 이루어야 됨을 알 수 있다.</p>
<p>따라서 왼쪽 괄호들을 만나면 스택에 삽입하다가 오른쪽 괄호들이 나오면 스택에서 가장 최근의 왼쪽 괄호를 꺼내어 타입을 맞추어보면 쉽게 괄호들의 오류를 검사할 수 있다.</p>
<p>스택은 이처럼 최근에 삽입한 것이 먼저 필요한 경우에 유용하다.</p>
<p>괄호의 오류 여부를 조사하려면 먼저 문자열에 있는 괄호를 차례대로 조사하면서 왼쪽 괄호를 만나면 스택에 삽입하고, 오른쪽 괄호를 만나면 스택에서 맨 위의 괄호를 꺼낸 후 짝이 맞는지를 검사한다.</p>
<p>이때, 스택이 비어 있으면 조건 1 또는 조건 2 등을 위반하게 되고 괄호의 짝이 맞지 않으면 조건 3에 위반된다.</p>
<p>마지막 괄호까지를 조사한 후에도 스택에 괄호가 남아 있으면 조건 1에 위반되므로 FALSE를 반환하고 그렇지 않으면 성공이므로 TRUE를 반환한다.</p>
<pre><code class="language-c">#include &lt;stdio.h&gt;
#define TRUE 1
#define FALSE 0

typedef char element;

typedef struct StackNode {

    element item;
    struct StackNode* link;

}StackNode;


typedef struct {
    StackNode* top;
}LinkedStackType;

void init(LinkedStackType* s) {
    s-&gt;top = NULL;
}

int is_empty(LinkedStackType* s) {
    return (s-&gt;top == NULL);
}

void push(LinkedStackType* s, element item) {
    StackNode* temp = (StackNode*)malloc(sizeof(StackNode));
    if (temp == NULL) {
        fprintf(stderr, &quot;메모리 할당에러\n&quot;);
        return;
    }
    else {
        temp-&gt;item = item;
        temp-&gt;link = s-&gt;top;
        s-&gt;top = temp;
    }
}

element pop(LinkedStackType* s) {
    if (is_empty(s)) {
        fprintf(stderr, &quot;스택이 비어있음\n&quot;);
        exit(1);
    }
    else {
        StackNode* temp = s-&gt;top;
        element item = temp-&gt;item;
        s-&gt;top = s-&gt;top-&gt;link;
        free(temp);
        return item;
    }
}

element peek(LinkedStackType* s) {
    if (is_empty(s)) {
        fprintf(stderr, &quot;스택이 비어있음\n&quot;);
        exit(1);
    }
    else {
        return s-&gt;top-&gt;item;
    }
}

int check_matching(char* in) {

    LinkedStackType s;
    char ch, open_ch;
    int n = strlen(in);
    init(&amp;s);

    for (int i = 0; i &lt; n; i++) {
        ch = in[i];

        switch (ch) {

        case &#39;(&#39;: case &#39;{&#39;: case &#39;[&#39;:
            push(&amp;s, ch);
            break;
        case &#39;)&#39;: case &#39;}&#39;: case &#39;]&#39;:
            if (is_empty(&amp;s)) return FALSE;
            else {
                open_ch = pop(&amp;s);
                if ((open_ch == &#39;(&#39; &amp;&amp; ch != &#39;)&#39;) || (open_ch == &#39;{&#39; &amp;&amp; ch != &#39;}&#39;) || (open_ch == &#39;[&#39; &amp;&amp; ch != &#39;]&#39;)) return FALSE;
                break;
            }

        }
    }
    if (!is_empty(&amp;s)) return FALSE;
    return TRUE;

}

int main() {
    if (check_matching(&quot;{ A[(i+1)]=0; }&quot;) == TRUE) printf(&quot;{ A[(i+1)]=0; } : 괄호검사성공\n&quot;);
    else printf(&quot;{ A[(i+1)]=0; } : 괄호검사실패\n&quot;);

    if (check_matching(&quot;if((i==0) &amp;&amp; (j==0)&quot;) == TRUE) printf(&quot;if((i==0) &amp;&amp; (j==0) : 괄호검사성공\n&quot;);
    else printf(&quot;if((i==0) &amp;&amp; (j==0) : 괄호검사실패\n&quot;);

    if (check_matching(&quot;A[(i+1])=0;&quot;) == TRUE) printf(&quot;A[(i+1])=0; : 괄호검사성공\n&quot;);
    else printf(&quot;A[(i+1])=0; : 괄호검사실패\n&quot;);

}</code></pre>
<p><img src="https://images.velog.io/images/woo_hyun_1/post/527e33f5-afe7-4f61-b6dc-ee67a1f4b200/image.png" alt=""></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[자료구조] 5. 스택 part 2]]></title>
            <link>https://velog.io/@woo_hyun_1/%EC%9E%90%EB%A3%8C%EA%B5%AC%EC%A1%B0-5.-%EC%8A%A4%ED%83%9D-part-2</link>
            <guid>https://velog.io/@woo_hyun_1/%EC%9E%90%EB%A3%8C%EA%B5%AC%EC%A1%B0-5.-%EC%8A%A4%ED%83%9D-part-2</guid>
            <pubDate>Wed, 02 Mar 2022 14:31:03 GMT</pubDate>
            <description><![CDATA[<h1 id="연결-리스트로-구현한-스택">연결 리스트로 구현한 스택</h1>
<p><img src="https://images.velog.io/images/woo_hyun_1/post/31eead37-5536-4f81-8ead-5b48dfe559b9/image.png" alt="">
이러한 스택이나 큐를 연결된 스택(linked stack)이라고 한다.</p>
<p>제공되는 외부 인터페이스는 완전히 동일하다. 달라지는 것은 스택의 내부 구현이다.</p>
<p>연결 리스트를 이용하여 스택을 만들게 되면 크기가 제한되지 않는다는 큰 장점이 있다.</p>
<p>동적 메모리 할당만 할 수 있으면 스택에 새로운 요소를 삽입할 수 있다.</p>
<p>반면에 연결 리스트를 이용한 스택은 동적 메모리 할당이나 해제를 해야 하므로 삽입이나 삭제 시간은 좀 더 걸린다.</p>
<p>연결된 스택은 기본적으로 연결 리스트이기 때문에 다음과 같이 노드를 정의한다.</p>
<p>노드는 우리가 저장하고 싶은 데이터 필드와 다음 노드를 가리키기 위한 포인터가 들어 있는 링크 필드로 구성된다.</p>
<p>또한 top은 더 이상 정수가 아니고 노드를 가리키는 포인터로 선언된다.</p>
<p>연결된 스택에 관련된 데이터는 top 포인터뿐이지만 일관성을 위하여 LinkedStackType이라는 구조체 타입으로 정의되었다.</p>
<p>모든 함수들은 이 구조체의 포인터를 매개 변수로 받아서 사용된다.</p>
<pre><code class="language-c">typedef int element;

typedef struct StackNode {

    element item;
    struct StackNode* link;

}StackNode;


typedef struct {
    StackNode* top;
}LinkedStackType;</code></pre>
<p>연결된 스택에서 삽입 연산을 구현해보자. 연결된 스택은 개념적으로 단순 연결 리스트에서 맨 앞에 데이터를 삽입하는 것과 동일하다.</p>
<p>연결된 스택에서는 헤드 포인터가 top이라는 이름으로 불리는 것 외에는 별 차이점이 없다.</p>
<p>삽입 연산에서는 먼저 동적 메모리 할당으로 노드를 만들고 이 노드를 첫 번째 노드로 삽입한다.</p>
<p><img src="https://images.velog.io/images/woo_hyun_1/post/1d4e1f9d-2d01-400b-b3ef-693291dd5911/image.png" alt=""></p>
<p>위와 같이 top의 값을 temp-&gt;link에 복사한 다음, temp를 top에 복사하면 된다.</p>
<p>삭제 연산에서는 top의 값을 top-&gt;link로 바꾸고, 기존의 top이 가리키는 노드를 동적 메모리 해제하면 된다.</p>
<p><img src="https://images.velog.io/images/woo_hyun_1/post/948f07a7-0ef6-406b-a49e-5fd9467af8a2/image.png" alt=""></p>
<p>스택에서 삭제 연산 시에 링크 필드의 변화는 위와 같다.</p>
<p>연결된 스택에서 공백 상태는 연결 리스트와 마찬가지로 top 포인터가 NULL인 경우이다.</p>
<p>그리고 포화 상태는 동적 메모리 할당만 된다면 노드를 생성할 수 있기 때문에 없는거나 마찬가지다.</p>
<pre><code class="language-c">e &lt;stdio.h&gt;

typedef int element;

typedef struct StackNode {

    element item;
    struct StackNode* link;

}StackNode;


typedef struct {
    StackNode* top;
}LinkedStackType;

void init(LinkedStackType* s) {
    s-&gt;top = NULL;
}

int is_empty(LinkedStackType* s) {
    return (s-&gt;top == NULL);
}

void push(LinkedStackType* s, element item) {
    StackNode* temp = (StackNode*)malloc(sizeof(StackNode));
    if (temp == NULL) {
        fprintf(stderr, &quot;메모리 할당에러\n&quot;);
        return;
    }
    else {
        temp-&gt;item = item;
        temp-&gt;link = s-&gt;top;
        s-&gt;top = temp;
    }
}

element pop(LinkedStackType* s) {
    if (is_empty(s)) {
        fprintf(stderr, &quot;스택이 비어있음\n&quot;);
        exit(1);
    }
    else {
        StackNode* temp = s-&gt;top;
        element item = temp-&gt;item;
        s-&gt;top = s-&gt;top-&gt;link;
        free(temp);
        return item;
    }
}

element peek(LinkedStackType* s) {
    if (is_empty(s)) {
        fprintf(stderr, &quot;스택이 비어있음\n&quot;);
        exit(1);
    }
    else {
        return s-&gt;top-&gt;item;
    }
}

void main() {
    LinkedStackType s;

    init(&amp;s);

    push(&amp;s, 1);
    push(&amp;s, 2);
    push(&amp;s, 3);
    printf(&quot;%d\n&quot;, pop(&amp;s));
    printf(&quot;%d\n&quot;, pop(&amp;s));
    printf(&quot;%d\n&quot;, pop(&amp;s));
    printf(&quot;%d\n&quot;, is_empty(&amp;s));

}</code></pre>
<p><img src="https://images.velog.io/images/woo_hyun_1/post/2e93b534-b261-4d46-909d-d495213f3aca/image.png" alt=""></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[자료구조] 5. 스택]]></title>
            <link>https://velog.io/@woo_hyun_1/%EC%9E%90%EB%A3%8C%EA%B5%AC%EC%A1%B0-5.-%EC%8A%A4%ED%83%9D</link>
            <guid>https://velog.io/@woo_hyun_1/%EC%9E%90%EB%A3%8C%EA%B5%AC%EC%A1%B0-5.-%EC%8A%A4%ED%83%9D</guid>
            <pubDate>Tue, 01 Mar 2022 15:44:14 GMT</pubDate>
            <description><![CDATA[<h1 id="스택-추상-데이터-타입">스택 추상 데이터 타입</h1>
<p><img src="https://images.velog.io/images/woo_hyun_1/post/e101d426-56b2-4aa3-a101-c8bc493bb56b/image.png" alt="">
스택(stack)은 가장 최근에 들어온 데이터가 가장 위에 있고, 또 먼저 나가게 된다.</p>
<p>이런 입출력 형태를 <strong>후입 선출(LIFO : Last-In First-Out)</strong>이라고 한다.</p>
<p>스택은 이러한 후입 선출의 형식으로 입출력이 일어나는 자료 구조이다.</p>
<p>스택은 제일 먼저 입력된 데이터가 맨 아래에 쌓이고 가장 최근에 입력된 데이터가 가장 위에 쌓이는 구조를 가지고 있다.</p>
<p>스택에서의 입출력은 맨 위에서만 일어나고 스택의 중간에서는 데이터를 삭제할 수 없다.</p>
<p>스택에서 입출력이 이루어지는 부분을 스택 상단(stack top)이라고 하고 반대쪽 바닥 부분을 스택 하단(stack bottom)이라고 한다.</p>
<p>스택에 저장되는 것을 요소(element)라고 부른다.</p>
<p>스택에 요소가 하나도 없을 때 스택을 공백 스택(empty stack)이라고 한다.</p>
<p>스택을 추상 자료형으로 정의해보자. 추상 자료형으로서의 스택은 스택의 상태를 변화시키는 연산들과 스택의 현재 상태를 검사하는 연산들로 구성된다.</p>
<blockquote>
<p>객체 : n개의 element 타입의 요소들의 순서 있는 모임
연산 : create() - 스택을 생성한다.
is_empty(s) - 스택이 비어 있는지를 검사한다.
is_full(s) - 스택이 가득 찼는가를 검사한다.
push(s,e) - 스택의 맨 위에 요소 e를 추가한다.
pop(s) - 스택의 맨 위에 있는 요소를 삭제한다.
peek(s) - 스택의 맨 위에 있는 요소를 삭제하지 않고 반환한다.</p>
</blockquote>
<p>스택에는 두 가지의 기본 연산이 있다.</p>
<p>하나는 삽입 연산으로 push 연산이라고 하고, 또 하나는 삭제 연산으로 pop연산이라고 한다.</p>
<p>is_empty와 is_full 연산은 스택이 공백 상태에 있는지와 포화 상태에 있는지를 검사하는 함수이다.</p>
<p>create 연산은 스택을 생성한다. peek 연산은 요소를 스택에서 삭제하지 않고 보기만 하는 연산이다.</p>
<p>pop 연산은 요소를 스택에서 완전히 삭제하면서 가져온다.</p>
<p>스택은 특히 자료의 출력 순서가 입력 순서의 역순으로 이루어져야 할 경우에 매우 간요하게 사용된다.</p>
<p>예를 들면 에디터에서 되돌리기(undo) 기능을 구현할 때 스택을 사용할 수 있다.</p>
<p>왜냐하면 수행된 명령어들 중에서 가장 최근에 수행된 것부터 되돌리기를 하여야 하기 때문이다.</p>
<p><em>가장 전형적인 스택의 사용 예는 함수 호출에서 복귀 주소를 기억하는 데 스택을 사용하는 것이다.</em></p>
<p>함수는 실행이 끝나면 가장 최근에 자신을 호출한 함수로 되돌아가야 한다.</p>
<p><img src="https://images.velog.io/images/woo_hyun_1/post/6ba32168-2b83-4789-bbbb-920509cad9ca/image.png" alt=""></p>
<p>이런 경우에 스택이 효과적으로 사용될 수 있다.</p>
<p>즉 함수가 호출된 순으로 스택에 현재 실행 중인 문장의 다음 번째 문장의 주소를 저장하고 하나의 함수가 끝나면 스택에서 복귀주소를 구해서 그곳으로 되돌아가는 것이다.</p>
<p>이 경우 사용되는 스택은 컴퓨터의 운영 체제만 사용하는 시스템 스택으로 사용자는 접근할 수 없다.</p>
<p>이 시스템 스택에는 함수가 호출될 때마다 활성화 레코드(activation record)가 만들어지며 여기에 함수로부터 복귀 후에 실행될 명령어의 주소인 프로그램 카운터(pc, program counter)값이 기록된다.</p>
<p>이 프로그램 카운터 값이 복귀 주소가 된다.</p>
<p>활성화 레코드에는 프로그램 카운터뿐만 아니라 함수 호출 시 매개 변수와 함수 안에서 선언된 지역 변수들이 함께 저장된다.</p>
<p>스택을 구현하는 방법에는 배열을 이용하는 방법과 연결 리스트를 이용하는 방법이 있다.</p>
<p>배열로 구현하는 방법은 간단한 반면에 스택의 크기가 고정되는 약점이 있다.</p>
<p>연결 리스트를 이용하는 방법은 구현이 약간 복잡한 반면, 스택의 크기를 필요에 따라 가변적으로 변경할 수 있다.</p>
<h1 id="배열로-구현한-스택">배열로 구현한 스택</h1>
<p>앞에서의 추상 자료형으로 공부했던 스택을 배열을 이용하여 구현해보자.</p>
<p>스택에는 여러 가지 필요한 내용을 넣을 수 있으나 여기서는 간단하게 int타입의 정수가 저장되는 것으로 하자.</p>
<p>따라서 int 타입의 1차원 배열 stack[MAX_STACK_SIZE]가 필요하다.</p>
<p>이 배열을 이용하여 스택의 요소들을 저장하게 된다.</p>
<p>또한 스택에서 가장 최근에 입력되었던 자료를 가리키는 top 변수가 필요하다.</p>
<p>가장 먼저 들어온 요소는 stack[0]에, 가장 최근에 들어온 요소는 stack[top]에 저장된다.</p>
<p><img src="https://images.velog.io/images/woo_hyun_1/post/b9e80cf0-0c12-45e0-8205-f01b464f0305/image.png" alt=""></p>
<p>top 변수는 스택에 아무런 데이터가 없으면 -1의 값을 갖는다.</p>
<p>0의 값을 가지면 안 되는 것을 이해해야 한다.</p>
<p>c언어의 배열에서 첫 번째 요소의 인덱스가 0이기 때문에 top의 값이 0이면 배열의 인덱스 0에 데이터가 있다는 것을 의미한다.</p>
<p><img src="https://images.velog.io/images/woo_hyun_1/post/b9c57fcf-de4c-47d9-a33c-23f24e9b0d3d/image.png" alt=""></p>
<blockquote>
<ol>
<li>is_empty 연산 : 스택이 비어 있는지를 검사하기 위하여 top을 -1과 비교한다. 만약에 top이 -1이면 TRUE가 반환될 것이다.</li>
<li>is_full 연산 : 스택이 가득 차 있는지를 검사하기 위하여 top을 MAX_STACK_SIZE-1 와 비교하여 같으면 포화 상태로 판정한다. 만약 top이 MAX_STACK_SIZE-1 이면 더 이상의 삽입은 불가능하다.</li>
<li>push 연산 : 스택에 새로운 요소를 삽입하기 전에 필요한 것은 스택이 가득 차지 않았나를 검사하는 것이다. 이것은 is_full()를 호출하여 검사하고 스택이 가득 차 있다면 오류 메세지가 출력되고 함수는 그냥 반환한다. 
push()에서는 먼저 top의 값을 증가하는 것을 유의하라. top을 가리키는 위치는 마지막으로 삽입되었던 요소이므로 top을 증가시키지 않고 삽입하면 마지막 요소가 지워지게 된다.</li>
<li>pop 연산 : 스택에서 하나의 요소를 제거하는 연산으로 top이 가리키는 요소를 스택에서 꺼내어 외부로 건네주는 연산이다. 먼저 요소를 제거하기 전에 스택이 비어 있는지를 검사해야 한다.
스택의 공백 여부는 is_empty()를 호출하여 검사하고 스택이 비어 있으면 오류 메세지를 출력한다.
스택이 비어 있지 않으면 top이 가리키는 값을 반환하고 top을 하나 감소시킨다.</li>
</ol>
</blockquote>
<h2 id="전역-변수로-구현하는-방법">전역 변수로 구현하는 방법</h2>
<pre><code class="language-c">#include &lt;stdio.h&gt;
#include &lt;stdlib.h&gt;

#define MAX_STACK_SIZE 100

typedef int element;
element stack[MAX_STACK_SIZE];
int top = -1;

int is_empty() {
    return (top == -1);
}

int is_full() {
    return (
        top == (MAX_STACK_SIZE - 1));
}

void push(element item) {
    if (is_full()) {
        fprintf(stderr, &quot;스택 포화 에러\n&quot;);
        return;
    }
    else {
        stack[++top] = item;
    }
}

element pop() {
    if (is_empty()) {
        fprintf(stderr, &quot;스택 공백 에러\n&quot;);
        exit(1);
    }
    else {
        return stack[top--];
    }

}

element peek() {
    if (is_empty()) {
        fprintf(stderr, &quot;스택 공백 에러\n&quot;);
        exit(1);
    }
    else {
        return stack[top];
    }
}

void main() {

    push(1);
    push(2);
    push(3);
    printf(&quot;%d\n&quot;, pop());
    printf(&quot;%d\n&quot;, pop());
    printf(&quot;%d\n&quot;, pop());
    printf(&quot;%d\n&quot;, is_empty());

    return 0;
}</code></pre>
<p><img src="https://images.velog.io/images/woo_hyun_1/post/597fcfa4-f59a-4fbc-a130-84654151f581/image.png" alt=""></p>
<p>그러나 이 방법은 만약 프로그램에서 하나 이상의 스택을 사용해야 할 때는 상당히 곤란해진다.</p>
<p>그리고 전역 변수를 사용하는 것은 프로그램을 복잡하게 만들어서 오류가 발생할 가능성을 높인다.</p>
<p>만약 스택에 저장되어야 하는 값이 정수나 문자가 아니고 더 복잡한 구조를 갖는 요소라면 어떻게 해야 할까?</p>
<p>이런 경우에는 스택의 요소를 정수가 아니라 구조체로 만들면 된다.</p>
<p>구조체 안에 필요한 모든 정보를 넣으면 된다.</p>
<pre><code class="language-c">#define _CRT_SECURE_NO_WARNINGS
#include &lt;stdio.h&gt;
#include &lt;string.h&gt;

#define MAX_STACK_SIZE 100
#define MAX_STRING 100

typedef struct {
    int student_no;
    char name[MAX_STRING];
    char address[MAX_STRING];
}element;

element stack[MAX_STACK_SIZE];

int top = -1;

int is_empty() {
    return (top == -1);
}

int is_full() {
    return (
        top == (MAX_STACK_SIZE - 1));
}

void push(element item) {
    if (is_full()) {
        fprintf(stderr, &quot;스택 포화 에러\n&quot;);
        return;
    }
    else {
        stack[++top] = item;
    }
}

element pop() {
    if (is_empty()) {
        fprintf(stderr, &quot;스택 공백 에러\n&quot;);
        exit(1);
    }
    else {
        return stack[top--];
    }

}

element peek() {
    if (is_empty()) {
        fprintf(stderr, &quot;스택 공백 에러\n&quot;);
        exit(1);
    }
    else {
        return stack[top];
    }
}

void main() {

    element ie, oe;
    strcpy(ie.name, &quot;킹우현&quot;);
    strcpy(ie.address, &quot;동탄신도시&quot;);

    ie.student_no = 201820734;

    push(ie);

    oe = pop();

    printf(&quot;name: %s\n&quot;, oe.name);
    printf(&quot;address: %s\n&quot;, oe.address);
    printf(&quot;student number: %d\n&quot;, oe.student_no);

}</code></pre>
<p><img src="https://images.velog.io/images/woo_hyun_1/post/024fb197-183c-4367-a1aa-862c47b9d330/image.png" alt=""></p>
<p>지금부터는 스택에 저장되는 요소의 타입은 항상 element라고 가정한다.</p>
<p>만약 정수 스택이 필요하면 element 타입을 정수로 정의하면 되고, 구조체가 필요하면 element 타입을 정의할 때 구조체로 정의하면 된다.</p>
<h2 id="관련된-데이터를-함수의-매개-변수로-전달하는-방법">관련된 데이터를 함수의 매개 변수로 전달하는 방법</h2>
<p>앞의 방법의 결점은 stack 배열과 top이 전역 변수로 선언되기 때문에 전체 프로그램에서 여러 개의 스택을 사용하기가 어렵다는 점이다.</p>
<p>최근의 C++이나 자바의 경우에는 이 문제를 객체 지향의 개념을 이용하여 우아하게 해결할 수 있다.</p>
<p>그러나 C에서도 다음과 같이 하면 이 문제를 어느 정도 완화할 수 있다.</p>
<p><em>즉, top과 stack 배열을 하나의 구조체로 결합시켜서 이 구조체의 포인터를 함수의 매개 변수로 전달한다.</em></p>
<p>다시말해서 StackType이라는 새로운 구조체 타입을 만들고 여기에 stack배열과 top을 넣는다.</p>
<p>그리고 이 구조체의 포인터를 각 함수의 매개 변수로 전달하는 것이다.</p>
<p>이렇게 하면 쉽게 여러 개의 스택을 만드는 것이 가능해진다.</p>
<p>즉, 필요할 때마다 StackType 타입의 구조체를 만들면 된다.</p>
<p><u>앞으로 모든 자료 구조는 이러한 방식으로 구현될 것이다.</u></p>
<p>이 방법에서는 StackType 구조체 안에 들어 있는 변수들을 초기화하기 위하여 init 함수가 필요하다.</p>
<p>여기서 주의할 것은 스택을 초기화하기 위하여 1차원 배열을 0으로 채울 필요는 없다.</p>
<p>배열에 어떤 값이 존재하더라도 top의 값만 -1로 하면 스택은 비어 있는 것으로 간주된다.</p>
<pre><code class="language-c">#include &lt;stdio.h&gt;

#define MAX_STACK_SIZE 100

typedef int element;
typedef struct {
    element stack[MAX_STACK_SIZE];
    int top;
}StackType;

void init(StackType* s) {
    s-&gt;top = -1;
}

int is_empty(StackType* s) {
    return (s-&gt;top == -1);
}

int is_full(StackType* s) {
    return (s-&gt;top == (MAX_STACK_SIZE-1));
}

void push(StackType* s, element item) {
    if (is_full(s)) {
        fprintf(stderr, &quot;스택 포화 에러\n&quot;);
        return;
    }
    else {
        s-&gt;stack[++(s-&gt;top)] = item;
    }
}

element pop(StackType* s) {
    if (is_empty(s)) {
        fprintf(stderr, &quot;스택 공백 에러\n&quot;);
        exit(1);
    }
    else {
        return s-&gt;stack[(s-&gt;top)--];
    }
}

element peek(StackType* s) {
    if (is_empty(s)) {
        fprintf(stderr, &quot;스택 공백 에러\n&quot;);
        exit(1);
    }
    else {
        return s-&gt;stack[s-&gt;top];
    }
}

void main() {

    StackType s;

    init(&amp;s);
    push(&amp;s, 1);
    push(&amp;s, 2);
    push(&amp;s, 3);

    printf(&quot;%d\n&quot;, pop(&amp;s));
    printf(&quot;%d\n&quot;, pop(&amp;s));
    printf(&quot;%d\n&quot;, pop(&amp;s));
    printf(&quot;%d\n&quot;, is_empty(&amp;s));

}</code></pre>
<p><img src="https://images.velog.io/images/woo_hyun_1/post/4003090c-b31d-4edb-a3c6-36fbd560cc18/image.png" alt=""></p>
<p>위의 코드에서 약간 복잡해지는 요인은 구조체가 아니라 구조체의 포인터를 각 함수에 전달하여야 한다는 점이다.</p>
<p>각 함수에서는 구조체의 포인터를 이용하여 스택을 조작한다.</p>
<p>이것은 C언어에서의 함수 매개 변수 전달 방식이 기본적으로 <strong>값 전달 방식(call by value)</strong>이기 때문이다.</p>
<p>즉 구조체를 함수 매개 변수로 전달하였을 경우, 구조체의 원본이 전달되는 것이 아니라 구조체의 복사본이 함수에 전달된다.</p>
<p>따라서 함수 안에서는 복사본을 수정하여도 원본에는 영향을 주지 못한다.</p>
<p>그러나 원본에 대한 포인터를 전달하면 원본을 변경할 수 있다.</p>
<p>스택의 상태를 변경하지 않는 is_empty, is_full, peek 에서는 구조체 복사본을 함수에 전달할 수 있지만 구조체 복사에 따른 부담이 고려되어야 한다.</p>
<p>위 코드는 c언어 프로그램에서 여러 개의 스택을 만들 수 있다는 큰 장점이 있다.</p>
<p>따라서 이제부터는 이와 같은 방식을 이용하여 모든 추상 자료형을 구현하기로 한다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[자료구조] 4. 연결 리스트로 구현된 리스트]]></title>
            <link>https://velog.io/@woo_hyun_1/%EC%9E%90%EB%A3%8C%EA%B5%AC%EC%A1%B0-4.-%EC%97%B0%EA%B2%B0-%EB%A6%AC%EC%8A%A4%ED%8A%B8%EB%A1%9C-%EA%B5%AC%ED%98%84%EB%90%9C-%EB%A6%AC%EC%8A%A4%ED%8A%B8</link>
            <guid>https://velog.io/@woo_hyun_1/%EC%9E%90%EB%A3%8C%EA%B5%AC%EC%A1%B0-4.-%EC%97%B0%EA%B2%B0-%EB%A6%AC%EC%8A%A4%ED%8A%B8%EB%A1%9C-%EA%B5%AC%ED%98%84%EB%90%9C-%EB%A6%AC%EC%8A%A4%ED%8A%B8</guid>
            <pubDate>Tue, 01 Mar 2022 07:34:19 GMT</pubDate>
            <description><![CDATA[<p>이번 절에서는 연결 리스트를 이용하여 리스트 ADT를 구현하여보자.</p>
<p>여기서는 연결 리스트 중에서 단순 연결 리스트를 사용한다.</p>
<p>선형 리스트의 여러 가지 연산 중에서 add 연산과 delete 연산을 중점적으로 설명하고자 한다.</p>
<p>먼저 연결 리스트의 삽입 함수인 insert_node와 삭제 함수인 remove_node는 함수의 매개 변수로 노드를 가리키는 포인터를 받는다.</p>
<p>사실 연결 리스트에서는 포인터로 여러 가지 처리를 하는 것이 효율적이다.</p>
<p>그러나 리스트 ADT의 정의에서는 함수의 매개 변수가 포인터가 아니고 리스트에서의 항목의 위치가 된다.</p>
<p>따라서 연결 리스트로 리스트를 구현하였을 경우, 리스트 ADT의 연산들은 연결 리스트에서 제공하는 연산들을 이용하여 구현된다.</p>
<p>여기서는 위치를 매개 변수로 받아서 삽입이나 삭제를 하는 함수를 작성해보자.</p>
<h1 id="리스트-adt의-구현">리스트 ADT의 구현</h1>
<p>리스트를 위한 구조체는 다음과 같이 정의된다.</p>
<p>head는 첫 번째 노드를 가리키는 헤드 포인터이고, length는 연결 리스트 내에 존재하는 노드의 개수를 나타낸다.</p>
<pre><code class="language-c">typedef struct LinkedListType{
    ListNode * head;
    int length;
}LinkedListType;</code></pre>
<p>연결 리스트를 이용한 리스트가 필요하면 언제든지 다음과 같은 문장을 이용하여 리스트를 만들 수 있다.</p>
<p>LinkedListType list1;</p>
<h1 id="is_empty-연산의-구현">is_empty 연산의 구현</h1>
<pre><code class="language-c">int is_empty(LinkedListType* list) {
    if (list-&gt;head == NULL)return 1;
    else return 0;
}</code></pre>
<h1 id="get_length-연산의-구현">get_length 연산의 구현</h1>
<pre><code class="language-c">int get_length(LinkedListType* list) {
    return list-&gt;length;
}</code></pre>
<h1 id="add연산의-구현">add연산의 구현</h1>
<p>선형 리스트 ADT의 연산들 중에서 add연산은 새로운 자료를 선형 리스트에 추가하는 함수이다.</p>
<p>먼저 동적 메모리 할당을 이용하여 노드를 생성한 다음, 노드의 데이터 필드에다 자료를 복사하고, 기존의 노드들 중에서 지정된 노드를 찾아서 지정된 노드의 뒤에 연결을 해주면 된다.</p>
<p>여기서는 get_node_at 함수를 정의하여 사용하였다.</p>
<p>get_node_at 함수는 매개 변수 pos로 위치를 받아서 그 위치에 해당하는 노드의 주소를 반환하는 함수이다.</p>
<p>만약 pos가 음수이면 NULL을 반환한다.</p>
<p>get_node_at 함수가 지정된 위치의 노드의 주소를 반환하면 이 값을 이용하여 insert_node함수를 호출하여 삽입을 수행한다.</p>
<p>add_last 함수와 add_first 함수는 add함수를 이용하여 쉽게 구현된다.</p>
<pre><code class="language-c">ListNode* get_node_at(LinkedListType* list, int pos) {
    //리스트 안에서 pos 위치의 노드를 반환한다

    int i;
    ListNode* tmp_node = list-&gt;head;

    if (pos &lt; 0)return NULL;

    for (i = 0; i &lt; pos; i++) {
        tmp_node = tmp_node-&gt;link;
    }

    return tmp_node;
}

void add(LinkedListType* list, int position, element data) {
    //주어진 위치에 데이터를 삽입한다

    ListNode* p;
    if ((position &gt;= 0) &amp;&amp; (position &lt;= list-&gt;length)) {
        ListNode* node = (ListNode*)malloc(sizeof(ListNode));

        if (node == NULL)error(&quot;메모리 할당 에러&quot;);

        node-&gt;data = data;
        p = get_node_at(list, position - 1);
        insert_node(&amp;(list-&gt;head), p, node);
        list-&gt;length++;
    }

}

void add_last(LinkedListType* list, element data) {
    add(list, get_length(list), data);
}

void add_first(LinkedListType* list, element data) {
    add(list, 0, data);
}</code></pre>
<h1 id="delete-연산의-구현">delete 연산의 구현</h1>
<p>삭제 연산은 공백이 아닌 리스트에서 pos 위치의 자료를 삭제한다.</p>
<p>마찬가지로 get_node_at 함수를 사용하여 (pos-1)위치에 해당하는 노드의 주소를 얻은 다음, remove_node 함수를 호출하면 된다.</p>
<p><em>(pos-1) 위치의 노드 주소를 반환받는 이유는 노드 삭제 시에 그 노드의 선행 노드 주소가 필요하기 때문이다.</em></p>
<pre><code class="language-c">void delete(LinkedListType* list, int pos) {
    if (!is_empty(list) &amp;&amp; (pos &gt;= 0) &amp;&amp; (pos &lt; list-&gt;length)) {
        ListNode* p = get_node_at(list, pos - 1);
        ListNode* removed = get_node_at(list, pos);
        remove_node(&amp;(list-&gt;head), p, removed);
        list-&gt;length--;
    }
}</code></pre>
<h1 id="get_entry-연산의-구현">get_entry 연산의 구현</h1>
<p>get_entry 연산은 위치 pos에 해당하는 데이터를 반환하는 연산이다.</p>
<p>먼저 pos가 length보다 작은지를 확인하고, 작으면 get_node_at 함수를 이용하여 위치에 해당하는 노드의 주소를 얻은 후에 이 노드가 가지고 있는 데이터 값을 반환하면 된다.</p>
<pre><code class="language-c">element get_entry(LinkedListType* list, int pos) {
    ListNode* p;
    if (pos &gt;= list-&gt;length)error(&quot;위치 오류&quot;);

    p = get_node_at(list, pos);

    return p-&gt;data;
}</code></pre>
<h1 id="clear-연산의-구현">clear 연산의 구현</h1>
<p>clear 연산은 모든 노드를 지우는 함수이다. 리스트의 길이만큼 delete 함수를 호출하면 된다.</p>
<pre><code class="language-c">void clear(LinkedListType* list) {
    for (int i = 0; i &lt; list-&gt;length; i++) {
        delete(list, i);
    }
}</code></pre>
<h1 id="display-연산의-구현">display 연산의 구현</h1>
<p>display 연산은 리스트가 가지고 있는 데이터를 화면에 출력하는 함수로서 list의 헤드 포인터가 가리키는 노드에서부터 NULL을 만날 때까지 노드의 데이터 값을 출력하면 된다.</p>
<p>노드의 데이터 값의 타입에 따라서 출력하는 부분은 변경되어야 한다.</p>
<pre><code class="language-c">void display(LinkedListType* list) {

    ListNode* node = list-&gt;head;
    printf(&quot;( &quot;);

    for (int i = 0; i &lt; list-&gt;length; i++) {
        printf(&quot;%d &quot;, node-&gt;data);
        node = node-&gt;link;
    }

    printf(&quot; )\n&quot;);
}</code></pre>
<h1 id="is_in_list-연산의-구현">is_in_list 연산의 구현</h1>
<p>연결 리스트에서 데이터 필드가 item인 노드를 탐색하는 연산이다.</p>
<p>연결 리스트상의 모든 노드를 검색하여 데이터 필드가 item인 노드를 찾는다.</p>
<p>헤드 포인터에서부터 시작하여 NULL을 만날 때까지 while 루프를 수행한다.</p>
<p>이때 헤드 포인터를 직접 사용하면 안되고 반드시 복사하여 사용하여야 한다.</p>
<p>헤드 포인터를 변경하면 연결리스트가 상실된다.</p>
<pre><code class="language-c">int is_in_list(LinkedListType* list, element item) {
    ListNode* p;
    p = list-&gt;head;

    while ((p != NULL)) {
        if (p-&gt;data == item)
            break;
        p = p-&gt;link;
    }

    if (p == NULL)return FALSE;
    else return TRUE;
}</code></pre>
<h1 id="전체-프로그램">전체 프로그램</h1>
<pre><code class="language-c">#include &lt;stdio.h&gt;
#include &lt;malloc.h&gt;
#include &lt;stdlib.h&gt;
#include &lt;limits.h&gt;

#define FALSE 0
#define TRUE 1

typedef int element;

typedef struct ListNode {
    element data;
    struct ListNode* link;
}ListNode;

typedef struct LinkedListType{
    ListNode * head;
    int length;
}LinkedListType;

void error(char* message) {
    fprintf(stderr, &quot;%s\n&quot;, message);
    exit(1);
}

void init(LinkedListType* list) {
    if (list == NULL)return;
    list-&gt;length = 0;
    list-&gt;head = NULL;
}

void insert_node(ListNode** phead, ListNode* p, ListNode* new_node) {
    if (*phead == NULL) { //공백 리스트인 경우
        new_node-&gt;link = NULL;
        *phead = new_node;
    }
    else if (p == NULL) { //p가 NULL이면 첫 번째 노드로 삽입
        new_node-&gt;link = *phead;
        *phead = new_node;
    }
    else { //p 다음에 삽입
        new_node-&gt;link = p-&gt;link;
        p-&gt;link = new_node;
    }
}

void remove_node(ListNode** phead, ListNode* p, ListNode* removed) {
    if (p == NULL) {
        *phead = (*phead)-&gt;link;
    }
    else {
        p-&gt;link = removed-&gt;link;
    }

    free(removed);
}

int is_empty(LinkedListType* list) {
    if (list-&gt;head == NULL)return 1;
    else return 0;
}

int get_length(LinkedListType* list) {
    return list-&gt;length;
}

ListNode* get_node_at(LinkedListType* list, int pos) {
    //리스트 안에서 pos 위치의 노드를 반환한다

    int i;
    ListNode* tmp_node = list-&gt;head;

    if (pos &lt; 0)return NULL;

    for (i = 0; i &lt; pos; i++) {
        tmp_node = tmp_node-&gt;link;
    }

    return tmp_node;
}

void add(LinkedListType* list, int position, element data) {
    //주어진 위치에 데이터를 삽입한다

    ListNode* p;
    if ((position &gt;= 0) &amp;&amp; (position &lt;= list-&gt;length)) {
        ListNode* node = (ListNode*)malloc(sizeof(ListNode));

        if (node == NULL)error(&quot;메모리 할당 에러&quot;);

        node-&gt;data = data;
        p = get_node_at(list, position - 1);
        insert_node(&amp;(list-&gt;head), p, node);
        list-&gt;length++;
    }

}

void add_last(LinkedListType* list, element data) {
    add(list, get_length(list), data);
}

void add_first(LinkedListType* list, element data) {
    add(list, 0, data);
}

void delete(LinkedListType* list, int pos) {
    if (!is_empty(list) &amp;&amp; (pos &gt;= 0) &amp;&amp; (pos &lt; list-&gt;length)) {
        ListNode* p = get_node_at(list, pos - 1);
        ListNode* removed = get_node_at(list, pos);
        remove_node(&amp;(list-&gt;head), p, removed);
        list-&gt;length--;
    }
}

element get_entry(LinkedListType* list, int pos) {
    ListNode* p;
    if (pos &gt;= list-&gt;length)error(&quot;위치 오류&quot;);

    p = get_node_at(list, pos);

    return p-&gt;data;
}

void clear(LinkedListType* list) {
    for (int i = 0; i &lt; list-&gt;length; i++) {
        delete(list, i);
    }
}

void display(LinkedListType* list) {

    ListNode* node = list-&gt;head;
    printf(&quot;( &quot;);

    for (int i = 0; i &lt; list-&gt;length; i++) {
        printf(&quot;%d &quot;, node-&gt;data);
        node = node-&gt;link;
    }

    printf(&quot; )\n&quot;);
}

int is_in_list(LinkedListType* list, element item) {
    ListNode* p;
    p = list-&gt;head;

    while ((p != NULL)) {
        if (p-&gt;data == item)
            break;
        p = p-&gt;link;
    }

    if (p == NULL)return FALSE;
    else return TRUE;
}



int main() {

    LinkedListType list1;

    init(&amp;list1);

    add(&amp;list1, 0, 20);
    add_last(&amp;list1, 30);
    add_first(&amp;list1, 10);
    add_last(&amp;list1, 40);

    //list1 = (10,20,30,40)
    display(&amp;list1);

    //list1 = (10,20,30)
    delete(&amp;list1, 3);
    display(&amp;list1);

    //list1=(20,30)
    delete(&amp;list1, 0);
    display(&amp;list1);

    printf(&quot;%s\n&quot;, is_in_list(&amp;list1, 20) == TRUE ? &quot;성공&quot; : &quot;실패&quot;);
    printf(&quot;%d\n&quot;, get_entry(&amp;list1, 0));

    return 0;
}</code></pre>
<p><img src="https://images.velog.io/images/woo_hyun_1/post/0302f5e2-d6e0-4a17-bab9-fda98c9d9175/image.png" alt=""></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[자료구조] 4. 리스트 응용]]></title>
            <link>https://velog.io/@woo_hyun_1/%EC%9E%90%EB%A3%8C%EA%B5%AC%EC%A1%B0-4.-%EB%A6%AC%EC%8A%A4%ED%8A%B8-%EC%9D%91%EC%9A%A9</link>
            <guid>https://velog.io/@woo_hyun_1/%EC%9E%90%EB%A3%8C%EA%B5%AC%EC%A1%B0-4.-%EB%A6%AC%EC%8A%A4%ED%8A%B8-%EC%9D%91%EC%9A%A9</guid>
            <pubDate>Sun, 27 Feb 2022 15:59:50 GMT</pubDate>
            <description><![CDATA[<h1 id="연결-리스트의-응용--다항식">연결 리스트의 응용 : 다항식</h1>
<p>다항식은 단순 연결 리스트로 표현 가능한데, 이 경우에 각 항이 하나의 노드로 표현된다.</p>
<p>각 노드는 계수(coef)와 지수(expon) 그리고 다음 항을 가리키는 링크(link)필드로 구성되어 있다.</p>
<pre><code class="language-c">typedef struct ListNode {

    int coef;
    int expon;
    struct ListNode* link;

}ListNode;</code></pre>
<p>각 다항식은 다항식의 첫 번째 항을 가리키는 포인터로 표현된다.</p>
<p>ListNode *A, *B;</p>
<p>다항식이 연결 리스트로 표현되어 있기 때문에 포인터 변수 p와 q를 이용하여 다항식 A와 B의 항들을 따라 순회하면서 각 항들을 더하면 된다.</p>
<p>p와 q가 가리키는 항의 지수에 따라 3가지 경우로 나누어 처리할 수 있다.</p>
<ol>
<li><p>p.expon == q.expon : 두 계수를 더해서 0이 아니면 새로운 항을 만들어 다항식 C에 추가한다. 그리고 p와 q는 모두 다음 항으로 이동한다.</p>
</li>
<li><p>p.expon &lt; q.expon : q가 가리키는 항을 새로운 항으로 복사하여 다항식 C에 추가한다. 그리고 q만 다음 항으로 이동한다.</p>
</li>
<li><p>p.expon &gt; q.expon : p가 가리키는 항을 새로운 항으로 복사하여 다항식 C에 추가한다. 그리고 p만 다음 항으로 이동한다.</p>
</li>
</ol>
<p>앞의 과정들을 p나 q 둘 중에서 어느 하나가 NULL이 될 때까지 되풀이한다.</p>
<p>p나 q중에서 어느 하나가 NULL이 되면 아직 남아 있는 항들을 C로 전부 가져오면 된다.</p>
<p><em>여기서는 하나의 연결 리스트가 두 개의 포인터 head와 tail로 표현되고 있다.</em></p>
<p>head는 첫 번째 노드를, tail은 마지막 노드를 가리킨다.</p>
<p>이런 식으로 효율적인 계산을 위하여 첫 번째 노드와 마지막 노드를 가리키는 포인터를 동시에 사용하는 수도 많다.</p>
<p>보통은 <strong>헤더 노드(Header node)</strong>라고 하는 특수한 노드가 있고 이 헤더 노드가 head와 tail포인터를 동시에 가지고 있다.</p>
<p>추가로 연결 리스트에 들어 있는 항목들의 개수인 length 변수도 가지는 경우가 많다.</p>
<p>이런 경우, 하나의 연결 리스트는 하나의 헤더 노드에 의하여 표현된다.</p>
<p>실제로 헤더 노드를 사용하게 되면 편리한 점이 매우 많다.</p>
<p>하나의 예를 들면 맨 끝에 노드를 추가하는 경우, 단순 연결 리스트의 경우 매번 추가할 때마다 처음부터 포인터를 따라서 끝까지 가야 한다.</p>
<p>그러나 만일 마지막 노드를 항상 가리키는 포인터가 있는 경우에는 아주 효율적으로 추가하는 것이 가능해진다.</p>
<p>반면, 헤더 노드의 개념을 사용하기 위해서는 항상 연결 리스트를 생성한 다음, 초기화를 해주어야 한다.</p>
<p>여기서는 init함수를 이용하여 초기화하였다. </p>
<p>여기서도 새로운 노드가 만들어질 때마다 결과 다항식의 마지막 노드를 찾는 작업을 피하기 위하여 마지막 노드를 가리키는 tail 포인터를 헤더 노드 안에서 유지한다.</p>
<p>insert_node_last 함수는 새로운 노드를 만들어서 다항식의 마지막에 추가하는 역할을 한다.</p>
<p>이때 헤더 노드를 가리키는 포인터가 함수의 매개 변수로 전달되는 것을 유의하라.</p>
<p>이는 헤드와 테일 포인터를 변경하기 위한 것이다.</p>
<p>많은 연결 리스트 연산들이 이 함수처럼 헤드 포인터에서 시작하여 노드들을 하나씩 따라가면서 처리를 하는 형식으로 되어 있다.</p>
<pre><code class="language-c">#include &lt;stdio.h&gt;
#include &lt;stdlib.h&gt;

//연결 리스트의 노드의 구조
typedef struct ListNode {

    int coef;
    int expon;
    struct ListNode* link;

}ListNode;

//연결 리스트 헤더
typedef struct ListHeader {
    int length;
    ListNode* head;
    ListNode* tail;
}ListHeader;

//초기화 함수
void init(ListHeader* plist) {
    plist-&gt;length = 0;
    plist-&gt;head = plist-&gt;tail = NULL;
}

//오류 처리 함수
void error(char* message) {
    fprintf(stderr, &quot;%s\n&quot;, message);
    exit(1);
}

//plist는 연결 리스트의 헤더를 가리키는 포인터, coef는 계수, expon은 지수
void insert_node_last(ListHeader* plist, int coef, int expon) {
    ListNode* temp = (ListNode*)malloc(sizeof(ListNode));
    if (temp == NULL)error(&quot;메모리 할당 에러&quot;);
    temp-&gt;coef = coef;
    temp-&gt;expon = expon;
    temp-&gt;link = NULL;

    if (plist-&gt;tail == NULL) {
        plist-&gt;head = plist-&gt;tail = temp;
    }
    else {
        plist-&gt;tail-&gt;link = temp;
        plist-&gt;tail = temp;
    }
    plist-&gt;length++;
}

void poly_add(ListHeader *plist1,ListHeader *plist2, ListHeader *plist3) {

    ListNode* a = plist1-&gt;head;
    ListNode* b = plist2-&gt;head;

    int sum;

    while (a &amp;&amp; b) {

        if (a-&gt;expon == b-&gt;expon) {
            sum = a-&gt;coef + b-&gt;coef;
            if (sum != 0) insert_node_last(plist3, sum, a-&gt;expon);
            a = a-&gt;link;
            b = b-&gt;link;
        }
        else if (a-&gt;expon &gt; b-&gt;expon) {
            insert_node_last(plist3, a-&gt;coef, a-&gt;expon);
            a = a-&gt;link;
        }
        else {
            insert_node_last(plist3, b-&gt;coef, b-&gt;expon);
            b = b-&gt;link;
        }

    }

    for (; a != NULL; a = a-&gt;link) {
        insert_node_last(plist3, a-&gt;coef, a-&gt;expon);
    }
    for (; b != NULL; b = b-&gt;link) {
        insert_node_last(plist3, b-&gt;coef, b-&gt;expon);
    }

}

void poly_print(ListHeader* plist) {
    ListNode* p = plist-&gt;head;
    for (; p; p = p-&gt;link) {
        printf(&quot;%d %d\n&quot;, p-&gt;coef, p-&gt;expon);
    }
}

int main() {

    ListHeader* list1, * list2, * list3;

    init(&amp;list1);
    init(&amp;list2);
    init(&amp;list3);

    insert_node_last(&amp;list1, 3, 12);
    insert_node_last(&amp;list1, 2, 8);
    insert_node_last(&amp;list1, 1, 0);

    insert_node_last(&amp;list2, 8, 12);
    insert_node_last(&amp;list2, -3, 10);
    insert_node_last(&amp;list2, 10, 6);

    poly_add(&amp;list1, &amp;list2, &amp;list3);
    poly_print(&amp;list3);

    return 0;
}</code></pre>
<p><img src="https://images.velog.io/images/woo_hyun_1/post/4aece281-aa46-407a-881e-de2ea1c07e5f/image.png" alt=""></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[DB] 3. 테이블 구조 참조하기]]></title>
            <link>https://velog.io/@woo_hyun_1/DB-3.-%ED%85%8C%EC%9D%B4%EB%B8%94-%EA%B5%AC%EC%A1%B0-%EC%B0%B8%EC%A1%B0%ED%95%98%EA%B8%B0</link>
            <guid>https://velog.io/@woo_hyun_1/DB-3.-%ED%85%8C%EC%9D%B4%EB%B8%94-%EA%B5%AC%EC%A1%B0-%EC%B0%B8%EC%A1%B0%ED%95%98%EA%B8%B0</guid>
            <pubDate>Sun, 27 Feb 2022 13:12:47 GMT</pubDate>
            <description><![CDATA[<p>이번에는 DESC 명령으로 테이블 구조를 참조하는 방법에 대해 학습한다.</p>
<p>SELECT 명령으로 테이블의 데이터를 읽어왔고, 테이블은 한 개 이상의 열로 구성된다.</p>
<p>Hello World의 SELECT 명령에서는 생략했지만, 열을 지정하여 조건을 붙이거나 특정 열의 값을 읽어올 수 있다.</p>
<p>테이블에 어떤 열이 있는지 참조할 수 있다면 SELECT 명령을 작성하기 쉬워진다.</p>
<h1 id="desc-명령">DESC 명령</h1>
<p><img src="https://images.velog.io/images/woo_hyun_1/post/935bc0c2-86e9-4514-b3b4-c7b7488afb91/image.png" alt=""></p>
<p>이와 같이 DESC 명령으로 테이블에 어떤 열이 정의되어 있는지 알 수 있다.</p>
<p>Field : 열 이름
Type : 해당 열의 자료형
Null : 널값 허용유무
Key : 해당 열이 키로 지정되어 있는가
Default : 생략했을 경우 적용되는 기본값</p>
<h1 id="자료형">자료형</h1>
<p>테이블은 하나 이상의 열로 구성되며 DESC 명령으로 그 구조를 참조할 수 있다는 것을 알았다.</p>
<p>열에는 몇 가지 속성을 지정할 수 있는데 그중 가장 중요한 속성은 자료형이다.</p>
<ol>
<li>INTEGER형</li>
<li>CHAR형</li>
<li>VARCHAR형</li>
<li>DATE형</li>
<li>TIME형</li>
</ol>
<p><img src="https://images.velog.io/images/woo_hyun_1/post/830745b3-c0e9-446d-8363-c90b40f78435/image.png" alt=""></p>
<blockquote>
<p>문자열형에는 고정 길이(CHAR)와 가변 길이(VARCHAR)가 있다 !</p>
</blockquote>
]]></description>
        </item>
        <item>
            <title><![CDATA[[DB] 2. Hello World 실행하기]]></title>
            <link>https://velog.io/@woo_hyun_1/DB-2.-Hello-World-%EC%8B%A4%ED%96%89%ED%95%98%EA%B8%B0</link>
            <guid>https://velog.io/@woo_hyun_1/DB-2.-Hello-World-%EC%8B%A4%ED%96%89%ED%95%98%EA%B8%B0</guid>
            <pubDate>Sun, 27 Feb 2022 12:31:54 GMT</pubDate>
            <description><![CDATA[<h1 id="select--from-테이블명-실행">&#39;SELECT * FROM 테이블명&#39; 실행</h1>
<p>SQL명령은 mysql 클라이언트에 문자를 입력하여 실행할 수 있다.</p>
<p><img src="https://images.velog.io/images/woo_hyun_1/post/3b2f3382-f85d-432c-8cc5-b7806f6156cc/image.png" alt=""></p>
<p><img src="https://images.velog.io/images/woo_hyun_1/post/9d85b85f-5204-48b3-b0d3-0dfa501d028d/image.png" alt=""></p>
<blockquote>
<p>mysql 클라이언트에 SQL명령을 입력하여 실행할 수 있다.
이때 SQL 명령의 마지막에는 세미콜론을 붙인다.</p>
</blockquote>
<h1 id="select-명령-구문">SELECT 명령 구문</h1>
<p>Hello World에서 실행한 SQL 명령은 SELECT 명령이다.</p>
<p>SELECT는 DML에 속하는 명령으로 SQL에서 자주 사용된다.</p>
<p>SELECT명령으로 데이터베이스의 데이터를 읽어올 수 있다.</p>
<p>SELECT명령은 &#39;질의&#39;나 &#39;쿼리&#39;라고 불리기도 한다.</p>
<blockquote>
<p>SELECT(명령의 종류) *(모든 열) FROM sample21(테이블명);
별은 모든 열을 의미하는 메타문자이다. SQL명령은 몇 개의 구로 구성된다.</p>
</blockquote>
<h1 id="예약어와-데이터베이스-객체명">예약어와 데이터베이스 객체명</h1>
<p>SELECT, FROM은 구를 결정하는 키워드이자 예약어이다.</p>
<p>데이터베이스에는 테이블 외에 다양한 데이터를 저장하거나 관리하는 &#39;데이터베이스 객체&#39;를 만들 수 있다.</p>
<p>ex)뷰(view) , 6장에서 자세히 설명</p>
<p>데이터베이스 객체는 이름을 붙여 관리한다. 같은 이름이나 예약어와 동일한 이름을 가진 데이터베이스 객체는 만들 수 없다.</p>
<p><em>또한 예약어와 데이터베이스 객체명은 대소문자를 구별하지 않는다.</em></p>
<p>SQL명령과 달리 많은 DB 제품들은 데이터의 대소문자를 구별한다.</p>
<h1 id="hello-world를-실행한-결과--테이블">Hello World를 실행한 결과 = 테이블</h1>
<p>SELECT 명령을 실행하면 표 형식의 데이터가 출력된다.</p>
<p>표 형식 데이터는 <strong>&#39;행(레코드)&#39;</strong>과 <strong>&#39;열(컬럼/필드)&#39;</strong>로 구성된다.</p>
<p>행은 모두 동일한 형태로 되어 있으며 옆으로 열이 나열되는데, 열마다 이름이 지정되어 있다.</p>
<p>각각의 행과 열이 만나는 부분을 <strong>&#39;셀&#39;</strong>이라고 부른다. 셀에는 하나의 데이터 값이 저장되어 있다.</p>
<p>숫자만으로 구성된 수치형 데이터는 오른쪽 정렬로 표시되고, 임의의 문자로 구성된 문자열형 데이터와 날짜와 시각을 나타내는 날짜시간형 데이터는 왼쪽으로 정렬되어 표시된다.</p>
<blockquote>
<p>데이터는 자료형으로 분류할 수 있다.
열은 하나의 자료형만 가질 수 있다.</p>
</blockquote>
<h1 id="값이-없는-데이터--null">값이 없는 데이터 = NULL</h1>
<p>NULL은 특별한 데이터 값으로 아무것도 저장되어 있지 않은 상태를 의미한다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[운영체제] 프로세스 생성 실습 및 퀴즈]]></title>
            <link>https://velog.io/@woo_hyun_1/%EC%9A%B4%EC%98%81%EC%B2%B4%EC%A0%9C-%ED%94%84%EB%A1%9C%EC%84%B8%EC%8A%A4-%EC%83%9D%EC%84%B1-%EC%8B%A4%EC%8A%B5</link>
            <guid>https://velog.io/@woo_hyun_1/%EC%9A%B4%EC%98%81%EC%B2%B4%EC%A0%9C-%ED%94%84%EB%A1%9C%EC%84%B8%EC%8A%A4-%EC%83%9D%EC%84%B1-%EC%8B%A4%EC%8A%B5</guid>
            <pubDate>Sun, 27 Feb 2022 09:50:02 GMT</pubDate>
            <description><![CDATA[<pre><code class="language-c">#include &lt;stdio.h&gt;
#include &lt;unistd.h&gt;
#include &lt;wait.h&gt;

int value=5;

int main()
{
    pid_t pid;

    pid = fork();

    printf(&quot;Hello, Process! %d\n&quot;,pid);

    return 0;
}</code></pre>
<p><img src="https://images.velog.io/images/woo_hyun_1/post/8e8c65c7-fc05-4d5c-b1eb-882f16e25dfe/image.png" alt=""></p>
<pre><code class="language-c">#include &lt;stdio.h&gt;
#include &lt;unistd.h&gt;
#include &lt;wait.h&gt;

int value=5;

int main()
{
    pid_t pid;

    pid = fork();

    if(pid&gt;0) wait(NULL); //부모 프로세스를 wait 상태로 변경
    printf(&quot;Hello, Process! %d\n&quot;,pid);

    return 0;
}</code></pre>
<p><img src="https://images.velog.io/images/woo_hyun_1/post/394dad2d-fd8b-4168-83cf-df89a1b9dfc8/image.png" alt=""></p>
<pre><code class="language-c">#include &lt;stdio.h&gt;
#include &lt;unistd.h&gt;
#include &lt;wait.h&gt;

int value=5;

int main()
{
    pid_t pid;

    pid = fork();

    if(pid==0){ //child process
        value+=15;
        return 0;
    }
    else if(pid&gt;0){ //parent process
        wait(NULL);
        printf(&quot;Parent: value = %d\n&quot;,value);
    }

}</code></pre>
<p><img src="https://images.velog.io/images/woo_hyun_1/post/629d3b35-f94d-4d25-a9e2-431153844811/image.png" alt=""></p>
<pre><code class="language-c">#include &lt;stdio.h&gt;
#include &lt;unistd.h&gt;

//How many processes are created?

int main(){

    fork();
    fork();
    fork();

}</code></pre>
<p>답은 8이다. 먼저 첫 번째 fork()에서 두 개의 프로세스가 생성되고, 그 두 개의 프로세스에서 fork()를 통해 네 개, 마지막 fork()에서 총 8개가 된다.</p>
<pre><code class="language-c">#include &lt;stdio.h&gt;
#include &lt;unistd.h&gt;
#include &lt;wait.h&gt;

int value=5;

int main()
{
    pid_t pid;

    pid = fork();

    if(pid==0){ //child process
        execlp(&quot;/bin/ls&quot;,&quot;ls&quot;,NULL);
        printf(&quot;LINE J\n&quot;); //실행되지 않음(ls로 덮어씌워졌기 때문)
    }
    else if(pid&gt;0){ //parent process
        wait(NULL);
        printf(&quot;Child Complete\n&quot;);
    }

    return 0;

}</code></pre>
<p><img src="https://images.velog.io/images/woo_hyun_1/post/23b3e625-1746-4a4e-be97-a79d786ab50d/image.png" alt=""></p>
<pre><code class="language-c">#include &lt;stdio.h&gt;
#include &lt;unistd.h&gt;
#include &lt;wait.h&gt;
#define SIZE 5

int nums[SIZE]={0,1,2,3,4};

int main()
{
    pid_t pid;
    int i;
    pid = fork();

    if(pid==0){
        for(i=0;i&lt;SIZE;i++){
            nums[i]*=i;
            printf(&quot;CHILD: %d \n&quot;,nums[i]);
        }
    }
    else if(pid&gt;0){
        wait(NULL);
        for(i=0;i&lt;SIZE;i++){
            printf(&quot;PARENT: %d \n&quot;,nums[i]);
        }
    }

    return 0;

}</code></pre>
<p><img src="https://images.velog.io/images/woo_hyun_1/post/b9462b83-0412-430d-809b-0c98638e0d14/image.png" alt=""></p>
<h1 id="quiz">Quiz</h1>
<p><img src="https://images.velog.io/images/woo_hyun_1/post/6a199876-e593-40a3-abb3-847263776116/image.png" alt="">
1)</p>
<p><img src="https://images.velog.io/images/woo_hyun_1/post/b09c03d0-a506-4a7f-8333-9f1c0be2f3d3/image.png" alt=""></p>
<p>1) (X)
2) (O)</p>
<p><img src="https://images.velog.io/images/woo_hyun_1/post/903512ab-f825-4c73-904c-2a78f8def053/image.png" alt="">
5)</p>
<p><img src="https://images.velog.io/images/woo_hyun_1/post/be9e442d-f565-4595-9a39-3dc64e3e1bff/image.png" alt="">
2)</p>
<p><img src="https://images.velog.io/images/woo_hyun_1/post/27cd767e-b0ad-4c38-9181-3e4fc252c859/image.png" alt="">
4)</p>
<p><img src="https://images.velog.io/images/woo_hyun_1/post/bfc05799-c5f3-48ab-ac7f-bc7ea10bb99e/image.png" alt=""></p>
<p>1) (X)
4) (O)</p>
<p><img src="https://images.velog.io/images/woo_hyun_1/post/3f10c66a-b5a4-40d1-b573-0ecd2f7abaa4/image.png" alt="">
4) (X)
2) (O)</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[운영체제] 프로세스]]></title>
            <link>https://velog.io/@woo_hyun_1/%EC%9A%B4%EC%98%81%EC%B2%B4%EC%A0%9C-%ED%94%84%EB%A1%9C%EC%84%B8%EC%8A%A4</link>
            <guid>https://velog.io/@woo_hyun_1/%EC%9A%B4%EC%98%81%EC%B2%B4%EC%A0%9C-%ED%94%84%EB%A1%9C%EC%84%B8%EC%8A%A4</guid>
            <pubDate>Sat, 26 Feb 2022 16:26:26 GMT</pubDate>
            <description><![CDATA[<h1 id="프로세스의-정의">프로세스의 정의</h1>
<p><img src="https://images.velog.io/images/woo_hyun_1/post/9da0981d-e0e1-4658-8d24-7834ed94bb3d/image.png" alt="">
프로세스란 실행중인 프로그램을 의미한다.</p>
<p>운영체제에서의 작업 단위는 프로세스이며, 작업을 수행하기 위해 CPU time과 메모리, 확실한 리소스(Files, I/O device)들을 필요로 한다.</p>
<p>OS가 해야하는 가장 기본적인 일은 프로세스를 관리하는 것이다.</p>
<p>여러 개의 섹션으로 나눠져 있는 프로세스들을 살펴보면 다음과 같다.
<img src="https://images.velog.io/images/woo_hyun_1/post/30f5e91d-d062-4dc2-8755-ef32a420c956/image.png" alt=""></p>
<p><img src="https://images.velog.io/images/woo_hyun_1/post/9e4cd12d-b4b7-4af1-b272-094655ed79a8/image.png" alt=""></p>
<p>Text section : 명령어들(the executable code)
Data section : 전역변수들(global variables)
Heap section : 메모리 allocatation
Stack section : 함수 호출할 때의 데이터 임시 저장(함수 매개변수, 주소 반환값, 지역 변수)</p>
<p><img src="https://images.velog.io/images/woo_hyun_1/post/410392f7-63c0-421f-85b4-ec87137092c7/image.png" alt="">
<img src="https://images.velog.io/images/woo_hyun_1/post/0a95dc9b-eb56-4df9-bbc6-0c382f8922ad/image.png" alt="">
New : 프로세스가 생성된 상태
Running : 정렬된 프로세스를 CPU가 읽고 실행하는 명령어들이 실행중인 상태
Waiting : 다른 실행중인 프로세스로 인해 기다리고 있는 상태
Ready : CPU를 점유할 준비되어있는 상태
Terminated : 종료한 상태</p>
<p><img src="https://images.velog.io/images/woo_hyun_1/post/31994d72-499b-4b06-838f-ef65b3c1bd34/image.png" alt="">
<img src="https://images.velog.io/images/woo_hyun_1/post/19bb6e39-51bf-42ee-8cce-49877849de40/image.png" alt="">
각각의 프로세스를 관리하기 위해서 운영체제에서는 PCB(Process Control Block)이라는 구조체로 프로세스들을 표시한다.</p>
<p>PCB에는 특정 프로세스와 관련된 많은 정보가 포함되어 있다.</p>
<p>프로세스 상태, PC, CPU 레지스터, CPU-스케쥴링 정보, 메모리 관리 정보(할당 관련), 입출력 정보 등</p>
<p><img src="https://images.velog.io/images/woo_hyun_1/post/62a08c2a-f5a8-4c1c-b76e-d62dd20d3df8/image.png" alt="">
프로세스는 단일 스레드 실행을 수행하는 프로그램이다.
• 단일 제어 스레드를 통해 프로세스는 한 번에 하나의 작업만 수행할 수 있다.
• 최신 운영 체제는 프로세스가 여러 스레드를 실행하여 한 번에 둘 이상의 작업을 수행할 수 있도록 프로세스 개념을 확장했다.(운영체제의 존재 이유)</p>
<p>스레드는 가벼운 프로세스이다.(위에서의 thread와는 다른 의미, 4장에서 멀티스레딩에 대해서 다룰 것)</p>
<p><img src="https://images.velog.io/images/woo_hyun_1/post/efaf0d2d-a45d-4f51-b1e1-bccb513a8cd5/image.png" alt="">
▪ 멀티프로그래밍의 목적은 CPU 활용도를 최대화하기 위해 어떤 프로세스를 항상 실행시키는 것이다.
▪ 시간 공유의 목적은 사용자가 실행 중인 각 프로그램과 상호 작용할 수 있도록 프로세스 간에 CPU 코어를 자주 전환하는 것이다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[운영체제] 운영체제란 무엇인가]]></title>
            <link>https://velog.io/@woo_hyun_1/%EC%9A%B4%EC%98%81%EC%B2%B4%EC%A0%9C-%EC%9A%B4%EC%98%81%EC%B2%B4%EC%A0%9C%EB%9E%80-%EB%AC%B4%EC%97%87%EC%9D%B8%EA%B0%80</link>
            <guid>https://velog.io/@woo_hyun_1/%EC%9A%B4%EC%98%81%EC%B2%B4%EC%A0%9C-%EC%9A%B4%EC%98%81%EC%B2%B4%EC%A0%9C%EB%9E%80-%EB%AC%B4%EC%97%87%EC%9D%B8%EA%B0%80</guid>
            <pubDate>Sat, 26 Feb 2022 12:47:45 GMT</pubDate>
            <description><![CDATA[<h1 id="운영체제란">운영체제란?</h1>
<p>운영체제란 컴퓨터 시스템을 운영하는 소프트웨어이다. ex)윈도우10, 리눅스, Mac OS</p>
<h2 id="컴퓨터와-정보">컴퓨터와 정보</h2>
<p>컴퓨터란 정보를 처리하는 기계이다.</p>
<p>여기서 정보란 불확실성(uncertainty)를 측정하여 수치적으로(quantitative) 표현(representation)으로 나타낸 것이다.</p>
<p>정보의 최소 단위 : bit(binary digit)
정보의 처리 : 정보의 상태 변환(0-&gt;1 , 1-&gt;0)
부울 대수(Boolean Algebra) : NOT, AND, OR
논리 게이트 : NOT, AND, OR, XOR, NAND, NPR
논리 회로 : IC, LSI ... (무어의 법칙, 황의 법칙)
정보의 저장과 전송 : 플립-플롭, 데이터 버스</p>
<h2 id="컴퓨터가-정보를-어떻게-처리하는가">컴퓨터가 정보를 어떻게 처리하는가?</h2>
<p>덧셈 : 반가산기, 전가산기
뺄셈 : 2의 보수 표현법
곱셈과 나눗셈 : 덧셈과 뺄셈의 반복
실수 연산 : 부동 소수점 표현법
함수 : GOTO</p>
<h2 id="컴퓨터가-만능인가">컴퓨터가 만능인가?</h2>
<p>범용성(Universality) : NOT, AND, OR 게이트만으로 모든 계산을 할 수 있다.</p>
<p>또한 NAND 게이트만으로 모든 계산을 할 수 있다.</p>
<p>여러가지 S/W를 통해 범용적으로 계산을 할 수 있는 것을 범용 컴퓨터(General-purpose computer)라고 한다.(단순한 계산기와의 차이)</p>
<p>계산 가능성(Computability) : Turing-computable, 튜링 머신으로 계산가능한 것을 의미한다.</p>
<p>튜링 머신으로 풀 수 없는 문제에는 정지 문제(Halting Problem)이 있다.</p>
<h2 id="컴퓨터는-누가-만들었는가">컴퓨터는 누가 만들었는가?</h2>
<p>컴퓨터의 할아버지는 앨런 튜링(튜링 머신), 아버지는 폰 노이만(ISA)이다.</p>
<p><img src="https://images.velog.io/images/woo_hyun_1/post/a1e71194-1a17-48a9-bbe9-5998f9648c38/image.png" alt=""> 
앨런 튜링이 모든 현대 컴퓨터의 원형을 설계한 것이나 마찬가지.</p>
<p><img src="https://images.velog.io/images/woo_hyun_1/post/02f45306-45be-4b26-b4aa-864da5ec1bbc/image.png" alt="">
폰 노이만은 내장형 프로그램(stored-program) 방식을 처음으로 도입하였다.</p>
<p>내장형 프로그램 컴퓨터란 메모리에 프로그램을 저장하는 컴퓨터를 의미한다.</p>
<p>컴퓨터라는 H/W는 S/W에 따라서 하드웨어의 목적이 달라진다.(범용성)</p>
<p>RAM이라는 메모리에 프로그램(명령어들의 집합)이 탑재되면 그 명령어들을 CPU가 하나씩 <strong>&#39;fetch&#39;</strong>하여 <strong>&#39;execute&#39;</strong>한다.</p>
<p>이러한 fetch-execute cycle을 가진 내장형 프로그램 컴퓨터를 처음으로 설계한 것이 폰 노이만이고, 이를 폰 노이만 아키텍쳐(ISA)라고 부른다.</p>
<h2 id="프로그램이란">프로그램이란?</h2>
<p><img src="https://images.velog.io/images/woo_hyun_1/post/721d5b69-f31e-4b37-a178-dba0c62f7134/image.png" alt="">
프로그램이란 컴퓨터 하드웨어에게 특정한 일을 수행하도록 말해주는 &#39;명령어들의 집합&#39;이다.</p>
<h2 id="운영체제도-프로그램인가">운영체제도 프로그램인가?</h2>
<p><img src="https://images.velog.io/images/woo_hyun_1/post/b3365420-f1c2-49d6-83dd-c748d85155f6/image.png" alt="">
운영체제는 하드웨어 위에서 애플리케이션 프로그램들에게 서비스를 제공하는 컴퓨터에서 항상 실행중인 프로그램이다.</p>
<ul>
<li>프로세스, 리소스, 유저 인터페이스 등을 관리</li>
</ul>
<p><img src="https://images.velog.io/images/woo_hyun_1/post/d56611c1-f4c0-4a07-aff6-05e3c7989e2b/image.png" alt="">
운영체제란 <u>하드웨어를 제어하면서 APP에게 서비스를 제공하며 유저와의 인터페이스, 프로세스, 리소스등을 관리하는 소프트웨어</u>이다.</p>
<p><img src="https://images.velog.io/images/woo_hyun_1/post/30d4d7bb-9326-45f6-b9a4-97cfc0d07ccf/image.png" alt=""></p>
<ol>
<li>컴퓨터의 하드웨어를 제어/관리하는 소프트웨어</li>
<li>운영체제는 애플리케이션 프로그램 및 유저들과 하드웨어간의 중간 매개역할</li>
</ol>
<p>OS의 범용적인 정의는 없지만 공통적인 정의로는 &quot;컴퓨터에서 항상 실행되고 있는 프로그램 한개&quot;라면 kernel은 운영체제의 핵심이다.</p>
<p>Kernel에서 System programs와 Application programs에 대한 인터페이스를 제공해준다.(우리는 수업 때 kernel에 대해 배울 것)</p>
<p><img src="https://images.velog.io/images/woo_hyun_1/post/3b20a484-ec85-460f-a761-6b308a607215/image.png" alt="">
현대 컴퓨터 시스템은 하나 이상의 CPU와 장치 제어자들과 버스로 연결되어있다.</p>
<p><img src="https://images.velog.io/images/woo_hyun_1/post/4200653e-5fe6-4ee4-b7b6-5dd91996032a/image.png" alt="">
부트스트랩 프로그램은 컴퓨터 전원을 키기 위한 첫번째 프로그램으로 프로그램들을 실행하기전에 메모리에 O/S를 로딩한다.</p>
<p><img src="https://images.velog.io/images/woo_hyun_1/post/22538319-e19c-4ad6-b592-0c8122dd14f5/image.png" alt="">
Interrupt란 시스템 버스를 통해 CPU에게 신호를 전송하는 방법이다. (CPU와 I/O device가 통신하는 방식)</p>
<h2 id="quiz">Quiz</h2>
<p><img src="https://images.velog.io/images/woo_hyun_1/post/a5571163-d8a5-4eff-bb8b-9e37fe64ea57/image.png" alt="">
2)사건의 확률이 1/4 이므로 정보량은 -log2(2^(-2)) = 2 이다.</p>
<p><img src="https://images.velog.io/images/woo_hyun_1/post/4e60b780-8340-4f4b-9537-72f04ac1cd0d/image.png" alt="">
1,5)</p>
<p><img src="https://images.velog.io/images/woo_hyun_1/post/3588c00e-b379-4a7e-9a59-d9d460123667/image.png" alt="">
3)</p>
<p><img src="https://images.velog.io/images/woo_hyun_1/post/0a271da2-c08a-4c47-a436-c4cf454ce42d/image.png" alt="">
4)</p>
<p><img src="https://images.velog.io/images/woo_hyun_1/post/820f6088-8232-476f-b83e-d1e4ec1d08e9/image.png" alt="">
1)</p>
<p><img src="https://images.velog.io/images/woo_hyun_1/post/a5716e1d-f380-4992-bb76-d87d47d629ba/image.png" alt="">
3)</p>
<p><img src="https://images.velog.io/images/woo_hyun_1/post/f29a1901-59dc-4590-b394-b79e5ce3990e/image.png" alt="">
1)</p>
<p><img src="https://images.velog.io/images/woo_hyun_1/post/93bb22c4-6b5f-4e2c-ae42-7e3b1cdfa803/image.png" alt="">
1)</p>
]]></description>
        </item>
    </channel>
</rss>