• 도트 멤버 연산자 & 화살표 멤버 연산자

둘 다 멤버데이터를 참조 할 때 사용한다

 

차이점이라면

 

도트 멤버연산자 - 객체에 사용

 

화살표 멤버연산자 - 객체의 주소에 사용

pttrA 같은 경우

(*pptrA) = 객체를 가르키는 주소

이니까 ->만 붙이면 되겠다

 

 


  • 데이터의 저장공간

Stack(자동공간)

지역변수가 저장되는 영역 LIFO 구조로 되어있다

해당 변수가 속한 스코프가 끝나면 자동으로 메모리 해제된다

 

Code&Data(정적공간)

전역변수가 저장되는 영역 프로그램이 종료될 때 메모리 해제된다

 

Heap(동적공간)

책에서는 Free store와 같다고 한다

근데 new로 할당하면 free store이고 malloc으로 할당하면 heap 뭐 이런 소리도 있던데

일단 내가 사용하고 있는 VC++에서의 new는 내부적으로 malloc이 실행되기에 그냥 같은 말이라고 생각한다

 

이 책 포인터부분에서 이 저장공간을 작성했다는건

사용자가 만든 함수 내부에 지역변수로 포인터써서 동적할당하고 해제 안했을때의 메모리 릭 문제를 강조하는거 같다

 

※메모리에 대해 좀 더 공부


  • 변수형의 조합(포인터 장난)

파트 이름은 변수형의 조합.. 이지만 그냥 배열, 구조체에 포인터를 이용할 수 있다 라는 내용이다

 

예제 비슷하게 장난 같은걸 쳐봤다

3번은 왼쪽부터 쭉 읽으면 논리적으로는 완벽해보인다만 오류가 나온다

 

그 이유는 연산자 실행 순서 때문인데

 

모든 식에서(괄호없는 수식) * 보다 . 가 먼저 실행되기 때문에 

 

(arr+1).member 가 실행되는것이다

 

그렇기에 괄호를 한번 더 쳐주어서 *가 먼저 실행되게 하면 정상 실행된다

 

안쓰던 더블포인터랑 포인터 배열 사용 했는데 장난치다보니까 나도 헷갈리더라ㅋㅋㅋㅋㅋ

미래의 나에게 알려준다....

 

 

  • 문자열 상수

배열의 식별자   =    배열의 첫번째 데이터의 주소

(밑에서는 a)

문자열 상수      = 문자열의 첫번째 문자 주소

(밑에서는 "ABCDEFG" , "Is english")

 

문자열은 첫번째 문자의 주소부터 null값 까지 데이터를 찾는 방식으로 사용이 된다

 

그렇기에 저 "Is english"도 문자열이기에 메모리 어딘가에 저장이 되고

첫번째 문자의 주소가 있을 것이고 null값 또한 있을 것 이다

 

첫번째 주소는 "Is english" 이 자체로 첫번째 문자의 주소를 나타낸다

 


 

쉽게 "ABCDEFG"로 확인한다

위에 말처럼 "ABCDEFG" 는 문자열의 첫번째 문자 주소가 될수도있다.

 

(int*) 을 붙여준 이유는 안붙이면 cout가 문자열주소 로 파악하고 문자열을 출력하기때문에

주소를 출력하려고 변환했다

 

"ABCDEFG"가 가진 주소는 00B0AB30, 그 주소로 가 무슨 데이터가 있는지 확인한다

 

41이 들어있다, 메모리는 16진수형태로 나타나며 41은 10진수로 65다

 

65는 아스키 코드로 'A' 이므로

 

"ABCDEFG" 가 'A'의 주소를 가지고 있다고 볼 수 있다


 

컴파일러마다 다르지만 같은 내용이 담긴 문자열 상수가 여러개가 사용되면

 

하나로 취급하여 하나의 주소로 사용 하는 경우도 있다고 한다

[메모리에 하나만 저장하여 쓰인다는 말]

  • 포인터

주소 저장 목적의 변수

 

&[주소연산자] - 해당 변수의 주소값을 반환


*[간접 참조 연산자] - 포인터 앞에 붙을시에 포인터가 가진 주소에 데이터를 반환

 

int * a 가 있다면 a는 int형 포인터다

 

이 말은 int가 이 주소의 데이터형 단위 라는 것이며

 

이 데이터형 단위로 읽는다는 것이다

 

 

 


 

  • NULL , nullptr

NULL 은 상수 0 이라고 define되어 있다

그렇기에 포인터외의 자료형도 사용할수가 있다

 

 

nullptr C++에서 생겼으며 말 그대로 NULL값을 가진 포인터를 의미하여 포인터끼리만 연산이 가능하다

 

모두 포인터에 사용했을시에 핵심은 데이터가 0인지 판단하는것이지 정상적으로 할당받은 데이터를 판단할수는 없다

                                                                                          [ex) new로 할당 받은 주소]

 


 

  •  New

new 자료형 - 운영체제에서 자료형만큼의 데이터공간의 주소를 반환

저렇게 new만 써도 메모리가 할당된다

그렇기에 저 반환하는 주소를 포인터에 대입시키는 것이다

 

저 new의 실체는 operator new 라는 함수이다

 

배열형식으로 선언은

new 자료형 [num]

 


 

  • Delete

new가 메모리를 운영체제에서 받아왔다면 이건 운영체제에 받아온 메모리를 반환한다

 

이것도 마찬가지로 operator delete 가 본체이다

 

array형식을 delete할때는 " delelte [ ] 식별자  " 로 해줘야한다

그 이유는 소멸자 문제가 발생하기 때문이다.

[ 위에는 소멸자가 딱히 관련이 없기에 delete[ ] 를 delete로 바꾸어도 정상으로 돌아가긴한다 ]

소멸자가 한번 호출후 에러가 난다

 

 

이러한 주소하나만 delete에 넘겨주어도 주소가 가지고있는 할당된 메모리가 해제되는 이유같은 내용은

다른 글에 다시 정리한다

[ 작성중인 글 ]

https://ddidding.tistory.com/23

 


 

  • 배열 포인터

[ ] 를 사용하여 해당 인덱스의 배열 값을 나타내듯이 사용할 수 있다

 

+ 와 - 를 이용하여 해당 인덱스의 주소를 알아낼 수 있다

여기서의 0, 1, 2, 3 이 의미하는것은 정수 0, 1 이 아니라 a 포인터가 담는 자료형(int) 의 크기만큼 주소를 더한다는 뜻

 

그렇기에 int형의 크기 4 BYTE 만큼 주소가 증가한걸 볼 수 있다

 

위에 연산이 주소를 나타내는 것이기에

주소의 값을 나타내는 간접 참조 연산자 ( * ) 를 같이 사용하면 그 주소가 가지고있는 값을 확인할 수 있다

 

여기서 해당값의 주소를 알려주는 주소연산자( & )를 사용하면

다시 주소가 나오겠지ㅋㅋㅋ

 

배열과 포인터의 차이점이라면

 

1. 포인터는 변수이고

배열의 식별자는 상수라는 점이다

 

2. Sizeof를 사용했을 때

a 와 b 모두 첫번째 값의 주소를 나타내지만

 

포인터는 주소의 크기 ( 자료형의 크기가 아님 )

배열은 배열의 크기가 출력된다

 

 

  • 구조체

배열에 여러 데이터형을 넣고 싶다 -> 구조체

 

각 항목을 멤버

 

구조체 태그를 식별자로 사용가능

 

태그를 생략할 수 있는데 태그가 없으니 변수를 생성할 수 없다, 그렇기에 변수 정의와 함께 사용

앞으로 MyStruct밖에 사용 불가

 

멤버들이 저장되는 메모리크기는 가장 큰 자료형의 크기로 저장됨

 

이러한게 많이 비효율적이라 생각이 들면 비트필드 이용

 

지정한 비트만큼만 데이터가 저장된다 ( 컴파일러에 따라 다르지만 VsC++에서는 정수형 & bool형 으로만 사용가능 )

단 자료형보다 큰 비트제어는 불가능하다

 

Signed 일경우 맨 앞자리는 부호비트로보고 나머지를 계산

ex)

1) b에 13를 넣는다

2) 13 = 1101 (이진수)

3) b는 3비트만 사용하여 "101"로 데이터가 잘림

4) 맨앞은 부호비트로 채용, 음수가 됨

5) 나머지 데이터 "01"이 음수이므로 음수형으로 2의 보수를 취한다 [ 십진수를 음수 이진수로 표현 2의 보수 취하기]

6) 그럼 "10" 이 되므로  3이다

6) 최종적으로 -3 데이터 가 들어가있는게 된다 

 

unsigned는 부호비트가 없으므로 어디서 잘리는지만 보면 된다

ex)

1) c에 5를 넣는다

2) c = 101 (이진수)

3) c는 2비트만 사용하여 "01" 로 잘림

4) 최종적으로 1저장

 

※ 구조체와 클래스 차이 공부 필요

 


  • 공용체 (Union)

가장 큰 변수의 메모리를 모든 변수가 공유함

 

 

공용체 , 익명공용체

 

유니온의 크기는 가장 큰값이여도 각자 사이즈는 다르다
같은 주소

이런식으로 const도 바꿀수있나보다

 


  • 열거형

상수형에 이름붙인 나열된 자료형

 

경험상 어떠한 카테고리안의 항목을 다룰 때 편한거 같다

 

예를들어 플레이어의 상태 카테고리라면

이런식으로 쓸수있다

태그명(위에서 State)는 변수를 만들지 않을거면 사용하지 않아도 된다 , 상수값 중복가능

 

데이터형이 Enum형일수도있고 int형으로 될수도있다 그렇기에 산술연산이 가능한데

 

산술연산 가능은 컴파일러마다 다르다 (하지만 이식성을 위해 쓰지말자), 대입연산과 비교연산 가능

 

따로 초기화 해주지 않는 이상 계속 0부터 1씩 증가되어 값이 대입된다

[ 중간에 딱 한값만 100으로 넣어도 그뒤에는 101, 102 .... 이런식이다 ]

 

변수에 값 대입시에 무조건 해당 Enum에 정의된 열거자(식별자)를 넣어줘야하는데 

ex) playerState = Idle;

 

명시적인 데이터형 변환을 사용하면 가능하다

ex) playerState = State(99) // "99"라는 int형을 State형으로 강제 형변환

 

저렇게 99라는 없는 상수도 넣을수 있는데 최대값 범위가 공식으로 있다고 하는데 사실 잘 모르겠다 해봤는데 

그 공식에서 나온 값을 넘어서도 출력이 잘 된다

 

추가+

enum은 몇가지 정수형에 의해 표현되는데

C++98 이하 버전에서는 실행하는 방식에 따라 달랐지만 C++11이후로 선택할수있는 문법이 생겼다

 

  • 배열

선언 - typename Name [Size];

 

0부터 시작

 

 

배열의 이름은 수식에 사용시 자료형의 포인터 형으로 사용된다

자료형의 포인터 형으로 사용될 때 배열의 전체 주소가 아닌 첫번째 원소의 주소이다

arr1에 마우스를 가저다 대면 나오는 창, int* 라고 한다

 

이 때문에 배열과 배열의 대입이 이루어지지 않는다

 

그리고 여기에 얹어서 두가지 특징이 더 있는데

 

첫번째. 배열의 이름은값을 바꿀수 없는 상수(r-value)라는 점이다

 

두번째.  [0]번째 데이터의 주소와 배열 전체를 의미하는 주소는 같다

 


 

  • 문자열

연속되어 저장되어 있는 문자들

 

char text [10] = { 'a', 'b', 'c' }; // 는 a,b,c가 각 배열 인덱스에 복사되어 들어간다

char text [10] = "abc"          // 는 abc가 한번에 들어간다

 

char text [ ] = "abc" // 가 되는 이유는 초기 값을 정해주었기 때문

 

상수표현 " ~ "  -> 자료형이 const char *

 

문자열을 다룰때 끝을 알아야 그만큼 데이터를 사용할텐데 Null을 끝으로 인식하는 방법으로 사용한다

그렇기에 문자열상수( " ~ " )는 우리가 별도로 Null을 넣지 않아도 마지막에 Null이 자동으로 붙는다

그래서 Null이 붙은 크기가 고정되어야 문자열상수의 데이터를 온전히 사용할 수 있기 때문에

( " ~ " )는 const형이 붙어 문자열 상수라 한다

 ' ~ ' 와는 다를 수 밖에 없다

 

cout에서 char * 을 출력할때 다음주소를 한글자씩 출력하면서 Null을 찾는다

Null을 붙여주지 않아서 Null을 찾을때까지 출력하여 이상한 값이 나온다

 

 

char e = "a"; //불가능

char e = "abcd"; //불가능

char * e = "abcd"; //불가능

 

모두 대입하는 문자열 상수의 자료형[ const char * ]과 맞지 않다

마지막 불가능 코드는 "abcd"는 수정이 되지 않는 자료형인데 char * 은 수정이 가능한 자료형이다 그렇기에 대입 불가

 

입력 함수

cin = 화이트스페이스를 끝으로 간주 & 개행문자를 남김

※ 단 화이트스페이스, 개행문자가 제일 처음나오면 멀쩡한 문자가 나올때까지 무시

 

cin.get( ) = 개행문자를 끝으로 간주 & 개행문자를 남김 

cin.getline( ) = 개행문자를 끝으로 간주 & 개행문자를 읽고 폐기

 

strcpy = 문자열 복사

strcat = 문자열 추가

strlen = 데이터형의 길이가 아닌 문자열의 길이 반환

 

 


 

  • String

기존 C에서 Null 으로 마지막을 알아내는 방법과 달리

문자의 길이를 따로 저장하기에 Null관련 이슈가 없다

 

다만 실제로는 null로 끝나는 문자열과의 호환성을 위해 메모리상에 null을 포함하긴 한다

 

문자열 다루는 더 나은 방법의 클래스

 

들어오는 데이터에 따라 크기 자동 조절

 

배열처럼 인덱스 참조 가능

 

==, = , + , += 연산 가능

 

 

strncpy

strncat

.size( )

std::getline( ) - string용 getline


 

  • raw 문자열

문자열 하나하나가 모두 독립적인 문자열 (특수문자까지도)

 

R"~(   로 시작해서

)~"로 끝나야한다

 

 


 

많은 도움이 된 글

https://blog.naver.com/tipsware/221018307213

 

'문자열 상수'의 잘못된 사용에 대하여

C 언어 관련 전체 목차 : http://blog.naver.com/tipsware/221010831969 1. 배열로 선언된 변수의 초기화 ...

blog.naver.com

 

  • 식별자

"밑줄문자 두개"로 시작

"밑줄문자+대문자"로 시작

 

이 두가지는 예약어의 규칙에 속하기 때문에 훗날 문제가 될 수 도있으니

 

예약어 목록에 없다면 실행은되나 되도록 피하자

#include <iostream>

int main() {

	int __ABC = 3;
	int _Abc = 2;
	
	std::cout << __ABC << _Abc; //모두 출력 성공
	
	return 0;
}

 


 

  • 정수 자료형

소수부가 없는 자료형

 

char, short, int, long 같은 자료형, 크기는 컴파일러마다 다를 수 가 있다

 

 

※ 보통 8비트 = 1바이트 이지만 c++에서는 컴파일러의 기본 문자 세트를 수용할 수 있는 최소한의 비트수가 바이트!

ex) ASCII는 최소 8비트로 나타내므로 ASCII가 기본 문자 세트라면 8비트가 1바이트가 된다

 

정수 상수가 저장되는 자료형은 최소 int형이다

 

문자를 정수형으로 표현한다 (Char)

char형은 문자와 숫자를 저장한다

 

wchar_t형은 1바이트로 나타낼수 없는 문자를 위해 탄생

상수형은 접두사로 'L'이 붙는다

 


 

  • 멤버 연산자 (memvership operator)

객체의 멤버 사용할 경우 사용

 

ex) std::cout.puts(); 에서

1. " std::cout " // 2. " . "  // 3. " puts(); "

1.(객체)  2.(멤버연산)  3.멤버(함수)

 


 

  • const

상수, 값이 변화하지 않는다.

 

한마디로 데이터를 값이변하지않게 상수화 시킨다

 

그렇기에 무조건 선언과 동시에 정의로 초기화해야한다

[단 메모리에 올라갈때만 초기화 해주는듯 하다]

사용하지 않아 에러 X
바로 에러
해결

※클래스는 생성자에 이니셜라이저로 초기화, [ C++11 부터 바로 초기화 가능 ]

 

보통 관습으로 모두 대문자로 식별자를 만든다 

 

 

위치에 따라 상수화되는게 다르다!

const의 위치에 따라 어느게 상수화 되는지 달라진다

※ const int * == int const *

 

멤버 함수 한정으로 함수의 선언 뒤에 const를 붙일 수 있는데

붙이게 되면 함수 내에서 멤버변수를 변경할수 없게 만든다

접근지정자는 상관없다

 


 

  • 지수 표기법

ex) 314.234

가수부(기본값) 3.14234 // 지수부(스케일) E+3 ( 10의 3제곱이라는 뜻 )

=> 3.14234E+3  ( = 31.4234E+2 최종값이 똑같으면 가수부에 소수점을 어디에 찍든 상관없는듯하다 ) 

 

저장하는 방식은 위의 지수표기법과 비슷한데  [부호(0 or 1), 가수부(기본값), 지수부(스케일)]로 나누어 저장

 


 

  • 부동 소수점

부동자세의 움직이지 않는다는 느낌이 아닌

 

뜰 부, 움직일 동/ 공중에 떠서 (소수점이) 움직인다는 느낌 = 소수점을 움직이므로 여러 자리의 소수점을 표현 가능

 

※ 부동소수점 오차의 이유

https://ddidding.tistory.com/57

 


 

  • static_cast<> ()

자료형 변환

보통 형변환과 마찬가지로 사용한다고 데이터형이 영구적으로 바뀌는게 아니라 일시적이다

 

저렇게 상수를 포인터로 캐스팅하는건 안되나보다

 

주소연산자를 사용해서 다른 형의 주소로 캐스팅도 안된당

그냥 선형변환 후연산이 된다는 추가 사진


 

  • auto

"초기화 된 변수만" 자동으로 자료형을 추론해 정의해주는 키워드

 

편리하다! 하지만 아무곳이나 사용한다면 다른사람이나 훗날 코드를 본다면 욕나올듯

 

아직은 모르지만 나중에 복잡한 데이터형을 다룰때 가끔 사용할거같다

  • 전처리기 (preprocesser)

 

컴파일직전에 실행되는 프로그램

 

#으로 시작하여 줄바꿈으로 끝난다

 

 


 

  • name space

식별자의 영역을 생성

 

같은 식별자를 구분할수있게 해줌 & 확실한 출처의 식별자를 사용할수있게 한다

 

근데 중복정의가 가능한가보다

[ 하지만 식별자까지 중복은 불가능 ]

 

#include <iostream>

namespace AA {
	int a = 1;
}

namespace AA {
	int b = 2;
}

int main() {

	//실행가능
	std::cout << AA::b;
	
	return 0;
}

 

근데 내부에 중복으로 사용했을 경우 식별자까지 중복이 가능하다 ㅋㅋ [ 내부 중첩은  C++17부터 가능 ]

#include <iostream>

namespace AA {
	int a = 1;

	namespace AA {
		int a = 3;
	}
}

namespace AA {
	int b = 2;
}

int main() {

	std::cout << AA::a; // 1출력
	std::cout << AA::AA::a; // 3출력
	
	return 0;
}

 

namespace의 이름이 길다면 별명도 붙일수있다


using으로 간편하게 사용할수 있는데 using이 들어간 영역안에서만 유효하다

#include <iostream>

namespace AA {
	int myInt = 1;
}

void test() {

	//test()안에서만 AA를 사용시 정의를 하지 않아도 된다
	using namespace AA;

	//AA안에있는 myInt
	std::cout<< myInt;
}

int main() {

	//using namespace AA가 없으니 AA를 정의해줘야 한다

	std::cout << myInt; // 오류
	
	return 0;
}

using으로 간편하게 사용할수 있는데 using이 들어간 영역안에서만 유효하다

 

 

 


 

  • 함수 선언
//테스트 함수 선언
void A(int n) {

	std::cout << n;
}

int main() {

	A(5);

	return 0;
}

main에서 A가 호출되었을 때 일어난 일은

 

1. 함수 A시작 

 

2. 지역변수 n 생성

 

3. 지역변수 n에 5가 대입

 

이다. 

 

이걸 확실하게 알고있으면 나중 매개변수에 포인터 장난질 해놓은걸 덜 헤멜수있다

 

 


 

  • 키워드

특별한 의미가있는 미리 정해놓은 예약된 식별자,

 

사용자가 다른 의미로 사용할수 없다.

(단 사용 할 수 있는 언어도 있음 / C++은 X )

 

int for = 0;  // for도 키워드중 하나이기에 따로 사용 불가능

 

 

예약어라는 비슷한 개념도 있는데

 

키워드는 어떠한 사용의미를 지니고 있는 말이고

 

예약어는 사용하지 않지만 사용자에게 혼란을 막고

ex) java에서 const는 사용하지 않지만 예약어로 정해져있기에 사용 불가능하다 ( final사용 )

 

다음 버전이 업그레이드 될때의 사용하게 될지도 모르는 단어들을 미리 예약어로 정해놓아 사용못하게 해놓는다

https://m.blog.naver.com/PostView.naver?isHttpsRedirect=true&blogId=youmasan&logNo=130025032660

 

 

 

+ Recent posts