2차원 배열의 선언은 다음과 같다.

int arr1[3][4];

이는 3행 4열을 가진 이차원 배열 arr1을 의미하며 그림으로 표현하면 다음과 같다.

[0][0] [0][1] [0][2] [0][3]
[1][0] [1][1] [1][2] [1][3]
[2][0] [2][1] [2][2] [2][3]

그렇다면 이 배열의 sizeof 연산을 한 결과를 예시를 통해 확인해보자.

<소스코드>

1
2
3
4
5
6
7
8
9
#include <stdio.h>
 
int main(void) {
    int arr1[3][4];
 
    printf("3행 4열인 배열 arr1의 크기는 %d 입니다.\n"sizeof(arr1));
 
    return 0;
}
cs

<실행결과>

 

위의 표를 보면 3행 4열 이므로 총 12칸이 존재하고 int 형 배열이므로 12 x 4이므로 48바이트 인 것을 확인할 수 있다.

이차원 배열은 다음의 형태로 선언과 동시에 초기화할 수 있는데 총 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
35
36
37
38
#include <stdio.h>
 
int main(void) {
    int arr1[3][3= {
        {123},
        {456},
        {789}
    };
 
    int arr2[3][3= {
        {1},
        {45},
        {789}
    };
 
    int arr3[3][3= { 1234567 };
 
    for (int i = 0; i < 3; i++) {
        for (int j = 0; j < 3; j++) {
            printf("%d ", arr1[i][j]);
        }
        printf("\n");
    }
    printf("\n");
    for (int i = 0; i < 3; i++) {
        for (int j = 0; j < 3; j++) {
            printf("%d ", arr2[i][j]);
        }
        printf("\n");
    }
    printf("\n");
    for (int i = 0; i < 3; i++) {
        for (int j = 0; j < 3; j++) {
            printf("%d ", arr3[i][j]);
        }
        printf("\n");
    }
}
cs

<실행결과>

3차원 배열도 위의 2차원 배열과 비슷하므로 이 포스팅에서는 생략 하겠다.

'C' 카테고리의 다른 글

8. 2차원 배열과 포인터  (0) 2021.06.26
7. 이중 포인터  (0) 2021.06.25
5. 포인터와 함수  (0) 2021.06.25
4. 포인터와 배열  (0) 2021.06.22
3. 포인터  (0) 2021.06.21
함수의 인자로 배열 전달

함수 호출시 전달되는 인자의 값은 매개변수에 복사가 되는 형태이다. 즉 int Func(int number); Func(num); 이라는 문장이 있다면 실제의 num값이 아닌 num에 저장된 값이 number에 복사가 되는 것이다. 그렇다면 Func 함수 내부에서 number값을 하나 증가 혹은 감소시키면 num은 어떻게 될까?

정답은 아무 상관이 없다 이다. 이유는 두 변수는 서로 다른 변수이기 때문이다. 

그렇다면 배열을 인자로 전달하려면 어떻게 해야 할까? 바로 주소값을 알려주면 되는 것이다.

int arr[3] = {1, 2, 3}; 다음의 형태로 저장된 배열이 있다면 Func(arr); 의 형태로 배열의 주소 값을 전달하면 되는 것이다. 앞에서 배열의 이름은 주소 값이라는 것을 배웠기 때문에 가능한 일이다. 다음의 예시를 통해 함수의 매개변수로 배열을 인자로 전달하는 형태를 살펴보자.

<소스코드>

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include <stdio.h>
 
void showArray(int array[], int len) { // 배열을 함수의 인자로 전달받는 함수의 선언
    for (int i = 0; i < len; i++) {
        printf("%d ", array[i]);
    }
}
 
int main(void) {
    int arr[5= { 12345 };
    int length = sizeof(arr) / sizeof(int);
 
    showArray(arr, length); // 함수의 호출
 
    return 0;
}
cs

<실행결과>


Call by value와 Call by reference

함수의 호출에는 두가지 방식이 존재한다. 바로 값에 의한 호출, 참조에 의한 호출이 그것이다. 기존에 배웠던 함수들의 대부분은 Call by value 였다. 그렇다면 Call by reference는 왜 존재하는 것일까? 다음의 예시를 통해 알아보자.

<소스코드>

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
#include <stdio.h>
 
void SwapByValue(int num1, int num2) { // Call by value에 의한 함수 SwapByValue
    int temp; 
    // swap
    temp = num1;
    num1 = num2;
    num2 = temp;
}
 
void SwapByReference(int * num1, int * num2) { // Call by reference에 의한 함수 SwapByReference
    int temp;
    // swap
    temp = *num1;
    *num1 = *num2;
    *num2 = temp;
}
 
int main(void) {
    int n1 = 3, n2 = 5;
 
    SwapByValue(n1, n2);
    printf("Call by value\n");
    printf("n1 = %d, n2 = %d\n", n1, n2);
 
    puts("");
 
    printf("Call by reference\n");
    SwapByReference(&n1, &n2);
    printf("n1 = %d, n2 = %d\n", n1, n2);
    return 0;
}
cs

<실행결과>

먼저 SwapByValue 함수를 호출한 경우 main함수의 n1, n2가 그대로인 것을 확인할 수 있다. 이는 이 포스팅의 맨 처음 부분에 나왔던 number값을 증가시켜도 num값은 변화하지 않는 것과 동일한 이유 때문이다. 따라서 SwapByReference 방식을 이용한 즉 Call By Reference 방식을 이용하여 주소 값을 통해 접근하게 해야 main 함수에서도 변경이 될 수 있는 것이다. 이를 그림으로 표현하면 다음과 같다.

call by value의 경우
Call by reference의 경우

위의 그림에서 볼 수 있듯이 call by value와 다르게 call by reference의 경우 주소값을 통해 함수 내부에서 main영역에 있는 변수에 접근할 수 있다.


'C' 카테고리의 다른 글

7. 이중 포인터  (0) 2021.06.25
6. 다차원 배열  (0) 2021.06.25
4. 포인터와 배열  (0) 2021.06.22
3. 포인터  (0) 2021.06.21
2. 배열을 이용하여 문자열의 표현  (0) 2021.06.21
배열이란?

배열이란 둘 이상의 변수를 모아 놓은 것이다. 배열의 선언 방식은 다음과 같다.

위에서 볼 수 있듯이 int arr[10]; 이면 자료형이 int, 배열의 이름이 arr, 배열의 길이가 10이라는 것을 말하는 것이다.

1
int arr[10];
cs

위에서 볼 수 있듯이 int arr[10]; 이면 자료형이 int, 배열의 이름이 arr, 배열의 길이가 10이라는 것을 말하는 것이다.

또한 특징이 있는데 배열의 시작은 0부터 시작한다는 것이다. 따라서 위의 길이가 10인 배열의 경우 0번째 원소부터 9번째 원소까지 존재한다.

배열의 가장 큰 장점이 존재하는데 바로 반복문을 이용하여 순차적으로 접근이 가능하다는 점이다. 이것을 예시를 통해 알아보자.

1
2
3
4
5
6
7
8
9
10
11
12
#include <stdio.h>
 
int main(void) {
    int arr[5= {010203040 }; // 전부 더하면 100 이다. 
    int sum = 0;
 
    for(int i = 0; i < 5; i++) { // 반복문을 통해 모든 원소들을 더함
        sum += arr[i];
    }
    printf("배열의 모든 원소의 합 : %d", sum);
    return 0;
}
cs

배열의 선언과 동시에 초기화

배열의 초기화의 방법은 총 3가지가 존재한다. 다음을 통해 알아보자.

  1. int arr[5] = {1, 2, 3, 4, 5}; // 차례차례 초기화
  2. int arr1[ ] = {1, 2, 3, 4, 5}; // 컴파일러에 의해서 자동으로 길이 5가 채워진다
  3. int arr3[5] = {1, 2};  // 3, 4, 5 번째 요소는 자동으로 0으로 채워진다.

배열의 길이를 구하는 sizeof() 함수

배열의 길이를 따로 명시하지 않더라도 sizeof 함수를 통해 알 수 있다. 먼저 일반적인 배열 int arr[5] = {1, 2, 3, 4, 5};를 생각해보면 int형이므로 한 요소당 4byte씩 총 20byte이다. 따라서 sizeof(arr);는 20byte이다. 이를 int의 크기 4byte로 나누면 5 즉 배열의 길이를 구할 수 있다. 따라서 배열의 길이는 int len = sizeof(arr) / sizeof(int);로 구할 수 있다. 예시를 보면 다음과 같다.

<소스코드>

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#include <stdio.h>
 
int main(void) {
    int arr1[5= {010203040 };  
    double arr2[4= {0.01.02.03.0};
    float arr3[6= {0.01.02.03.04.05.0};
 
    printf("배열 arr1의 크기 : %d\n"sizeof(arr1));
    printf("배열 arr2의 크기 : %d\n"sizeof(arr2));
    printf("배열 arr3의 크기 : %d\n"sizeof(arr3));
 
    int len1 = sizeof(arr1) / sizeof(int); // 배열 1의 길이
    int len2 = sizeof(arr2) / sizeof(double); // 배열 2의 길이
    int len3 = sizeof(arr3) / sizeof(float); // 배열 3의 길이
 
    printf("배열 arr1의 길이 : %d\n", len1);
    printf("배열 arr2의 길이 : %d\n", len2);
    printf("배열 arr3의 길이 : %d\n", len3);
 
    return 0;
}
cs

<실행결과>

 

'C' 카테고리의 다른 글

5. 포인터와 함수  (0) 2021.06.25
4. 포인터와 배열  (0) 2021.06.22
3. 포인터  (0) 2021.06.21
2. 배열을 이용하여 문자열의 표현  (0) 2021.06.21
1-1 배열 예제  (0) 2021.06.21

+ Recent posts