<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>sAN_i.log</title>
        <link>https://velog.io/</link>
        <description>@p_eunsan_</description>
        <lastBuildDate>Sat, 25 Nov 2023 17:24:28 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <copyright>Copyright (C) 2019. sAN_i.log. All rights reserved.</copyright>
        <atom:link href="https://v2.velog.io/rss/silv_san_i" rel="self" type="application/rss+xml"/>
        <item>
            <title><![CDATA[[C언어] 문자열 처리 - 11.26]]></title>
            <link>https://velog.io/@silv_san_i/C%EC%96%B8%EC%96%B4-%EB%AC%B8%EC%9E%90%EC%97%B4-%EC%B2%98%EB%A6%AC-11.26-e8d6vxx9</link>
            <guid>https://velog.io/@silv_san_i/C%EC%96%B8%EC%96%B4-%EB%AC%B8%EC%9E%90%EC%97%B4-%EC%B2%98%EB%A6%AC-11.26-e8d6vxx9</guid>
            <pubDate>Sat, 25 Nov 2023 17:24:28 GMT</pubDate>
            <description><![CDATA[<h1 id="문자열-처리-함수">문자열 처리 함수</h1>
<p>C언어에서 문자열이란 마지막에 NULL 문자를 가지는 문자형 배열로 표현되며, 기본 타입에 포함되지 않는다. 따라서 C 컴파일러가 기본 타입을 위해 제공하는 다양한 연산자를 자유롭게 사용할 수 없다.</p>
<p>C언어는 문자열을 처리하기 위한 다양한 함수를 별도로 제공하고 있다. 
C에서 제공하는 대표적인 문자열 처리 함수는 다음과 같다.</p>
<blockquote>
<p>strlen() 함수
strcat(), strncat() 함수
strcpy(), strrncpy() 함수
strcmp(), strncmp() 함수
atoi(), atol(), atoll(), atof() 함수
toupper(), tolower() 함수</p>
</blockquote>
<h2 id="strlen-함수">strlen() 함수</h2>
<p>strlen() 함수는 인수로 전달된 문자열의 길이를 반환하는 함수이다.
이때 문자열 여부를 구분하는 마지막 문자인 NULL 문자는 문자열의 길이에서 제외된다.</p>
<pre><code class="language-c"> #include &lt;stdio.h&gt;
 #include &lt;string.h&gt;

 int main(void)
 {

   char str[] = &quot;C언어&quot;;
   printf(&quot;이 문자의 길이는 %d입니다.\n&quot;, strlen(str));

   return 0;
 }
 /* [실행결과]
  이 문자열의 길이는 7입니다.
 */</code></pre>
<hr>
<h2 id="strcat-함수와-strncat-함수">strcat() 함수와 strncat() 함수</h2>
<p>strcat()함수와 strncat() 함수는 하나의 문자열에 다른 문자열을 연결해주는 함수이다.</p>
<p>strcat() 함수의 첫 번째 인수로 전달된 문자열은 기준 문자열이 된다. 두 번째 인수로 전달된 추가하고자 하는 문자열의 복사본이 기준 문자열 뒤에 추가된다.</p>
<p>이때 기본 문자열이 저장된 배열의 공간이 충분하지 않으면, 배열을 채우고 남은 문자들이 배열 외부로 흘러넘칠 수 있다. 이런 현상을 <strong>배열 오버플로우</strong>라고 한다. 배열 오버플로우 현상을 방지하기 위해 strcat() 함수 대신에 strncat() 함수를 사용하는 것이 좋다. </p>
<p>strncat() 함수는 strcat() 함수와 하는 일은 같지만, 세 번째 인수로 추가할 문자열의 최대 길이를 지정할 수 있다. 이 함수는 NULL 문자를 만나거나, 추가하는 문자의 개수가 세 번째 인수로 전달된 최대 길이에 도달할 때까지 추가를 계속한다.</p>
<pre><code class="language-c"> #include &lt;stdio.h&gt;
 #include &lt;string.h&gt;

 int main(void)
 {

  char str01[20] = &quot;C language is &quot;; // 널 문자를 포함하여 15문자
  char str02[] = &quot;Cool! and funny!&quot;;  

  //strcat(str01, str02);   // 이 부분의 주석 처리를 삭제한 후 실행시키면 배열 오버플로우가 발생함

  strncat(str01, str02, 5); // 이렇게 최대 허용치를 설정해 놓으면 배열 오버플로우에 대해서는 안전해짐
  puts(str01);

  return 0;
 }

/* [실행결과]
C language is Cool! 
*/
</code></pre>
<p>위의 예제에서는 우선 널 문자를 포함한 총 15바이트 크기의 문자열을 20바이트 크기의 배열에 저장한다. 그리고 그 문자열에 정확히 5바이트 크기의 문자열을 추가하는 예제이다.</p>
<p>이때 strncat() 함수가 아닌 strcat() 함수를 사용해도 괜찮지만, 만약 5바이트 이상의 문자열을 추가하려고 한다면 배열 오버플로우가 발생할 것이기 때문에 상황에 맞게 쓰도록 하는 것이 좋다.</p>
<hr>
<h2 id="strcpy-함수와-strncpy-함수">strcpy() 함수와 strncpy() 함수</h2>
<p>strcpy() 함수와 strncpy() 함수는 문자열을 복사하는 함수이다.</p>
<p>strcpy()함수는 첫 번째 인수로 전달된 배열에, 두 번째 인수로 전달된 문자열을 복사한다. 하지만 이때 첫번째 인수로 배열의 크기가 복사할 문자열의 길이보다 작으면, 배열 오버플로우가 발생한다. 배열 오버플로우 현상을 방지하기 위해서는 strcpy() 함수 대신에 strncpy() 함수를 사용하는 것이 좋다.</p>
<p>strncpy() 함수는 strcpy() 함수와 하는 일은 같지만, 세 번째 인수로 복사할 문자열의 최대 길이를 지정할 수 있다. 이 함수는 NULL 문자를 만나거나, 복사하는 문자의 개수가 세 번째 인수로 전달된 최대 길이에 도달할 때까지 복사를 계속한다.</p>
<pre><code class="language-c">#include &lt;stdio.h&gt;
#include &lt;string.h&gt;

int main(void)
{
  char str01[20] = &quot;C is Cool!&quot;;
  char str02[11];  
// str02 배열의 크기만큼만 복사를 진행하며, 마지막 한 문자는 NULL 문자를 위한 것임

  strncpy(str02, str01, sizeof(str02)-1);
  str02[sizeof(str02)-1] = &#39;\0&#39;; // 이 부분을 주석 처리하면, 맨 마지막에 널 문자를 삽입하지 않음

  puts(str02);

  return 0;
}


/* [실행결과]
C is Cool!
*/</code></pre>
<hr>
<h2 id="strcmp-함수와-strncmp-함수">strcmp() 함수와 strncmp() 함수</h2>
<p>strcmp() 함수와 strncmp() 함수는 문자열의 내용을 비교하는 함수이다.</p>
<p>strcmp() 함수는 인수로 두 개의 문자열 포인터를 전달받아, 해당 포인터가 가리키는 문자열의 내용을 서로 비교한다.두 문자열의 모든 문자는 아스키 코드값으로 자동 변환되며, 문자열의 맨 앞에서부터 순서대로 비교된다.</p>
<p>strcmp() 함수의 상황별 반환값은 다음과 같다.</p>
<pre><code class="language-c">int strcmp(const char *s1, const char *s2);

// 반환 값이 양수 : s1이 s2보다 앞에 있다
// 반환 값이 0 : s1이 s2와 같다
// 반환 값이 음수 : s1이 s2보다 뒤에 있다. 
</code></pre>
<p>strncmp() 함수는 strcmp() 함수와 하는 일은 같지만, 세 번째 인수로 비교할 문자의 개수를 지정할 수 있다. 이 함수는 일치하지 않는 문자를 만나거나, 세 번째 인수로 전달된 문자의 개수만큼 비교를 계속한다.</p>
<pre><code class="language-c">#include &lt;stdio.h&gt;
#include &lt;string.h&gt;  

int main(void)

{
  char str[20];
  char ch;  
  while (1)
   {
       puts(&quot;미국의 수도를 입력하세요 :&quot;);
       scanf(&quot;%s&quot;, str);
       if (strcmp(str, &quot;워싱턴&quot;) == 0 || strcmp(str, &quot;washington&quot;) == 0){  // 문자열의 비교
          puts(&quot;정답입니다!&quot;);
          break;
       }
       else
          puts(&quot;아쉽네요~&quot;);
      fflush(stdin);  

      puts(&quot;\n이 프로그램을 끝내고자 한다면 &#39;q&#39;를 눌러주세요!&quot;);
      puts(&quot;계속 도전하고자 하시면 Enter를 눌러주세요!&quot;);
      scanf(&quot;%c&quot;, &amp;ch);  

      if (ch == &#39;q&#39;){ // 문자의 비교
          break;
       }
      fflush(stdin);
   }
   return 0;
}

/* [실행결과]
미국의 수도를 입력하세요 : 
뉴욕
아쉽네요~

이 프로그램을 끝내고자 한다면 &#39;q&#39;를 눌러주세요!
계속 도전하고자 하시면 Enter를 눌러주세요!

미국의 수도를 입력하세요 : 
워싱턴

정답입니다!
*/</code></pre>
<hr>
<h2 id="atoi-atol-atoll-atof-함수">atoi(), atol(), atoll(), atof() 함수</h2>
<p>atoi(), atol(), atoll(), atof() 함수들은 인수로 전달된 문자열을 해당 타입의 숫자로 변환시켜주는 함수이다.</p>
<pre><code class="language-c">
#include &lt;stdio.h&gt;
#include &lt;string.h&gt;

int main(void)
{
  char str01[] = &quot;10&quot;;
  char str02[] = &quot;20&quot;;  

  printf(&quot;문자열을 숫자로 변환해서 곱한 값은 %d입니다.\n&quot;, atoi(str01) * atoi(str02));

  return 0;
}
/* [실행결과]
문자열을 숫자로 변환해서 곱한 값은 200입니다.
*/</code></pre>
<hr>
<h2 id="toupper-함수와-tolower-함수">toupper() 함수와 tolower() 함수</h2>
<p>toupper() 함수와 tolower() 함수는 인수로 전달된 문자열의 영문자를 모두 대문자나 소문자로 변환시켜주는 함수이다.</p>
<pre><code class="language-c"> #include &lt;stdio.h&gt;
#include &lt;string.h&gt;

int main(void)
{
   int i, str_len;
   char str[] = &quot;Hello C World!&quot;;  

   printf(&quot;원래 문자열 : %s\n&quot;, str);

   str_len = strlen(str);

   for (i = 0; i &lt; str_len; i++){
      str[i] = toupper(str[i]);
   }
   printf(&quot;바뀐 문자열 : %s\n&quot;, str);

   return 0;
}
/* [실행결과]
원래 문자열 : Hello C World!
바뀐 문자열 : HELLO C WORLD! 
*/</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[[C언어] 포인터 - 11.19]]></title>
            <link>https://velog.io/@silv_san_i/C%EC%96%B8%EC%96%B4-%ED%8F%AC%EC%9D%B8%ED%84%B0-11.15</link>
            <guid>https://velog.io/@silv_san_i/C%EC%96%B8%EC%96%B4-%ED%8F%AC%EC%9D%B8%ED%84%B0-11.15</guid>
            <pubDate>Sun, 19 Nov 2023 12:56:59 GMT</pubDate>
            <description><![CDATA[<p><img src="https://velog.velcdn.com/images/silv_san_i/post/f5616e9a-a6a2-4dd2-be7e-a338b3035b35/image.png" alt=""></p>
<hr>
<h1 id="포인터">포인터</h1>
<p><strong>포인터(Pointer)</strong>란 어떠한 값을 저장하는 것이 아닌, 어떠한 값의 주소를 저장하는 것이다. 메모리의 주소값을 저장하는 변수이며, 포인터 변수라고도 부른다.</p>
<p>char형 변수가 문자를 저장하고, 
int형 변수가 정수를 저장하는 것처럼 포인터는 주소값을 저장한다.</p>
<pre><code class="language-c">char word = &#39;alphabet&#39;;
int num = 100;

char *ptr = &amp;word; //포인터 선언
int *ptr = &amp;num; </code></pre>
<hr>
<h1 id="주소값의-이해">주소값의 이해</h1>
<p>데이터의 주소값이란 해당 데이터가 저장된 메모리의 시작 주소를 의미한다.
C언어에서는 이러한 주소값을 1바이트 크기의 메모리 공간으로 나누어 표현한다.</p>
<p>예를 들어, int형 데이터는 4바이트의 크기를 가지지만
int형 데이터의 주소값은 시작 주소 1바이트만을 가리킨다.</p>
<hr>
<h1 id="포인터-연산자">포인터 연산자</h1>
<p>C언어에서 포인터와 연관되어 사용되는 연산자는 다음과 같다.</p>
<h2 id="주소-연산자-">주소 연산자 (&amp;)</h2>
<p>주소 연산자는 변수의 이름 앞에 사용하여, 해당 변수의 주소값을 반환한다.
&#39;&amp;&#39;기호는 앰퍼샌드(ampersand)라고 읽으며, 번지 연산자라고도 불린다.</p>
<pre><code class="language-c">#include &lt;stdio.h&gt;

int main()
{
  int i = 5;
  char c = 73;
  float f = 11.9;

  printf(&quot;i의 주소:%u\n&quot;, &amp;i);
  printf(&quot;c의 주소:%u\n&quot;, &amp;c);
  printf(&quot;f의 주소:%u\n&quot;, &amp;f);

  return 0;
}

/*[실행결과]
i의 주소: 012FFAOC
c의 주소: 012FFA03
f의 주소: 012FF9F0 
*/</code></pre>
<h2 id="간접-참조-연산자">간접 참조 연산자(*)</h2>
<p>참조 연산자는 포인터의 이름이나 주소 앞에 사용해,
포인터에 가리키는 주소에 저장된 값을 반환한다.
C언어에서 &#39;*&#39;기호는 사용하는 위치에 따라 다양한 용도로 사용된다.</p>
<p>이항 연산자로 사용하면 곱셈 연산으로 사용되며, 
포인터의 선언 시에 사용되면 포인터가 가리키는 값을 가져오는 연산자 된다.</p>
<pre><code class="language-c">#include &lt;stdio.h&gt;

int main()
{
  int i = 5;
  int *p;
  p = &amp;i;
  printf(&quot;값은 %d&quot;, *p);

  return 0;
}

/*[실행결과]
값은 5
*/</code></pre>
<hr>
<h1 id="span-stylecolorred포인터-사용시-주의사항-span"><span style="color:red">포인터 사용시 주의사항 </span></h1>
<h2 id="포인터의-선언">포인터의 선언</h2>
<pre><code class="language-c">타입* 포인터이름;
</code></pre>
<p>타입이란 포인터가 가리키고자 하는 변수의 타입을 명시한다.
포인터 이름은 포인터가 선언된 후에 포인터에 접근하기 위해 사용된다.</p>
<p>포인터를 선언한 후 참조 연산자(*)를 사용하기 전에 
포인터는 반드시 먼저 초기화되어야 한다.
그렇지 않으면 의도하지 않은 메모리의 값을 변경하게 되기 때문이다.
C 컴파일러는 초기화하지 않은 포인터에 참조 연산자를 사용하면 오류를 초래한다.</p>
<p>따라서 다음과 같이 포인터의 선언과 동시에 초기화를 함께 하는 것이 좋다.</p>
<pre><code class="language-c">타입* 포인터이름 = &amp;변수이름;

  또는

타입* 포인터이름 = 주소값;</code></pre>
<hr>
<h1 id="함수-호출시-인수-전달-방법">함수 호출시 인수 전달 방법</h1>
<p>함수를 호출할 때에는 함수에 필요한 데이터를 인수(argument)로 전달해 줄 수 있습니다.
이렇게 함수에 인수를 전달하는 방법에는 크게 다음과 같이 두 가지 방법이 있습니다.</p>
<h2 id="값에-의한-호출-call-by-value">값에 의한 호출 (call-by-value)</h2>
<p>값에 의한 호출은 인수로 전달되는 변수가 가지고 있는 값을 함수 내의 매개변수에 복사하는 방식이다. 이렇게 복사된 값으로 초기화된 매개변수는 인수로 전달된 변수와는 완전히 별개의 변수가 된다. 따라서 함수 내에서의 매개변수 조작은 인수로 전달되는 변수에 아무런 영향을 미치지 않는다.</p>
<pre><code class="language-c">#include &lt;stdio.h&gt;

void modify(int value)
{
  value = 99;
}

int main()
{
   int number = 1;

  modify(number);
  printf(&quot;number = %d\n&quot;, number);

  return 0;
}

/*[실행결과]
number = 1
*/</code></pre>
<h2 id="참조에-의한-호출-call-by-reference">참조에 의한 호출 (call-by-reference)</h2>
<p>참조에 의한 호출은 인수로 변수의 값을 전달하는 것이 아닌, 해당 변수의 주소값을 전달한다. 즉, 함수의 매개변수에 인수로 전달된 변수의 원래 주소값을 저장하는 것이다. 이 방식을 사용하면 인수로 전달된 변수의 값을 함수 내에서 변경할 수 있게 된다.</p>
<pre><code class="language-c">#include &lt;stdio.h&gt;

void modify(int* ptr)
{
  *ptr = 99;
}


int main()
{
  int number = 1;
  modify(&amp;number);
  printf(&quot;number = %d\n&quot;, number);

  return 0;
}

/* [출력결과]
number = 99 
*/</code></pre>
<hr>
<h1 id="배열과-포인터">배열과 포인터</h1>
<p>포인터와 배열은 매우 긴밀한 관계를 맺고 있으며, 
어떤 부분에서는 서로를 대체할 수도 있습니다.</p>
<pre><code class="language-c">#include &lt;stdio.h&gt;

int main()
{
    int arr[3] = {10, 20, 30}; // 배열 선언  
    printf(&quot;배열 이름을 이용하여 배열 요소에 접근 : %d %d %d\n&quot;, arr[0], arr[1], arr[2]);
    printf(&quot;배열 이름으로 포인터 연산 통해 접근 : %d %d %d\n&quot;, *(arr+0), *(arr+1), *(arr+2));

    return 0;
}
/* [실행결과]
배열 이름을 이용하여 배열 요소에 접근 : 10 20 30
배열 이름으로 포인터 연산 통해 접근 : 10 20 30 
*/</code></pre>
<hr>
<h1 id="다양한-포인터">다양한 포인터</h1>
<h2 id="포인터의-포인터">포인터의 포인터</h2>
<p>포인터의 포인터란 포인터 변수를 가리키는 포인터를 의미한다.
참조 연산자(*)를 두 번 사용하여 표현하며 이중 포인터라고도 부른다.</p>
<pre><code class="language-c">#include &lt;stdio.h&gt;

int main()
{
    int num = 10;              // 변수 선언
    int* ptr_num = &amp;num;       // 포인터 선언
    int** pptr_num = &amp;ptr_num; // 포인터의 포인터 선언  

    printf(&quot;변수 num의 값은 %d입니다.\n&quot;, num);
    printf(&quot;포인터 ptr_num가 가리키는 주소에 저장된 값은 %d입니다.\n&quot;, *ptr_num);
    printf(&quot;이중 포인터 pptr_num가 가리키는 주소에 저장된 포인터가 가리키는 주소에 저장된 값은 %d입니다.\n&quot;,**pptr_num);  

    return 0;
}
/* [실행결과]
변수 num가 저장하고 있는 값은 10입니다.
포인터 ptr_num가 가리키는 주소에 저장된 값은 10입니다.
이중 포인터 pptr_num가 가리키는 주소에 저장된 포인터가 가리키는 주소에 저장된 값은 10입니다.
*/</code></pre>
<h2 id="함수-포인터">함수 포인터</h2>
<p>프로그램에서 정의된 함수는 프로그램이 실행될 때 모두 메인 메모리에 올라가게 된다.
이때 함수의 이름은 메모리에 올라간 함수의 시작 주소를 가리키는 포인터 상수가 된다. 이렇게 함수의 시작 주소를 가리키는 포인터 상수를 함수 포인터라고 부른다.</p>
<p>함수 포인터의 포인터 타입은 함수의 반환값과 매개변수에 의해 결정된다.
즉 함수의 원형을 알아야만 해당 함수에 맞는 함수 포인터를 만들 수 있습니다.</p>
<pre><code class="language-c">#include &lt;stdio.h&gt;

int main()
{

   double (*calc)(double, double) = NULL; // 함수 포인터 선언
   double result = 0;  
   double num01 = 3, num02 = 5;
   char oper = &#39;*&#39;;  

   switch (oper)
   {
     case &#39;+&#39;:
         calc = add;
         break;

     case &#39;-&#39;:
         calc = sub;
         break;

     case &#39;*&#39;:
         calc = mul;
         break;

     case &#39;/&#39;:
         calc = div;
         break;

     default:
         puts(&quot;사칙연산(+, -, *, /)만을 지원합니다.&quot;);
   }  
    result = calculator(num01, num02, calc);
    printf(&quot;사칙 연산의 결과는 %lf입니다.\n&quot;, result);
    return 0;
}
/* [실행결과]
사칙 연산의 결과는 15.000000입니다.
*/</code></pre>
<h2 id="void-포인터">void 포인터</h2>
<p>void 포인터는 일반적인 포인트 변수와는 달리 대상이 되는 데이터의 타입을 명시하지 않은 포인터이다. 따라서 변수, 함수, 포인터 등 어떠한 값도 가리킬 수 있지만, 포인터 연산이나 메모리 참조와 같은 작업은 할 수 없다. 즉, void 포인터는 주소값을 저장하는 것 이외에는 아무것도 할 수 없는 포인터이다.</p>
<p>또한, void 포인터를 사용할 때에는 반드시 먼저 사용하고자 하는 타입으로 명시적 타입 변환 작업을 거친 후에 사용해야 한다.  </p>
<pre><code class="language-c">#include &lt;stdio.h&gt;

int main()
{
    int num = 10;
    void* p_num = &amp;num;

    printf(&quot;변수 num가 저장하고 있는 값은 %d입니다.\n&quot;, (int*)p_num);
    printf(&quot;void 포인터 p_num가 가리키는 주소에 저장된 값은 %d입니다.\n&quot;, *(int*)p_num);

    *(int*)p_num = 20;  // void 포인터를 통한 메모리 접근  
    printf(&quot;void 포인터 p_num가 가리키는 주소에 저장된 값은 %d입니다.\n&quot;, *(int*)p_num)


    return 0;
}
/* [실행결과]
변수 num가 저장하고 있는 값은 10입니다.
void 포인터 ptr_num가 가리키는 주소에 저장된 값은 10입니다.
void 포인터 ptr_num가 가리키는 주소에 저장된 값은 20입니다. 
*/</code></pre>
<h2 id="null-포인터">NULL 포인터</h2>
<p>0이나 NULL을 대입해 초기화한 포인터를 널 포인터(null pointer)라고 한다.
NULL 포인터는 아무것도 가리키지 않는 포인터라는 의미한다.</p>
<hr>
<p><img src="https://velog.velcdn.com/images/silv_san_i/post/1feeeec3-695c-4a71-9cdd-e507a27278c2/image.png" alt=""></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[C언어] 배열 정리 - 11.05]]></title>
            <link>https://velog.io/@silv_san_i/C%EC%96%B8%EC%96%B4-%EB%B0%B0%EC%97%B4-%EC%A0%95%EB%A6%AC-11.05</link>
            <guid>https://velog.io/@silv_san_i/C%EC%96%B8%EC%96%B4-%EB%B0%B0%EC%97%B4-%EC%A0%95%EB%A6%AC-11.05</guid>
            <pubDate>Sun, 05 Nov 2023 09:47:39 GMT</pubDate>
            <description><![CDATA[<p><img src="https://velog.velcdn.com/images/silv_san_i/post/70fd035f-3d8c-4042-a312-30ea49e173d4/image.jpg" alt=""></p>
<hr>
<h1 id="배열">배열</h1>
<p><strong>배열(Array)</strong>은 연관이 되어있는 데이터들을 하나의 변수에 저장하는 것을 의미한다. 
즉, 배열은 연관이 되어있는 데이터들을 하나의 변수에 담아 관리하기 위해 사용되는 변수이다. 배열을 선언하게 되면 그 배열이 몇 개의 원소를 가지고 있으며, 원소들의 데이터형이 무언인지 컴파일러에게 알려주게 된다.</p>
<hr>
<h2 id="배열의-선언">배열의 선언</h2>
<p>배열은 보통 변수들이 가질 수 있는 자료형을 갖고 있기에 배열의 이름 앞에 사용할 자료형을 선언해주어야 한다. 그리고 대괄호[] 안의 수는 선언할 때 배열의 원소 크기를 나타낸다. 배열 선언의 예시는 다음과 같다.</p>
<pre><code class="language-c">int i_arr[5]; // 5개의 정수형 배열 선언
char c_arr[10]; // 10개의 문자형 배열 선어 
float f_arr[125]; // 125개의 실수형 배열 선언</code></pre>
<p><span style="color:blue">&lt; 참고사항 &gt;</span><br>배열은 첨자 번호 익덱스를 이용해 각각의 원소에 접근할 수 있는 특징을 갖는다. 인덱스는 1이 아닌 0으로 시작하게 되므로 선언한 배열의 첫번째 원소는 arr[0]이 된다. </p>
<hr>
<h2 id="배열의-초기화">배열의 초기화</h2>
<p>배열을 초기화 하지 않는다면 일반 변수와 마찬가지로 아무 의미없는 쓰레기 값이 들어가게 된다. 따라서 배열의 초기화는 매우 중요하다. 배열의 초기화는 다음과 같다.</p>
<pre><code class="language-c">int i_arr[5] = {1,2,3,4,5};
char c_arr[3] = {&#39;x&#39;,&#39;y&#39;,&#39;z&#39;};
float f_arr[7] = {1.1, 1.2, 1.3, 1.4, 1.5, 1.6, 1.7};</code></pre>
<p>일반적으로 배열의 원소의 값과 초기값 리스트의 개수는 일치해야 한다. </p>
<hr>
<h3 id="배열의-선언된-원소의-값보다-초기값이-더-많을-경우">배열의 선언된 원소의 값보다 초기값이 더 많을 경우</h3>
<p>배열의 선언된 원소의 값보다 초기값이 더 많을 경우에는 실행은 될지라도 컴파일러에 따라 원소의 크기가 배열의 크기보다 크다는 Excess elements in array initializer가 발생한다.</p>
<pre><code class="language-c">#include &lt;stdio.h&gt;

int main(void)
{
    int i_arr[5] = {1,2,3,4,5,6,7}; // 배열의 선언보다 많은 양을 초기화 
    for (int i = 0; i&lt;5; i++){
        printf(&quot;%d번째 원소: %d\n&quot;, i, i_arr[i]);
    }
    return 0;
}
// Excess elements in array initializer 에러 코드 발생 </code></pre>
<hr>
<h3 id="배열의-선언된-원소의-값보다-초기값이-더-적을-경우">배열의 선언된 원소의 값보다 초기값이 더 적을 경우</h3>
<p>초기화한 값을 제외하고 나머지는 0으로 초기화 된다. </p>
<pre><code class="language-c">#include &lt;stdio.h&gt;

int main(void)
{
    int i_arr[5] = {1,2,3}; // 배열의 선언보다 적은 양을 초기화 
    for (int i = 0; i&lt;5; i++){
        printf(&quot;%d번째 원소: %d\n&quot;, i, i_arr[i]);
    }
    return 0;
}
/*실행 결과:
0번째 원소: 1
1번째 원소: 2
2번째 원소: 3
3번째 원소: 0
4번째 원소: 0
*/</code></pre>
<hr>
<h3 id="모든-원소를-0으로-초기화-하는-경우">모든 원소를 0으로 초기화 하는 경우</h3>
<pre><code class="language-c">#include &lt;stdio.h&gt;

int main(void)
{
    int i_arr[5] = {0}; // 모든 원소의 초기화 값이 0
    for (int i = 0; i&lt;5; i++){
        printf(&quot;%d번째 원소: %d\n&quot;, i, i_arr[i]);
    }
    return 0;
}</code></pre>
<hr>
<h2 id="다차원-배열">다차원 배열</h2>
<p>다차원 배열은 2차원 이상의 배열을 의미한다. 배열 요소로 또 다른 배열을 가지는 배열을 의미하기도 한다. 즉, 2차원 배열은 배열 요소로 1차원 배열을 가지는 배열이고, 3차원 배열은 배열 요소로 2차원 배열을 가지는 배열이다. 다차원 배열의 선언은 다음과 같다. </p>
<pre><code class="language-c">int i_arr[10]; // 1차원 배열 선언
int i_arr[3][5]; // 2차원 배열 선언 arr[행][열]
int i_arr[3][5][7]; // 3차원 배열 선언 arr[[면][행][열]</code></pre>
<hr>
<h3 id="2차원-배열의-초기화">2차원 배열의 초기화</h3>
<p>2차원 배열은 배열의 요소로 1차원 배열을 가지는 배열을 의미한다. 
2차원 배열의 초기화는 다음과 같다.</p>
<pre><code class="language-c">int i_arr[3][5] = {
  {0,1,2,3,4}, // 첫 번째 행의 원소들 초기화
  {5,6,7,8,9}, // 두 번째 행의 원소들 초기화 
  {10,11,12,13,14} // 세 번째 행의 원소들 초기화 
 }</code></pre>
<p><span style="color:blue">&lt; 참고사항 &gt; </span><br>행 단위로 초기화할 값들을 별도의 중괄호로 명시해야 한다. </p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[C언어] 조건문, 반복문 정리 - 10.03]]></title>
            <link>https://velog.io/@silv_san_i/C%EC%96%B8%EC%96%B4-%EC%A1%B0%EA%B1%B4%EB%AC%B8-%EB%B0%98%EB%B3%B5%EB%AC%B8-%EC%A0%95%EB%A6%AC-10.03</link>
            <guid>https://velog.io/@silv_san_i/C%EC%96%B8%EC%96%B4-%EC%A1%B0%EA%B1%B4%EB%AC%B8-%EB%B0%98%EB%B3%B5%EB%AC%B8-%EC%A0%95%EB%A6%AC-10.03</guid>
            <pubDate>Tue, 03 Oct 2023 13:54:03 GMT</pubDate>
            <description><![CDATA[<p>C 프로그램은 절차적 프로그램 또는 명령형 프로그램에 속한다.
수많은 명령문이 포함되어 있으며, 이 명령문은 처음부터 끝까지 순서대로 실행된다.
따라서 원하는 결과를 얻기 위해 프로그램의 순차적인 흐름을 제어해야만 한다.
이때 사용하는 명령문을 제어문이라라고 한다.</p>
<p>제어문에는 조건문과 반복문 등이 있다. 
이러한 제어문에 속하는 명령문들은 중괄호({})로 둘러싸여 있으며, 
중괄호 영역을 블록(block)이라고 한다.</p>
<hr>
<h1 id="조건문"><strong>조건문</strong></h1>
<p>조건문은 주어진 조건식의 결과에 따라 별도의 명령을 수행하도록 제어하는 명령문이다.</p>
<p>C언어에서 사용하는 대표적인 조건문의 형태는 다음과 같다.</p>
<blockquote>
<p>if 문
if / else 문
if / else if / else 문
switch 문</p>
</blockquote>
<h3 id="if-문">if 문</h3>
<p>if 문은 조건식의 결과가 참(True)이면 주어진 명령문을 실행하며
거짓(False)이면 아무것도 실행하지 않는다.</p>
<p>C언어에서if 문의 문법은 다음과 같다.</p>
<pre><code class="language-c">if (조건식)
{
    조건식의 결과가 참일 때 실행하고자 하는 명령문;
}</code></pre>
<hr>
<h3 id="if--else-문"><strong>if / else 문</strong></h3>
<p>if 문과 함께 사용하는 else 문은 if 문과 반대로 
조건식의 결과가 거짓(False)이면 주어진 명령문을 실행한다.</p>
<p>C언어에서 if / else 문의 문법은 다음과 같다.</p>
<pre><code class="language-c">if (조건식) {
    조건식의 결과가 참일 때 실행하고자 하는 명령문;
}
else {
    조건식의 결과가 거짓일 때 실행하고자 하는 명령문;
}</code></pre>
<p>else 문을 사용하면 if 문보다 더 직관적으로 표현할 수 있다. </p>
<hr>
<h3 id="if--else-if--else-문"><strong>if / else if / else 문</strong></h3>
<p>else if 문은 if 문처럼 조건식을 가질 수 있기 때문에 
중첩된 if 문을 더 간결하게 표현할 수 있도록 해준다.
else if 문은 여러 번 사용될 수 있어 복잡한 조건도 만들 수 있다. </p>
<p>C언어에서 else if 문의 문법은 다음과 같다.</p>
<pre><code class="language-c">if (조건식) {
    조건식의 결과가 참일 때 실행하고자 하는 명령문;
} else if {
    조건식의 결과가 거짓일 때 실행하고자 하는 명령문;
} else {
    조건식 1의 결과 거짓, 조건식 2의 결과 거짓일 때 실행하고자 하는 명령문;
}</code></pre>
<hr>
<h3 id="switch-문"><strong>switch 문</strong></h3>
<p>switch 문은 if / else 문과 마찬가지로 주어진 조건 값의 결과에 따라
프로그램이 다른 명령을 수행하도록 하는 조건문이다.
switch문은 if / else 문보다 가독성이 좋으며, 속도 또한 빠른 편이다. </p>
<p>하지만 switch 문의 조건 값으로는 int형으로 승격할 수 있는 값만 사용된다.
따라서 if / else 문보다는 사용할 수 있는 상황이 적은 편이다.</p>
<p>C언어에서 switch 문의 문법은 다음과 같다.</p>
<pre><code class="language-c">switch(조건 값) {
    case 값1:
        조건 값이 값1일 때 실행하고자 하는 명령문;
        break;
    case 값2:
        조건 값이 값2일 때 실행하고자 하는 명령문;
        break;
    default:
        조건 값이 어떠한 case 절에도 해당하지 않을 때 실행하고자 하는 명령문;
        break;</code></pre>
<p><span style="color:blue">&lt; 참고사항 &gt;</span>
switch 문에서 char형을 사용할 시 case 값1을 &#39;값1&#39;로 표현해주어야 한다.
int형 혹은 숫자를 사용할 시에는 &#39;&#39; 표현을 할 필요가 없다. </p>
<hr>
<h1 id="반복문"><strong>반복문</strong></h1>
<p>반복문은 똑같은 명령을 일정 횟수만큼 반복하여 수행하도록 하는 명령문이다. 
C언어에서 사용되는 대표적인 반복문의 형태는 다음과 같다.</p>
<blockquote>
<p>while 문 
do / while 문
for 문</p>
</blockquote>
<hr>
<h3 id="while-문"><strong>while 문</strong></h3>
<p>while 문은 특정 조건을 만족할 때까지 주어진 명령문을 반복 실행한다.
while문은 조건식이 참(True)인지를 판단하여, 참이면 내부의 명령문을 실행한다. 
내부의 명령문을 전부 실행한 후 다시 조건식으로 돌아와 또 한번 참인지를 판단한다.
이렇게 표현식의 검사를 통해 반복해서 실행되는 반복문을 루프(loop)라고 한다. </p>
<p>C언어에서 while 문의 문법은 다음과 같다. </p>
<pre><code class="language-c">while (조건식)
{
    조건식의 결과가 참인 동안 반복적으로 실행하고자 하는 명령문;
}</code></pre>
<p><span style="color:red">&lt; 주의사항 &gt;</span>
while 문 내부에서 조건식의 결과를 변경하는 명령문이 존재하지 않을 경우
프로그램은 영원히 반복되고 이를 무한 루프(infinite loop)에 빠졌다고 한다.
반복문에서는 조건식의 거짓일 때 반복문이 종료가 되지만,
무한루프는 조건식의 거짓이 항상 참이므로 반복문이 종료되지 않고 무한히 실행된다.</p>
<p>무한 루프는 특별히 의도한 바가 아니라면 반드시 피해야 한다.
따라서 while 문을 작성할 때는 조건식의 결과가 어느 순간 거짓(False)을 갖도록 해야한다. </p>
<hr>
<h3 id="do--while-문"><strong>do / while 문</strong></h3>
<p>while 문은 루프에 진입하기 전에 먼저 조건식부터 검사한다.
하지만 do / while 문은 먼저 루프를 한 번 실행한 후에 조건식을 검사한다.
즉, do / while 문은 조건식의 결과와 상관없이 무조건 한 번은 루프를 실행한다.</p>
<p>C언어에서 do / while 문의 문법은 다음과 같다. </p>
<pre><code class="language-c">do {
    조건식의 결과가 참인 동안 반복적으로 실행하고자 하는 명령문;
}   while (조건식);</code></pre>
<hr>
<h3 id="for-문"><strong>for 문</strong></h3>
<p>for 문은 while 문과 달리 초기식, 조건식, 증감식을 모두 포함하고 있다.
따라서 while 문보다는 더 간결하게 반복문을 표현할 수 있다.</p>
<p>C언어에서 for 문의 문법은 다음과 같다.</p>
<pre><code class="language-c">for (초기식; 조건식; 증감식)
{
  조건식의 결과가 참인 동안 반복적으로 실행하고자 하는 명령문;
}</code></pre>
<p><span style="color:blue">&lt; 참고사항 &gt;</span>
이때 for 문을 구성하는 초기식, 조건식, 증감식은 각각 생략될 수 있습니다. 
또한, for 문에서 실행될 명령문이 한 줄 뿐이면 중괄호({})를 생략할 수 있습니다.</p>
<hr>
<h1 id="조건문-반복문-정리"><strong>조건문, 반복문 정리</strong></h1>
<h3 id="문제풀이">[문제풀이]</h3>
<p><strong>문제 7.</strong> 삼각형 세 변의 길이를 입력받아서 삼각형의 종류를 결정하는 프로그램 작성.
많은 종류 중에서 정삼각형, 이등변 삼각형만 구별해 보자. </p>
<pre><code class="language-c">include&lt;stdio.h&gt;
int main()
{
    int a, b, c;
    printf(&quot;삼각형의 세변을 입력하시요:&quot;);
    scanf(&quot;%d %d %d&quot;, &amp;a, &amp;b, &amp;c);

    if (a == b &amp;&amp; b == c)
    {
        printf(&quot;정삼각형&quot;);
    }
    else if (a == b || b == c || c == a)
    {
        printf(&quot;이등변 삼각형&quot;);
    }
    else
        printf(&quot;삼각형&quot;);

    return 0;
}</code></pre>
<hr>
<p><strong>문제10.</strong> switch 문을 이용해 자신의 학점을 입력하면 학점에 대한 코멘트를 출력하는 
프로그램 작성.</p>
<pre><code class="language-c">#define _CRT_SECURE_NO_WARNINGS
#include &lt;stdio.h&gt;

int main(void)
{
    char grade;
    printf(&quot;학점을 입력하시오:&quot;);
    scanf(&quot;%c&quot;, &amp;grade);

    switch (grade) {
    case &#39;A&#39;: /*char형일 경우에 &#39;&#39;으로 표시*/
        printf(&quot;아주 잘했어요!&quot;);
        break;
    case &#39;B&#39;:
        printf(&quot;좋습니다.&quot;);
        break;
    case &#39;C&#39;:
        printf(&quot;만족스럽습니다.&quot;);
        break;
    case &#39;D&#39;:
        printf(&quot;더 노력해보세요.&quot;);
        break;
    case &#39;F&#39;:
        printf(&quot;참 안타깝습니다.&quot;);
        break;
    default:
        printf(&quot;대체 무슨 점수죠.&quot;);
        break;
    }

    return 0;
}</code></pre>
<hr>
<p><strong>문제12.</strong> 컴퓨터는 막대 그래프를 그리는데 사용된다. 막대는 세로로 그려지게 된다. 
사용자로부터 1-50사의 숫자 10개를 입력받아 숫자만큼의 별표를 출력하는 프로그램 작성.</p>
<pre><code class="language-c">#include&lt;stdio.h&gt;
int main()
{
    int data;
    int i, j;
    for (i = 0; i &lt; 10; i++)
    {
        printf(&quot;데이터를 입력하시오:&quot;);
        scanf(&quot;%d&quot;, &amp;data);
        if (data &lt; 1 || data &gt; 50)
        {
            printf(&quot;범위가 벗어났습니다! 다시 입력하시오.\n&quot; );

            continue;
        }
        for (j = 0; j &lt;= data; j++)
        {
            printf(&quot;*&quot;);
        }
        printf(&quot;\n&quot;)
    }
    return 0;
}</code></pre>
]]></description>
        </item>
    </channel>
</rss>