4 분 소요



포인터와 동적 배열


  • 동적 배열은 프로그램이 실제로 실행된 후에만 크기가 결정되는 배열이다.

  • C++에서 포인터와 동적 메모리 할당을 사용하여 동적 배열을 구현할 수 있다.

  • 포인터는 변수의 메모리 주소다.

  • 표인터 변수는 값이 포인터인 변수다.

Syntax:	
	Type_name  *var_name ;
	Type_name*  var_name ;
Examples:
	double *ptr ;  // == double* ptr
	char *c1_ptr , *c2_ptr ; 
	// == char* c1_ptr, c2_ptr 



포인터 예시

Example:	
	
	int i = 42 ;
	int j = 80 ;
	int *p1, *p2 ;
	p1 = &i ; p2 = &j ;
	p2 = p1 ;
	cout << *p1 << endl ; //42
	cout << *p2 << endl ; //42
	cout << i << endl ; //42
	cout << j << endl ; //80
Example:	
	
	int i = 42 ;
	int j = 80 ;
	int *p1, *p2 ;
	p1 = &i ; p2 = &j ;
	*p2 = *p1 ;
	cout << *p1 << endl ; //42
	cout << *p2 << endl ; //42
	cout << i << endl ; //42
	cout << j << endl ; //42



Dynamic variable


다이나믹 베리어블은 선언되지 않았지만 실행중에 생성되는 프로그램이다.

New 오퍼레이션은 특정 유형의 메모리를 할당하고 이 새로운 동적 변수에 대한 포인터를 반환한다.


Example:	
	
	int *p1 ;
	double *p2 ;
 	p1 = new int ;
	*p1 = 42 ;
	p2 = new double[4] ;
	p2[2]=5.5 ;

출력값



delete operator

삭제 오퍼레이터는 변수에 사용된 메모리를 헤제한다.

Example:	delete

	int *p1 ;
	double *p2 ;
	p1 = new int ;
	*p1 = 42 ;
	p2 = new double[4] ;
	p2[2]=5.5 ;
	delete p1;
 	delete[ ] p2 ;

출력값




파라미터로서의 포인터와 배열


벨류 파라미터 예시


Example:	
void make_it_42(int*  i_ptr)
  { *i_ptr = 42 ; }	

  
  int *main_ptr ;
  main_ptr = new int ;
  make_it_42(main_ptr) ; 
   // 이 뒤로 i_ptr은 더이상 사용할 수 없다.

출력값



배열 파라미터 예시

void make_it_all_42(double data[ ], size_t n) 
  {	size_t i; 
      for (i=0;i<n;++i)
  	data[i]=42 ;
  }	
  
  double main_array[10] ;
  make_it_all_42(main_array,10) ;
  cout << main_array[5] ; //42



const 파라미터의 예시

 bool is_42(const int* i_ptr) 
 {    
    return (*i_ptr == 42) ;  
 }
double average(const double data[], size_t n);
{    
	size_t   i ;  double sum ;
  assert(n>0) ;
  sum = 0 ; 
  for(i=0; i<n; ++i)
		sum += data[i] ;
		// data[i] += 1; 을 사용하면 에러가 난다.
  return (sum/n) ;
}



레퍼런스 파라미터의 예시

 void allocate_doubles(double*& p, size_t& n);
 {    
    cout << Enter the number of doubles: ;
    cin >>  n ;    
    p = new double[n] ;
}


  • 포인터이면서 레퍼런스의 파라미터 : *&

  • 때때로 함수는 새 포인터가 새 위치를 가리키도록 포인터 파라미터를 실제로 변경한다.

  • 함수 자체에서 만든 배열을 다른곳(main)에서 제어하고 싶을때 포인터레퍼런스 파라미터를 사용한다.

  • 함수는 리턴타입이 한 개라 배열이나 다른 타입을 리턴받고 싶을 때 사용한다.



동적배열을 통한 bag class

이전 장에서 다룬 bag class를 포인터를 사용하면 컴파일 시간 이 아닌 런타임 에 크기가 결정되는 데이터 구조를 정의할 수 있다.


 The Static Bag:
 class bag {    
    
    value_type data[CAPACITY] ;    
    size_type used;
} 
 The Dynamic Bag:
 class bag {    
    
    value_type *data ;    
    size_type used;
    size_type capacity ;	
}


동적 가방 클래스를 정의하려면 먼저 constructor을 정의해야 합니다.

bag(size_type init_capacity = Default_Capacity);

bag::bag(size_type init_capacity )
{
	data = new value_type[init_capacity]; //중요!
	capacity = init_capacity; //중요!
	used = 0; // 초기화, 중요!
}



copy constructor

Copy constructor : 소스 오브젝트를 복사해서 새 인스턴스를 생성한다.

bag(const bag& source);

bag::bag(const bag& source)
{
	data = new value_type[source.capacity];
	capacity = source.capacity;
	used = source.used;
	copy(source.data, source.data + used, data);
}




bag(const bag& source);
// Data Sharing !!!
bag::bag(const bag& source)
{
  data = source.data ; 
	//이 개체는 소스 개체와 데이터 배열을 공유한다.
  capacity = source.capacity ;
  used = source.used ;
}



destructor

  • frees 동적 메모리
~bag( );

bag::~bag( )
{
  delete [ ] data ;
}

함수가 종료되도 다이나믹 배열은 메모리를 놓지 않고 가지고 있다.

따라서 딜리트는 명령어는 할당되어있는 메모리를 시스템에 돌려주라 라는 의미다.



assignment operator “=”

할당 오퍼레이터

  • 먼저 할당(a = a)을 확인한다.
  • 배열의 크기가 일치하지 않으면 새 배열에 메모리를 할당한다.
  • 원본 데이터를 새로 할당된 데이터 배열에 복사한다.
  • Copy constructor와 비슷하다.

Example



void bag::operator = (const bag& source)  { 
  value_type *new_data;
    if (this == &source) //ca[acity 같은지 확인
     	return;
    if (capacity != source.capacity)//만약 다르면
    {
			new_data = new value_type[source.capacity];
			delete [ ] data ;
     	data = new_data ;
     	capacity = source.capacity ;
    }
    used = source.used ;
    copy(source.data, source.data+used,data) ;
}



reserve function

Reserve(예약) 기능 : 가방의 용량증가

void bag::reserve(size_type new_capacity) 
{
	value_type *larger_array ;
  	if (new_capacity == capacity)
  	 	return ;
    if (new_capacity < used)     
  		new_capacity = used ; 

    larger_array = new value_type[new_capacity] ;
    copy(data, data+used, larger_array) ;
    delete [ ] data ;
    data = larger_array ;
    capacity = new_capacity ;
}



insert function

Insert (삽입) 기능 : 공간을 확보한다.

void bag::insert(const value_type& entry)
{
  if (used == capacity)
		reserve(used+1) ; 	

  data[used] = entry ;
    ++used ;	
}



”+” operator

  • 두 개의 백을 추가하고 결과를 반환한다.
bag operator +(const bag& b1,const bag& b2)
{
  bag answer(b1.size() + b2.size()) ;
	
  answer += b1 ;
  answer += b2 ;
  return answer ;	
}



”+=” operator

  • 오브젝트에 새 가방을 추가한다.
void bag::operator +=(const bag& addend)
{
  if (used + addend.used > capacity )
		reserve(used + addend.used) ;
  copy(addend.data, addend.data+addend.used,data+used) ;	
      used += addend.used ;
}



Notes

클래스의 멤버 변수가 동적 메모리에 대한 포인터인 경우 destructor, copy constructor 및 오버로드 할당 오퍼레이터를 제공해야한다.

댓글남기기