[ 문제 ]

#include <iostream>
#include <vector>
using namespace std;
 
 
//정수 벡터 v의 모든 원소 합을 반환하는 
//long long sum(const vector<int>& v)를 작성하시오.
//비어 있으면 0.
 
long long sum(const vector<int>& v) 
{
    // 여기에 답안을 작성해주세요.
 
}
 
int main() {
    vector<int> v{ 3, 6, 7, 9 };
    cout << sum(v) << "\n"; // 25
}

[ 개념 ]

1. const 참조자 (const vector<int>& v)

함수의 매개변수를 유심히 보시면 & 기호와 const가 붙어 있습니다.

  • 참조자 (&): 벡터의 크기가 클 때, 데이터를 통째로 복사하면 메모리와 시간 낭비가 심하겠죠? 원본 데이터를 그대로 가리켜서 효율을 높이는 개념입니다.

  • const: 원본을 가져다 쓰되, 함수 내부에서 실수로 벡터의 값을 변경하지 못하도록 읽기 전용으로 안전장치를 걸어둔 것입니다.

2. 범위 기반 for 문 (Range-based for loop) 또는 반복자 (Iterator)

벡터의 모든 원소를 처음부터 끝까지 순회하며 접근해야 합니다.

  • 전통적인 for(int i = 0; i < v.size(); i++) 방식을 사용할 수도 있지만, C++11부터 도입된 범위 기반 for 문을 사용하면 훨씬 깔끔하게 벡터의 모든 요소에 접근할 수 있습니다.

3. 데이터 타입의 범위와 오버플로우 (Data Type Overflow)

매개변수로 받는 벡터는 int형 데이터들을 담고 있지만, 함수가 반환하는 타입은 long long입니다.

  • int형 정수들을 아주 많이 더하다 보면, int가 표현할 수 있는 숫자의 한계를 넘어서는 오버플로우(Overflow)가 발생할 수 있습니다.

  • 더 큰 정수를 담을 수 있는 long long 타입을 반환 타입과 누적 합 변수에 왜 사용해야 하는지 이해하는 것이 중요합니다.


범위 기반 for문

  1. 전통적 for문
    #include <iostream> 
    using namespace std; 
    int main() { int sum = 0; 
    // 합을 저장할 변수 초기화 
    for (int i = 1; i <= 10; i++) 
    { 
    // 초기화: i = 1 
    // 종료 조건: i <= 10 
    // 사후 동작: i++ sum += i; 
    // 실제 동작: sum에 i를 더함 
    } cout << "Sum: " << sum << endl; 
    // 출력: 합계 출력 // 출력값: Sum: 55 
    return 0; }
     
  2. 범위 기반 for문
    vector<int> v = {10, 20, 30};
     
     for (int x : v) 
     {
         cout << x << " "; 
     }
     // 출력 결과: 10 20 30

long long 타입 핵심 요약

  1. long long 메모리 크기: 8 Byte (64 bit) int의 메모리 크기 : 4 Byte / 32 bit
  2. 리터럴 접미사 LL 사용
    long long big_number = 100000000000LL; // 뒤에 LL을 붙여 long long형 숫자임을 명시

참조자(&)

: 원본을 복사하지 않고 직접 참조해서 사용

  1. 함수에서 원본을 직접 사용하기 위해 사용
    void addOne(int& n)
     {
         n++;
     }
     
     int x = 5;
     addOne(x);
     
     cout << x; // 6

2.큰데이터를 복사하지 않기 위해 사용

void print(const vector<int>& v)  
{  
cout << v[0];  
}
//만약 &가 없으면
 
vector<int> nums(1000000);
print(nums);

3.포인터와 비교

int a = 10;
 
int* p = &a;   // 포인터
 
int& r = a;    // 참조자
//참조자가 문법이 더 간단해서 함수 매개변수에서 많이 사용
//참조자(`&`)는 변수의 별명을 만들어 복사 없이 원본 데이터를 직접 사용할 수 있게 해주는 기능

const

: 참조는 가능하지만 값을 수정할 수 없음

vector<int> nums = {1, 2, 3};  
  
void func(const vector<int>& v) {  
// v.push_back(4); // 오류! const라 수정 불가  
cout << v[0]; // 읽기만 가능  
}

[ 풀이 ]

#include <iostream>
#include <vector>
using namespace std;
 
//정수 벡터 v의 모든 원소 합을 반환하는 
//long long sum(const vector<int>& v)를 작성하시오.
//비어 있으면 0.
 
long long sum(const vector<int>& v) 
{
	long long sum1 = 0;
	
	for(int x : v)
	{
		sum1 += x;
		
	}
	return sum1;
}
 
int main() {
    vector<int> v{ 3, 6, 7, 9 };
    cout << sum(v) << "\n"; // 25
}
 
#include <iostream>
#include <vector>
using namespace std;
 
 
//정수 벡터 v의 모든 원소 합을 반환하는 
//long long sum(const vector<int>& v)를 작성하시오.
//비어 있으면 0.
 
long long sum(const vector<int>& v) 
{
	long long sum1=0;
	for(int i=0; i < v.size(); i++)
	{
		sum1 += v[i];
	}
	return sum1;
}
 
int main() {
    vector<int> v{ 3, 6, 7, 9 };
    cout << sum(v) << "\n"; // 25
}

[ 해설 ]

#include <iostream> // cout 사용을 위한 헤더
#include <vector>   // vector 사용을 위한 헤더
 
using namespace std;
 
// 정수 벡터의 모든 원소를 더한 값을 반환하는 함수
// const : 함수 안에서 벡터를 수정하지 않겠다는 의미
// &     : 벡터를 복사하지 않고 원본을 참조하여 성능 향상
// long long : 합계가 int 범위를 넘을 수 있으므로 더 큰 자료형 사용
long long sum(const vector<int>& v)
{
    // 합계를 저장할 변수
    // 처음에는 아무것도 더하지 않았으므로 0으로 초기화
    long long sum1 = 0;
 
    // 범위 기반 for문(range-based for)
    // v 벡터의 원소를 처음부터 끝까지 하나씩 x에 저장하며 반복
    //
    // 1회전 : x = 3
    // 2회전 : x = 6
    // 3회전 : x = 7
    // 4회전 : x = 9
    for (int x : v)
    {
        // 현재 원소를 합계에 누적
        //
        // 1회전 : sum1 = 0 + 3 = 3
        // 2회전 : sum1 = 3 + 6 = 9
        // 3회전 : sum1 = 9 + 7 = 16
        // 4회전 : sum1 = 16 + 9 = 25
        sum1 += x;
    }
 
    // 반복이 끝난 후 최종 합계를 반환
    return sum1;
}
 
int main()
{
    // 정수 4개를 가진 벡터 생성
    vector<int> v{ 3, 6, 7, 9 };
 
    // sum 함수 호출
    // v의 모든 원소를 더한 결과를 출력
    //
    // 3 + 6 + 7 + 9 = 25
    cout << sum(v) << "\n";
 
    return 0;
}
#include <iostream> // cout 사용
#include <vector>   // vector 사용
 
using namespace std;
 
// 정수 벡터 v의 모든 원소의 합을 반환하는 함수
//
// const : 함수 내부에서 v를 수정하지 않음
// &     : 벡터를 복사하지 않고 원본을 참조함
// long long : 합계가 커질 수 있으므로 사용
long long sum(const vector<int>& v)
{
    // 원소들의 합을 저장할 변수
    // 처음에는 합계가 없으므로 0으로 초기화
    long long sum1 = 0;
 
    // i를 0부터 시작하여
    // 벡터의 마지막 인덱스 전까지 반복
    for (int i = 0; i < v.size(); i++)
    {
        // v[i] : i번째 원소
        //
        // i = 0 → v[0] = 3
        // i = 1 → v[1] = 6
        // i = 2 → v[2] = 7
        // i = 3 → v[3] = 9
        //
        // 각 원소를 sum1에 누적
        sum1 += v[i];
 
        /*
        반복 과정
 
        i=0 : sum1 = 0 + 3 = 3
        i=1 : sum1 = 3 + 6 = 9
        i=2 : sum1 = 9 + 7 = 16
        i=3 : sum1 = 16 + 9 = 25
        */
    }
 
    // 최종 합계 반환
    return sum1;
}
 
int main()
{
    // 정수 4개를 가진 벡터 생성
    vector<int> v{ 3, 6, 7, 9 };
 
    // sum 함수 호출 후 결과 출력
    // 3 + 6 + 7 + 9 = 25
    cout << sum(v) << "\n";
 
    return 0;
}