본문 바로가기
수업 복습/C 복습 노트

[C언어] C언어 수업 9차시

by LimitLog 2021. 5. 11.

1. 배열(Array)

하나의 이름으로 참조되는 같은 자료형을 갖는 메모리의 연속적인 공간을 의미한다. 배열 변수명 뒤에 선언된 대괄호[] 안에 원소의 수를 주게 된다. 배열은 선언되면 원소의 수만큼 메모리에 할당을 받게 되는데 배열 내에 있는 각 원소를 배열 원소(array element)라고 부른다.

 

 

 

2. 1차원 배열

배열 변수명 뒤에 대괄호가 하나 선언된 구조를 말한다. 1차원 배열의 일반적인 형식은 다음과 같다.

자료형(type) 배열명(var-name)[원소의수(size)]

1
int array1[5]; //자료형 배열명[원소의수]
cs

배열의 원소들은 연속된 기억장소에 할당받는다. 위 선언문의 메모리 구조는 다음과 같다. 할당된 각 원소들의 위치를 이라고 한다. 1차원 배열은 열의 집합이다.

빨간색으로 표시한 숫자가 열 번호이다.

array1은 정수형 배열이므로 한 칸당 4byte씩 5칸, 총 20byte를 메모리로부터 할당받게 된다.

 

배열의 원소에도 당연히 접근할 수 있다. 이 방식을 통해 배열을 초기화할 수 있다.

배열명(var-name)[열 번호] = 값(value);

1
    array1[0= 10//array1의 0번째 열 값에 10 대입.
cs

 

또는 선언과 동시에 배열을 초기화하는 방법도 있다.

1
int array1[5= {10,20,30,40,50};
cs

 

1
int array1[5= {0,}; //모든 요소를 0으로 초기화
cs

 

1
int array1[5= { 10,20 }; //0번째 요소를 10으로, 1번째 요소를 20으로 초기화하고 나머지 전부 0으로 초기화
cs

 

다음은 정수형 배열을 사용한 간단한 예제이다.

1
2
3
4
5
6
7
8
9
int main() { //배열1
    int count[5= { 10,20,30,40,50 };
    int i;
    printf("SIZEOF(count) : %d\n",sizeof(count)); //배열의 전체 크기
    for (i = 0; i < 5; i++) {
        printf("Count[%d] : Value %d,     SIZEOF %d,     Point %p\n", i, count[i], sizeof(count[i]),&count[i]); //원소의 값, 하나의 원소 크기, 원소의 시작주소
    }
    return 0;
}
cs

 

문자형 배열도 사용할 수 있다. 문자형 배열은 꼭 마지막에 공백(NULL)이 들어갈 자리를 마련해야 한다.

1
2
3
4
5
6
7
8
9
10
11
12
13
void main() { //배열2
    char chs1[6= { 'a','p','p','l','e','\0' };
    char chs2[6= "apple";
    char chs3[5= "apple";
 
    printf(" > 문자형 배열로 문자열 \"apple\" 을 표현하는 프로그램 \n ");
    printf("  1. 배열의 요소를 중괄호로 하나씩 나열 ... [ %s ] \n ", chs1);
    printf("     배열의 크기  [ %d ] \n "sizeof(chs1));
    printf("  2. 배열의 요소를 한꺼번에 나열 ...[ %s ] \n ", chs2);
    printf("     배열의 크기  [ %d ] \n "sizeof(chs2));
    printf("  3. 배열의 크기를 5로 설정 ... [ %s ] \n ", chs3);
    printf("     배열의 크기  [ %d ] \n "sizeof(chs3));
}
cs

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
int main() { //배열2-1
    char string1[10= "ABCDEF";
    char string2[7= "ABCDEF";
    char string3[] = { 'A','B','C','D','E','F' };
    char string4[] = "ABCDEF";
    char string5[] = { 'A','B','C','D','E','F' ,'\0'};
 
    printf(" %s\n",string1);
    printf(" %s\n",string2);
    printf(" %s\n",string3);
    printf(" %s\n",string4);
    printf(" %s\n",string5);
    return 0;
}
cs

 

다음은 정수를 입력받아 홀수는 앞에서부터, 짝수는 뒤에서부터 정렬하는 프로그램이다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
int main() { //배열3
    int arr[6];
    int temp;
    int frontCount = 0;
    int rearCount = (sizeof(arr)/sizeof(int)) - 1;
 
    printf(" >> 총 6개의 숫자를 입력할 수 있습니다.\n");
    for (int i = 0; i < sizeof(arr) / sizeof(int); i++) {
        printf("  > 숫자 입력 : ");
        scanf("%d",&temp);
        if (temp % 2 != 0) { //사용자가 입력한 수가 홀수이면
            arr[frontCount++= temp; //frontCount 열에 temp값을 저장하고 frontCount에 1을 더함
        }
        else { //짝수이면
            arr[rearCount--= temp; //rearCount 열에 temp값을 저장하고 rearCount에서 1을 뺌
        }
    }
    printf(" >> 배열 요소의 출력 : ");
    for (int i = 0; i < (sizeof(arr) / sizeof(int)); i++)
        printf("[ %d ] ", arr[i]);
 
    return 0;
}
cs

 

다음은 알파벳을 순서대로 출력하는 프로그램이다. 문자는 아스키 코드값을 갖고 있기 때문에 다음과 같은 프로그래밍이 가능하다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
int main(void) { //배열4
    char arr[26];
    char ch;
    int i;
 
    for (i = 0, ch = 'A'; i < 26; i++) {
        arr[i] = ch++;
    }
    for (i = 0; i < 26; i++)
        printf("%c ",arr[i]);
 
    printf("\n");
    return 0;
}
cs

 

 

 

3. 배열 원소의 정렬, 탐색, 빈도 계산

선택 정렬이란 제자리 정렬 알고리즘의 하나이다. 주어진 리스트에서 최소값을 찾은 후 그 값을 맨 처음 위치의 요소와 교환한다. 그 다음 맨 처음을 제외한 요소에서 같은 작업을 반복하는 정렬 방식을 뜻한다.

아래는 선택 정렬 알고리즘을 구현한 프로그램이다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
#define SIZE 10
int main(void) { //99까지 난수를 생성해 선택정렬
    int list[SIZE] = {0, };
    int  temp; //값을 바꾸기 위한 임시버퍼
    int least; //탐색한 최솟값의 열 정보를 갖는 변수
 
    srand(time(NULL));
    printf(">> 정렬 이전(난수 생성) :  ");
    for (int i = 0; i < SIZE; i++) {
        list[i] = rand() % 99;
        printf("[ %d ]",list[i]);
    }
    printf("\n");
 
    for (int i = 0; i < SIZE - 1; i++) {
        least = i; //i번째 값을 최소값으로 가정
        for (int j = i + 1; j < SIZE; j++) { //최소값 탐색
            if (list[j] < list[least])
                least = j;
        }
        //현재 정렬되지 않는 남은 요소 중에서 list[least]는 최소값이다.
        //아래는 초동역학 위치전환기
        // list[least]의 값이 최소값이므로 남은 요소의 제일 앞으로 보낸다.
        temp = list[i];
        list[i] = list[least];
        list[least] = temp;
    }
    printf(">> 정렬 이후 :  ");
    for (int i = 0; i < SIZE; i++) {
        printf("[ %d ]",list[i]);
    }
    printf("\n");
    return 0;
}
cs

 

버블 정렬이란 두 인접한 원소를 비교하여 정렬하는 방법이다. 시간 복잡도가 상당히 느리지만 비교적 단순한 알고리즘 덕분에 자주 사용된다.

아래는 버블 정렬 알고리즘을 구현한 프로그램이다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
#define SIZE 10
 
void bubble_sort(int list[]); //버블정렬을 할 함수
int main(void) { //99까지 난수를 생성해 버블버블정렬
    int list[SIZE] = { 0, };
 
    srand(time(NULL));
    printf(">> 정렬 이전 :  ");
    for (int i = 0; i < SIZE; i++) { //난수생성및출력
        list[i] = rand() % 99;
        printf("[ %d ]", list[i]);
    }
    printf("\n");
    bubble_sort(list);
    return 0;
}
void bubble_sort(int list[]) {
    int temp; //임시버퍼
    bool roop = true//루프 탈출 여부
 
    while (roop) {
        roop = false;
        for (int i = 0; i < SIZE - 1; i++) {
            if (list[i] >  list[i + 1]) {
                temp = list[i];
                list[i] = list[i + 1];
                list[i + 1= temp;
                roop = true//자리를 바꾼 요소가 있을 경우 계속 루프를 돈다.
            }
        }
    }//자리를 바꾼 요소가 하나도 없으면 정렬이 끝났으므로 탈출
 
    printf(">> 정렬 이후 :  "); //출력
    for (int i = 0; i < SIZE; i++)
        printf("[ %d ]", list[i]);
    printf("\n");
}
cs

 

순차 탐색은 어렵지 않다. 그냥 입력한 값을 배열 내에서 순차적으로 탐색해 나가는 알고리즘이다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#define SIZE 10
int main(void) { //순차 탐색
    int key, i;
    int list[SIZE] = { 1,2,3,4,5,6,7,8,9 };
 
    printf("탐색할 값을 입력하시오 : ");
    scanf("%d",&key);
 
    for (i = 0; i < SIZE; i++) {
        if (list[i] == key) //입력한 키값과 같은 원소가 있을 경우
            printf("탐색 성공 인덱스 : %d \n",i);
    }
    printf("탐색 종료 \n");
    return 0;
}
cs

위 두 예제처럼 난수를 발생시켜 찾게 하면 조금 더 재미있는 알고리즘이 될 수 있다.

 

빈도 계산 알고리즘도 절대 어렵지 않다. 입력한 값의 열의 값을 늘리기만 하면 된다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#define SIZE 10
int main(void) { //빈도 계산
    int freq[SIZE];
    int i, score;
 
    for (i = 0; i < SIZE; i++) {
        freq[i] = 0;
    }
    while (1) {
        printf(" > 0~9 숫자를 입력하시오(종료:그외) : ");
        scanf("%d"&score);
        if (score < 0 || score >9break//루프탈출
        freq[score]++//freq 배열의 score열에 1을 더함.
    }
    printf("\n>> 값 빈도\n");
    for (i = 0; i < SIZE; i++//출력
        printf(" > %2d   %2d\n", i, freq[i]);
 
    return 0;
}
 
cs

 

'수업 복습 > C 복습 노트' 카테고리의 다른 글

[C언어] C언어 수업 11차시  (0) 2021.05.25
[C언어] C언어 수업 10차시  (0) 2021.05.18
[C언어] C언어 수업 8차시  (0) 2021.05.04
[C언어] C언어 수업 7차시  (0) 2021.04.20
[C언어] C언어 수업 6차시  (0) 2021.04.13

댓글