Notice
Recent Posts
Recent Comments
Link
«   2025/05   »
1 2 3
4 5 6 7 8 9 10
11 12 13 14 15 16 17
18 19 20 21 22 23 24
25 26 27 28 29 30 31
Archives
Today
Total
관리 메뉴

메모장

열혈 C++ 복습 2 본문

C++ 복습

열혈 C++ 복습 2

Captic 2019. 11. 17. 18:39

♨ 개인적 해석이 다분한 글임으로, 인지하지 못한 오류가 있을 수 있습니다 

교재 - <윤성우 열혈 C++ 프로그래밍>

 

▣ C언어 용어/개념 복습

 - const 키워드 : 변수를 상수화 / 상수화된 변수는 저장된 값을 변경할 수 없다

 - 실행중인 프로그램의 메모리 공간 : 데이터/스택/힙

    데이터 : 전역변수가 저장되는 공간

    스   택 : 지역변수 및 매개변수가 저장되는 영역

       힙    : malloc 함수호출에 의해 프로그램이 실행되는 과정에서 동적으로 할당되는 영역

       -> malloc과 free : malloc은 동적으로 메모리 할당 / free는 할당된 영역 해제

 

▣ 새로운 자료형 bool

- ture / false : 얘네로 그냥 참/거짓 표현 가능 ( 기본적으로 0을 거짓, 나머지 정수를 참을 의미)

- bool변수의 크기는 1byte

 

▣ 참조자(Reference)의 이해

 - 변수 = 할당된 메모리에 붙여진 이름  ∴ 변수를 통해서 해당 메모리에 접근 가능

 - " & " 를 이용하여 이미 할당한 변수 이외의 다른 이름을 해당 메모리에 붙일 수 있다

 예)

-> 변수(num1)와 참조자(num2) 모두 같은 공간을 의미하기 때문에 참조자를 이용해서 값을 변경할 수 있다

    ∴ 참조자 = 자신이 참조하는 변수를 대신할 수 있는 다른 이름

 

 - 대신 참조자는 변수를 대상으로만 선언이 가능하다, 선언 후에는 변수와 같은 역할을 수행할 수 있다

   (지역/전역의 구분도 동일하게 적용된다)

 - 참조자 수에는 제한이 없다 -> 한 개의 변수에 여러개의 참조자를 붙일 수 있다

 - 참조자를 대상으로한 참조자를 선언할 수도 있다. 그러나 참조자는 선언과 동시에 변수를 참조해야만 한다

  -> int &ref = 20;    (X) : 변수가 아닌 상수를 참조할 수 없다

      int &ref;            (X) : 선언만하고 참조를 나중에할 수 없다

      int &ref = NULL (X) : NULL값도 안된다

      int &ref = arr[3] (O) : 배열요소는 변수로 간주되어 참조 가능하다

 

▣ 참조자(레퍼런스)와 함수

 - Call-by-value 와 Call-by-reference

  -> Call-by-value : 값을 인자로 전달하는 함수의 호출방식

      Call-by-reference : 주소 값을 인자로 전달하는 함수의 호출방식

 - 여기서 reference가 그 레퍼런스

 예) 

 -> 주소 값이 외부 변수의 "참조"도구로 사용되는 함수의 호출

     주소를 인자로 받는다?               -> 아른모직다

     주소를 받아 참조도구로 사용한다 -> Call-by-reference

 

 - 함수 외부에 선언된 변수의 접근 방법

   1. 주소 값을 이용한다

   2. 레퍼런스(참조자)를 이용한다

 

 - 참조자를 이용한 Call-by-reference

 예)

->매개변수에 있는 두 참조자의 선언은 사실 인자로 받은 변수들로 각각을 초기화하겠다는 뜻

  (실제로 SwapByRef(val1, val2)가 실행되면 int &ref1 = val1, int &ref2 = val2 로 실행된다)

 

 - 참조자를 이용한 Call-by-reference의 단점

 -> 위와 같이 참조자를 이용한 Call-by-reference함수가 있다면 호출부만 보고서 판단하기 어려워 진다

     즉, 해당 함수의 원형을 확인해야 하고, 매개변수에 참조자가 선언되었다면

     함수의 정의부까지 가서 확인해봐야 한다

 - 이에 대한 대안으로 함수 선언부 매개변수에 const를 두어 함수 선언부만 보고 값이 변경되지 않다는 것을 보여준다

 예)  void NoSwap(const int &num);  -> 참조자 num에 의해서 값이 변경되지 않는다

 

- 반환형이 참조형(Reference Type)인 경우

예) 

-> 순서대로 파악해보면

   1) num1을 1로 초기화 한다

   2) RefRetFuncOne함수를 이용해 num1의 주소에 있는 값(1)에 +1을 한 후

      그 값을 레퍼런스 num2에 초기화한다 

     (∴ num1의 주소 = num2의 주소)

   3) num1++

   4) num2++ (num1의 주소에 있는 값++ = num1++)

   5) 그래서 num1과 num2의 출력값은 동일하다

 => 결정적으로 int형 변수는 단 1개이고 나머지는 레퍼런스, 매개변수에 선언된 레퍼런스 임으로

      결국 1개의 4byte 메모리 공간에 대해서만 작업한 것

 

또 다른 예)

-> 이번에도 순서대로 파악해보면

   1) num1을 1로 초기화 한다

   2) 이전과 동일한 RefRetFuncOne함수를 이용해 num1의 주소에 있는 값(1)에 +1을 한 후

      그 값으로 변수 num2를 초기화한다 

     (∴ num1의 주소 ≠ num2의 주소 / 이때의 num1 = 2, num2 = 2)

   3) num1++         // num1 = 3

   4) num2 + 100    // num2= 102

 

=> RefRetFuncOne은 동일하게 사용되었으나 반환된 레퍼런스가

     변수에 저장되는가 레퍼런스에 되는가에 따라 차이가 생겼다

 

 

- 잘못된 참조의 반환

 -> 위 함수에서 함수 내 지역변수인 num을 참조형으로 반환하고 있다

     그러나 이 함수가 반환되면 지역변수 num은 소멸한다

  ∴ 이 함수를 통해 참조자를 초기화 했다면 오류가 생긴다

     (찌끄래기 값을 참조하게된다 = 원하는 결과를 절대 얻을 수 없다)

 

 - const 참조자의 또 다른 특징

 const가 붙은(상수화된) 변수에 대한 레퍼런스를 선언하기 위해선 레퍼런스에도 const를 붙여야 한다

 예) const int num = 20;

              int& ref = num;   (X)

      const int& ref2 = num;  (O)

 

 또한 const를 이용하여 '상수'도 참조할 수 있다

-> int num = 20 + 30;

    위 문장에서 20과 30은 리터럴 (상수) (literal constant)라 한다

    리터럴 상수는 해당 행에서만 존재하고 다음 행으로 넘어가면 존재하지 않는다

 

이때 const를 이용하여 리터럴 상수를 레퍼런스로 참조할 수 있다

예) const int &ref = 30;

 리터럴 상수 30에 대한 임시 변수를 만들고 const 레퍼런스가 그 임시변수를 참조하게 된다

 

활용법

-> "위 같이 정의된 함수에 인자의 전달을 목적으로 변수를 선언한다는 것은 매우 번거로운 일이다

    그러나 임시변수를 통한 const 레퍼런스의 상수 참조를 허용함으로써, 매우 간단히 호출이 가능해졌다"

     고 책에 적혀 있다

=> 킹직히 좀 헷갈린다;

     인자로 상수를 주고 그것을 위한 변수를 따로 설정하지 않고 임시변수 정도만 만들고 실행가능하다는 말인가?

     아니면 호출 시에 상수를 그냥 넣을 수 있다는 말인가?

   추후에 다시 와서 정리해야지

 

▣ malloc & free -> new & delete

 - malloc/free 복습

예) 1. 길이 정보를 인자로 받아서, 2. 해당 길이의 문자열 저장이 가능한 배열을 생성하고,

     3. 그 배열의 주소 값을 반환하는 함수

C++에서 C언어의 헤더파일을 사용가능하다(추후 설명이 나온다)

-> 여기서 보이는 malloc의 단점

   1. 할당할 대상의 정보를 무조건 바이트 크기단위로 전달해야 한다

   2. 반환형이 void형 포인터 이기 때문에 적절한 형 변환을 거쳐야 한다

=> 이를 보안하기위해 나온 new 키워드!!

 

-> int형 변수의 할당       : int * ptr1 = new int;

    double형 변수의 할당 : double * ptr2 = new double;

    길이가 3인 int형 배열의 할당       : int * arr1 = new int[3];

    길이가 7인 double형 배열의 할당 : double * arr2 = new double[7];

 

- 객체의 생성에는 반드시 new & delete

-> 이것도 잘 모르겠으나 아무튼 malloc과 new간에는 작동방식에 차이가 있다는 것은 확실하다

 

 - 힙에 할당된 변수를 포인터를 사용하지 않고 접근하는 방법

 -> 레퍼런스!

  예) 

-> 레퍼런스의 선언을 통해서 포인터 연산 없이 힙 영역에 접근 가능

 

 

▣ C++에서 C언어의 표준함수 호출하기

 - C++에서 C언어 표준함수를 사용하기 위해 기존 C언어 헤더파일에서 확장자 .h를 빼고 접두어 c-를 추가하면 된다

 예) 이전 코드들에서 보았던 #include<cstdlib>,  #include<cstring>등

∴ #include <stdio.h>  -> #include <cstdio>

    #include <stdlib.h>  -> #include <cstdlib>

    #include <math.h>  -> #include <cmath>

    #include <string.h>  -> #include <cstring>

 

 

 

연습문제

더보기

▣ 2-1 참조자 기반의 Call-by-reference 구현

1. 참조자를 이용해서 다음 요구사항에 부합하는 함수를 각각 정의하고 이를 확인할 수 있는 main함수를 작성하라

 - 인자로 전달된 int형 변수의 값을 1씩 증가시키는 함수

 - 인자로 전달된 int형 변수의 부호를 바꾸는 함수

 

2. 아래 코드에서 문제점을 말하시오

 

 

3. 다음 코드에 SwapPointer(ptr1, ptr2)라는 함수 호출부를 추가하면 ptr1과 ptr2가 가리키는 대상이

   서로 바뀌도록 SwapPoint함수를 정의하라

 

▣ 2-2 const 포인터와 const 참조자

 const int num = 12;

 

포인터 변수를 선언하여 위 변수를 가리켜라 그리고 이 포인터 변수를 참조하는 참조자를 선언하고

포인터 변수와 참조자를 이용하여 num에 저장된 값을 출력하라

 

▣ 2-3 구조체에 대한 new & delete 연산

typedef struct __Point

{

  int xpos;

  int ypos;

} Point;

 

위의 구조체를 기반으로 두 점의 합을 계산하는 함수를 다음의 형태로 정의하고

(덧셈결과는 함수의 변환을 통해서 얻게 한다)

Point& PntAdder(const Point &p1, const Point &p2);

 

임의의 두 점을 선언하여, 위 함수를 이용한 덧셈연산을 진행하는 main 함수를 정의하라

단, 구조체 Point 관련 변수의 선언은 무조건 new 연산자를 이용해서 진행해야 하며,

할당된 메모리 공간의 소멸도 필수여야 한다.

 

(동적할당 및 변수를 함수의 참조형 매개변수의 인자로 어떻게 전달해야 하는가?

 함수 내에 선언된 변수를 참조형으로 반환하려면 해당 변수는 어떻게 선언해야 하는가?

 이 두 질문에 대한 답을 할 수 있어야 가능한 문제이다)

 

▣ 2-4 C++ 표준함수 호출

 1. 다음 표준함수를 호출하는 예제를 만들되, C++의 헤더(<cstring>)를 선언해서 만들어라

 2. rand, srand, time 이 세 함수를 이용해서 0이상 100미만의 난수를 총 5개 생성하는 예제를 만들되

    C++의 헤더(time - <ctime> / rand, srand = <cstdlib>)를 선언해서 작성하라

'C++ 복습' 카테고리의 다른 글

열혈 C++ 복습 4  (0) 2019.11.22
열혈 C++ 복습 3  (0) 2019.11.19
열혈 C++ 복습 1  (0) 2019.11.17
C++ 복습 1  (0) 2019.08.04