배열 은 "하나의 변수에 여러 개의 값을 넣고 싶을 때 사용한다"
배열 을 정의 하기 위해선,
기본처럼 변수 타입을 지정하고, 변수 이름을 적은 뒤
[] 와 함께 몇 개의 요소를 담을 것인지 정해준다
string cars[4]; // 이렇게 배열 변수만 정의하거나
string cars[4] = {"Volvo", "BMW", "Ford", "Mazda"};
// 요소도 바로 할당 가능

이전에 인덱스 를 사용할 때와 비슷하게
배열도 [] 를 통해 각 요소에 접근할 수 있다
cout << cars[1];
cars[0] = "Opel"; // 요소를 새로 정의해줌으로써 덮어쓰기
for 루프를 사용해 배열 안의 요소를 순환하며 코드를 실행할 수 있다
string cars[4] = {"아반떼", "소나타", "스타렉스", "쏘렌토"};
// for 루프로 하나씩 출력
for (int i = 0; i < 5; i++) {
cout << cars[i] << "\n";
}

이상한 게 같이 출력되는데 한글이 원인일지도
앞서 배운 foreach 루프는,
배열의 요소를 순환하는 데 특화되어 있다 (vector 나 list 도 가능)
for (타입 변수이름 : 배열이름) {
// 실행할 코드
}

사실 배열을 정의할 때 배열의 크기까지 지정해줄 필요는 없다.
컴파일러가 알아서 인식해주기 때문.
string cars[] = {"싼타페", "그랜져", "코란도"};
다만, 배열 크기까지 정해주는 게 나중에 오류 날 일이 적다고 한다
물론, 처음에 나왔듯이
배열만 생성해주고 나중에 각각 요소 채워넣는 것도 가능string cars[3]; cars[0] = "포르쉐"; cars[1] = "페라리"; ...이게 가능한 건 처음에 배열 크기를 정해줬을 때 뿐이다!
배열을 다루다 보면 고정 크기 와 동적 크기 라는 말을 자주 보게 될텐데,
배열(array)의 경우 고정 크기 라고 불리는 이유는
한 번 크기를 정해주고 나면 크기를 늘리거나 줄일 수 없기 때문
하지만 벡터는 크기를 늘리고 줄일 수 있기 때문에,
동적 크기 로 불리며 배열 요소의 삭제나 추가 연산에 쓰인다
벡터 = "크기 조정 가능한 배열"
// A vector with 3 elements
vector<string> cars = {"Volvo", "BMW", "Ford"};
// Adding another element to the vector
cars.push_back("Tesla");
※ 벡터를 사용하려면 헤더 추가해줘야 한다

sizeof() 연산자를 통해 배열 크기를 구할 수 있다
cout << sizeof(배열이름);

"96" 이 나온 걸 확인할 수 있는데,
이는 sizeof 연산자가 "배열 크기" 를 구한다는 의미가
배열 요소 개수 가 아니라 배열의 용량 크기 를 구해주기 때문.
즉 배열의 '요소 개수'를 확인하고 싶다면
배열 전체의 크기를 요소 하나의 크기로 나눠주는 과정을 거쳐야한다.

문자열 배열로 진행해서 알기 어렵지만,
숫자 배열로 하면 더 쉽게 확인할 수 있다
(int는 하나에 4바이트)
이를 통해서 루프문의 조건 부분을 바꿔줄 수 있는데
기존의 i 를 사용하는 방식도 깔끔하고 좋지만,
그건 배열의 크기를 알 때 사용할 수 있는 방식이라서 :
int myNumbers[5] = {10, 20, 30, 40, 50};
for (int i = 0; i < 5; i++) {
cout << myNumbers[i] << "\n";
}
이런 조건 보다 sizeof() 을 활용하게 되면,
배열의 크기를 몰라도 사용할 수 있고, 지속 가능한 코드가 된다.
int myNumbers[5] = {10, 20, 30, 40, 50};
for (int i = 0; i < sizeof(myNumbers) / sizeof(myNumbers[0]); i++) {
cout << myNumbers[i] << "\n";
}
하지만 여전히 foreach 루프가 제일 깔끔하고 좋다
int myNumbers[5] = {10, 20, 30, 40, 50};
for (int i : myNumbers) {
cout << i << "\n";
}
위 3가지 코드는 모두 똑같이 동작한다

// An array storing different ages
int ages[8] = {20, 22, 18, 35, 48, 26, 87, 70};
float avg, sum = 0; // 평균과 총합 을 미리 실수 변수로 선언
int i; // 예시에 있지만 필요없는 부분이라고 판단하고 실험구동에선 삭제
// Get the length of the array
int length = sizeof(ages) / sizeof(ages[0]);
// Loop through the elements of the array
// for 하고 변수 하나 선언해 주고 그걸로 배열을 순환하는 루프
for (int age : ages) {
sum += age;
}
// Calculate the average by dividing the sum by the length
avg = sum / length;
// Print the average
cout << "The average age is: " << avg << "\n";

// An array storing different ages
int ages[8] = {20, 22, 18, 35, 48, 26, 87, 70};
// Get the length of the array
int length = sizeof(ages) / sizeof(ages[0]);
// Create a variable and assign the first array element of ages to it
// 우선 변수 하나 만들어서 맨앞 요소 넣어주고
int lowestAge = ages[0];
// Loop through the elements of the ages array to find the lowest age
// 반복문 거치면서 더 작은 요소가 나오면 덮어씌워주는 구조, 마지막에 출력
for (int age : ages) {
if (lowestAge > age) {
lowestAge = age;
}
}
// Print the lowest age
cout << "The lowest age is: " << lowestAge << "\n";

다차원 배열 = "배열"로 이루어진 "배열" 로,
이걸 생성하려면 똑같이 변수 타입 지정=>배열 이름 설정=>
[]를 통해 [배열갯수][각 배열의 요소 수] 로 정의해 주면 된다.
string letters[2][4] = {
{ "A", "B", "C", "D" },
{ "E", "F", "G", "H" }
};
[]하나 당 하나의 '차원' 이라고 생각하면 된다.
그래서 "다차원 배열"
string letters[2][4] = {
{ "A", "B", "C", "D" },
{ "E", "F", "G", "H" }
};
cout << letters[0][2]; // Outputs "C"
간단하게 생각해서 순서대로 골라주면 된다
위의 letters[0][2] 의 경우
인덱스 0번, 1번째 배열의 => 인덱스 2번, 3번째 요소 여서 "C"
요소를 수정할 때도 비슷하게
"몇 번 배열의 몇 번 요소를 덮어씌울 건지" 써주면 된다
string letters[2][4] = {
{ "A", "B", "C", "D" },
{ "E", "F", "G", "H" }
};
letters[0][0] = "Z";
cout << letters[0][0]; // Now outputs "Z" instead of "A"
다차원 배열 내부를 루프할 경우에는,
각 '차원'에 따라 반복을 설정해 줘야한다
string letters[2][4] = {
{ "A", "B", "C", "D" },
{ "E", "F", "G", "H" }
};
for (int i = 0; i < 2; i++) { // 1차 루프
for (int j = 0; j < 4; j++) { // 2차 루프
cout << letters[i][j] << "\n";
}
}
우리가 다차원 배열을 사용하는 이유는 :
그리드 를 표현하기에 적합하기 때문이다.
아래는 그리드의 예시)
// 칸에 배가 있으면 1 , 없으면 0
bool ships[4][4] = {
{ 0, 1, 1, 0 },
{ 0, 0, 0, 0 },
{ 0, 0, 1, 0 },
{ 0, 0, 1, 0 }
};
// 히트 수와 턴 수를 기록하기 위한 변수
int hits = 0;
int numberOfTurns = 0;
// 배를 전부 찾을 때까지 계속할 수 있도록 반복문 : "while"
while (hits < 4) {
int row, column;
cout << "Selecting coordinates\n"; // 좌표 선택
// 행 고르기
cout << "행 번호를 골라주세요 (0과 3 사이): ";
cin >> row; // 입력 받기
// 열 고르기
cout << "열 번호를 골라주세요 (0과 3 사이): ";
cin >> column;
// 해당 좌표에 배가 존재하는 지 확인
if (ships[row][column]) {
// 배를 찾았다면, 해당 좌표에서 배를 삭제
ships[row][column] = 0;
// 히트 카운트 ++
hits++;
// 배를 찾았다고 알리고, 남은 배 수를 표시
cout << "Hit! " << (4-hits) << " left.\n\n";
} else {
// 배를 못 찾았다고 알림
cout << "Miss\n\n";
}
// 턴 수 ++
numberOfTurns++;
}
cout << "Victory!\n";
cout << "You won in " << numberOfTurns << " turns";

구조체 , Structures(struct) 는
다수의 서로 연관 있는 변수를 한 데 묶은 것이다.
구조체 안의 각 변수들은 member 로 여겨진다
"배열"과 다르게, 구조체는 변수 타입이 다르더라도 한 데 묶을 수 있다
ex) int string bool etc.
struct 키워드를 사용해,
{} 안에 구성원을 정의해주는 것으로 구조체를 만들 수 있다
또한 구조체의 "이름" 은 {} 안을 다 채운 뒤 마지막으로 적어준다
struct { // Structure declaration
int myNum; // Member (int variable)
string myString; // Member (string variable)
} myStructure; // Structure variable
구조체 안 member 에 접근하려면, . 구문을 사용한다
// Create a structure variable called myStructure
struct {
int myNum;
string myString;
} myStructure;
// Assign values to members of myStructure
myStructure.myNum = 1;
myStructure.myString = "Hello World!";
// Print members of myStructure
cout << myStructure.myNum << "\n"; // myStructure의.myNum
cout << myStructure.myString << "\n"; // myStructure의.myString
하나의 구조체를 여러 개 만들어서 사용하는 경우가 있는데 :
struct {
string brand;
string model;
int year;
} myCar1, myCar2; // 콤마를 써서 추가로 만들어줄 수 있다
// Put data into the first structure
myCar1.brand = "BMW";
myCar1.model = "X5";
myCar1.year = 1999;
// Put data into the second structure
myCar2.brand = "Ford";
myCar2.model = "Mustang";
myCar2.year = 1969;
// Print the structure members
cout << myCar1.brand << " " << myCar1.model << " " << myCar1.year << "\n";
cout << myCar2.brand << " " << myCar2.model << " " << myCar2.year << "\n";
구조체를 만들 때 "이름" 을 부여함으로써,
그 이름을 데이터 타입 처럼 활용할 수 있다
즉, 해당 구조체를 써서 변수를 생성할 수 있다.
struct car { // This structure is now named "car"
string brand;
string model;
int year;
};
이렇게 car 라는 구조체를 만듬으로써 =>
car myCar1;
car 타입 변수를 선언할 수 있게 된다
<성적표 만들기>
struct {
string name;
int age;
char grade;
} test;
name = "Liam";
age = 35;
grade = A;
cout << "Name: " << name << "Age: " << age << "Grade: " << grade;
예제를 만족하기 위해선
메인 함수 밖에서 구조체를 먼저 선언하고
메인 함수에서 구조체를 타입으로 만든 변수를 선언하고서
변수.구성원식으로 값을 할당해주고 출력...
하는 방식으로 진행해야했다.
#include <iostream>
#include <string>
using namespace std;
struct student {
string name;
int age;
char grade;
};
int main() {
student s1;
s1.name = "John";
s1.age = 35;
s1.grade = 'A';
cout << "Name: " << s1.name << "\n";
cout << "Age: " << s1.age << "\n";
cout << "Grade: " << s1.grade << "\n";
return 0;
}