[ 혼공C ] 5주차 : 배열
본문 바로가기

혼공 스터디/혼자 공부하는 C언어

[ 혼공C ] 5주차 : 배열

728x90
반응형

 

Chapter 8 배열

1. 배열의 선언과 사용

  • 같은 형태의 많은 데이터를 반복문으로 처리하기 위해
    메모리에 연속적으로 저장해 놓고 쪼개서 사용하는 방법

1) 배열의 선언

  • 배열 또한 다른 자료형처럼 선언을 통해서 저장 공간을 확보
  • 하나의 이름으로 한꺼번에 확보
  • 저장 공간의 개수와 상관없이 하나의 이름을 사용

// 8-1 5명의 나이를 저장할 배열을 선언하고 사용하는 방법
#include <stdio.h>

int main(void)
{
    int ary[5];

    ary[0] = 10;
    ary[1] = 20;
    ary[2] = ary[0] + ary[1];
    scanf("%d", &ary[3]);

    printf("%d\n", ary[2]);
    printf("%d\n", ary[3]);
    printf("%d\n", ary[4]);

    return 0;
}
50
30
50
-858993460
  • 변수를 선언할 때
    • 각 변수는 독립적인 저장 공간을 가지며 각각의 이름을 사용

 

  • 배열로 선언할 때
    • 저장 공간이 연속으로 할당되며 배열명이 전체 공간의 이름이 됨

  • int형 변수는 크기가 4바이트이므로 5개를 연속으로 할당하면 총 20바이트가 할당됨
  • 배열의 나누어진 조각을 배열 요소(element)라고 하는데, 각각의 배열 요소는 int형 변수와 똑같이 사용
  • 배열 요소는 배열명에 첨자(index)를 붙여 표현하며 index는 0부터 시작

 

(1) 배열의 사용

  • 배열을 선언할 떄와 배열 요소를 사용할 때 대괄호([ ]) 속 숫자의 의미는 다르다.
  • 선언할 때는 배열 요소의 전체 개수를 표시하며, 사용할 때는 각 요소가 배열에서 몇 번째에 있는지를 의

 

[ 배열의 첨자가 사용 범위를 벗어난다면 ]

 

  • 침범한 영역이 어떤 용도로 사용되느냐에 따라 결과가 달라짐
  • 컴파일러가 경고 메시지로 알려 주기도 하지만 배열 요소에 포인터 연산을 통해 접근하므로
    확실한 에러 메시지를 표시하지 않는다.
  • 범위를 벗어난 영역에 접근하는 배열 코드는 실행 단계에서 문제를 일으킬 때나 발견할 수 있으므로
    버그를 찾아내기 힘들다;;;;

 

2) 배열 초기화

  • 배열도 변수와 마찬가지로 최초 할당에 저장 공간에는 쓰레기 값이 저장되어 있다.
  • 배열도 원하는 값을 가지려면 선언과 동시에 초기화해야한다.
  • 배열은 중괄호로 묶어서 초기화

 

[ 초기화 1 ] 기본적인 초기화 방법

  • 첫 번째 요소부터 차례로 초기화 됨

 

 

[ 초기화 2 ] 초깃값이 배열 요소의 개수보다 적은 경우

  • 왼쪽부터 차례로 초기화하고 남은 배열 요소는 모두 0으로 채운다.

 

[ 초기화 3 ] 자동 초기화 기능

  • 배열 요소 개수가 아무리 많아도 모든 요소를 쉽게 0으로 초기화할 수 있습니다.

 

 

[ 초기화 4 ] 배열 요소 개수가 생략된 형태

  • 이 경우 컴파일러는 초깃값 개수만큼 배열 요소 개수를 정하고 저장 공간을 할당함
  • 아래 그림과 같이 메모리에 저장 공간이 할당되고 초기화

[ 초기화 5 ] double형 배열과 char형 배열을 선언하고 초기화

  • 각각의 자료형에 맞게 double형 배열은 실수 값으로 초기화
  • char형 배열은 문자로 초기화

  • 배열의 초기화는 선언 시 최초 한 번만 가능
  • 그 이후에는 배열 요소에 일일이 값을 대입해야함
  • 초기화 때 처럼 중괄호를 사용한 대입 연산으로 한 번에 값을 바꾸는 것은 불가

 

3) 배열과 반복문

  • 연속된 저장 공간을 할당하고 초기화할 수 있어 같은 유형의 변수가 많이 필요할 때 배열을 사용
// 8-2 배열과 반복문을 사용한 성적 처리 프로그램
#include <stdio.h>

int main(void)
{
    int score[5];
    int i;
    int total = 0;
    double avg;
    for (i = 0; i < 5; i++)
    {
        scanf("%d", &score[i]);
    }

    for (i = 0; i < 5; i++)
    {
        total += score[i];
    }
    avg = total / 5.0;

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

    printf("평균 : %.1lf\n", avg);

    return 0;
}
80 95 77 84 100
   80   95   77   84  100
평균 : 87.2

 

4) sizeof 연산자를 활용 배열 처리

  • 많은 양의 데이터를 처리하므로 배열을 다룰 때는 반복문이 필수!
  • 배열 요소의 개수가 바뀌면 배열을 처리하는 반복문을 모두 수정해야하는 부담이 있다
  • 이 문제의 해결책으로 배열 요소의 개수를 직접 계산에 반복문에 사용하는 방법을 사용할 수 있음

// 8-3 sizeof 연산자를 사용한 배열
#include <stdio.h>

int main(void)
{
    int score[5];
    int i;
    int total = 0;
    double avg;
    int count;

    count = sizeof(score) / sizeof(score[0]);

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

    for (i = 0; i < count; i++)
    {
         total += score[i];
    }
    avg = total / (double)count;

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

    printf("평균 : %.1lf\n", avg);

    return 0;

}
80
95
77
84
100
   80   95   77   84  100
평균 : 87.2

 

 

[ 확인 문제 8 - 1 - 1 ]

정수 5개를 저장할 배열 실수 10개를 저장할 배열 배열 요소 개수가 3개인 int형 배열 첨자의 최댓값이 4인 char형 배열
int ary[5]; double ary[10]; int ary[3]; char ary[5];

 

[ 확인 문제 8 - 1 - 2 ]

int ary[6]={1,2,3}

 

[ 확인 문제 8 - 1 - 3 ]

#include <stdio.h>

int main(void)
{
    int A[ 3 ] = { 1, 2, 3 }
    int B[10];
    int i;

    for ( i = 0; i < 10; i++)
    {
         B[ i ] = A[ i % 3 ];
     }

    for ( i = 0; i < 10; i++)
    {
         printf( "%5d", B[ i ] );
     }
    return 0;
}

 

2. 문자를 저장하는 배열

  • 단어는 알파벳의 나열, 그 순서에 따라 단어의 뜻이 달라짐
  • 모든 알파벳 문자는 한 바이트로 충분히 표현가능, char형 배열을 사용

1) char형 배열의 선언과 초기화

  • char형 배열을 선언할 때 꼭 기억해야 할 점은 저장할 문자열의 길이보다 최소한 하나 이상 크게 배열을 선언해야한다.
  • 여분이 공간이 필요한 이유!!
    널 문자(\0)를 저장하기 위해!!!
8-4 // 문자열을 저장하는 char형 배열
#include <stdio.h>

int main(void)
{
    char str[80] = "applejam";

    printf("최초 문자열 : %s\n", str);
    printf("문자열 입력 : ");
    scanf("%s", str);
    printf("입력 후 문자열 : %s\n", str);

    return 0;
}
최초 문자열 : applejam
문자열 입력 : grape
입력 후 문자열 : grape

(1) 널문자(null character)의 용도

  • char형 배열에 저장된 0
  • 모든 문자는 아스키 코드 값으로 저장되며 결국 널 문자는 아스키 코드 값이 0인 문자를 말하며
    문자 상수로는 \0으로 표현

  • 널 문자는 문자열의 끝을 표시하는 용도로 사용됨
  • printf 함수가 배열의 크기와 관계없이 초기화된 문자열만을 정확히 출력하는 것도 널 문자가 있기 때문

[ 여기서 잠깐 ] :: char형 배열 선언 시 초기화하지 않은 경우

  • char형 배열 선언 시 초기화를 하면 남는 배열 요소가 0으로 채워지므로 자동으로 문자열의 끝에 널 문자가 저장되나,
    초기화하지 않은 상태에서 배열 요소에 문자를 직접 대입한다면 반드시 마지막 문자 다음에는 널 문자를 대입
char str[80];
str[0] = 'a';
str[1] = 'p';
str[2] = 'p';
str[3] = 'l';
str[4] = 'e';
str[5] = '\0';

(2) char형 배열 선언 시 주의할 점

  1. 배열의 크기는 최대한 넉넉하게
  2. 배열 요소의 개수는 최소한 '문자열 길이+1'

 

2) 문자열 대입

  • strcpy 함수
    • char형 배열에 새로운 문자열을 저장하는 함수
    • 저장할 문자열의 길이를 파악해 딱 그 길이만큼만 char형 배열에 문자열을 복사
    • 물론 문자열 끝에 널 문자도 자동으로 붙여줌
8-5 // 문자열을 대입하는 strcpy 함수
#include <stdio.h>
#include <string.h>

int main(void)
{
    char str1[80] = "cat";
    char str2[80];

    strcpy(str1, "tiger");
    strcpy(str2, str1);
    printf("%s, %s\n", str1, str2);

    return 0;
}
tiger, tiger

 

3) 문자열 전용 입출력 함수: gets, puts

  • scanf 함수는 char형 배열에 문자열을 입력할 수 있지만 
    빈칸 전까지만 입력한다.
  • 빈칸을 포함해서 문자열을 입력할 수 있는 새로운 방식이 필요함.
8-6 // 빈칸을 포함한 문자열 입력
#include <stdio.h>

int main(void)

{
    char str[80];

    printf("문자열 입력 : ");
    gets(str);
    puts("입력된 문자열 : ");
    puts(str);

    return 0;
}
문자열 입력 : Love is belief...
입력된 문자열 :
Love is belief...

 

(1) 빈칸을 포함해 문자열을 입력하는 gets 함수

  • gets 함수는 문자열 입력 중간에 빈칸이나 탭 문자를 사용할 수 있다
  • Enter를 누르기 전까지 전체를 하나의 문자열로 배열에 저장
  • 마지막에 널 문자를 붙여서 문자열의 끝을 표시

 

(2) gets와 짝을 이뤄 문자열을 출력하는 puts 함수

  • puts 함수는 문자열 상수나 char형 배열의 배열명을 주면 문자열을 화면에 출력한다.
  • printf 함수의 문자열 출력 기능과 같음
  • 문자열을 출력한 후에 자동으로 줄을 바꾸는 차이가 있음

 

4) 문자열의 끝에 널 문자가 없다면?

  • printf 함수를 비롯한 많은 문자열 처리 함수가 널 문자로 문자열의 끝을 확인한다.
  • 따라서 char형 배열에 무엇을 저장하든 널 문자가 나올 때까지가 하나의 문자열이다.
8-7 널 문자가 없는 문자열
#include <stdio.h>

int main(void)
{
     char str[5];

     str[0] = '0';
     str[1] = 'K';
     printf("%s\n", str);

     return 0;
}
0K儆儆儆儆儆儆儆儆儆儆儆儆儆儆儆儆儆?m묤

 

  • 배열이 초기화되지 않았으므로 배열에는 쓰레기 값이 남아있음
  • 심지어 할당된 배열에 널 문자가 없으면 이어지는 메모리 영역까지 출력하고
  • 널문자가 나올 때까지 출력한다.

 

 

728x90
반응형