모노산달로스의 행보

[C programming] 1차원 배열의 정의, 선언, 초기화, 주소와 값의 참조 본문

ProgrammingLanguage/C

[C programming] 1차원 배열의 정의, 선언, 초기화, 주소와 값의 참조

모노산달로스 2024. 4. 2. 20:10

C programming - 1차원 배열

 

 

리눅스 환경에서 네트워크 프로그래밍을 공부하기 위해서 C언어를 다시 복습해야 할 필요성을 느꼈습니다. 따라서 이번 기회에 배열부터 전처리기까지 내용들을 정리하겠습니다.

 


배열이란?

배열의 정의는 아래와 같습니다.

  • 같은 자료형을 가진 연속된 메모리 공간으로 이루어진 자료구조입니다
  • 같은 자료형을 가진 변수들이 여러 개 필요할 때 사용합니다
  • 많은 양의 데이터를 처리할 때 유용합니다

쉽게 정리하자면 같은 자료형의 변수들을 하나로 묶어놓은 것배열이라고 부릅니다

 

 

배열의 선언 방법은 다음과 같습니다.

int array[10];

 

자료형배열의 이름 그리고 배열의 길이를 선언합니다. 위 예시는 10의 길이를 가지는 array라는 이름의 int 자료형 배열입니다.

 

출처 : https://medium.com/@sadhna.narayansadhna/array-basics-before-you-start-coding-f9fa10e77cea

 

배열 요소의 순서를 세는 경우에는 0부터 시작하게 됩니다. 위 예시의 경우 int 자료형 배열로 index가 0부터 시작하는 것을 확인할 수 있습니다.

 

또한 상단의 메모리 공간을 확인해 보면 4바이트씩 늘어나는 것을 확인할 수 있습니다. 이는 곧 int 자료형 요소 하나는 4바이트의 공간이 필요하다는 의미입니다.

 

 


 

배열의 선언과 초기화

지금까지 내용을 바탕으로 배열을 선언하고 값을 초기화하겠습니다.

#include <stdio.h>
int main(void)
{
    int student[5];
    
    student[0] = 90;
    student[1] = 80;
    student[2] = 70;
    
    printf("Student 1's score : %d\n", student[0]);
    printf("Student 2's score : %d\n", student[1]);
    printf("Student 3's score : %d\n", student[2]);
    printf("Student 4's score : %d\n", student[3]);
    printf("Student 5's score : %d\n", student[4]);
    
    return 0;
}

예제 코드의 실행 결과

 

가장 먼저 int student[5]라는 배열을 선언하였습니다. 그리고 0번 index부터 순서대로 90, 80 ,70의 값을 초기화해 주는 것을 확인할 수 있습니다. 그리고 배열의 모든 값을 출력하는 코드입니다.

 

주의해야 할 사항으로 배열 index의 3번과 4번은 메모리 공간이 할당되어 있지만 실제 값은 초기화되어있지 않습니다. C언어에서는 compiler가 자동으로 값을 초기화해주지 않으므로 아무런 의미가 없는 Garbage Value(쓰레기 값)이 출력되었습니다.

 

 

이러한 상황을 방지하기 위해서 배열선언과 동시에 초기화할 수 있습니다.

#include <stdio.h>
int main(void)
{
    int array1[5] = {90, 80, 70, 60, 50};
    int array2[] = {90, 80, 70, 60, 50};
    int array3[5] = {90, 80, 70};

    printf("%d %d %d %d %d\n", array1[0], array1[1], array1[2] ,array1[3], array1[4]);
    printf("%d %d %d %d %d\n", array2[0], array2[1], array2[2] ,array2[3], array2[4]);
    printf("%d %d %d %d %d\n", array3[0], array3[1], array3[2] ,array3[3], array3[4]);
}

예제 코드의 실행 결과

C언어에서는 위와 같이 배열을 선언함과 동시에 값을 초기화하는 것이 가능합니다. 각각의 배열이 서로 다른 배열의 특징을 보여주고 있습니다.

 

array2의 경우 배열의 길이를 선언하지 않고 값을 초기화하였습니다. 이러한 경우 자동적으로 array2는 초기화한 값의 수만큼의 길이를 가지게 됩니다.

 

array3의 경우 배열의 일부 값만을 초기화하였습니다. 이러한 경우 나머지 값은 자동적으로 0으로 초기화되는 것을 확인할 수 있습니다.

 

 

마지막으로 배열 선언 시 주의점을 알아보겠습니다.

#include <stdio.h>
#define MAX 20 // defining integer constant
int main(void)
{
    int array1[3] = {10, 20, 30};
    int array2[3];
    array2 = {10, 20, 30} // error
    
    int a = 3; 
    const int SIZE = 10; // defining integer constant
    int array3[MAX];
    int array4[SIZE];
    int array5[a]; // error
    
    return 0
}

 

array2의 경우 배열의 선언과 초기화를 개별적으로 수행하고 있습니다. 배열의 선언과 초기화는 동시에 이루어져야 합니다.

 

array5의 경우 배열의 길이를 변수로 설정하였습니다. 이는 에러를 발생시킵니다. array3과 array4처럼 상수를 사용하여 배열의 길이를 설정해야 합니다.

 

 


 

배열의 주소와 값의 참조

지금까지는 배열을 단순히 선언하고 초기화하는 예제만을 보았습니다. 이번에는 배열을 제대로 활용하기 위해 배열의 값을 참조하는 방법을 알아보겠습니다.

#include <stdio.h>
int main(void)
{
    int array1[3] = {1, 2, 3};
    char array2[3] = {'A','B','C'};

    printf("%x %x %x \n", &array1[0], &array1[1], &array1[2]);
    printf("%x %x %x \n", &array2[0], &array2[1], &array2[2]);
    
    return 0;
}

예제 코드의 실행 결과

 

int 자료형의 배열과 char 자료형의 배열이 선언과 동시에 초기화되었습니다. 그리고 두 배열이 가지는 요소의 주소 값을 출력했습니다.

 

변수의 주소를 출력하는 것과 마찬가지로 배열의 주소를 표현하기 위해서 &를 사용할 수 있습니다. 이때 출력되는 주소를 나타내는 숫자 상수는 운영체제와 개발 환경에 따라서 달라집니다.

 

16진수 형태로 주소가 출력되는데 이를 잘 살펴보면 int 자료형의 배열은 4씩 증가하고 char 자료형의 배열은 1씩 증가하고 있는 것을 확인할 수 있습니다.

 

출처 :&nbsp;https://techbeamers.com/c-datatypes/

 

C언어의 자료형의 크기를 표로 정리하면 위와 같습니다. 배열의 주소가 증가하는 것을 통해 해당 자료형의 크기를 확인할 수 있습니다.

 

위 문단에서 배열의 주소를 참조하기 위해서 &를 사용했습니다. 하지만 배열의 이름만으로도 주소를 참조하는 것이 가능합니다.

#include <stdio.h>
int main(void)
{
    int array[3] = {1, 2, 3};

    printf("%x %x %x\n", array+0, array+1, array+2);
    printf("%x %x %x\n", &array[0], &array[1], &array[2]);
    
    return 0;
}

예제 코드의 실행 결과

 

두 표현 방식의 출력 결과 값이 같습니다. 즉 array + 0 == &array[0]과 같은 의미로 주소 참조에 사용이 가능합니다.

 


 

이번에는 * 연산자를 사용해서 배열의 값을 참조하는 예제입니다.

 

#include <stdio.h>
int main(void)
{
    int array[3] = {1, 2, 3};

    printf("%x %x %x\n", &array[0], &array[1], &array[2]);
    printf("%d %d %d\n", *&array[0], *&array[1], *&array[2]);
    printf("%d %d %d\n", array[0], array[1], array[2]);
    
    return 0;
}

예제 코드의 실행 결과

 

출력 결과를 통해 배열의 주소를 참조하는 연산자 &값을 참조하는 연산자 *가 서로 상쇄되는 것을 확인할 수 있습니다. 즉 *&array[0] == array[0]과 같은 의미로 값의 참조에 사용이 가능합니다.

 

 

#include <stdio.h>
int main(void)
{
    int array[3] = {1, 2, 3};

    printf("%x %x %x\n", array+0, array+1, array+2);
    printf("%d %d %d\n", *(array+0), *(array+1), *(array+2));
    printf("%d %d\n", *(array+0), *array);

    return 0;
}

예제 코드의 실행 결과

 

배열의 이름이 배열의 시작 주소를 의미하는 것을 활용하면 위와 같은 표현 방식을 사용할 수도 있습니다.

 

즉, *(array+i) == array[i] == *&array[i] 모두 같은 주소의 값을 참조하는 표현입니다.


 

이상으로 배열의 모든 내용을 정리했습니다.

 

다음 글에서는 다차원 배열에 대해서 알아보겠습니다.