같은 타입의 변수들로 이루어진 유한 집합입니다.
c++ 배열은 복합 타입으로 불립니다.
복합 타입은 다른 타입을 이용해서 정의한 타입을 복합타입이라고 합니다.
type var_name[demension]
타입 변수명 [차원] 으로 정의되어집니다.
배열의 차원은 컴파일 시점에 알고 있어야 하므로 차원에 들어갈 수 있는 값은 상수 표현식만 가능합니다.
배열을 초기화하지 않았을 경우 기본 초기화를 수행합니다.
이 때 배열의 각 요소에 들어갈 값은 미정입니다. (주의점)
int arr[10];
float arr_float[10];
unsigned int cnt = 10;
int array[cnt];
float arr_float[cnt];
int arr[] = {1, 2, 3, 4};
차원 수를 정하지 않고 다음과 같이 명시적 초기화를 수행하였을 경우 초기 값의 개수를 컴파일러가 파악하여 차원 수를 추측합니다.
// int arr[5] = {1, 2, 3, 0, 0};
int arr[5] = {1, 2, 3};
차원 수를 정했을 때 초기 값의 개수가 지정한 차원 수보다 작을 경우 나머지 공간에 대해 값 초기화를 수행합니다.
값 초기화에서 내장 타입의 경우 요소의 초기 값을 넣어주고, class 타입인 경우 기본 초기화를 수행합니다.
이 예시에서는 int 내장 타입이므로 초기 값 0을 넣어줍니다.
char array1[] = {'C', '+', '+'};
char array2[] = {'C', '+', '+', '\0'};
// 자동 null 문자 삽입
char array3[] = "C++";
// 오류
const char array4[3] = "C++";
문자 배열은 문자열 상수로 초기화가 가능합니다.
문자열 상수로 초기화 하는 경우 배열의 마지막 공간에 NULL 문자가 삽입됩니다.
4번째 예시 문자열 배열의 경우 마지막 공간에 NULL 문자를 삽입할 수 없으므로 컴파일러가 오류 메시지를 띄웁니다.
배열의 요소를 index라고 부릅니다.
index에 접근함으로써 배열의 특정 공간 값에 접근할 수 있게 됩니다.
int array[5] = {1, 2, 3, 0 ,0};
int x = 3;
// array[2] == 3, y == 6
int y = x + array[2];
int arr1[3] = {1, 2, 3};
// 불가능;
int arr2[] = arr;
int arr3[];
// 불가능
arr3[] = arr1;
배열은 다른 배열의 복사본으로 초기화 할 수 없습니다.
배열은 다른 배열에 대입하는 것도 불가능합니다.
배열은 메모리가 연속적인 데이터의 집합입니다.

int 타입 배열 arr에 차원의 크기를 10으로 정의하고 초기화하였을 때 들어간 값을 살펴보면
arr의 주소 메모리로 이동하였을 때 담겨있는 값이 인덱스 0의 값인 1이고 다음 값들은 4byte마다 담겨있는 것을 확인할 수 있습니다.
int 타입이므로 배열의 각 요소들은 각각 4byte씩 할당 받고 각 값들이 인덱스 0의 값 1부터 4byte 간격으로 담겨져 있는 것을 확인할 수 있습니다.
사용자 정의 자료형
struct MyType
{
int a;
float f;
}
struct MyType2
{
MyType myType;
int x;
double d;
}
구조체는 기본 타입 변수들과 구조체 타입 변수들을 내장 변수로 사용할 수 있습니다.
struct MyType
{
int a;
float f;
}
int main()
{
struct MyType myType;
}
-------------------------------
typedef struct _myType
{
int a;
float f;
}MYT
int main()
{
MYT myType;
}
typedef를 붙이지 않고 구조체를 정의하면 구조체를 불러올 때 struct 라는 타입명을 붙여 주어야 구조체라는 것을 컴파일러가 인식할 수 있습니다.
typedef를 붙이게 되면 구조체 선언 후 사용하려고 할 때 struct 타입 명이 아닌 내가 지정한 타입명만 붙여주면 사용할 수 있습니다.
typedef struct _myType
{
int a;
float f;
}MYT
int main()
{
MYT myType = {10, 3.14f};
// 10
myType.a;
// 3.14f
myType.f;
}
구조체 초기화 시 다음과 같이 초기화가 가능합니다.
내장 변수 int 타입 a와, float 타입 f를 가지고 있으므로 다음과 같이 초기화 하면 a의 값은 10, f의 값은 3.14f를 가지게 됩니다.
해당 값들을 사용하고 싶다면 . 을 활용하여 MYT 타입의 인스턴스 myType.a, myType.f를 통해 사용이 가능합니다.

값을 1 더했으니 1이 증가할 것 같지만 int 자료형의 크기인 4byte 만큼 증가한 것을 확인할 수 있습니다.
c++ 에서 주소에 1을 더한다는 행위는
sizeof(자료형)만큼 이동한다는 것과 동일합니다.
포인터는 자료형의 관점을 가지면서 해당 자료형의 주소를 가지는 변수입니다.
그렇다면 포인터에 1을 더하면 어떤 값으로 변환될까요?

마찬가지로 포인터도 주소 값을 담고 있는 변수이므로 값 1을 더하면 int 자료형의 크기인 4만큼 증가하는 것을 확인할 수 있습니다.
포인터에서 주소를 더한 방식과 동일합니다.
c++에서 포인터의 주소 값에 1을 더하게 되면 현재 자료형의 크기만큼 주소 공간을 옮기게 됩니다.

실제로 배열의 요소에 대한 접근은 다음과 같이 iArr 의 처음 주소로 접근하면 0번 인덱스로 접근.
1을 더할 때마다 int 자료형의 크기인 4byte 만큼의 주소를 이동합니다.
5를 더한 주소값은 확인해보면 0000001AFC6FF888 ⇒ 0000001AFC6FF89C 이고 16진수 표기법이므로 C - 8 = 4, 9 - 8 = 16 ⇒ 16 + 4 = 20
즉 iArr의 초기 주소에 5를 더한 값은 5 *
sizeof(int)만큼 이동한 것을 확인할 수 있습니다.
순서를 유지하는 노드 기반 컨테이너 자료구조입니다.
원소 탐색 시 임의접근 반복자
(at(), [])으로 접근은 불가능하고, 양방향 반복자(++, --)을 통해서 접근이 가능합니다.
push_front(), push_back(), pop_front(), pop_back()의 멤버 함수를 이용해서 list양 끝에서 삽입, 삭제가 가능합니다.삽입과 삭제에
O(1)의 시간이 소요됩니다.탐색에
O(N)의 시간이 소요됩니다.
// my_list.h
#ifndef MY_LIST_H
#define MYLIST_H
typedef struct Node
{
Node* next;
int data;
}
class LinkedList
{
private:
Node* head;
public:
LinkedList();
~LinkedList();
int front();
int back();
void push_back(int data);
void pop_back();
void push_front(int data);
void pop_front();
}
// my_list.cpp
LinkedList::LinkedList()
{
this->head = nullptr;
}
LinkedList::~LinkedList()
{
Node* cur = this->head;
if (cur == NULL)
{
return;
}
while(cur){
Node* next_node = cur->next;
delete cur;
cur = next_node;
}
}
int LinkedList::front()
{
assert(this->head);
return this->head->data;
}
int LinkedList::back()
{
assert(this->head);
Node* cur = this->head;
while(cur->next)
{
cur = cur->next;
}
return cur->data;
}
void LinkedList::push_back(int data)
{
if (this->head == nullptr)
{
Node* new_node = new Node{ nullptr, data};
this->head = new_node;
return;
}
Node* cur = this->head;
while(cur->next)
{
cur = cur->next;
}
Node* new_node = new Node {nullptr, data};
cur->next = new_node;
}
void LinkedList::push_front(int data)
{
if (this->head == nullptr)
{
Node* new_node = new Node{ nullptr, data};
this->head = new_node;
return;
}
Node* cur = this->head;
Node* new_node = new Node{ nullptr, data};
new_node->next = cur;
this->head = new_node;
}
void LinkedList::pop_back()
{
Node* cur = this->head;
if (cur == nullptr)
{
std::cout << "List is NULL" << std::endl;
return;
}
while(cur->next->next != nullptr)
{
cur = cur->next;
}
delete cur->next;
cur->next = nullptr;
}
void LinkedList::pop_front()
{
Node* cur = this->head;
if (cur == nullptr)
{
std::cout << "List is NULL" << std::endl;
return;
}
if (cur->next)
{
this->head = cur->next;
delete cur;
}
else
{
this->head = nullptr;
delete cur;
}
}
#endif MY_LIST_H
다음 문제에서 틀린 부분을 확인하고 틀린 이유를 말한 뒤 올바르게 고쳐주세요.
int cnt = 10;
int cArr[cnt];
int main()
{
}
다음 문제에서 틀린 부분을 확인하고 틀린 이유를 말한 뒤 올바르게 고쳐주세요.
char cArr[3] = "C++";
다음 문제에서 출력되는 정수의 값은?
int main()
{
int iArr[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
std::cout << "정수의 값은 ? " << *(iArr + 5) << std::endl;
}
이중 원형연결 리스트를 구현해주세요.