자료구조(1)

PM/iOS Developer KimKU·2022년 1월 13일
0
post-thumbnail

자료구조에 대한 공부📚를 시작하자.

1. 개념 및 정의

자료구조(Data Structure)는 컴퓨터🖥 에서 처리할 자료를 효율적으로 관리하고 구조화시키기 위한 학문이다. 즉, 자료를 효율적으로 사용하기 위해서 자료의 특성에 따라서 분류하고 구성하고 저장 및 처리하는 모든 작업을 의미한다.

2. C 언어에서의 포인터

컴퓨터의 메모리는 데이터를 보관하는 장소
바이트(8 bits) 단위로 주소가 지정됨
**모든 변수는 주소를 가짐**

  • 포인터(pointer)는 메모리 주소를 값으로 가지는 변수이다. 포인터 변수는 다음과 같이 선언된다.
    type-name * variable-name

  • variable-name은 선언된 포인터 변수의 이름이며, *는 variable-name이 포인터 변수임을 표시하고, type-name은 포인터 변수 variable-name에 저장될 주소에 저장될 데이터의 유형을 지정한다.

  • 연산자 &는 변수로부터 그 변수의 주소를 추출하는 연산자이다.

3. C 언어에서의 배열

포인터와 배열은 매우 긴밀히 연관되어 있다.
예를 들어 다음과 같이 선언된 배열 a가 있다고 하자.

int a[10]
  • 배열의 이름은 배열의 시작 주소를 저장하는 포인터 변수이다.
    (단 그 값을 변경할 수 없음)

4. C 언어에서의 포인터 연산

  • *a와 a[0]은 동일한 의미이다.
  • 또한 a[1]은 (a+1)과 동일하고, a[i]는 (a+1)와 동일하다.
  • 코드와 함께 살펴보자.🧐
#include <stdio.h>
int main()
{
    int data[] = {1, 2, 3};
    char data2[] = {'a', 'b', 'c'};
    long long data3[] = {1, 2, 3};
    
    int *p = &data[0]; 
    char *q = &data2[0];
    long long *r = &data3[0];
    
    printf("%d %x\n", p, p);
    printf("%d %x\n", p+1, p+1);
    printf("%d %x\n", p+2, p+2);
    
    printf("%d %x\n", q, q);
    printf("%d %x\n", q+1, q+1);
    printf("%d %x\n", q+2, q+2);

    printf("%d %x\n", r, r);
    printf("%d %x\n", r+1, r+1);
    printf("%d %x\n", r+2, r+2);

    return 0;
}

실행결과:
215844684 cdd874c
215844688 cdd8750
215844692 cdd8754

215844649 cdd8729
215844650 cdd872a
215844651 cdd872b

215844656 cdd8730
215844664 cdd8738
215844672 cdd8740

코드를 분석해보자.

현재 int, char, long long 자료형이 쓰였다. 각 byte의 크기를 살펴보면int는 4byte, char는 1byte, longlong은 8byte이다. 또한 %d는 10진수, %x는 16진수이다.

그러므로 int형의 주소는 4byte씩 늘어났으며, char형은 1byte씩, long long은 8byte씩 늘었다.

5. C 언어에서의 동적메모리 할당

  • 변수를 선언하는 대신 프로그램의 요청으로 메모리를 할당할 수 있다.
  • 이것을 동적 메모리 할당 (dynamic memory allocation) 이라고 부른다.
  • malloc 함수를 호출하여 동적 메모리 할당을 요청하면 요구하는 크시의 메모리를 할당하고 그 시작 주소를 반환한다.

malloc 함수를 사용하는 법에 대해 알아보자.🤔

int *p;
p = (int *)malloc(40);

위 코드에 대해 간단히 알아보자.

malloc이 반환하는 주소는 타입이 없는 주소이다. 그러므로 (int *)는 정수들을 저장하기 위해 사용하는 명령어이다.

다음으로 malloc(40)에 대해 알아보자. 40은 할당받을 메모리의 크기를 byte단위로 지정한 것이다. 여기서는 10개의 정수를 저장하기 위해서 40바이트를 요청하였다. int의 byte 크기는 4 이므로 10개의 배열이 생성된다.


  • malloc 함수를 사용하면 배열의 크기가 부족한 상황이 발생한다.
  • 동적으로 할당된 배열은 공간이 부족할 경우 더 큰 배열을 할당하여 사용할 수 있다.

배열을 키우기 위한 코드를 간단히 알아보자.

 int *array = (int *)malloc(4*sizeof(int));
 
 int * tmp = (int *)malloc(8*sizeof(int));
 int i;
 for(int i = 0; i<4; i++)
     tmp[i] = array[i];
 
 array = tmp;

첫 코드에서 배열 array에 16byte의 크기가 생성되었다. sizeof 함수는 int의 크기인 4byte를 가지고 있고 4를 곱했기 때문에 16byte이다. 그리고 정수를 사용하기 위한 (int *)코드가 사용되었으므로 배열 array는 4개의 배열이 할당되었다.

이 작은 배열의 크기를 키우기 위해서는 임의의 배열 tmp가 필요하다. 위의 코드를 보면 tmp는 8*sizeof(int)의 크기가 생성되었다. 즉 32byte라는 뜻이다. 이제 8개의 배열을 가진 tmp를 array = tmp 라는 코드를 통해 array에 대입하였으며 array8*sizeof(int)의 크기를 가진 배열이 되었다.

profile
With passion and honesty

0개의 댓글