※ C / C++을 이미 알고 있으나 개인적인 공부를 위해 포스팅 하는 글이므로
C++에 대한 구체적인 정보를 담고 있지 않습니다.
▶ 배열
int a=10; //바구니
int b = a;
ㆍ 여태 사용하던 변수들의 [이름]은 바구니의 이름이였다.
ㆍ 하지만 배열은 [이름]이 좀 다르게 동작한다.
struct StatInfo
{
int hp = 0xAAAAAAAA;
int attack = 0xBBBBBBBB;
int defence = 0xDDDDDDDD;
};
int main()
{
//배열의 크기는 상수여야 한다. VC컴파일러 기준
const int monsterCnt = 10;
StatInfo monsters[monsterCnt];
StatInfo Players[10];
// players = monsters; 이건 안됨.
auto WhoAmI = monsters; //이건돼서 확인을 해보면 StatInfo*로 작동하고있다.
}
ㆍ players = monsters... 이건 오류가 발생한다.
ㆍ 배열의 이름은 곧 배열의 시작 주소이다, 정확히는 시작 위치를 기리키는 TYPE* 포인터
StatInfo* monster_0 = monsters;
monster_0->hp = 100;
monster_0->attack = 10;
monster_0->defence = 1;
ㆍ monster_0에 monsters의 첫번째 주소를 할당해줬다.
ㆍ 다음 주소에 접근하려면 포인터 연산을 기억해보자!
StatInfo* monster_1 = monsters + 1;
monster_1->hp = 200;
monster_1->attack = 20;
monster_1->defence = 2;
ㆍ 포인터 연산은 정말+1을 하라는게 아니라 다음 주소를 가리키라는 말이였다
ㆍ 포인터와 참조는 자유자재로 변환이 가능하다 했으니 참조로도 해보자!
StatInfo& monster_2 = *(monsters + 2);
monster_2.hp = 300;
monster_2.attack = 30;
monster_2.defence = 3;
ㆍ 잘 된다.
ㆍ 주의할건 아래 코드는 완전히 다른 의미 이므로 조심하자
StatInfo temp = *(monsters + 2);
temp.hp = 300;
temp.attack = 30;
temp.defence = 3;
ㆍ 해당 코드는 3번째 주소의 내용물이 바뀌는게 아니라 그냥 temp만 변화한다. 여태까지 공부한걸 이해했다면 쉽게 이해가 된다. (실제 주소 접근이 아니란 소리)
//배열 초기화 문법 몇가지
int numbers[5] = {}; //빈거로 만들면 기본값인 0으로 댐
//어셈블리까보면 걍 하나하나 접근해서 0으로하고있음, 성능은같다
int numbers1[10] = { 1,2,3,4,5 }; //안한건 0으로초기화
int numbers2[] = { 1,2,3,4,5,6,7,8,9,0,11 }; // 데이터 개수 만큼의 크기에 해당하는 배열로 만들어준다
▶ 포인터와 배열은 다른거다. 차이점 (문자열)
const char* test1 = "Hello World";
char test2[] = "Hello World";
ㆍ 두 코드를 어셈블리로 확인해보자. 차이점이 보인다
1) const char* test1 = "Hello World";
ㆍ mov로 test라는 바구니에 Hello World를 옮겨주는 작업을 하고있고 유추해 보건데 offset string은 이제 첫번째 주소 뒤에 1바이트 자료형인 char를 하나씩 자리에 맞게 넣어준다는 소리같다.
ㆍ .read only data에 Hello World를 박아줬다는 뜻
2) char test2[] = "Hello World";
ㆍ 좀 더 복잡한 무언가가 일어나고있다, 주소가 4바이트씩 끊어서 복사되고있다.
ㆍ [H] [e] [l] [l] / [o] [] [w] [o] / [r] [l] [d] [\0] /
ㆍ 얘는 별도의 바구니가 만들어 진 것이 아니다!!
ㆍ 포인터는 [주소를 담는 바구니]
ㆍ 배열은 [닭장] 즉, 그 자체로 같은 데이터 끼리 붙어있는 '바구니 모음'
ㆍ 다만 [배열이름] 은 '바구니 모음' 의 [시작 주소]
ㆍ 즉 배열과 배열이름은 다른걸 말한다. 배열 = 배열그자체(전체) 배열이름 = 배열의 시작주소
※ 쉽게말해
1) 포인터는 크기가 늘어나도 계속 4or8 크기 고정 (시작주소) (연산을 통해 다음 주소 접근)
2) 배열은 실질적인 크기가 늘어나면 크기도 늘어난다 (배열의 본체 자체는 어마어마하게 클 수도 있는 배열 그 전체를 의미한다)
char test2[] = "Hello World";
char test3[1];
test2 = test3
//해당 코드는 오류
ㆍ 배열이름은 바구니가 아니라 배열의 첫번째주소이다. 따라서 오류
★ 배열을 함수 인자로 넘겨준다면?
void Test(char a[])
{
a[0] = 'x';
}
int main()
{
char test2[] = "Hello World";
Test(test2); // 배열의 시작 주소만 넘긴다
cout << test2 << endl;
}
ㆍ xello World로 바뀐다.
ㆍ그 이유는 컴파일러가 자동으로 char* 형으로 바꿔주기 때문이다.
'C++프로그래밍 > C 와 C++ 기초실습' 카테고리의 다른 글
배열과 포인터 (차이점 및 다중 포인터) + 포인터 주의 사항 (0) | 2024.09.19 |
---|---|
다중 포인터 (const char**) 문자열 (1) | 2024.09.18 |
포인터와 참조타입 비교,차이 (const pointer) (0) | 2024.09.18 |
참조타입 (0) | 2024.09.18 |
포인터 실습 해보기 (일반return과 포인터를 이용한 원본객체 조정) (0) | 2024.09.17 |