C Programming Language/C++

C++11 ν‚€μ›Œλ“œ) nullptr(널포인터), auto(μ˜€ν† ), decltype(λ””ν΄νƒ€μž…), lvalue(μ’ŒμΈ‘κ°’)와 rvalue(μš°μΈ‘κ°’)

567Rabbit 2024. 8. 14. 20:15

nullptr (널포인터)

- 포인터 νƒ€μž…μ˜ μƒμˆ˜λ‘œ, 포인터가 μ–΄λ–€ μœ νš¨ν•œ λ©”λͺ¨λ¦¬ μ£Όμ†Œλ„ 가리킀지 μ•ŠμŒμ„ λͺ…μ‹œμ μœΌλ‘œ ν‘œν˜„ν•œλ‹€.

- 포인터가 μœ νš¨ν•œ λ©”λͺ¨λ¦¬ μ£Όμ†Œλ₯Ό 가리킀지 μ•Šμ„ λ•Œ μ‚¬μš©ν•˜λŠ” κ°’μœΌλ‘œ, 0μ΄λ‚˜ NULL을 λŒ€μ‹ ν•˜μ—¬ μ‚¬μš©λœλ‹€

- nullptrλ₯Ό μ‚¬μš©ν•˜λ©΄ ν•¨μˆ˜ μ˜€λ²„λ‘œλ”©μ—μ„œ λͺ…ν™•ν•˜κ²Œ νƒ€μž…μ„ ꡬ뢄할 수 μžˆλ‹€. μ΄λŠ” NULL이 μ •μˆ˜ν˜•μœΌλ‘œ μ·¨κΈ‰λ˜κΈ° λ•Œλ¬Έμ— λ°œμƒν•  수 μžˆλŠ” ν˜Όλ™μ„ ν”Όν•  수 μžˆλ‹€.

 

#include <iostream>

int main() {
    int* ptr = nullptr;

    if (ptr == nullptr) {
        std::cout << "Pointer is null" << std::endl;
    }

    // nullptrμ™€μ˜ λΉ„κ΅λŠ” νƒ€μž… μ•ˆμ „ν•˜κ²Œ μˆ˜ν–‰λ©λ‹ˆλ‹€.
    if (ptr != nullptr) {
        std::cout << "Pointer is not null" << std::endl;
    }

    return 0;
}

- ptr이 nullptrκ³Ό 비ꡐ할 λ•Œ, 비ꡐ μ—°μ‚°μžλŠ” 포인터 νƒ€μž…μ— 맞게 μ•ˆμ „ν•˜κ²Œ μˆ˜ν–‰λœλ‹€.

  μ΄λŠ” nullptrκ°€ 포인터 νƒ€μž…κ³Ό λͺ…ν™•νžˆ μ—°κ΄€λ˜μ–΄ 있기 λ•Œλ¬Έμ΄λ‹€.

 

 

 

auto (μ˜€ν† )

- νƒ€μž… 선언을 κ°„μ†Œν™”ν•˜μ—¬ μ½”λ“œλ₯Ό κ°„κ²°ν•˜κ²Œ ν•  수 μžˆλ‹€.

- λ³΅μž‘ν•œ νƒ€μž…μ΄λ‚˜ ν…œν”Œλ¦Ώ μ‚¬μš© μ‹œ μ•ˆμ „ν•˜κ²Œ νƒ€μž…μ„ μΆ”λ‘ ν•œλ‹€

- λ°˜λ³΅μžλ‚˜ λ³΅μž‘ν•œ νƒ€μž…μ˜ λ³€μˆ˜λ₯Ό μ‰½κ²Œ λ‹€λ£° 수 μžˆλ‹€.

- autoλ₯Ό μ‚¬μš©ν•˜λ©΄ λ³€μˆ˜μ˜ νƒ€μž…μ„ λͺ…μ‹œμ μœΌλ‘œ μ„ μ–Έν•˜μ§€ μ•Šκ³ , λ³€μˆ˜μ˜ μ΄ˆκΈ°κ°’μ— 따라 νƒ€μž…μ„ μžλ™μœΌλ‘œ μΆ”λ‘ ν•œλ‹€.

- λ³€μˆ˜μ˜ νƒ€μž…μ„ μ»΄νŒŒμΌλŸ¬κ°€ μžλ™μœΌλ‘œ μΆ”λ‘ ν•˜λ„λ‘ ν—ˆμš©ν•œλ‹€. 이λ₯Ό 톡해 μ½”λ“œμ˜ 가독성을 높이고, νƒ€μž… 선언을 κ°„μ†Œν™”ν•  수 μžˆλ‹€. autoλŠ” 특히 λ³΅μž‘ν•œ νƒ€μž…μ΄λ‚˜ ν…œν”Œλ¦Ώ μ‚¬μš© μ‹œ μ½”λ“œμ˜ μœ μ§€λ³΄μˆ˜μ„±μ„ ν–₯μƒμ‹œν‚€λŠ” 데 도움을 μ€€λ‹€.

 

 

<주둜 μ‚¬μš©λ˜λŠ” 상황>

 

1. 반볡자 (Iterators) μ‚¬μš©

#include <iostream>
#include <vector>

int main() {
    std::vector<int> vec = {1, 2, 3, 4, 5};

    // autoλ₯Ό μ‚¬μš©ν•˜μ—¬ 반볡자의 νƒ€μž…μ„ μžλ™μœΌλ‘œ μΆ”λ‘ 
    for (auto it = vec.begin(); it != vec.end(); ++it) {
        std::cout << *it << " ";
    }
    std::cout << std::endl;

    return 0;

- auto it = vec.begin();μ—μ„œ it의 νƒ€μž…μ€ std::vector<int>::iterator둜 μžλ™μœΌλ‘œ 좔둠됨

- 이λ₯Ό 톡해 반볡자의 νƒ€μž…μ„ λͺ…μ‹œμ μœΌλ‘œ μ„ μ–Έν•  ν•„μš”κ°€ μ—†μŒ

 

 

2. λ³΅μž‘ν•œ νƒ€μž…μ˜ λ³€μˆ˜ μ„ μ–Έ

#include <iostream>
#include <map>
#include <string>

int main() {
    std::map<std::string, int> my_map;
    my_map["apple"] = 3;
    my_map["banana"] = 5;

    // autoλ₯Ό μ‚¬μš©ν•˜μ—¬ 맡의 μš”μ†Œλ₯Ό 반볡
    for (auto& pair : my_map) {
        std::cout << pair.first << ": " << pair.second << std::endl;
    }

    return 0;
}

- auto& pair : my_mapμ—μ„œ pair의 νƒ€μž…μ€ std::pair<const std::string, int>둜 μžλ™μœΌλ‘œ 좔둠됨

- λ³΅μž‘ν•œ νƒ€μž…μ„ λͺ…μ‹œμ μœΌλ‘œ μ„ μ–Έν•  ν•„μš”κ°€ μ—†μ–΄ μ½”λ“œκ°€ 간결해짐

 

 

3. ν•¨μˆ˜ λ°˜ν™˜ νƒ€μž…

#include <iostream>
#include <vector>

auto getVector() -> std::vector<int> {
    return std::vector<int>{1, 2, 3, 4, 5};
}

int main() {
    auto vec = getVector(); // vecλŠ” std::vector<int>둜 좔둠됨

    for (const auto& element : vec) {
        std::cout << element << " ";
    }
    std::cout << std::endl;

    return 0;
}

- auto getVector() -> std::vector<int> κ΅¬λ¬Έμ—μ„œ ν•¨μˆ˜ getVector의 λ°˜ν™˜ νƒ€μž…μ„ auto와 ν›„ν–‰ λ°˜ν™˜ νƒ€μž… ν‘œκΈ°λ²•μœΌλ‘œ 지정

- auto vec = getVector();μ—μ„œ vec의 νƒ€μž…μ€ std::vector<int>둜 μžλ™μœΌλ‘œ 좔둠됨

 

 

auto의 단점

  • λͺ…ν™•μ„±: νƒ€μž… 좔둠이 μ˜ˆμƒκ³Ό λ‹€λ₯Ό 수 있으며, μ΄ˆκΈ°κ°’μ΄ ν•„μš”ν•˜λ‹€
  • 가독성: κ³Όλ„ν•œ μ‚¬μš©μ€ μ½”λ“œμ˜ 가독성을 μ €ν•˜μ‹œν‚¬ 수 μžˆλ‹€.

 

 

 

decltype (λ””ν΄νƒ€μž…)

- λ³€μˆ˜λ‚˜ ν‘œν˜„μ‹μ˜ νƒ€μž…μ„ μΆ”λ‘ ν•˜λŠ” 경우 μ‚¬μš©λ¨

- λ³€μˆ˜ μ„ μ–Έμ—μ„œ νƒ€μž…μ„ λͺ…μ‹œμ μœΌλ‘œ 지정할 ν•„μš” 없이, ν‘œν˜„μ‹μ˜ νƒ€μž…μ„ μžλ™μœΌλ‘œ μΆ”λ‘ ν•  수 있게 ν•΄μ€€λ‹€.

- 이 κΈ°λŠ₯은 νƒ€μž… 좔둠을 톡해 더 μœ μ—°ν•˜κ³  μ•ˆμ „ν•œ μ½”λ“œ μž‘μ„±μ„ 지원

- autoμ™€μ˜ μ°¨μ΄μ μœΌλ‘œλŠ”, decltypeλŠ” ν‘œν˜„μ‹μ˜ νƒ€μž…μ„ μΆ”λ‘ ν•˜μ—¬ λ³€μˆ˜λ‚˜ ν•¨μˆ˜μ˜ νƒ€μž…μ„ μžλ™μœΌλ‘œ κ²°μ •ν•œλ‹€λŠ” 점이닀.

 

decltype(expression) variable_name;

: expression의 νƒ€μž…μ΄ variable_name에 ν• λ‹Ήλœλ‹€.

 

 

1. λ³€μˆ˜μ˜ νƒ€μž… μΆ”λ‘ 

#include <iostream>

int main() {
    int x = 10;
    decltype(x) y = 20;  // y의 νƒ€μž…μ€ int둜 좔둠됨

    std::cout << "y: " << y << std::endl;

    return 0;
}
  • decltype(x) y = 20;μ—μ„œ decltype(x)λŠ” x의 νƒ€μž…μ„ μΆ”λ‘ ν•˜λ―€λ‘œ, y의 νƒ€μž…μ€ intκ°€ λœλ‹€

 

2. ν•¨μˆ˜μ˜ λ°˜ν™˜ νƒ€μž… μΆ”λ‘ 

#include <iostream>

int add(int a, int b) {
    return a + b;
}

decltype(add(1, 2)) subtract(int a, int b) {
    return a - b;
}

int main() {
    auto result = subtract(10, 5);  // result의 νƒ€μž…μ€ int둜 좔둠됨
    std::cout << "Result: " << result << std::endl;

    return 0;
}
  • decltype(add(1, 2))λŠ” add ν•¨μˆ˜μ˜ λ°˜ν™˜ νƒ€μž…μ„ μΆ”λ‘ . subtract ν•¨μˆ˜λŠ” add와 같은 λ°˜ν™˜ νƒ€μž…μ„ κ°€μ§€λ―€λ‘œ, resultλŠ” int νƒ€μž…μœΌλ‘œ μΆ”λ‘ λœλ‹€

 

3. λ³΅μž‘ν•œ ν‘œν˜„μ‹μ˜ νƒ€μž… μΆ”λ‘ 

#include <iostream>
#include <vector>

int main() {
    std::vector<int> vec = {1, 2, 3, 4, 5};

    // autoλ₯Ό μ‚¬μš©ν•˜μ—¬ 반볡자 νƒ€μž… μΆ”λ‘ 
    auto it = vec.begin();

    // decltype을 μ‚¬μš©ν•˜μ—¬ 반볡자 νƒ€μž… μΆ”λ‘ 
    decltype(vec.begin()) it2 = vec.begin();

    std::cout << "Using auto: " << *it << std::endl;
    std::cout << "Using decltype: " << *it2 << std::endl;

    return 0;
}
  • auto it = vec.begin();와 decltype(vec.begin()) it2 = vec.begin();μ—μ„œ it와 it2λŠ” std::vector<int>::iterator νƒ€μž…μœΌλ‘œ 좔둠됨

 

4. ν•¨μˆ˜μ™€ λžŒλ‹€ ν‘œν˜„μ‹μ˜ νƒ€μž… μΆ”λ‘ 

#include <iostream>
#include <functional>

int main() {
    // λžŒλ‹€ ν‘œν˜„μ‹ μ •μ˜
    auto lambda = [](int a, int b) { return a + b; };

    // decltype을 μ‚¬μš©ν•˜μ—¬ λžŒλ‹€μ˜ νƒ€μž… μΆ”λ‘ 
    decltype(lambda) another_lambda = [](int a, int b) { return a - b; };

    std::cout << "Lambda result: " << lambda(5, 3) << std::endl;
    std::cout << "Another lambda result: " << another_lambda(5, 3) << std::endl;

    return 0;
}
  • decltype(lambda)λŠ” λžŒλ‹€ ν‘œν˜„μ‹μ˜ νƒ€μž…μ„ μΆ”λ‘ . another_lambdaλŠ” λ™μΌν•œ νƒ€μž…μ˜ λžŒλ‹€λ‘œ μ •μ˜λ¨

 

 

 

decltype(x)와 decltype((x))의 차이

 

은 C++μ—μ„œ ν‘œν˜„μ‹μ˜ νƒ€μž…μ„ μΆ”λ‘ ν•  λ•Œ μ‚¬μš©λ˜μ§€λ§Œ, 이 두 κ°€μ§€λŠ” νƒ€μž… 좔둠에 μžˆμ–΄ μ€‘μš”ν•œ 차이점이 μžˆλ‹€.

이 차이점은 특히 λ³€μˆ˜μ˜ νƒ€μž…μ΄ 참쑰인 κ²½μš°λ‚˜ ν‘œν˜„μ‹μ΄ 볡합적인 κ²½μš°μ— μ€‘μš”ν•œ 역할을 함

 

  1. decltype(x):
    • xκ°€ μ°Έμ‘° νƒ€μž…μ΄ μ•„λ‹ˆλ©΄ x의 νƒ€μž…μ„ κ·ΈλŒ€λ‘œ μΆ”λ‘ ν•©λ‹ˆλ‹€.
    • xκ°€ μ°Έμ‘° νƒ€μž…μ΄ μ•„λ‹ˆλ©΄ decltype(x)λŠ” x의 μ‹€μ œ νƒ€μž…μ„ λ°˜ν™˜ν•©λ‹ˆλ‹€.
  2. decltype((x)):
    • xκ°€ μ°Έμ‘° νƒ€μž…μ΄λΌλ©΄, decltype((x))λŠ” μ°Έμ‘° νƒ€μž…μ„ ν¬ν•¨ν•©λ‹ˆλ‹€.
    • xκ°€ μ°Έμ‘° νƒ€μž…μ΄ μ•„λ‹ˆλΌλ©΄, decltype((x))λŠ” xλ₯Ό κ΄„ν˜Έλ‘œ κ°μ‹Έμ„œ ν‘œν˜„μ‹μœΌλ‘œ μ·¨κΈ‰ν•˜λ―€λ‘œ x의 νƒ€μž…μ΄ μ°Έμ‘°κ°€ μ•„λ‹Œ νƒ€μž…μœΌλ‘œ μΆ”λ‘ λ©λ‹ˆλ‹€.

정리:

  • decltype(x)λŠ” λ‹¨μˆœνžˆ λ³€μˆ˜ x의 νƒ€μž…μ„ μΆ”λ‘ 
  • decltype((x))λŠ” xλ₯Ό ν‘œν˜„μ‹μœΌλ‘œ 닀루며, x의 μ°Έμ‘° νƒ€μž…μ„ ν¬ν•¨ν•˜λŠ” κ²½μš°κ°€ 있음

 

 

 

lvalue와 rvalue

 

lvalue:

  • λ©”λͺ¨λ¦¬μ˜ νŠΉμ • μœ„μΉ˜λ₯Ό κ°€λ¦¬ν‚€λŠ” ν‘œν˜„μ‹μœΌλ‘œ, κ·Έ μœ„μΉ˜μ—μ„œ 값을 μ½κ±°λ‚˜ μ“Έ 수 μžˆλ‹€. λŒ€μž… μ—°μ‚°μžμ˜ μ’ŒμΈ‘μ— μœ„μΉ˜ 
    • μœ„μΉ˜: λ©”λͺ¨λ¦¬μ˜ νŠΉμ • μœ„μΉ˜λ₯Ό 가리킴.  값을 읽고 μ“Έ 수 μžˆλŠ” μœ„μΉ˜ (μ’ŒμΈ‘μ— μœ„μΉ˜).
    • 예: λ³€μˆ˜, λ°°μ—΄μ˜ μš”μ†Œ.
    • μ˜ˆμ‹œ: int x = 5; x = 10;μ—μ„œ xλŠ” lvalue
    • λ©”λͺ¨λ¦¬μ˜ μœ„μΉ˜λ₯Ό μ°Έμ‘°ν•  수 μžˆλŠ” κ°’μœΌλ‘œ, 주둜 λ³€μˆ˜λ‚˜ 객체의 멀버λ₯Ό λ‚˜νƒ€λ‚Έλ‹€. 

 

rvalue:

  • μž„μ‹œ 값을 λ‚˜νƒ€λ‚΄λŠ” ν‘œν˜„μ‹μœΌλ‘œ, κ·Έ 값을 읽을 수만 있으며, μ§μ ‘μ μœΌλ‘œ 값을 μ“Έ μˆ˜λŠ” μ—†λ‹€.λŒ€μž… μ—°μ‚°μžμ˜ μš°μΈ‘μ— μœ„μΉ˜
    • μœ„μΉ˜: μž„μ‹œ(μΌμ‹œ)적인 κ°’. λ©”λͺ¨λ¦¬ μœ„μΉ˜κ°€ μ—†κ³ , κ°’λ§Œ μ‘΄μž¬ν•œλ‹€. μž„μ‹œμ μΈ κ°’ (μš°μΈ‘μ— μœ„μΉ˜).
    • 예: λ¦¬ν„°λŸ΄, μ—°μ‚° κ²°κ³Ό.
    • μ˜ˆμ‹œ: x + 5 λ˜λŠ” 10은 rvalue
    • μž„μ‹œμ μ΄λ©° λ©”λͺ¨λ¦¬ μœ„μΉ˜λ₯Ό 가지지 μ•ŠλŠ” κ°’μœΌλ‘œ, 주둜 μƒμˆ˜λ‚˜ μ—°μ‚° κ²°κ³Όλ₯Ό λ‚˜νƒ€λ‚Έλ‹€.
int x = 10; // 10은 rvalue 
x = x + 5; // x + 5λŠ” rvalue