C++/Syntax
2021. 3. 11. 16:48
배열 (Array)
상수 포인터, 포인터 상수는 무슨 의미인지는 알겠는데 사용하면 더 헷갈린다...
변수란 뭘까
#include <iostream>
int main()
{
using namespace std;
int a = 1;
cout << &a << endl;
}
/* stdout
00FAF990
*/
int a = 1
을 정의하면 스택에sizeof(int)
만큼 공간이 확보된다.여기서의 변수명
a
는 단지 프로그래머가 메모리 공간에 접근할 때 필요한 것이다.이
a
라는 변수는 컴파일러가 기계어로 번역할 때 메모리 주소로 변환된다.즉 사람의 입장에서 메모리에 편하게 접근하려고 만든게 변수이고, 컴파일러가 처리하는 것이다.
배열 예제
#include <iostream>
int main()
{
using namespace std;
int arr[10]{ 0, 1, 2, 3, 4, 5, };
cout << typeid(arr).name() << endl; // int [10]
cout << typeid(&arr).name() << endl; // int (*)[10]
cout << typeid(&arr[0]).name() << endl; // int *
cout << sizeof(arr) << endl; // 40
cout << sizeof(&arr) << endl; // 4
cout << sizeof(&arr[0]) << endl; // 4
// 이 3개는 같은 주소를 가리킴
cout << arr << endl;
cout << &arr << endl;
cout << &arr[0] << endl;
// 배열 두 번째 요소의 주소
cout << &arr[1] << endl;
// 아래는 배열 전체의 다음 주소 (이렇게 사용하면 안됨)
cout << (&arr)[1] << endl;
}
/* stdout
int [10]
int (*)[10]
int *
40
4
4
0118F840
0118F840
0118F840
0118F844
0118F868
*/
int arr[10]
을 정의하면 스택에sizeof(int) * 10
만큼 공간이 확보된다.배열의 이름인
arr
은 사람이 편하게 접근할 수 있도록 컴파일러가 처리하는 것이다.-
자료형을 표현
arr
:int [10]
배열 자료형이라고 생각하면 될 듯
배열 자료형이라는 것은 들어본 적이 없으나, 내부적으로 이렇게 처리한다고 생각하는게 맞는 것 같다.
&arr
:int (*)[10]
int [10]
의 배열을 가리키는 포인터이 주소에 1을 더하면 배열의 크기만큼 주소가 이동된다.
&arr[0]
:int *
, arr[0]를 찾아가서 주소를 찍은 것이므로 일반적인 포인터와 같음
javascript
의 경우 배열을 선언한 뒤typeof
로 살펴보면Object
라고 뜨는 것을 볼 수 있다.
에러 예제
int main()
{
int* p;
int(*pa)[3];
int arr[2][3] = { 3, };
p = arr; // cannot convert from 'int [2][3]' to 'int *'
p = (int *)arr; // 이건 가능
p = &arr; // cannot convert from 'int (*)[2][3]' to 'int *'
pa = arr; // 가능
pa = &arr; // cannot convert from 'int (*)[2][3]' to 'int (*)[3]'
int(*ppa)[2][3];
ppa = arr; // cannot convert from 'int [2][3]' to 'int (*)[2][3]'
ppa = &arr; // 가능
int arr2[2];
pa = arr2; // cannot convert from 'int [2]' to 'int (*)[3]'
int arr3[2][3][4];
int*** ppp;
ppp = arr3; // cannot convert from 'int [2][3][4]' to 'int ***'
}
- 7번째 줄 (
p = arr;
)int [2][3]
이라는 2차원 배열 자료형을int *
에 대입하려해서 오류 발생
- 8번째 줄
- 직접 형변환을 한 뒤 역참조를 해보면 값이 제대로 나오는 것을 확인할 수 있다.
int [2][3]
도 주소를 나타내지만, 묵시적 형변환이 작동하지 않는 경우임을 알 수 있다.- 비슷한 예로
int *
변수에double *
변수 값을 대입하면,cannot convert from 'double *' to 'int *'
에러가 발생하는 것을 볼 수 있다.
- 비슷한 예로
- 9번째 줄
&arr
가int (*)[2][3]
타입이라는 것은int [2][3]
의 배열을 가리키는 포인터임을 의미한다.
- 10번째 줄
arr
는int [2][3]
타입이고, 묵시적 형변환을 통해int (*)[3]
으로 변환되었음을 볼 수 있다.
배열을 레퍼런스로 전달하는 예제
#include <iostream>
void printElements(const int(&arr)[5])
{
std::cout << arr << std::endl;
for (int i = 0; i < 5; ++i)
std::cout << arr[i] << " ";
std::cout << std::endl;
}
int main()
{
using namespace std;
int arr[5] = { 1, 2, 3, 4, 5 };
std::cout << arr << std::endl;
printElements(arr);
}
/* stdout
00CFFC08
00CFFC08
1 2 3 4 5
*/
참고
std::array
컨테이너
'C++ > Syntax' 카테고리의 다른 글
C++ 문자열 (string) (0) | 2021.03.11 |
---|---|
C++ nullptr_t (0) | 2021.03.11 |
C++ 반복문 (0) | 2021.03.11 |
C++ switch (0) | 2021.03.11 |
C++ 제어 흐름 (Control Flow) (0) | 2021.03.11 |