메모리의 주소를 가지고 있는 변수
int i = 10;
char c = 69;
cout << &i; // 변수 i가 저장된 메모리의 주소가 출력
cout << (void*)&c; //
##포인터 선언 및 초기화 방법
1
int* ptr;
ptr = &i;
2
int* ptr = &i;
void 포인터는 자료형이 정해지지 않은 특성 때문에 어떤 자료형으로 된 포인터든 모두 저장할 수 있다.
반대로 다양한 자료형으로 된 포인터에도 void 포인터를 저장할 수도 있다. 이런 특성 때문에 void 포인터는 범용 포인터라고 불린다.
단, void 포인터는 자료형이 정해지지 않았으므로 값을 가져오거나 저장할 크기도 정해지지 않았기 때문에 void 포인터는 역참조를 할 수 없다.
ptr = numPtr1; // void 포인터에 int 포인터 저장
printf("%d", *ptr); // 컴파일 에러. void 포인터는 역참조할 수 없음
메모리상에서 주소는 동일한 크기이기 때문에 어떤 형태이든 주소의 형식은 차이가 없지만, 포인터가 가리키는 타입을 확실하게 함으로써 프로그래밍 실수를 예방하기 위해서
Tip.
포인터가 선언만 되고 초기화되지 않았다면 포인터는 임의의 주소를 가르키게 됨.
NULL로 초기화화는 편이 좋다.!
배열의 이름은 포인터이다 -> 배열의 이름에다 다른 변수의 주소를 대입할 수 있을까?
no , 배열의 이름은 포인터 상수이다. 값 변경 불가
메모리의 공간
1, 코드 : 프로그램 코드 저장
2, 전역 : 전역변수 global, 정적변수 static, 배열 array, 구조체 structure 등이 저장
3, 스택 : 함수 호출 시 함수의 매개 변수와 지역 변수 생성. 함수 호출이 끝나면 자동으로 소멸
4, 힙 : 동적 할당으로 사용 가능
new 키워드가 반환하는 것은 할당된 메모리의 주소
만약 delete 키워드를 사용하여 반납하지 않을 시, 메모리 누수(memory leak)발생.
const int* p1
-> p1이 담고자하는 주소에는 const int가 저장되어 있다.
int* const p1
-> p1이 담고자하는 주소에는 int가 저장되어 있고, 이 값(주소)는 변경할 수 없다.
참조에 의한 호출(call by reference)
1, 포인터 이용
void func(int* a, int* b){}
int main(){
int A = 10;
int B = 20;
func(&A, &B);
}
2, 레퍼런스 이용
void func(int& a, int& b){}
int main(){
int A = 10;
int B = 20;
func(A, B);
}
2가 더 깔끔하다.
함수의 매개 변수로 변수의 주소를 전달
문자열을 나타내는 두 가지 방법.
문자 배열을 생성하고 맨 끝에 NULL문자를 추가 (NULL문자는 ASCII코드값이 0)
클래스 String 사용
char str[] = "hello";
char s1[3] = "cat";
char s2[6] = "catdog";
strcmp(s1, s2) // strcmp에서는 사전 기준으로 s1이 낮으면 음수, 같으면 0,높으면 양수를 반환한다
// s1의 t이후 값이 0(NULL)이기때문에 음수가 반환된다.