25.05.23 (3) - C++ Tutorial 5

김영하·2025년 5월 23일

C++

목록 보기
5/32

C++ Tutorial


C++ Arrays

배열

배열 은 "하나의 변수에 여러 개의 값을 넣고 싶을 때 사용한다"
배열 을 정의 하기 위해선,
기본처럼 변수 타입을 지정하고, 변수 이름을 적은 뒤
[] 와 함께 몇 개의 요소를 담을 것인지 정해준다

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 루프

앞서 배운 foreach 루프는,
배열의 요소를 순환하는 데 특화되어 있다 (vectorlist 도 가능)

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바이트)


sizeof()를 루프에 활용하기

이를 통해서 루프문의 조건 부분을 바꿔줄 수 있는데
기존의 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";


C++ Structures (struct)

C++ 구조체

구조체 , 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 타입 변수를 선언할 수 있게 된다


예제

<성적표 만들기>

  • 이름 (string)
  • 나이 (int)
  • 등급 (char)
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;
}
profile
내일배움캠프 Unreal 3기

0개의 댓글