C++ 프로그래밍 기초 2

김여울·2025년 5월 28일

내일배움캠프

목록 보기
9/139

💭
어제에 이어 오늘 아침 라이브 세션도 알고리즘 특강이었다. 뇌를 컴퓨터처럼 만드는 느낌이다. 아직은 그 사고 흐름이 낯설어서 한 번 더 강의를 들어야 할 것 같다. 코드 카타도 풀었지만 자꾸 막혀서 얼른 C++ 강의를 들어야겠다... 문제를 풀면서 새로 알게 된 것도 많아서 정리해두면 좋을 것 같다. 저녁에는 17조 팀 레포를 만들고 동휘님께 VS Code 설명도 들었다.

/ 몫 구하기
% 나머지 구하기

// programmers 120806 - 두 수의 나눗셈

#inclue <iostream>

int solution(int num1, int num2)
{	// 정확한 계산을 위해 num1을 형변환 
	double result = (double)num1 / num2 * 1000;   // double -> 소수점까지 
    return (int)result;
}
// 하나만 형 변환 -> 나머지는 자동 변환
// programmers 120807 - 숫자 비교하기

#inclue <iostream>

int solution(int num1, int num2)
{
    if(num1 == num2)
    {
        return 1;
    }
    else    // if나 else if에서 모든 조건 검사한 후 남은 경우 처리 용도 -> 조건 없음
    {
        return -1;
    }
}
// programmers 120829 - 각도기

#include <iostream>

int solution(int angle) 
{
    if (angle < 90) 
    {
        return 1; 
    } 
    else if (angle == 90) 
    {
        return 2; 
    } 
    else if (angle < 180) 
    {
        return 3; 
    } 
    else if (angle == 180)
    {
        return 4; 
    }
}

// if(0 < angle < 90) <- 두 개 이상의 비교를 한 줄에 쓸 수 없음
// if(0 < angle && angle < 90) <- 연산자를 이용해해 한 줄에 쓸 수 있음
// else 없이 else if 여러 개 사용 가능

~ 1강 127분
📎강의 자료 + 필기

선언

1️⃣ 함수를 먼저 정의하는 이유

함수들을 먼저 정의하고 int main()을 쓴다.
main() 함수는 프로그램의 시작점이기 때문에 main() 안에서 다른 함수를 부르려면 그 함수가 이미 정의돼 있어야 한다.

2️⃣ using namespace std;

이름이 겹치는 걸 막기 위한 이름공간(namespace)

std::cout << "Hello!";

std Standard(표준)의 줄임말
cout 표준 출력 도구인데 std라는 이름공간에 들어있다

std::cout 쓰기 귀찮아서

using namespace std;

cout << "Hello!";

➡️ 이제 std:: 안 붙여도 된다

🧩 std 네임스페이스 구조

+---------------------+
|  namespace std      |
|---------------------|
|  cout               |
|  cin                |
|  endl               |
|  vector             |
|  string             |
|  map                |
|  ...등등            |
+---------------------+

배열

1️⃣ 정의

  • 하나의 이름으로 동일한 타입의 변수를 여러 개 관리 가능
  • 목적이 같으므로 하나로 관리하기 위해 배열 사용
  • int arr[4] int 타입 변수 4개를 담는 배열
    • arr[0]이 맨 처음 원소, arr[3]이 마지막 원소
    • arr[4] 같은 범위를 벗어난 접근은 에러 발생 가능

2️⃣ 특징

  • 변수처럼 선언과 동시에 초기화, 선언 후 추기화, 선언만 모두 가능
  • 통째로 복사나 대입 불가능 / 개별 원소를 복사하는 것은 가능
  • 배열의 각 원소는 변수랑 동일하므로 cincout 통해 입출력 가능
#include <iostream>
using namespace std;

// 배열 선언과 초기화 예제
int main() {
    // 선언과 동시에 초기화
    int arr1[3] = {1, 2, 3};

    // 선언 후 개별 원소 초기화
    int arr2[3];
    arr2[0] = 10;
    arr2[1] = 20;
    arr2[2] = 30;

    // 배열 출력
    cout << "arr1: " << arr1[0] << ", " << arr1[1] << ", " << arr1[2] << endl;
    cout << "arr2: " << arr2[0] << ", " << arr2[1] << ", " << arr2[2] << endl;

    return 0;
}

/*
출력 예시:
arr1: 1, 2, 3
arr2: 10, 20, 30
*/
#include <iostream>
using namespace std;

// 배열의 복사 및 대입 불가능한 예제
int main() {
    int arr1[3] = {1, 2, 3};
    int arr2[3];

    // 개별 원소를 복사하는 것은 가능
    for (int i = 0; i < 3; i++) {
        arr2[i] = arr1[i];
    }

    // 배열 통째로 대입 (불가능, 주석 처리)
    // arr2 = arr1;  // 컴파일 오류 발생

    // 복사된 배열 출력
    cout << "arr2: " << arr2[0] << ", " << arr2[1] << ", " << arr2[2] << endl;

    return 0;
}

/*
출력 예시:
arr2: 1, 2, 3
*/

함수

함수를 정의하고 호출하면 코드를 길게 쓰지 않음 ➡ 가독성이 좋음
기존에 사용했던 코드를 수정 없이 계속 사용 가능 ➡ 재사용성 높음

1️⃣ 작업의 구성요소

  1. 인자
    작업에 사용되는 외부 값

  2. 동작
    어떤 작업을 수행할지 정의

int add(int a, int b)  
// int a, int b <- 인자 
// add가 동작
  1. 반환
  • return 값;
  • 최종적으로 외부에 전달할 값
  • 함수의 반환 타입
    • 함수가 결과로 어떤 값 하나를 돌려주는지 그 값의 종류(자료형)
    • 함수가 return으로 보내는 값의 '자료형'
    • 반환타입을 void로 하면 아무 값도 돌려주지 않음
// 기본 구조

반환타입 함수이름(매개변수들)
{
    return 반환값;
}
int GetHealth()     // int가 반환 타입
{
    return 100;    // 이 함수는 100이라는 int를 결과로 내보냄
}
  1. 이름
    이 작업을 호출할 수 있도록 이름을 정함
// 목적: 두 개의 정수를 더하는 함수 정의 및 호출 예제
#include <iostream>
using namespace std;

// 두 정수를 더하는 함수
int add(int a, int b) {
    return a + b; // 결과 반환 -> 함수를 위한 공간이 반납됨 -> 메모리 공간에서 사라짐
}

int main() {
    int result = add(3, 7);
    cout << "3 + 7 = " << result << endl; // 출력: 3 + 7 = 10
    return 0;
}

2️⃣ void

  • 아무 값도 돌려주지 않음 = return값 ❌
  • 그냥 일만 하고 끝남
  • 반환값 없이 특정 메세지 출력
  • 을 반환하지 않기 때문에 return;만 사용
void f()
{
	// 코드 1
	return;
	
	// 코드2   -   실행되지 않음!
}
// 이 때는 함수를 종료시키라는 의미로 return 사용 가능
// 코드1만 실행되고 빠져나옴

3️⃣ 값을 전달하는 방식

값 전달 (일반 변수)

일반적인 변수(값 타입 변수)는 값을 복사해 함수로 전달
함수 내부에서 값 변경해도 원본 변수 값은 변경 ❌

#include <iostream>
using namespace std;

// 함수: 값 전달 (Call by Value)
void modifyValue(int x) {
    x = 100;  // 함수 내부에서 값 변경
}

int main() {
    int num = 50;
    modifyValue(num); // 값 전달 (복사됨)
    
    cout << "값 전달 후 num: " << num << endl;
    // 출력: 값 전달 후 num: 50
    return 0;
}
  1. modifyValue 함수로 호출하면 함수를 위한 독립적 공간 x가 새로 생김

  2. 그 공간에 num 안에 있는 값을 인자로 넘김
    📦 num -> [50]
    📦 x -> [50] <- 복사됨
    x = 100 으로 바꿔도 num 은 그대로 50

  3. 이때 num을 그대로 활용하는게 아니라 num 안에 있는 값을 인자에 복사해서 사용

  4. 인자는 독립된 공간을 갖음 = int num

  5. 함수가 종료되면 함수를 위한 공간이 사라져(메모리에서 없어짐) int num은 그대로 있음

주소값 전달 (변수)

값이 아닌 주소값을 함수에 전달 ➡ 해당 변수에 접근 가능
함수가 종료된 후에도 해당 주소의 변수는 값이 수정되어 있음⭕

#include <iostream>
using namespace std;

// 함수: 포인터를 사용한 값 변경
void modifyValue(int* ptr) {
    *ptr = 100;  // 포인터가 가리키는 변수의 값을 변경
}

int main() {
    int num = 50;
    modifyValue(&num); // num의 주소 전달

    cout << "포인터 전달 후 num: " << num << endl;
    // 출력: 포인터 전달 후 num: 100
    return 0;
}

(&num) : 주소값을 전달
1. num의 주소값인 28이 넘어감
2. 주소값에 접근해 num을 수정 할 수 있음
3. 함수가 종료되고 변수가 사라져도 num 값이 변경된 채로 남음

ptr 사용
1. 50이 아닌 num의 주소가 넘어감
2. 그 주소값을 따라가서 값을 바꿔라
3. 함수가 종료되어도 실제 값은 100으로 바뀜

구분전달 내용함수 안에서 값 변경하면?
값 전달값만 복사 (num → x)원본(num)은 변하지 않음
주소 전달주소를 전달 (&num → ptr)원본(num)이 변할 수 있음

주소값 전달 (배열)

배열의 주소값을 함수에 전달 ➡ 해당 배열에 접근 가능
함수 종료 이후 해당 배열의 값 수정되어 있음

❓배열은 함수의 인자를 어떻게 넘기나
함수의 배열을 넘기면 시작주소가 넘어감 <- 실제 배열의 주소값 정보
➡ 인자로 넘긴 배열들의 값을 실제로 변경 가능
➡ 함수 끝나도 변경된 채로 있음

#include <iostream>
using namespace std;

// 함수: 포인터를 사용한 값 변경
void modeifyArr(char* ptr) {
    ptr[0] = 'X';  // 포인터가 가리키는 변수의 값을 변경
}

int main() {
    char str[4] = {'A', 'B', 'C', 'D'};
    modeifyArr(str); // num의 주소 전달

    cout << "포인터 전달 후 str[0] = " << str[0] << endl;
    // 출력: 포인터 전달 후 str[0] = X
    return 0;
}

참조자 전달

참조자로 값 전달 ➡ 함수 내부에서 값 변경 ➡ 원본 변수의 값도 변경됨
참조자 = 어떤 변수의 별명

변수의 값을 수정하고 대입하는 걸 기존 변수의 문법을 그대로 활용함
특별한 문법 없음
하지만 어떤 변수의 별명이 된 이상, 다른 변수의 별명이 될 수 없음

메모리 공간에 num으로도, x로도 접근 가능
함수가 종료되면 x라는 레퍼런스는 없어지지만 main()에 있던 num값은 수정됨

#include <iostream>
using namespace std;

// 함수: 참조를 사용한 값 변경
void modifyValueByReference(int& x)  // x는 레퍼런스 (별명)
{
    x = 200;  // 참조를 사용하여 원본 값 변경
}

int main() {
    int num = 50;
    modifyValueByReference(num); // 참조 전달

    cout << "참조 전달 후 num: " << num << endl;
    // 출력: 참조 전달 후 num: 200
    return 0;
}

0개의 댓글