본문 바로가기

C언어/복습

[C언어]DAY10_2차원 배열

2차원 배열 이해

- 메모리상에서 1차원에 연속으로 할당된다.

 


#include <stdio.h>
#define COL 3
#define ROW 2

int main(){
	int i = 0;
	int j = 0;

	int arr[ROW][COL] = { {65,66, 67}, {68, 69, 70} };

	printf("%d\n", sizeof(arr)); //24bytes = 2(ROW)x3(COL)x4(byte)

	//출력
	for(i=0; i<ROW; i++){
		for(j=0; j<COL; j++){
			printf("i = %d, j= %d, arr[%d][%d]= %d\n", i, j, i, j, arr[i][j]);
		}
	}

}

 


2차원 배열에서 주소와 인덱스의 의미

- int type의 1차원 배열의 원소: int

- 2차원 배열의 원소: 1차원배열

- int type의 1차원 배열의 이름의 의미: 원소(int)의 시작주소

- 2차원 배열의 이름의 의미: 1차원 배열(원소)의 시작주소

- int type의 1차원 배열의 인덱스의 크기: sizeof(int) = 4byte

- 2차원 배열의 인덱스의 크기: 1차원배열의 크기

 

#include <stdio.h> 

#define COL 3

#define ROW 2

 

int main() { //2차원배열 선언

     int arr[ROW][COL] ={ {64, 65, 66}, {67, 68, 69} } ;

     int i = 0;

     int j = 0;

 

// 출력

// 64 65 66

// 67 68 69

 

          for(i=0; i < ROW; i ++){

               for(j=0; j printf("%d ", arr[i][j]);
          }
          printf("\n");
          }
          //size
          printf("%d %d %d\n", sizeof(arr), sizeof(arr[0]), sizeof(arr[0][0]));
          //주소 []로
          printf("%p %p %p %p\n", arr, arr[0] , arr[1], &arr[0][0]);
          //주소
          //1의 의미: 다음 원소의 위치:
          //원소=1차원배열=1차원베열의 크기 12byte
          printf("%d %d\n", arr+0, arr+1);

          //arr[i]= *(arr+i)
          //*(arr+0) = arr[0]
          //*(arr+1) = arr[1]
          printf("%d %d\n", *(arr+0), *(arr+1));

          //**(arr+0) = arr[0][0]
          //**(arr+0) = arr[1][0]
          printf("%d %d\n", **(arr+0), **(arr+1));

          //arr[0][1]
          //*(arr+0) = arr[0]
          //a= *(arr+0)
          //*(a+i) = arr[0][1]
          //*(*(arr+0)+1) = arr[0][1]
          printf("%d \n", *(*(arr+0)+1) );
}

 

 


 

2차원 배열과 배열포인터

- 배열포인터란? 배열을 가르키는 포인터 : 배열의 크기만큼 읽어야 함
- int 포인터: int를 가르키는 포인터(주소) 4byte만큼 읽어야 함
- double 포인터: double을 가르키는 포인터 (주소) 8byte만큼 읽어야 함
- char포인터: char를 가르키는 포인터 : 1byte만큼 읽어야 함

 

#include
#define ROW 2
#define COL 3


int main()
{
     int arr[ROW][COL] = { {70, 71, 72},
                                    {73, 74, 75} };
     int i = 0;
     int j = 0;
     int (*p_arr)[COL] = arr;
     //연산자 우선순위때문에 형식을 이렇게 써줘야함.
     //arr은 int[]이 아니라, int[][COL]로 이루어진 배열임을 의미.
     //배열 포인터란, 예를 들어, int[COL]을 원소로 갖는 데이터 타입을 가리키는 포인터.
     char a = 'a';
     char *p_a = &a;

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

     printf("%d %d %d\n", sizeof(arr[0]), sizeof(p_arr), sizeof(*p_arr));
     printf("%d %d %d\n", sizeof(a), sizeof(p_a), sizeof(*p_a));

     //배열포인터는 배열과 똑같이 사용하면 된다.
     printf("%d %d\n", arr[0][0], p_arr[0][0]);
     //*연산자를 사용해서
     //arr[i] = *(arr+1)
     //arr[i][j] = *(*(arr+1)+j)
     printf("%d %d\n", *(*(arr+0)+0), (*(p_arr+0)+0));

     printf("%d %d\n", arr[1][2], p_arr[1][2]);
     printf("%d %d\n", *(*(arr+1)+2), *(*(p_arr+1)+2));
}


//목표: 배열포인터의 사용 예 #3

//이유: 함수인자로 2차원 배열을 보내고자 할 때

 

#include <stdio.h>
#define ROW 2
#define COL 3

void print_array2d(int(*arr)[COL], int size)
{
	int i = 0;
	int j = 0;

	for(i=0; i <ROW; i++){
		for(j=0; j <COL; j++){
			//printf("%d ", arr[i][j]);
			//* 참조연산자 사용해서 출력.
			printf("%d ", *(*(arr+i)+j));
		}
		printf("\n");
	}
}

void print_array1d(int* arr, int size) //주소를 담는 것은 포인터이다. ***중요! 배열을 넘길 때는 주소를 넘겨야함!!***
{
	int i =0;
	for(i=0; i <ROW; i++){
		printf("%d ", arr[i]);
		//printf("%d ", *(arr+i));
		}
		printf("\n");
}

void change_array2d(int (*arr)[COL], int size)
{
	int i = 0;
	int j = 0;

		for(i=0; i <ROW; i++){
		for(j=0; j <COL; j++){
			arr[i][j] += 100;
		}
		printf("\n");
	}

}

int main()
{
	int arr[ROW][COL] = { {1, 2, 3},
						  {4, 5, 6} };
	int i = 0;
	int j = 0;
	int arr_1[COL] = {1, 2, 3};

	print_array2d(arr, 2);
	print_array1d(arr_1, 3); //배열 이름은 주소이다.
	//2차원 배열 각 원소에 100씩 더해주기
	change_array2d(arr,2);
	print_array2d(arr, 2);
}

 

1차원 배열일 경우,
*(arr+0) = arr[0] 는 값이 나온다.

BUT,
2차원 배열일 경우,
*(arr+0) = arr[0]는 주소이다.

2차원 배열 arr[0][0]의 값을 알기 위해서는
**(arr+0)을 해야한다.
-> *(arr[0]+0)

**(arr+1)
-> *(arr[0]+1)

 

=============

a= *(arr+0)
*(a+i) = arr[0][1]

=============

 

//*p_arr이 왜 12byte인지


참조연산자를 안붙일 경우,
함수에서 나오면 값이 사라지기 때문에
main의 주소값에 값을 저장해야한다.

return은 한번 밖에 사용할 수 없기 때문에
포인터를 이용하여 여러 값을 저장한다.

=====================

연습 & 자료 사이트

BAEKJOON
https://www.acmicpc.net/

kaggle
https://www.kaggle.com/

프로그래머스
https://programmers.co.kr/

=====================

 

Q. return의 의미

A.

 ① return; : void형 함수의 종료

 ② rereturn 반환값; : 반환값이 있는 함수의 종료 및 결과값 반환