언어 자료구조 알고리즘/C 언어 문법

23.배열

언제나휴일 2009. 8. 19. 05:47
반응형

배열

 

 다루는 내용

  - 배열의 선언 및 초기화

  - 배열의 기본적인 사용

 

 배열은 같은 형태의 데이터(레코드)를 연속적인 메모리(논리적인 메모리)에 할당하여 관리하는 자료구조를 말한다.

C언어에는 정적인 배열 형식의 변수를 선언할 수 있는 매커니즘을 제공하고 있다.

반면, 동적인 배열은 동적 메모리 할당에 관련된 함수 호출을 통해 사용할 수 있지만 형식으로는 제공하고 있지 않다.

 

정적 배열과 동적 배열

배열은 자료를 보관하는 컨테이너이다.  배열은 데이터를 보관하는 버퍼가 연속적인 메모리에 할당되어 하나의 관리명으로 관리할 수 있는데 해당 버퍼의 크기(즉, 보관할 수 있는 원소의 개수)가 컴파일 시에 정해지는가 혹은 런타임에 정해지는가에 따라 정적 배열과 동적 배열로 나눌 수 있다.

배열의 선언 및 초기화   

배열

선언 원소 형식 배열명[원소개수]
초기화 원소형식 배열명[원소개수] = {초기 값 리스트};
선언 원소 형식의 일부 배열명[원소개수]원소형식의 일부; 
초기화 원소 형식의 일부 배열명[원소개수]원소형식의 일부={초기 값 리스트}; 

int arr1[10] ;

int arr2[10]={1}; //첫번째 원소는 1로 초기화, 나머지는 0으로 초기화

int arr3[10][4]; //배열명: arr3, 원소 개수 4, 원소 형식: int  [4]

int arr4 [10][4] = { {1,2},{2,3}}; //초기값이 명시되지 않은 멤버는 0으로 초기화

 

C언어에서 대부분의 변수명은 할당된 메모리에 있는 값을 의미한다.

하지만, 배열명과 함수명은 할당된 메모리 주소를 값으로 의미한다.

배열명의 경우 여러 개를 관리하기 위한 관리명이기 때문에 특정 원소의 값을 의미할 수는 없다.

이에 배열명은 모든 원소를 관리할 수 있게 하기 위해 할당된 첫번째 주소 즉, 첫 번째 원소의 주소를 값으로 지니고 있다.

이러한 이유로 배열명은 원소 타입의 포인터 상수로 취급한다.

 

 Look & Feel & Think

위의 예를 보면 arr2를 변경하는 것을 허용하고 있지 않다.  배열명은 원소 타입의 포인터 상수 취급을 받기 때문에 변경할 수가 없다.


배열명은 할당된 메모리 주소를 값으로 지니고 있기 때문에 위의 예에서 다르다가 출력되는 것이다.


이러한 배열을 사용할 때는 언제나 배열명이 원소에 대한 포인터 상수 취급을 받는다는 것을 잊지 말아야 한다.

배열을 사용할 때에는 인덱스 연산자, 간접 연산자, 주소 연산자, 산술 연산자, 지시 연산자 등을 사용하게 된다.

포인터[정수] 와  *(포인터+정수)는 완벽한 동치이다.(선언부의 지시연산자[]를 얘기하는 것이 아니며 인덱스 연산자를 말한다.)

즉, 인덱스 연산자를 사용할 때 포인터[정수]뿐만 아니라 정수[포인터]도 가능하다.  물론, 후자의 경우 가독성이 크게 떨어질 수 있기 때문에 사용을 하는 것을 결코 권하고 싶지 않다.

 

#include <stdio.h>

void main()
{
    int arr[10]={1,2,3,4,5,6,7,8,9,10};

    int i = 0;

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

 

    for(i=0;i<10;i++)
    {
        printf("%d\n",*(i+arr));
    }

 

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


배열명이나 혹은 배열명 + 정수를 인자로 넘길 때 원소 타입의 포인터 형식으로 받아 처리하는 예이다.
 

#include <stdio.h>
int CalSum(int *base,size_t asize);
void main()
{
    int arr[10]={1,2,3,4,5,6,7,8,9,10};

    printf("%d\n",CalSum(arr,10));
    printf("%d\n",CalSum(arr+2,5));
}

int CalSum(int *base,size_t asize)
{
    int sum = 0;
    while(asize)
    {
     sum += *base;
     base++;
     asize--;
    }
    return sum;
}


배열명이나 혹은 배열명 + 정수를 인자로 넘길 때 배열 형식으로 받아 처리하는 예이다.  함수의 입력 매개변수는 호출하는 곳에서 초기화를 하기 때문에 입력 매개변수에 배열을 선언하면서 원소의 개수를 명시하지 않아도 컴파일 에러가 나지 않는다.  물론, 다른 입력 매개변수로 처리할 원소의 개수를 넘기는 것을 잊지 말아야 할 것이다.
 

#include <stdio.h>
int CalSum(int base[],size_t asize);
void main()
{
    int arr[10]={1,2,3,4,5,6,7,8,9,10};

    printf("%d\n",CalSum(arr,10));
    printf("%d\n",CalSum(arr+2,5));
}

int CalSum(int base[],size_t asize)
{
    int sum = 0;
    size_t i = 0;
    for(i=0;i<asize;i++)
    {
        sum += base[i];
    }
    return sum;
}


반응형

'언어 자료구조 알고리즘 > C 언어 문법' 카테고리의 다른 글

24. 배열의 사용  (0) 2009.08.19
22. 제어문 - 반복문  (0) 2009.08.19
21.제어문 - 선택문  (0) 2009.08.19
20. 제어문 - 조건문  (0) 2009.08.19
19. 기본입출력 - 입력  (0) 2009.08.19
18. 기본 입출력 - 출력  (0) 2009.08.19
17.기본 입출력 개요  (0) 2009.08.19
16. 지시/주소/인덱스/간접연산자  (0) 2009.08.19
15. 비트/ 쉬프트 연산자  (0) 2009.08.19
14. 비교/논리 연산자  (0) 2009.08.19