카테고리 없음

C/C++ 2주차 (19~30강)

Yeni_aa 2022. 3. 12. 18:17

 

#include <stdio.h>
//배열 포인터를 배워보자
int main() {
	int arr[3] = { 1,2,3};

	printf("arr = %d\n", arr); //14679244
	printf("arr + 1 = %d\n", arr+1); //14679248

	printf("&arr = %d\n", &arr); //14679244
	printf("&arr +1 = %d\n", &arr + 1); //14679256 //왜 12가 더해짐?
	//&arr + 1 == &arr에 sizeof(arr)를 더한 값
}

19강. 종합문제

1번. 시험점수 입력하기

// 시험점수 입력해서 출력하기 
#include <stdio.h>
int main()
{
    int a;
    scanf_s("%d", &a);

    if (a > 100 || a < 0) {
        printf("잘못 입력하셨습니다.\n");
    }
    else {

        if (a >= 90) {
            printf("%c\n", 'A');
        }
        else if (a >= 80) {
            printf("%c\n", 'B');
        }
        else if (a >= 70 ) {
            printf("%c\n", 'C');
        }
        else if (a >= 60) {
            printf("%c\n", 'D');
        }
        else {
            printf("%c\n", 'E');
        }
    }
}

2번. 약수구하기

//자연수를 입력받아 소수를 출력해보자
//약수들은 나눴을 때 나머지가 0이되는 수들
#include <stdio.h>
int main() {
	int a;
	scanf_s("%d", &a);

	for (int i = 1; i <= a; i++) {
		if (a % i == 0) { //i가 a의 약수라는 의미
			printf("%d, ", i);
		}
	}
}

쉼표가 안나오게 출력하는 방법

//쉼표가 안나오게 출력하는 방법: for문을 a의 1/2까지만 돌리고, 마지막에 끝값만 따로 프린트
#include <stdio.h>
int main() {
	int a;
	scanf_s("%d", &a);

	for (int i = 1; i <= a/2; i++) {
		if (a % i == 0) {
			printf("%d, ", i);
		}
	}
	printf("%d\n", a);
}

3번. 일의 자릿수가 3,6,9인 경우 1 2 * 4 5 * 7 8 * ...n까지 출력하기

//1의 자릿수가 3의 배수인 경우 *을 출력 
// 1 2 * 4 5 * ... n 
#include <stdio.h>
int main() {
	int n;
	scanf_s("%d", &n);

	for (int i = 1; i <= n; i++)
	{
		if (i % 3 != 0) 
			printf("%d ", i);
		else if (i % 3 == 0) 
			printf("* ");
	}
    printf("\n");
}

★4번문제

//입력받은 n을 계단형태로 홀수로만 출력하기
//1
//1 3 
//1 3 5
//1 3 5 7
#include <stdio.h>
int main() {
	int n,sum;
	scanf_s("%d", &n);

	for (int i = 1; i <= n; i++) {
		for (int j = 1; j <= i; j++) {
			printf("%d ", 2*j - 1);
		}
		printf("\n");
	}
}

5번째 문제

// n=4
/*
1
1 2 3
1 2 3 4 5
1 2 3 4 5 6 7
*/

#include <stdio.h>
int main() {
int n,sum;
scanf_s("%d", &n);

for (int i = 1; i <= n; i++) {
for (int j = 1; j <= 2*i-1; j++) {   // j<=2*i-1로 해주는 게 중요
printf("%d ", j);
}
printf("\n");
}
}

 

 

 

20강. 배열

 

- 배열선언 방법1. 배열을 만들어 놓고 값 넣어주기

int arr[5];

for(int i=0; i<=4; i++){

     arr[i]=i*5;

 

- 배열선언 방법2. 배열선언 할 때 값 배정하기
int arr[5] = { 3,1,4,2,5 }; //배열 선언 방법 2

 

- 배열의 크기는 sizeof()함수로 알 수 있음

#include <stdio.h>
int main(){

	int arr[5] = { 3,1,4,2,5 }; //배열 크기를 sizeof(arr)/sizeof(int)로 출력 


	for (int i = 0; i < sizeof(arr)/sizeof(int); i++) {   //20바이트 / 4바이트 ==> 5 배열의 원소를 알 수 있음.
		printf("%d ", arr[i]);
	}

}

 

21강. 배열의 활용

 

- 입력받은 숫자를 거꾸로 출력하기

//입력받은 숫자를 거꾸로 출력
#include <stdio.h>
int main(){

	int n;
	int arr[1000]; //일단 넉넉하게 배열칸을 만들어 놓고

	printf("입력할 숫자의 개수: ");
	scanf_s("%d", &n);

	for (int i = 0; i < n; i++) {
		scanf_s("%d", &arr[i]);   //내가 배열에 들어갈 숫자들을 직접 지정 
	}

	for (int i = n - 1; i >= 0; i--) {
		printf("%d ", arr[i]);
	}
	printf("\n");

}

-최댓값 구하기 

//최대최소 구하는 문제
#include <stdio.h>
int main(){

	int n;
	int arr[100]; //일단 넉넉하게 배열칸을 만들어 놓고

	scanf_s("%d", &n);
	for (int i = 0; i < n; i++) {
		scanf_s("%d", &arr[i]);  // 3 1 4 2 5
	}

	int max = arr[0]; //max = 3 저장
	for (int i = 1; i < n; i++) { //arr[1] ~ arr[4]까지
		if (max < arr[i]) max = arr[i]; //3<4이면 max= 4;
	}
	printf("%d\n", max);
}

- 최소값을 구할 때는

int min = arr[0]; //max = 3 저장
for (int i = 1; i < n; i++) { //arr[1] ~ arr[4]까지
if (min > arr[i]) min = arr[i]; //3<4이면 max= 4;
}

 

- 짝수의 개수 구하기

//짝수의 개수
#include <stdio.h>
int main(){
	int n;
	int arr[100]; //일단 넉넉하게 배열칸을 만들어 놓고

	scanf_s("%d", &n);
	for (int i = 0; i < n; i++) {
		scanf_s("%d", &arr[i]);  // 3 1 4 2 5
	}
	int cnt = 0;
	for (int i = 0; i < n; i++) {
		if (arr[i] % 2 == 0) 
			cnt++;
	}
	printf("%d\n", cnt);
}

 

22강. 2차원 배열 <- 배열안의 배열

//2차원 배열
#include <stdio.h>
int main() {
	int n;
	int arr[3][4] = {
		{1,2,3,4},
		{5,6,7,8},
		{9,10,11,12}
	};
}

★2차원 배열을 for문을 써서 출력할 때 주의해야 할 점이 있음.

2차원배열 0 1 2 3
0 arr[0][0] arr[0][1] arr[0][2] arr[0][3]
1 arr[1][0] ...    
2        

i는 바깥쪽 행, j는 안쪽 열로 가게 해서 for문 돌리기

 

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

 

★ex) 파스칼의 삼각형 

//2차원 배열 - 파스칼의 삼각형
// i행 j열에 있는 숫자는
// [i][j]= [i-1  j-1] + [i-1 j]
#include <stdio.h>
int main() {

	
	int p[10][10];

	for (int i = 0; i < 10; i++) {
		for (int j = 0; j <= i; j++) {
			if (j == 0 || j == i) {  // 1C0, 2C0,3C0,,,또는 1C1, 2C2,,,
				p[i][j] = 1;
			}
			else {
				p[i][j] = p[i - 1][j - 1] + p[i - 1][j];
			}
			printf("%d ", p[i][j]);
		}
		printf("\n");
	}
	
}

 

23강. 문자열

 

#include <stdio.h>
int main() {
	char arr[100] = "Hello, world!";
	printf("%s\n", arr);
	
}

- 배열의 크기: ['a' ,'b', 'c', '\0'] 이렇게 되니까 배열의 길이는 4

#include <stdio.h>
int main() {
	char arr[] = "abc";
	
	printf("배열의크기: %d\n", sizeof(arr) / sizeof(char)); //4

}

- 배열에 문자열 입력받을 때 주의: scanf_s("%s", s, sizeof(s)/sizeof(char));   <-- 크기도 써줘야함. 

#include <stdio.h>
int main() {
	char s[100];

	scanf_s("%s", s,sizeof(s)/sizeof(char)); //string은 scanf입력 받을 때 &안씀. 

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

}

 

string.h를 사용해보자 

- strlen(str)함수 --> 문자열의 길이 반환 

#include <stdio.h>
#include <string.h>
int main() {
	char str[100] = "Hello";

	int len;

	len = strlen(str); //함수가 반환하는 값 = str의 길이를 len에 저장. 
	printf("문자열의 길이는:  %d\n", len);

}

-strcpy(str2, str1)   --> str1의 내용을 str2로 복사

#include <stdio.h>
#include <string.h>
int main() {
	char str1[] = "Hello";
	char str2[100];  ///그냥 char str[]; 이렇게만은 선언할 수 없음. 빈 배열이라도 크기는 알려줘야함. 

	strcpy(str2, str1);
	printf("str2의 내용: %s\n", str2);

}

-strcat(str, 덧붙일문자열) 

#include <stdio.h>
#include <string.h>
int main() {
	char str[100] = "Hello";
	strcat(str, "World");

	printf("%s\n", str);
}

-strcmp(str1, str2) : 두 문자열을 비교, 사전순으로 누가 더 먼저 있는지도 

//str1이 str2보다 사전순으로 앞쪽에 있다 --> -1반환
//str1이 str2보다 사전순으로 뒤쪽에 있다 --> 1반환
//str1이 str2이랑 같다. -->0반환

#include <stdio.h>
#include <string.h>
//strcmp : 두 문자열 비교, 사전순으로 누가 먼저 있는지도
int main() {
	char str1[] = "sample";
	char str2[] = "simple";

	int cmp = strcmp(str1, str2); 
	//str1이 str2보다 사전순으로 앞쪽에 있다 --> -1반환
	//str1이 str2보다 사전순으로 뒤쪽에 있다 --> 1반환
	//str1이 str2이랑 같다. -->0반환

	printf("%d\n", cmp);
}

 

24강. 변수 가리키기 

포인터란(pointer)? 변수의 주소를 저장하는 변수이다. 

#include <stdio.h>
//포인터는 변수의 주소를 저장하는 변수
int main() {
	int a = 20;
	char c = 'h';

	int* ptr_a;  //가리킬 변수형*ptr_변수이름;
	char* ptr_c;

	ptr_a = &a; //&는 주소값 , a의 주소값을 ptr_a에 저장. 

	printf("%d\n", ptr_a);
}

-printf를 이용해 포인터의 다양한 출력값을 이해해보자. 

#include <stdio.h>
//포인터는 변수의 주소를 저장하는 변수
int main() {
	int a = 20;

	int* ptr_a;  //포인터 선언, 가리킬 변수형*ptr_변수이름;
	ptr_a = &a; //&는 주소값 , a의 주소값을 ptr_a에 저장. 

	printf("a의 값: %d\n", a);
	printf("a의 주소값: %d\n", &a);
	printf("ptr_a에 저장된 값: %d\n", ptr_a);
	printf("ptr_a가 가리키는 변수의 값: %d\n", *ptr_a); //a == *ptr_a
}

a의 값 = 포인터가 가리키는 변수의 값

a의 주소값 = 포인터에 저장된 값 

#include <stdio.h>
//포인터는 변수의 주소를 저장하는 변수
int main() {
	int a = 10;
	int b = 20;

	int* ptr;

	ptr = &a;
	printf("ptr이 가리키는 변수에 저장된 값: %d\n", *ptr);

	ptr = &b;
	printf("ptr이 가리키는 변수에 저장된 값: %d\n", *ptr);
}

- *ptr == a와 같다. 

#include <stdio.h>
//포인터는 변수의 주소를 저장하는 변수
int main() {
	int a = 10;
	
	int* ptr;
	ptr = &a;
	
	printf("a의 값: %d\n", a);

	*ptr = 20;  // a=20; == *ptr=20; 같은 의미임. 

	printf("a의 값: %d\n", a);
}

<꼭 이해해보기>

#include <stdio.h>
int main() {
	int a = 10;

	int *ptr; //포인터 ptr을 선언
	ptr = &a; //포인터가 a의 주소를 가리키도록 선언 

	//포인터를 가리키는 포인터를 만들어보자

	int **ptr_ptr; //포인터를 가리키는 포인터 ptr_ptr
	ptr_ptr = &ptr; //포인터를 가리키는 포인터에는 포인터의 주소를 저장

	printf("a = %d\n", a);
	printf("&a = %d\n", &a);

	printf("ptr = %d\n", ptr); //ptr안에 저장된 a의 주소값
	printf("&ptr= %d\n", &ptr); //ptr의 주소값 

	printf("ptr_ptr= %d\n", ptr_ptr); //ptr_ptr안에 저장된 ptr의 주소값

	printf("ptr_ptr= %d\n", *ptr_ptr); //ptr_ptr안에 저장된 값 = ptr 

	printf("ptr_ptr= %d\n", **ptr_ptr); // **ptr_ptr = a

}

 

25강. 배열과 포인터와의 관계 이해

 

//포인터 + 1 = 포인터가 가리키고 있는 형의 크기만큼 더하게됨, int는 4바이트니까 4가 더해짐.

 

#include <stdio.h>
int main() {
int a = 10;
int *ptr_a = &a;

printf("ptr_a의 값 : %d\n", ptr_a);
printf("ptr_a +1의 값: %d\n", ptr_a + 1);
}

 

-배열을 선언하면 실제로 주소값은 4바이트씩 차이나는 형태로 할당되어 있음.

#include <stdio.h>
int main() {
	int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };

	for (int i = 0; i < 10; i++) {
		printf("&arr[%d] = %d\n",i, &arr[i]); //arr의 주소를 출력해보자
	}
}

 

위의 코드 결과.

- arr = &arr[0] 이랑 같다 

#include <stdio.h>
int main() {
	int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };

	printf("arr의 값: %d\n", arr); //arr[0]의 값과 똑같음! 

	for (int i = 0; i < 10; i++) {
		printf("&arr[%d] = %d\n",i, &arr[i]); //arr의 주소를 출력해보자
	}
}
//즉 arr == &arr[0] 똑같은 말임. 
//arr +1 == &arr[0] +1 == &arr[1]

★즉 arr+i 는 &arr[i]와 같다 

arr[i]가 아니라 주소값인 &arr[i]임!!  

#include <stdio.h>
int main() {
	int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };
    
	for (int i = 0; i < 10; i++) {
		printf("&arr[%d] = %d\n",i, &arr[i]); // &arr[i]와
		printf("arr + %d = %d\n", i, arr+i); // arr+i는 출력값이 같다
	}
}
//즉 arr == &arr[0] 똑같은 말임. 
//arr +1 == &arr[0] +1 == &arr[1]

 

#include <stdio.h>
int main() {
	int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };

	for (int i = 0; i < 10; i++) {
		printf("%d ", arr[i]); //1,2,3,4,5,6,7,8,9,10
	}
	printf("\n");
	
	for (int i = 0; i < 10; i++) {
		printf("%d ", *(arr + i)); //arr+i = &arr[i]  //*arr[i] : arr[i]값에 들어있는 주소값을 불러와라 .
	}
}

★arr[i] = *(arr[i]) = *(arr + i)

세가지 모두 같은 의미임. 

-★☆ 배열과 포인터의 관계

#include <stdio.h>

//이 세개의 for문만 이해한다면 배열과 포인터의 관계를 거의 다 파악. 
int main() {
	int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };

	for (int i = 0; i < 10; i++) {
		printf("%d ", arr[i]); //1,2,3,4,5,6,7,8,9,10
	}
	printf("\n");
	
	for (int i = 0; i < 10; i++) {
		printf("%d ", *(arr + i)); //arr+i = &arr[i]  //*arr[i] : arr[i]값에 들어있는 주소값을 불러와라 .
	}
	printf("\n");

	for (int *ptr = arr; ptr < arr + 10; ptr++) {
		printf("%d ", *ptr);
	}
	//int *ptr =arr; 포인터를 하나 선언하고 초기값에 arr(&arr[0])을 집어넣어라
	// ptr + 1 = arr + 1 = &arr[1]
}

 

26강. 배열 가리키기 ( 배열 포인터)

- 배열 포인터에 들어가기전.. 배열의 주소 복습

#include <stdio.h>
//배열 포인터를 배워보자
int main() {
	int arr[3] = { 1,2,3};
	int *ptr = arr; //이건 배열 포인터가 아니라는 점 명심!! 

	//arr[i] = *(arr[i]) = *(arr+i) = *(ptr+i) = *(i+ptr) == i[ptr] 
	// *(ptr + i) == i[ptr]

	for (int i = 0; i < 3; i++) {
		printf("%d", i[ptr]);
	}
	printf("\n");
}

☆arr[i] = *(arr[i]) = *(arr + i) = *(ptr +i) = *(i +ptr) = i(ptr)

 

<배운 개념 정리>

1. arr == &arr[0]  <=>  ptr == &ptr[0]

2. *ptr == ptr[0]

3. ptr + 1 == ptr에 sizeof(*ptr)을 더한 값.  EX)100번지 + 1 하면 104번지

 

 

 

- 배열 전체의 주소를 가리키는 기준값은 배열 첫번째 칸인 arr[0]임. 

- 배열을 가리키는 포인터에다 + 1하면 sizeof(arr)만큼 더해짐

#include <stdio.h>
//배열 포인터를 배워보자
int main() {
	int arr[3] = { 1,2,3};

	printf("arr = %d\n", arr); //14679244
	printf("arr + 1 = %d\n", arr+1); //14679248

	printf("&arr = %d\n", &arr); //14679244
	printf("&arr +1 = %d\n", &arr + 1); //14679256 //왜 12가 더해짐?
	//&arr + 1 == &arr에 sizeof(arr)를 더한 값
}

- 배열 포인터 ★내용을 잘 숙지 

#include <stdio.h>
int main() {
	//배열 포인터: 배열 자체를 가리키는 포인터
	int arr[3] = { 1,2,3 };

	int(*ptr_arr)[3];  //길이 3인 int형 배열을 가리키는 포인터를 선언 
	ptr_arr = &arr; //포인터 ptr_arr에  배열의 주소값을 할당

	//ptr_arr이라는 포인터는 arr[0]의 주소를 가리킴

	for (int i = 0; i < 3; i++) {
		printf("%d\n", (*ptr_arr)[i]); //배열포인터가 가리키는 i번째 값을 출력 //저번에 했던 거랑 다름 
	}
}

 

27강. 2차원 배열과 배열 포인터

 

- 들어가기 전 2차원 배열 크기, 주소 복습

#include <stdio.h>
int main() {
	int arr[2][3] = { {1,2,3,},{4,5,6} };

	printf("%d\n", sizeof(arr)); //24 = 4바이트 * 6
	printf("%d\n", sizeof(arr[0])); //12 = 4바이트 * 3
	printf("%d\n", sizeof(arr[0][0])); //4 = 4바이트 한 칸

	printf("%d\n",&arr); //18086112
	printf("%d\n", &arr[0]); //18086112
	printf("%d\n", &arr[0][0]); //18086112
}

- 2차원 배열과 배열 포인터

/*
1. arr == &arr[0]
2. *arr == arr[0]
3. arr + 1 == arr에 sizeof(*arr)을 더한 값 //ptr로 고쳐도 됨. 
*/

#include <stdio.h>
int main() {
	int arr[2][3] = { {1,2,3,},{4,5,6} };

	int(*ptr)[3] = arr; //★2차원 배열을 가리키는 배열포인터를 선언해서, 거기에 2차원배열을 넣으면 된다.

	//1. ptr[i] == arr[i] 맞음.
	//2. ptr[i][j] == arr[i][j] 맞음. 
	// ptr == arr 맞음. 

	for (int i = 0; i < 2; i++) {
		for (int j = 0; j < 3; j++) {
			printf("%d ", ptr[i][j]); //*ptr[i][j]쓰면 오류남
		}
		printf("\n");
	}
}

결론: 2차원 배열에서 

1. ptr[i] == arr[i] 
2. ptr[i][j] == arr[i][j]

 ptr == arr 

 

28강. 포인터 배열 

배열 포인터: 배열을 가리키는 포인터

포인터 배열: 포인터들의 배열

예제1.

//배열 포인터: 배열을 가리키는 포인터
//배열포인터: int(*ptr)[4]; 4개짜리 int형 배열을 가리키는포인터
//포인터 배열 : 포인터들의 배열

#include <stdio.h>
int main() {
	
	// 배열포인터: int(*ptr)[4]; 4개짜리 int형 배열을 가리키는포인터

	int arr[4] = { 1,2,3,4 };
	int *ptr[4]; // 4개짜리 칸 각각 포인터가 됨.

	for (int i = 0; i < 4; i++) {
		ptr[i] = &arr[i]; //포인터배열 원소안에 arr의 원소 주소가 들어감
	}

	for (int i = 0; i < 4; i++) {
		printf("%d ", *ptr[i]);
	}
	printf("\n");
}

 예제2. 

참고

더보기

#include <stdio.h>
int main() {
char str[] = "Hello";
printf("%s\n", &str[0]); //&str[0] == str //첫번째만 가리켜 주면 끝까지 출력해주는 printf
}

#include <stdio.h>
int main() {
char strings[3][10] = { "Hello", "World", "Doodle" };

for (int i = 0; i < 3; i++) {
printf("%s\n", strings[i]); //string[i] == &string[i] == &string[i][0] 
}
}

예제3.

#include <stdio.h>
int main() {
	
	char strings[3][10] = { "Hello", "World", "Doodle" };
	char* p_str[3]; //3개짜리 포인터배열

	for (int i = 0; i < 3; i++) {
		p_str[i] = strings[i];
	}
	for (int i = 0; i < 3; i++) {
		printf("%s\n", p_str[i] ); 
	}

	
}

 

 

29강-30강. 종합문제

1. 100개 이하의 정수를 입력 받아 첫 줄에 짝수 번째 숫자들을 순서대로 출력하고,

다음 줄에 홀수 번째 숫자들을 순서대로 출력하는 프로그램을 만들어 보세요. 

#include <stdio.h>
int main() {
	
	int n;
	int arr[105];
	
	scanf_s("%d", &n);
	for (int i = 0; i < n; i++) {
		scanf_s("%d ", &arr[i]);
	}

	for (int i = 1; i < n; i+=2) {
		 	printf("%d ", arr[i]);
	}
	printf("\n");
	for (int i = 0; i < n; i+=2) {
			printf("%d", arr[i]);
	}
	printf("\n");
	
}

2. 코드를 보고 printf에서 뭐가 출력되는 지 맞춰보자.

#include <stdio.h>
int main() {
	
	int a = 10;
	int b = 20;

	int *ptr; //포인터 ptr 선언 

	ptr = &a; //포인터 ptr에 a의 주소값 저장, 포인터는 a를 가리킴
	*ptr = 30; // a =30;

	ptr = &b; //ptr에 b의 주소값 참조, 포인터는 b를 가리킴
	*ptr = 10; // b = 10;

	printf("%d\n", a); 30
	printf("%d\n", b); 10
	printf("%d\n", *ptr); 10
}

3. 코드를 보고 어떤 값이 출력될 지 맞춰보자!!

#include <stdio.h>
int main() {
	
	int arr[10] = { 3,1,4,1,5,9,2,6,5,3 };

	printf("%d\n", arr); //&arr[0] 인 100번지 출력 
	for (int i = 3; i < 7; i++) {
		printf("%d %d\n", arr + i, *(arr + i)); // 주소값 112, 116, 120, 124,1,5,9,2
	}
	
}

4. 10*10이하의 정수형 이차원 배열을 입력받아 그 배열의 각 행의 요소의 합을 출력하는 프로그램을 만들라

#include <stdio.h>
int main() {
	int n, m; //행과 열의 갯수
	int arr[12][12];

	scanf_s("%d%d", &n, &m);
	for (int i = 0; i < n; i++) {
		for (int j = 0; j < m; j++) {
			scanf_s("%d", &arr[i][j]);
		}
	}

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

 

5. 출력값 예측

&arr =100

arr = 100

*arr = 100

 

&arr[0] = 100

arr[0] =100

*arr[0] =0

 

&arr[0][0] = 100

arr[0][0] = 0

 

 

6. 출력값 예측

&arr[0][0] = 100

arr[0] + 1 =104

&arr[0] + 1 = 112 //&arr[0] == arr

arr+1 = 112

&arr + 1 = 136//&arr는 2차원 포인터 전체