프로그래밍 74

#33. 포인터 & 배열

*문자열 = 문자의 배열 cout 단지 주소 저장 const char* Test1 = "Hello World"; // .rodata char Test2[] = "Hello World"; 1. 포인터의 경우 리터럴상수의 주소를 rax 에 저장 [Test1] 에 주소를 넣어준다. 2. 배열의 경우 Hello world 리터럴 상수가 저장되어있는 곳과 [Test2] 값을 구하고 각각 rdi, rsi 레지스터에 넣고 rep movs byte prt [ rdi ], byte ptr [ rsi ] rsi 에 있는 값(리터럴상수) 을 rdi ( [Test2] ) 의 값으로 '복사' 한다. 즉, 포인터와 배열은 엄연히 다르다. 본 내용은 인프런의 루키스님 강의를 듣고 정리한 내용입니다. 강의 듣기 !!

프로그래밍/C++ 2022.07.19

#32. 배열기초

*배열 ( Array ) => 배열의 크기는 상수이어야만 함 ( VC 컴파일러기준 ) StatInfo Players[10]; StatInfo Monsters[10]; Players = Monsters => (X) => 배열의 이름은 무엇이되는가 ?? => 첫번째 시작 주소. => 정확히는 시작 위치를 가리키는 'TYPE 크기' 를 알고 있는 포인터 auto Monster_0 = Monsters; => Monster_0 의 타입은 무엇일까?? Monsters 는 배열이름으로 주소이므로, 해당 타입의 * 변수가 됨. *배열의 포인터연산 StatInfo& Monster_Ref1 = (*Monsters); Monster_Ref1.hp = 1; StatInfo& Monster_Ref2 = *(Monsters + ..

프로그래밍/C++ 2022.07.19

#31. 참조 & 포인터

*참조 vs 포인터 성능 : 똑같음 !! 편의성 : 참조 > 포인터 1. 편의성 관련 편의성이 좋다는게 꼭 장점만은 아니다. 포인터는 주소를 넘기니 확실하게 원본을 넘긴다는 힌트를 줄 수 있는데, (명시적) 참조는 자연스럽게 모르고 지나칠 수도 있음. ex) 마음대로 고친다면 ?? const 사용 -> (const StatInfo& info) 포인터도 const 사용 가능. * 기준으로 앞에 붙이냐 / 뒤에 붙이냐 에 따른 차이 (const StatInfo* info) = (StatInfo const* info) => 데이터를 수정할 수 없음. (StatInfo* const info) => 주소를 수정할 수 없음. 2. 초기화 여부 참조 타입은 바구니의 2번째 이름 (별칭) -> 참조하는 대상이 없으면 ..

프로그래밍/C++ 2022.07.19

#30. 참조 기초

*참조(Reference) => 로우레벨(어셈블리) 관점에서 실제 작동 방식은 int* 와 똑같음. => C++ 관점에서는 number 라는 바구니에 또 다른 이름을 부여한 것 ( '별명' ) => 실제 어셈블리에서는 똑같이 동작함 => 주소마저도 똑같음. *그렇다면 참조는 왜 쓰는걸까 ?? 1. 포인터의 -> 불편하다. 2. 참조는 무조건 초기화 해주어야 함. 3. 주소를 마음대로 바꿀 수 없다. *매개변수 * 와 값 복사 방식 void CreateMonster(StatInfo* info) { info->hp = 100; info->attack = 8; info->defence = 5; } void CreateMonster(StatInfo info) { info.hp = 100; info.attack ..

프로그래밍/C++ 2022.07.19

#29. 포인터 연산

1. 주소 연산자 ( & ) => 해당 변수의 주소를 달라. int number = 1; int* ptr = &number; 2. 산술 연산자 ( +, - ) * : 포인터타입, (8바이트) int : 주소를 따라가면 int(4바이트 정수형 바구니) 가 있다고 가정!! += 1 : 다음 int(4바이트 정수형 바구니) 로 이동시켜줘!! => pointer += 1; => 포인터 연산 시, pointer 가 가리크는 주소값이 '포인터TYPE 크기' 만큼 한번 이동함. => short 면 2바이트, long long 이면 8바이트, int 면 4바이트 이동 (배열과 유사.) => 포인터를 담는 변수크기 와는 무관 3. 간접 연산자 => 포털을 타고 이동한다 생각해보자. number = 3; *pointer ..

프로그래밍/C++ 2022.07.19

#28. 포인터 기초

*포인터는 왜 필요한걸까 ?? => 스택 메모리에 쌓이는 지역변수를 통해 실제 데이터 값을 수정하기 위해서 => 원본 수정을 위해서. TPYE* 변수이름; int* ptr = &number; => 주소를 담는 바구니 *어셈블리 mov & lea mov : 값 이동 lea : 주소 이동 @int* 크기 => 8바이트 (64비트환경) / 4바이트 (32비트환경) *주소를 가지고 어떻게 동작시킬까 ?? int number = 1; int* ptr = &number; int value1 = *ptr; *ptr = 2; * TYPE 은 왜 붙여주는 걸까 ?? => 메모리에서 그 데이터의 크기만큼 읽기 위해서 => 포인터에 대한 추가정보 *타입의 불일치 __int64* ptr2 = (__int64*)&number;..

프로그래밍/C++ 2022.07.19

#27. 함수 기타 내용

*스택 메모리 동작 과정 *스택 프레임 *스택 오버플로우 *함수 호출규약 *오버로딩 ( 함수 이름의 재사용 ) => 매개변수 갯수가 다르거나 => 매개변수 타입이 다르거나 (순서가 다른걸 포함) *반환형식만 오버로딩 ?? => ( X ) int Add(int a, int b) { return a + b; } float Add(float a, float b) { return a + b; } float Add(int a, int b) => ERROR!! { return a + b; } => 함수의 반환 타입은 함수 오버로딩에서 고려하지 않음. *기본 인자값 void SetPlayerInfo(int hp, int mp, int attack, int guildId = 0, int castleId = 0) => ..

프로그래밍/C++ 2022.07.18

#24. 함수 호출 규약 ( Calling Convention )

* 함수 호출 규약 '함수를 호출할 때 파라미터를 어떤 식으로 전달하는지' 에 대한 규칙을 정의한다. @Caller ( 호출자 ) : 함수를 호출한 곳. @Callee ( 피호출자 ) : 호출 당하는 함수. => 속성 페이지 -> 고급 -> 호출 규칙 수정 가능. ( cdecl, stdcall, fastcall 모두 x86 환경에서 진행해야함. ) *cdecl => Caller ( 호출자 ) 에서 매개변수 처리. 호출자에서 매개변수를 push 로 스택에 저장한다. 그림에서 보는 것처럼 호출자에서 esp 위치를 더하며 매개변수를 처리하고 있다. 여기서 더한다는 의미는 현재 스택에 저장된 매개 변수 메모리 주소는 의미가 없기 때문에 더하면서 현재 메모리 위치 ( esp ) 를 옮긴다. ( stack 은 메모..

프로그래밍/C++ 2022.07.18