'c강좌'에 해당되는 글 2건


안녕하세요 피터입니다.

오늘은 C언어의 배열 (Array)에 대해 알려드리겠습니다.


개요

배열은 이전 시간에 포스팅했던 루프(반복문) 과 단짝입니다.

[C언어 강좌-9] 반복문 (Loop)


배열 자체가 같은 크기의 메모리 공간을 연속적으로 할당한 것이기 때문에 각 요소(Element)들을 개별적으로 다루는 것보다 루프를 이용해서 접근하면 훨씬 코드가 심플해지고 효율적이기 때문입니다. 

루프와 함께 사용하지 않는다면 배열은 단순히 변수를 여러 개 선언한 것과 다를 바 없습니다.

루프의 반복자(iterator)는 배열의 각 항목(item)들에 접근하는 인덱스(index)로 사용하기에 매우 적합합니다.



문법(Syntax)

배열의 선언

배열을 선언하는 기본적인 문법은 아래와 같습니다.


datatype arrayname[arraysize];


문법 자체는 변수를 선언하는 것과 크게 다르지 않습니다.

지정된 datatype으로 arraysize 만큼의 메모리 공간을 할당하고, 이 메모리 공간에 접근할 때 arrayname을 이용해서 접근하는 것이죠.

단, arraysize 는 반드시 상수여야 합니다.

[C언어 강좌-5] 상수 (Constant)


int 타입의 크기가 10인 배열을 아래와 같이 선언하면 연속된 영역의 메모리 공간을 할당받게 됩니다.

int cost[10];


따라서 배열 전체 크기는 int 타입의 크기에 arraysize를 곱한 값이 됩니다.

4* 10 = 40

여기에서 한 가지 알아두셔야 할 것은 배열의 이름만 쓰게 되면 첫 번째 요소의 주소와 의미가 같다는 점입니다.

아직은 이 말이 무슨 뜻인지 정확하게 이해가 안되실 수도 있습니다.

이후에 포스팅할 예정인 포인터를 보시고 나면 이해가 좀 더 수월하실 거에요.


배열 요소 접근

이렇게 선언된 배열의 각 요소(element)는 아래와 같이 접근할 수 있습니다.


arrayname[index]


이때 주의하셔야 할 부분은 index 값은 0부터 시작하기 때문에 index의 최대값은 arraysize - 1이 된다는 점입니다.


Write: 배열 요소에 값을 저장

element에 값을 넣을 때는 = 연산자의 좌항(left value)에 넣어주면 됩니다.

int cost[10];
cost[0] = 10;
cost[5] = 30;
cost[9] = 50;


배열의 크기가 10으로 지정되었기 때문에 사용 가능한 인덱스 값은 0부터 9까지입니다.

이 범위를 벗어나는 인덱스를 사용하여 배열을 참조할 경우 스택영역의 메모리 overwrite으로 인해 프로그램이 오동작 하거나 메모리 참조 오류를 만나보실 수 있습니다.


Read: 배열 요소의 값을 읽기

element의 값을 읽어올 때는 = 연산자의 우항(right value)에 넣어주면 됩니다.

int last_cost;
last_cost = cost[9];


다음과 같이 printf 문에서 직접 읽어올 수도 있습니다.

printf("first array value is %d\n", cost[0]);


루프와 배열

int main(void)
{
int score[5]; scanf("%d", &score[0]); scanf("%d", &score[1]); scanf("%d", &score[2]); scanf("%d", &score[3]); scanf("%d", &score[4]); printf("%dst score is %d\n", 1, score[0]); printf("%dst score is %d\n", 2, score[1]); printf("%dst score is %d\n", 3, score[2]); printf("%dst score is %d\n", 4, score[3]); printf("%dst score is %d\n", 5, score[4]);

return 0;
}

위 코드는 크기가 5인 배열을 선언하고 각 요소에 값을 표준 입력(키보드 입력)으로 받아서 할당한 뒤 모든 배열의 요소를 순차적으로 출력하는 코드입니다.


배열을 사용하긴 했지만 특정 구문이 계속해서 반복되는 비효율적인 코드가 되어버렸습니다.


루프를 활용해서 코드를 개선해보겠습니다.

int main(void)
{
  int score[5];
  int i;

  for(i=0; i<5; i++)
  {
    scanf("%d", &score[i]);
  }

  for(i=0; i<5; i++)
  {
    printf("%dst score is %d\n", i+1, score[i]);
  }

  return 0;
}

루프 안에 scanf() 구문과 printf() 구문을 넣고 i 값을 인덱스로 접근하도록 바꾸니 코드가 훨씬 단순해지고 보기좋아졌습니다.

제가 항상 강조하는 것 중에 하나가 코드의 가독성인데 가동성을 높이기 위해서는 이런 작은 부분부터 신경을 써야 합니다.



여러분의 댓글은 저에게 크나큰 힘이 됩니다. 오류 및 의견 주시면 감사하겠습니다.

-Peter의 우아한 프로그래밍

블로그 이미지

친절한 Peter Ahn

IT 정보 공유, 프로그래밍 지식 공유

댓글을 달아 주세요



안녕하세요 피터입니다.

오늘은 C언어의 상수에 대해서 알아보겠습니다.


1. 상수란 무엇인가?

상수(Constant)란 프로그램이 실행되는 동안 '값이 고정되어 변경할 수 없는 메모리 공간'을 의미합니다. 

변수처럼 정의해서 사용할 수 있습니다. 

기본적으로 int나 char 와 같은 C언어 표준 자료형들은 모두 상수가 될 수 있습니다. 그렇기 때문에 상수는 한번 정의한 이후에 값을 변경할 수 없도록 제한한 변수와 의미가 같다고 볼 수 있습니다. 

문자열 그 자체가 값을 나타내는 것을 리터럴 상수(Literal constant)라고 하는데 줄여서 리터럴(Literal)이라고 부르기도 합니다. 


2. 상수를 정의하는 방법

상수를 정의하는 방법에는 두 가지 방법이 있습니다.

#define 전처리기를 사용하는 방법과 const 키워드를 사용하는 방법입니다.


2.1 #define 전처리기 (Preprocessor)

#define identifier value


#define으로 전처리기 지시자를 통해 상수를 정의할 수 있습니다. 

이렇게 정의된 상수는 전처리 단계에서 value로 치환된 이후 컴파일됩니다. 

#include <stdio.h>

#define LENGTH 10   
#define WIDTH  5
#define NEWLINE '\n'

int main() {

   int area;  
  
   area = LENGTH * WIDTH;
   printf("value of area : %d", area);
   printf("%c", NEWLINE);

   return 0;
}

2.2 const 키워드 (Prefix)

const 키워드를 통해 변수를 선언할 때 상수로 지정할 수 있습니다.

const type variable = value;
이렇게 선언된 변수는 값을 변경할 수 없습니다.

실제로 참조할 때는 #define 사용할 때와 차이가 없습니다.


#include <stdio.h>

int main() {

   const int  LENGTH = 10;
   const int  WIDTH = 5;
   const char NEWLINE = '\n';
   int area;  
   
   area = LENGTH * WIDTH;
   printf("value of area : %d", area);
   printf("%c", NEWLINE);

   return 0;
}

3. 리터럴 상수

리터럴 상수는 소스 코드상의 문자열이 그 자체로 값을 나타내는 것을 말합니다. 이 값들은 변수에 대입을 하거나 조건문에 비교값으로 사용할 수 있습니다.

3.1 정수 리터럴 (Integer Literal)

정수 리터럴은 prefix를 이용하여 10진수, 16진수, 8진수 등의 상수를  표현할 수 있습니다.
0x 로 시작하는 정수 리터럴은 16진수를 나타내며, 0 으로 시작하는 정수 리터럴은 8진수입니다.

sufix로 L이나 U를 사용할 수 있습니다.
L은 long, U는 unsigned 를 나타냅니다.

85         /* decimal */

0213       /* octal */

0x4b       /* hexadecimal */

30         /* int */

30u        /* unsigned int */

30l        /* long */

30ul       /* unsigned long */


212         /* Legal */

215u        /* Legal */

0xFeeL      /* Legal */

078         /* Illegal: 8 is not an octal digit */

032UU       /* Illegal: cannot repeat a suffix */


3.2 실수 리터럴 (Floating-point Literal)

3.14159       /* Legal */

314159E-5L    /* Legal */

510E          /* Illegal: incomplete exponent */

210f          /* Illegal: no decimal or exponent */

.e55          /* Illegal: missing integer or fraction */


3.3 문자 상수 (Character Constant)

' ' 로 감싸여진 단일문자를 문자 상수라고 합니다. ' ' 안에는 단일 문자만 올 수 있습니다. 문자가 2개 이상이면 문자열이 되기 때문에 " " 로 감싸야 합니다.

escape 문자인 '\' 가 붙은 특수 문자도 올 수 있습니다. 

주로 사용하는 '\t' 는 탭문자, '\n' 은 개행문자에 해당합니다.

'x'             /* Legal */

'\n'            /* Legal */

'\t'            /* Legal */


'xy'         /* Illegal: string */


3.4 문자열 리터럴 (String Literal)

" " 로 감싸여진 구문을 문자열 리터럴이라고 합니다. 
하나의 문자열이 너무 긴 경우 아래와 같이 escape 문자인 \ 를 사용해서 여러 행에 걸쳐 작성할 수 있습니다. 
(개행문자를 \ 를 통해 무시하게 되는 원리입니다)
또한 " " 로 감싸여진 문자열을 여러개를 나열하면 하나의 문자열로 인식합니다.
 

"hello, dear"


"hello, \

dear"


"hello, " "d" "ear"



여러분의 댓글은 저에게 크나큰 힘이 됩니다. 오류 및 의견 주시면 감사하겠습니다.

-Peter의 우아한 프로그래밍

블로그 이미지

친절한 Peter Ahn

IT 정보 공유, 프로그래밍 지식 공유

댓글을 달아 주세요