포인터 1
포인터란? 포인터 메모리의주소를가지고있는변수 메모리주소 100번지 101번지 102번지 103번지 int theage (4 byte) 변수의크기에따라 주로 byte 단위 주소연산자 : & 변수의주소를반환 메모리 2
#include <iostream> list 8.1 int main() using namespace std; unsigned short shortvar=5; unsigned long longvar=65535; long svar = -65535; cout << "shortvar:\t" << shortvar; cout << "\taddress of shortvar:\t"; cout << &shortvar << "\n"; cout << "longvar:\t" << longvar; cout << "\taddress of longvar:\t" ; cout << &longvar << "\n"; cout << "svar:\t\t" << svar; cout << "\taddress of svar:\t" ; cout << &svar << "\n"; return 0; shortvar : 5 Address of shortvar: 0012FF7C longvar : 65535 Address of longvar: 0012FF78 svar: -65535 Address of svar: 0012FF74 3
포인터선언 포인터선언방법 int *page = 0; 정수형변수의주소를담는 ( 가리키는 ) 변수 ( 포인터 ) page 는변수 저장되는내용은주소로해석 Null 과 Wild 포인터 null 포인터 : 0 으로초기화된포인터 wild 포인터 : 초기화되지않은포인터 포인터값할당 int howold = 50 ; int *page = 0 ; page = &howold; int howold = 50 ; int *page = &howold; 4
간접지정 (indirection) 연산자 간접지정연산자 메모리주소 포인터를사용하여실제값접근 (page를사용하여 howold 값에접근 ) int howold = 50 ; int *page = &howold; 100번지 101번지 102번지 int howold (4 byte) 100 page cout << page ; cout << *page ; 주소값이가리키는실제값을찾아가게함 5
구별 포인터변수 포인터, 주소, 변수 포인터변수에저장된주소값 포인터변수에저장된주소값이가리키는메모리에저장된실제값 100번지 int thisval 101번지 102번지 104 번지 int thatval 108 번지 int *pptr int thisval = 5; int thatval = 7; int *pptr = &thisval; int dbl_this = 2 * *pptr; pptr = &thatval; int dbl_that = 2 * *pptr; 6
#include <iostream> list 8.2 typedef unsigned short int USHORT; int main() using std::cout; USHORT myage; // a variable USHORT * page = 0; // a pointer myage = 5; cout << "myage: " << myage << "\n"; page = &myage; cout << "*page: " << *page << "\n\n"; cout << "Setting *page = 7...\n"; *page = 7; cout << "*page: " << *page << "\n"; cout << "myage: " << myage << "\n\n"; cout << "Setting myage = 9...\n"; myage = 9; cout << "myage: " << myage << "\n"; cout << "*page: " << *page << "\n"; return 0; 7
포인터를사용하는이유 자유기억장소의자료를다룰때 클래스멤버자료와클래스멤버함수에접근할때 함수에주소전달을할때 8
자유기억공간 (heap) 메모리의 5 가지영역 코드영역 전역공간 : 전역변수관리 스택 : 지역변수, 함수의매개변수관리 자유기억공간 레지스터 : special / general purpose register 지역변수의문제점 지속성 동적으로변수를잡을수없음 int num; std:: cin >> num ; int array[num]; 자유기억공간의이점 공간을제거하기전까지는메모리유지 동적으로변수를잡을수있음포인터로자유기억공간에대한접근및관리포인터를가진함수만이자유기억공간에접근가능 9
자유기억공간할당및해제 할당 ( new ) new 객체의형 ( 초기화값 ) new 객체의형 [ 개수 ] 자유기억장소할당및메모리주소반환 new unsigned short int new long (10000) new int [10] 2byte 자유기억장소할당 4byte 자유기억장소할당 (10000 으로초기화 ) 4byte 자유기억장소 10 개할당 10
자유기억공간할당및해제 (cont.) 자유기억공간사용 ( 포인터로관리 ) unsigned short int *ppointer ; ppointer = new unsigned short int ; *ppointer = 72; std::cout << *ppointer ; short int *ppointer = new short int ; *ppointer = 72; std::cout << *ppointer ; int num ; std::cin >> num ; int *array = new int[num] ; 11
자유기억공간할당및해제 (cont.) 해제 ( delete ) 자유공간의메모리는 ( 스택에저장된지역변수와달리 ) 자동소멸되지않음 강제적인해제필요 delete 포인터 ; delete ppointer ; 메모리누출 ( memory leak ) int *ppointer = new int ; *ppointer = 72; ppointer = new int ; *ppointer = 84; delete ppointer ; 앞선자유기억공간을해제할방법없음 12
#include <iostream> int main() using std::cout; list 8.4 int localvariable = 5; int * plocal = &localvariable; int * pheap = new int; *pheap = 7; cout << "localvariable: " << localvariable << "\n"; cout << "*plocal: " << *plocal << "\n"; cout << "*pheap: " << *pheap << "\n"; delete pheap; pheap = new int; *pheap = 9; cout << "*pheap: " << *pheap << "\n"; delete pheap; return 0; 13
자유기억장소에객체만들기 / 지우기 만들기 Cat *pcat = new Cat ; 지우기 delete pcat ; 리스트 8.5 자료멤버에접근 (*pcat).getage( ) ; pcat GetAge( ) ; 14
#include <iostream> class SimpleCat public: SimpleCat(); ~SimpleCat(); private: int itsage; ; list 8.5 SimpleCat::SimpleCat() std::cout << "Constructor called.\n"; itsage = 1; SimpleCat::~SimpleCat() std::cout << "Destructor called.\n"; 15
int main() std::cout << "SimpleCat Frisky...\n"; SimpleCat Frisky; std::cout << "SimpleCat *prags = new SimpleCat...\n"; SimpleCat * prags = new SimpleCat; std::cout << "delete prags...\n"; delete prags; std::cout << "Exiting, watch Frisky go...\n"; return 0; 16
#include <iostream> list 8.6 class SimpleCat public: SimpleCat() itsage = 2; ~SimpleCat() int GetAge() const return itsage; void SetAge(int age) itsage = age; private: int itsage; ; int main() SimpleCat * Frisky = new SimpleCat; std::cout << "Frisky is " << Frisky->GetAge() << " years old\n"; Frisky->SetAge(5); std::cout << "Frisky is " << Frisky->GetAge() << " years old\n"; delete Frisky; return 0; 17
Class 멤버자료가자유기억공간을가리키는포인터 클래스의생성자 ( 또는메소드 ) 자유기억공간할당 클래스의소멸자 자유기억공간해제 18
#include <iostream> class SimpleCat public: SimpleCat(); ~SimpleCat(); int GetAge() const return *itsage; void SetAge(int age) *itsage = age; int GetWeight() const return *itsweight; void setweight (int weight) *itsweight = weight; private: int * itsage; int * itsweight; ; SimpleCat::SimpleCat() itsage = new int(2); itsweight = new int(5); list 8.7 19
SimpleCat::~SimpleCat() delete itsage; delete itsweight; int main() SimpleCat *Frisky = new SimpleCat; std::cout << "Frisky is " << Frisky->GetAge() << " years old\n"; Frisky->SetAge(5); std::cout << "Frisky is " << Frisky->GetAge() << " years old\n"; delete Frisky; return 0; 20
this 포인터 this 포인터 그개체를가리키는포인터 모든클래스멤버함수가가지는숨겨진매개변수 컴파일러가자동적으로생성과삭제해줌 21
#include <iostream.h> class Rectangle public: Rectangle(); ~Rectangle(); list 8.8 void SetLength(int length) this->itslength = length; int GetLength() const return this->itslength; void SetWidth(int width) itswidth = width; int GetWidth() const return itswidth; private: int itslength; int itswidth; ; 22
Rectangle::Rectangle() itswidth = 5; itslength = 10; Rectangle::~Rectangle() int main() Rectangle therect; cout << "therect is " << therect.getlength() << " feet long.\n"; cout << "therect is " << therect.getwidth() << " feet wide.\n"; therect.setlength(20); therect.setwidth(10); cout << "therect is " << therect.getlength() << " feet long.\n"; cout << "therect is " << therect.getwidth() << " feet wide.\n"; return 0; 23
실종된포인터 메모리해제 (delete) 후포인터를다시사용 논리적에러발생 메모리해제후가능한포인터를널 (null) 로지정 24
typedef unsigned short int USHORT; #include <iostream> list 8.9 int main() USHORT * pint = new USHORT; *pint = 10; std::cout << "*pint: " << *pint << std::endl; delete pint; long * plong = new long; *plong = 90000; std::cout << "*plong: " << *plong << std::endl; *pint = 20; // deleted! std::cout << "*pint: " << *pint << std::endl; std::cout << "*plong: " << *plong << std::endl; delete plong; return 0; 25
const 포인터 const 의오른쪽항을상수로간주 const int *pone ; int * const ptwo ; const int * const pthree ; pone : 상수형 (int) 에대한포인터 int val = 5 ; const int * pone = &val ; val = 7 ; pone *pone = 10 ; (X) ptwo : 상수포인터 int a = 5, b = 7; int * const ptwo = &a ; *ptwo = 10; pone *ptwo = &b ; (X) 26
const 포인터 (cont.) const 객체에대한포인터를선언하면포인터가호출할수있는메소드는 const 메소드뿐 27
#include <iostream> using namespace std; list 8.10 class Rectangle public: Rectangle(); ~Rectangle(); void SetLength(int length) itslength = length; int GetLength() const return itslength; void SetWidth(int width) itswidth = width; int GetWidth() const return itswidth; private: int itslength; int itswidth; ; Rectangle::Rectangle() itswidth = 5; itslength = 10; Rectangle::~Rectangle() 28
int main() Rectangle* prect = new Rectangle; const Rectangle * pconstrect = new Rectangle; Rectangle * const pconstptr = new Rectangle; cout << "prect width: " << prect->getwidth() << " feet\n"; cout << "pconstrect width: " << pconstrect->getwidth() << " feet\n"; cout << "pconstptr width: " << pconstptr->getwidth() << " feet\n"; prect->setwidth(10); // pconstrect->setwidth(10); pconstptr->setwidth(10); cout << "prect width: " << prect->getwidth() << " feet\n"; cout << "pconstrect width: " << pconstrect->getwidth() << " feet\n"; cout << "pconstptr width: " << pconstptr->getwidth() << " feet\n"; return 0; 29