본문 바로가기
공부/c++

#2 배열과 포인터 | 포인터 간단 복습 | 포인터의 주소값 | 배열 포인터 | 2차원 배열과 배열 포인터 | c++

by 심심한 뾰 2021. 8. 8.
반응형

# 포인터 간단 복습

1
2
3
4
5
6
7
8
9
10
11
12
#include <iostream>
 
int main() {
  int a = 10;
 
  int *ptr_a = &a; //a의 주소값을 포인터 ptr_a에 저장한다.
                   //ptr_a 포인터는 a를 가리킴
  std::cout << *ptr_a << std::endl;
  *ptr_a = 20//포인터가 가리키는 a의 값을 20으로 저장하겠다.
  std::cout << *ptr_a << std::endl;;
}
 
cs

이 코드는 10을 저장하고 있는 a를 가리키는 ptr_a 포인터를 정의한 후,
포인터를 활용하여 a의 값을 20으로 바꾸는 코드이다.


# 포인터의 주소값 | 배열 포인터를 배우기 전 이해해야 할 것

1
2
3
4
5
6
7
8
9
10
#include <iostream>
 
int main() {
  int a = 10;
  int *ptr_a = &a; 
  
  std::cout <<"ptr_a의 값: " << ptr_a << std::endl;
  std::cout <<"ptr_a+1의 값: " << ptr_a+1 << std::endl;
}
 
cs

즉, 주소값에 1을 더할 경우, 그 변수의 형의 byte 수만

큼 주소값이 더해진다.

 

 

 

 

 

 

 

이 코드를 통해 더 잘 이해할 수 있을 것이다.

1
2
3
4
5
6
7
8
9
10
#include <iostream>
 
int main() {
  int arr[10= {1,2,3,4,5,6,7,8,9,10};
 
  for(int i = 0; i < 10; i++){
    std::cout << "&arr[" << i <<"] = " << &arr[i] << std::endl;
  }
}
 
cs

배열의 형이 int형인 만큼 주소값이 4씨 증가한다.

 

또한, 이 코드를 통해 하나 더 알 수 있는 것이 있다. 

1
2
3
4
5
6
7
8
9
#include <iostream>
 
int main() {
  int arr[10] = {1,2,3,4,5,6,7,8,9,10};
 
  std::cout << "arr의 값 "<< arr << std::endl;
  std::cout << "&arr[0]의 값 "<< &arr[0] << std::endl;
}
 
cs

ㅇㄴㄹㄴㅇㄹㄴㅁㅇㄹ

=> arr 와 &arr[0] 값은 같다.
=> arr[i]와 *(arr+i) 도 같다는 것을 알 수 있다.


이 코드를 통해 포인트를 조금 더 잘 이해할 수 있을 것이다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include <iostream>
 
int main() {
  int arr[10= {1,2,3,4,5,6,7,8,9,10};
 
  for(int i = 0; i < 10; i++){
    std::cout << arr[i] << " ";
  }
  std::cout << std::endl;
  for(int i = 0; i < 10; i++){
    std::cout << *(arr+i) << " ";
  }
  std::cout << std::endl;
  for(int *ptr = arr; ptr < arr + 10; ptr++){
    std::cout << *ptr << " ";
  }
}
 
cs

 

세개의 for문은 모두 같은 값을 출력하게 된다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include <iostream>
 
int main() {
  int arr[3= { 123 };
  int *ptr = arr;
 
  // arr[i] == *(arr + i) == *(ptr + i)
  // a[b] -> *(a + b)
 
  for(int i = 0; i < 3; i++){
    std::cout << i[ptr] << std::endl;
    // i[ptr] == *(i+ptr) 
  }
}
 
cs

 이 코드에서 나오는 for문은 실제로 사용하지 않는 코드이지만, 포인터를 배우는 과정에서는 이 코드를 이해해 보는 것이 도움이 된다. 

 즉, a[b] == *(a+b) == b[a] 이라는 소리이다.

 

[ ptr + 1 == ptr에 sizeof(*ptr)을 더한 값 ]

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include <iostream>
 
/*
  1. ptr == &ptr[0]
  2.*ptr == ptr[0]
  3. ptr + 1 == ptr에 sizeof(*ptr)을 더한 값
*/
 
int main() {
int arr[3] = {1, 2, 3};
 
std::cout << "arr = " << arr << std::endl;
std::cout << "arr + 1 = " << arr + 1 << std::endl; //4가 더해짐 -> int형의 크기만큼 더해짐
 
std::cout << "&arr = " << &arr << std::endl;
std::cout << "&arr + 1 = " << &arr + 1 << std::endl; //12가 더해짐 -> 배열의 크기(sizeof(arr))만큼 더해짐
}
 
cs







# 배열 포인터

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include <iostream>
 
//배열 포인터
int main(){
 
int arr[3= { 123 };
int (*ptr_arr)[3]; //길이 3인 int형 배열을 가리키는 포인터 선언
ptr_arr = &arr;
// int (*ptr_arr)[3] = &arr; 이렇게 선언도 가능
 
for(int i = 0; i < 3; i++){
  std::cout << (*ptr_arr)[i] << std::endl;
  //(*ptr_arr)는 가리키는 배열을 의미하기에 *(ptr_arr)[i]를 쓸 수 있게 된다. 
}
}
 
cs

 

이 배열 포인터는 arr 배열 그 자체를 가리키고 있다.




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

1
2
3
4
5
6
7
8
9
10
11
12
13
#include <iostream>
 
//배열 포인터
int main(){
int arr[2][3] = {{1,2,3},
                 {4,5,6}};
  
  std::cout << sizeof(arr) << std::endl;
  std::cout << sizeof(arr[0]) << std::endl;
  std::cout << sizeof(arr[0][0]) << std::endl;
}
 
 
cs

sizeof 연산자는 자료형이나 변수의 크기가 몇 바이트인지 알려준다.
sizeof(arr) : 24byte - int형 6개의 바이트 크기, 즉, 배열의 총 크기
sizeof(arr[0]) : 12byte - int형 3개의 바이트 크기, 즉, 한 행의 총 크기
sizeof(arr[0][0]) : 4byte - int형 1개의 바이트 크기, 즉, 한 형의 크기


1
2
3
4
5
6
7
8
9
10
11
#include <iostream>
 
//배열 포인터
int main(){
  int arr[2][3= {{1,2,3},
                 {4,5,6}};
 
  int(*ptr)[3= &arr[0]; //문제가 발생하지 않음
  
}
 
cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#include <iostream>
 
//배열 포인터
int main(){
  int arr[2][3= {{1,2,3},
                 {4,5,6}};
 
  int (*ptr)[3= arr;
 
  // 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++){
      std::cout << ptr[i][j] << " ";
    }
    std::cout << std::endl;
  }
 
  //ptr은 행 전체를 가리키는 포인터이고, ptr에 1을 더할 때마다 그 다음 행을 가리킨다고 이해할 수도 있다.
}
 
cs

✨✨ ptr은 행 전체를 가리키는 포인터이고, ptr에 1을 더할 때마다 그 다음 행을 가리킨다고 이해할 수도 있다.


이 코드를 이해한다면, 배열 포인터를 이해했다고 볼 수 있다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include <iostream>
 
//배열 포인터
int main(){
  int arr[2][3= {{1,2,3},
                 {4,5,6}};
 
  for(int(*row)[3= arr; row < arr+2; row++){
    for(int *col = *row; col < *row + 3; col++){
      std::cout << *col << " ";
    }
    std::cout << std::endl;
  }
  
}
 
//*row는 row가 가르키고 있는 배열 자체를 의미
 
cs

 

 

 

위의 코드를 더 잘 이해하기 위해, 이 코드를 짜보았다.

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
#include <iostream>
 
//배열 포인터
int main(){
  using namespace std;
  int arr[2][3= {{1,2,3},
                 {4,5,6}};
 
  int(*row)[3= arr;
  
  cout << "&arr[0] : " << &arr[0<< endl;
  cout << "row : " << row << endl;
  cout << "*row : " << *row << endl;
  cout << "&arr[1] : " << &arr[1<< endl;
  cout << "row+1 : " << row+1 << endl;
  cout << "*(row+1) : " << *(row+1<< endl;
 
  int *col = *row;
  cout << "col : " << col << endl;
  cout << "col+1 : " << col+1 << endl;
  cout << "*(col+1) : " << *(col+1<< endl;
  /*
  for(int(*row)[3] = arr; row < arr+2; row++){
    for(int *col = *row; col < *row + 3; col++){
      std::cout << *col << " ";
    }
    std::cout << std::endl;
  }
  */
  
}
 
//*row는 row가 가르키고 있는 배열 자체를 의미
 
cs

 

 

 

따라서,
&arr[0] == row == *row == col
&arr[1] == row+1 == *(row+1)


출처(source) - 유튜브 두들낙서님
https://www.youtube.com/c/%EB%91%90%EB%93%A4%EB%82%99%EC%84%9C

 

두들낙서

C/C++ 강좌를 올리고 있고 다른 컨텐츠는 할 수도 있고 안 할 수도 있는 채널. ▶ 두들낙서 지식공유 서버 참가하기: https://discord.gg/y4SXcjU

www.youtube.com

c++ 최고의 강좌,,

반응형