배열의 이름은 배열의 첫 번째 요소를 가리키는 포인터로 해석될 수 있다.
int arr[5] = {1, 2, 3, 4, 5};
다음과 같은 배열이 있다고 가정했을 때
int* ptr = arr; // ptr은 arr의 첫 번째 요소를 가리킴
for (int i = 0; i < 5; i++) {
std::cout << *(ptr + i) << " "; // 포인터 연산을 통해 배열 요소에 접근
}
위와 같이 포인터를 사용하여 배열의 요소에 접근할 수 있다. 위의 코드에서 *(ptr + i)는 arr[i]와 동일한 결과를 반환한다.
포인터와 배열은 메모리에서 밀접하게 연결되어 있으며, 배열의 이름은 배열의 첫 번째 요소를 가리키는 포인터로 해석될 수 있다. 포인터를 사용하여 배열의 요소에 접근할 수 있으며, 배열과 포인터는 서로 보완적인 역할을 한다.
STL을 사용하지 않고 iostream와 포인터의 특성 만을 이용해 벡터의 생성, 추가, 삭제 등을 직접 만들 수 있다.
template <typename T>
class CuVec
{
private:
int size;
T* data;
public:
CuVec() : size(0)
{
data = nullptr;
}
CuVec(int size)
: size(size)
{
data = new T[size]();
for (int i = 0; i < size; i++)
{
*(data + i) = 0;
}
}
~CuVec() = default;
int Size() { return size; }
T* Get() { return data; }
template <typename T>
이 클래스는 템플릿으로 정의되어 있어, 다양한 데이터 타입(T)을 사용할 수 있다. 예를 들어, CuVec<int>는 정수형 벡터를을, CuVec<double>은 실수형 벡터를 생성한다.
int size
현재 벡터 의 크기를 저장하는 변수
T* data
동적으로 할당된 벡터 의 시작 주소를 저장하는 포인터
public:
CuVec() : size(0)
{
data = nullptr;
}
기본 생성자: size를 0으로 초기화하고, data 포인터를 nullptr로 설정. 이는 빈 벡터를 생성한다.
CuVec(int size) : size(size)
{
data = new T[size]();
for (int i = 0; i < size; i++)
{
*(data + i) = 0;
}
}
매개변수가 있는 생성자: 주어진 크기(size)로 동적 벡터를 할당. new T[size]()를 사용하여 size만큼의 벡터을 생성하고, 모든 요소를 0으로 초기화
int Size()
현재 벡터의 크기를 반환하는 함수
T* Get()
벡터 의 시작 주소를 반환하는 함수. 이를 통해 외부에서 벡터의 요소에 접근할 수 있다.
벡터 크기 조정 함수
void ReSize(int newSize)
{
T* newArray = new T[newSize]();
for (int i = 0; i < size; i++)
{
newArray[i] = data[i];
}
for (int i = size; i < newSize; i++)
{
newArray[i] = 0;
}
T* oldData = data;
data = newArray;
size = newSize;
delete oldData;
}
ReSize라는 이름의 함수로, 새로운 벡터의 크기를 newSize로 설정한다.
T* newArray = new T[newSize]();
newSize 크기의 새로운 벡터 newArray를 동적으로 할당합니다. ()를 사용하여 기본값으로 초기화
for (int i = 0; i < size; i++)
{
newArray[i] = data[i];
}
기존 벡터 data의 요소를 새로운 벡터 newArray로 복사합니다. 이때, 기존 배열의 크기인 size만큼 반복
for (int i = size; i < newSize; i++)
{
newArray[i] = 0;
}
새로운 배열의 나머지 부분(기존 배열의 크기 이후)에는 기본값인 0으로 초기화
T* oldData = data;
data = newArray;
기존 데이터 포인터 data를 oldData에 저장한 후, data를 새로운 배열 newArray로 업데이트
size = newSize;
배열의 크기를 newSize로 업데이트
이렇게 포인터를 이용해 배열의 생성, 크기 조정등을 할 수 있다. 이와 비슷한 방식으로 다른 기능들도 추가할 수 있다.
배열 맨 마지막에 데이터 넣기
void Push(T newData)
{
T* newArray = new T[size + 1](); // 원래보다 하나 더 큰 배열 생성
for (int i = 0; i < size; i++)
{
newArray[i] = data[i]; // 원본의 값을 새 배열로
}
newArray[size] = newData; // 마지막 순번에 새로운 데이터
T* oldData = data;
data = newArray;
size++; // 1 늘어난 배열 크기를 기록
delete oldData;
}
배열 맨 마지막 데이터 삭제
void Pop()
{
T* newArray = new T[size - 1](); // 원래보다 하나 작은 배열 생성
for (int i = 0; i < size - 1; i++)
{
newArray[i] = data[i]; // 원본의 값을 새 배열로
}
// 새 배열이 먼저 끝났으니 추가할 값도 없다
T* oldData = data;
data = newArray;
size--; // 1 줄어든 배열 크기를 기록
delete oldData;
}
특정 인덱스에 특정 값 넣기
void Insert(int index, T newData)
{
T* newArray = new T[size + 1]();
for (int i = 0; i < index; i++)
{
newArray[i] = data[i];
}
newArray[index] = newData;
for (int i = index+1; i < size+1; i++)
{
newArray[i] = data[i-1];
}
T* oldData = data;
data = newArray;
size++;
delete oldData;
}
특정 인덱스 값 삭제
void Erase(int index)
{
T* newArray = new T[size - 1]();
for (int i = 0; i < index ; i++)
{
newArray[i] = data[i];
}
for (int i = index; i < size; i++)
{
newArray[i] = data[i+1];
}
T* oldData = data;
data = newArray;
size--;
delete oldData;
}
'C++' 카테고리의 다른 글
C++) 템플릿(Template) (0) | 2025.01.15 |
---|---|
C++) 암시적 멤버 함수 (0) | 2025.01.13 |
C++) 상속 (0) | 2025.01.10 |
C++) 클래스(Class) (0) | 2025.01.08 |
C++) 동적 할당 (0) | 2025.01.06 |