C 2차원 배열 리턴 - c 2chawon baeyeol liteon

*배열 (array)

같은 자료형의 변수를 일렬로 늘어놓은 형태이다. 반복되는 작업을 쉽게 하도록 해주며, 반복문에서 배열을 사용하면 반복되는 값을 쉽게 처리할 수 있다.

변수 이름 뒤에 대괄호 [ ] 를 붙여 size를 설정한다. 그리고 값을 초기화 할때는 중괄호 { }를 사용한다.

*배열의 선언

자료형 배열명[배열의 크기(요소의 개수)] = {값, 값, 값 ,,,,,,,,,}; 

(초기화값은 없어도 된다.)

배열의 값들은 요소(element)라고 부르며, 첫번째 요소의 자리값(index)은 0부터 시작한다. 즉, 첫번째 요소의 인덱스는 0이다.

만약 인덱스를 초과하는 범위의 값을 출력한다면, 컴파일 에러는 발생하지 않지만 쓰레기값이 출력된다. (엉뚱한 메모리주소값에 이미 저장되어 있는 값을 출력하기 때문에)

* 배열 선언시의 size 생략
int arr1[] = {10, 20, 30};  // 값을 초기화해 줄때는 크기를 생략해도 알아서 크기가 설정된다.
int arr2[] ;   // 값도 초기화하지 않고, 크기도 생략한다면 컴파일 에러가 발생한다.

두번째 줄처럼, 초기값과 size를 모두 생략한다면 컴파일에러가 발생한다.

*배열 예제 1: 배열을 선언하고 출력하기
#include <stdio.h>

int main(void){

    int a[10] = {1,2,3,4,5};
    int i ;

    for (i=0;i<10;i++){
        printf("%d\n", a[i]);
    }
    system("pause");
}
*배열 예제 2: 배열의 원소중, 최댓값 찾아 출력하기
#include <stdio.h>
#include <limits.h> // 각 자료형의 최소값, 최대값이 정의되어있는 헤더파일

int main(void){
    int a[10] = { 6, 5, 4, 3, 9, 8 , 0, 1, 11, 3};
    int i, maxValue =INT_MIN;  // INT_MIN = -214748364811 int로 표현할수 있는 가장 작은값
    printf("%d",maxValue);
    for (i=0; i<10; i++){
        if (maxValue<a[i]) maxValue=a[i];
    }
    printf("%d\n", maxValue);
}
배열 값을 모두 0으로 초기화하기

배열의 값을 초기화할때 { } 중괄호 속을 비워두면, 값이 모두 0으로 초기화된다.

#include <stdio.h>
int main(){
	int arr1[100] = { };
    for (int i = 0 ; i < 100 ; i++ ){
    printf("%d\n", arr1[i]);
    }
    return 0;
}


출력 >>>>>> 0 이 배열의 size만큼 출력된다.( 즉 0 * 100번 출력)

* 배열 + 반복문시 index 설정 

C에서는 인덱스를 벗어나도 에러발생이 없으므로, for문의 조건식에 배열의 size를 직접 숫자로 입력하기보다는 

for (int i = 0 ;  i < sizeof(Arr) / sizeof(int) ; i++) 와 같이 sizeof 함수를 이용하는게 실수를 방지할 수 있다.

* 배열과 포인터

배열의 첫번째 요소는 주소값만 담고있다. 즉, 배열은 주소값이기 때문에 포인터에 넣을 수 있다, 그리고 주소값이기 때문에 따로 주소값 연산자 &를 사용하지 않아도 된다. (즉 ,실제 동작에서는 배열 = 포인터 라고 할수있다)

#include <stdio.h>
int main(){
	int arr[] = {99,2,3,4,5};
    int *pointer = arr;   // &가 필요 없다.
    printf("%d\n", *pointer)  // 배열의 첫번째 요소 99 가 출력된다.
	printf("%d\n", *arr) // 배열 자체를 역참조해도 첫번째 요소인 99가 출력된다.
	printf("&d\n", pointer[3])  // 포인터를 사용해 인덱스에 접근 가능하다.

    return 0;
}

배열과 포인터의 차이점 : sizeof로 크기를 보았을때 다른 결과가 나온다.

배열 : 배열이 차지하는 메모리만큼 나온다. ( int 자료형 4개라면 4byte * 4 = 16byte )

포인터 : 포인터의 자료형의 size가 나온다. ( int형 포인트라면 4byte )

* 예제) 배열을 이용하여 10진수를 2진수로 바꾸기.
#include <stdio.h>
int main(){
    int decimal, index = 0;
    scanf("%d", &decimal);
    int binary[20] = {};
    while(decimal != 0){
        binary[index] = decimal % 2;
        decimal /= 2;
        index++;
    }

    for (int i = index-1 ; i >= 0; i--)
    {
        printf("%d", binary[i]);
    }
}
  • decimal : 사용자에게 입력받을 10진수.
  • index : 배열의 인덱스
  • binary : 2진수를 저장할 배열
  • 10진수를 2진수로 변환할때는, 2로 계속 나누고, 그 나머지를 역순으로 읽으면 된다. 따라서 위 코드에서는 decimal을 2로 계속 나누고, 나머지는 binary배열에 하나씩 저장한다. 그리고 마지막에 for문으로 저장된 binary배열을 역순으로 출력한다.

*문자열과 배열

C언어는 문자열이라는 자료형을 제공하지 않습니다. 따라서 C언어에서의 문자열은 문자(Char : Character)를 여러개 묶어놓는 문자들의 배열형태로 문자열을 표현합니다.

ex) char a[20] = "Hello world"

*문자열 예제 1 : 문자열에서 특정값 수정하기

#include <stdio.h>

int main(void){

    char a[20] = "Hello world";

    a[5] = '!';

    printf("%s\n",a);

    return 0;

}

*문자열 예제 2: 문자열에서 특정 알파벳의 개수 count하기

#include <stdio.h>

int main(void){
    char a[] = "Hello world";
    int count = 0;
    for (int i =0; i<=10; i++){
        if(a[i]=='l') count++;
        printf("추가");
    }
    printf("l의 개수는 : %d",count);
    return 0;
}

* 2차원 배열

2차원 배열은 세로(column) 가로(row)로 이루어져 있기 때문에 대괄호 [  ] 를 2번 사용해서 선언한다.

ex ) int arr[3][3] = { { 1, 2, 3 } , { 4, 5, 6 } };

따라서, 값에 접근할때도 2개의 인덱스를 입력하여 접근한다. 배열[세로인덱스][가로인덱스];

0으로 초기화된 배열 선언하기
#include <stdio.h>
int main(){
	int arr[5][5] = { };   // 5x5 배열 선언. 값을 넣지 않으면 0으로 초기화
    
    printf("%d",arr[1][1]);
    printf("%d",arr[2][1]);
    printf("%d",arr[3][1]);
    printf("%d",arr[4][1]);
    
    return 0;
}

출력 >>>>>> 0000 
(모두 0이 출력된다.)
2차원 배열 출력하기
#include <stdio.h>
int main(){
    int arr[10][2] =  { }  ;  // 10행 2열배열 선언, 0으로 초기화
    int row, col ;    
    for (int i =0 ; i < 10; i++){
        for (int j = 0; j < 2 ; j ++){
            printf("%d ", arr[i][j]);
        }
        printf("\n");
    }
}
C 2차원 배열 리턴 - c 2chawon baeyeol liteon
출력결과
sizeof 함수를 이용하여, 2차원 배열의 row, column 구하기
#include <stdio.h>
int main(){
	int numArr[3][4] = {    // 세로 크기 3, 가로 크기 4인 int형 2차원 배열 선언
        { 1, 2, 3, 4 },
        { 515, 466, 37, 58 },
        { 9, 10, 11, 12 }
    };
    
    int col = sizeof(numArr[0]) / sizeof(int); // size(numArr[0]) : 가로 한줄의 크기
	int row = sizeof(numArr) / sizeof(numArr[0]);
    
    printf("row = %d, col = %d",row, col);
    
    return 0;
}

가로 한줄(sizeof(numArr[0])을 int의 size로 나누게 되면, 가로 한줄에 몇개의 요소가 있는지 도출된다. 그 요소의 갯수가 세로의 개수이므로 col이 된다.

* 2차원 배열과 포인터

2차원 배열을 포인터에 넣으려면

  • 자료형 (*포인터이름)[가로크기];형태로 넣어야한다.
  • 포인터 이름을 감싼 소괄호 ( ) 가 반드시 있어야 한다.
  • 괄호를 적지 않는다면, 포인터를 담는 배열이라는 뜻이된다.
  • 자료형과 가로의 크기가 일치해야한다.
  • 포인터에 할당한 뒤, 역참조 하면 1차원 배열과 마찬가지로, 배열의 세로 첫 번째 주소값이 나온다.

* 포인터를 배열처럼 사용하기

  • 1. 자료형 *포인터이름 = malloc(sizeof(자료형) * 크기); 로 포인터를 선언한다.
  • 2. 포인터에 인덱스로 접근하여 값을 할당하거나, 출력하여 사용하면 된다.
  • 3. 마지막에 free 함수를 사용하여 , 메모리를 해제한다.
#include <stdio.h>
#include <stdlib.h>
int main(){
	int *arrPtr = malloc(sizeof(int) * 10);
    arrPtr[2] = 10;
    printf("%d",arrPtr[2]);
    free(arrPtr);
    
    return 0;
}

* 포인터를 2차원 배열로 사용하기.

포인터를 2차원 배열처럼 사용하려면, 반복문으로 메모리를 할당해줘야한다.

  • 자료형 **포인터이름 = malloc(sizeof(자료형 *) * 세로크기); 로, row(가로가 몇줄인지) 메모리 할당.
    • 반복문으로  포인터[i] = malloc(sizeof(자료형) * 가로크기);  로, column(세로가 몇줄인지) 메모리 할당.
    • free(포인터[i]); 반복문을 세로크기 만큼 반복하여 해제
    • free(포인터);와 같이 세로 공간 해제
#include <stdio.h>
#include <stdlib.h>   
int main()
{
    int **pointer = malloc(sizeof(int *) * 3);   // 이중 포인터에 (int 포인터 크기 * 세로 크기)만큼
    for (int i = 0; i < 3; i++)            // 세로 크기만큼 반복
    {
        pointer[i] = malloc(sizeof(int) * 4);    // (int 크기 * 가로 크기)만큼 동적 메모리 할당.
                                           // 배열의 가로
    }

    pointer[2][0] = 5;    // 세로 인덱스 2, 가로 인덱스 0인 요소에 값 할당

    printf("%d\n", pointer[2][0]);    // 5: 세로 인덱스 2, 가로 인덱스 0인 요소의 값 출력

    for (int i = 0; i < 3; i++)    // 세로 크기만큼 반복
    {
        free(pointer[i]);                // 2차원 배열의 가로 공간 메모리 해제
    }

    free(pointer);    // 2차원 배열의 세로 공간 메모리 해제
    return 0;
}