1. 2장을 시작하기 앞서서...
  1) 아래의 차이점은?
    - const int n = 10;     <-- int 형 변수 n의 데이터 상수화, n 값은 변경 불가
    - const int *n;           <-- int 형 포인트 변수 n의 데이터 상수화
    - int* const n;           <-- int 형 포인트 변수 n에 대한 포인트 상수화
    - const int* const n;   <-- 바로 위의 2가지 모두
  2) 스택과 힙의 필요성
    - (프로그램 코드가 들어가는 text 영역은 제외하고,)
      전역 변수와 static 변수등은 data 영역에 프로그램 시작시에 할당이 된다.
      하지만 지역변수와 매개변수등등 컴파일 타임에 크기가 결정되는 변수들은 stack 영역에 할당이 된다.
      함수 호출 시 할당되고 함수 종료시 할당이 해제되는 과정이 자동으로 반복된다
      문제가 되는 녀석들은 컴파일 타임에 크기가 결정되지 않는 변수들인데
      이러한 변수들은 프로그래머가 일일이 생성시 메모리 할당을 해줘야하고 종료시 해제시켜줘야 한다.
      프로그래머가 malloc아니 free 등으로 이런 변수들을 할당/해제하는 메모리 영역이 heap 영역이다.
  3) malloc/free
      위에서 설명한대로 컴파일 타임이 아니라 런타임에 크기가 결정되는 변수들은 heap 영역에
      동적 할당 및 해제 작업을 해줘야 한다... 그게 바로 malloc/free이다... 당근 free에 각별한 신경을 써야한다.

2. bool 자료형
  - C++에는 bool 자료형이 별도로 존재하므로 이를 잘 이용하자

3. 레퍼런스에 들어가기 앞서서 call by value와 call by reference에 관해서
  - 처음 C를 배울 때 call by value와 포인터를 이용한 call by reference 함수 호출에 관해 배웠었다
    주요한 차이점은 포인터를 이용한 call by reference의 경우, 매개 변수 조작이 함수가 종료되도 남아있고
    call by value의 경우에는 그렇지 않다는 것과 call by value가 메모리를 많이 잡아 먹는다는 것이였다...
    이 얘기는 2장에서 설명하는 call by reference에서도 동일하게 적용된다.

4. 레퍼런스 (reference)
  1) 의미
    - 이름을 지니는 공간에 별명을 붙여주는 행위, 즉 메모리 공간에 2개 이상의 이름을 붙이는 행위
    - 위의 의미에서도 알수 있듯이 이름이 존재하지 않는 상수 따위에겐 reference를 사용할 수 없다
  2) 형태
    - int &ref = val;
  3) 레퍼런스에 의한 call by reference

     - 위의 경우처럼 레퍼런스를 이용한 call by reference의 경우, 포인터를 이용해 함수를 구현하지 않으므로
      프로그래밍 상의 오류를 줄일 수 있고 가독성이 좋아 유지 보수가 편할 수 있다
    - 단점은, 포인터에 의한 call by reference 처럼 함수내에서 변수에 잘못된 연산을 했을 때
      이 결과가 함수를 종료된 이후에도 영향을 끼쳐 전체 프로그램에 문제를 야기할 수 있다는 것과
      함수 호출만봐서는 call by reference인지 call by value인지 알수가 없다는 것이다
    - 위의 잘못된 연산과 관해서는 const 키워드로 매개변수를 상수화 시켜 해결이 가능하므로
      필요한 경우에 따라 reference를 잘 이용하면 좋은 결과가 있을 수 있다
  4) 레퍼런스를 return 하는 함수의 경우
    - 절대 지역변수를 레퍼런스로 return 해서는 안된다
사용자 삽입 이미지

    - 위의 경우, 실행을 해보면 n, val, ref는 모두 같은 주소를 가지고(같은 주소에 붙은 이름이며)
      결과값도 예상한 것처럼 정확하게 나오는 것을 확인 가능하다
사용자 삽입 이미지

    - 이제 위와 같이 변경해서 실행해보면 결과값이 이전과 다르게 나오는 것이 확인 가능하다
    - 단지 매개변수를 reference에서 그냥 call by value로 변경했을 뿐인데 이유는 무엇일까?
      위에서 말한 것처럼 절대 지역변수를 레퍼런스로 return 해서는 안되기 때문이다
    - 2가지 모두 매개변수를 reference 타입으로 return하지만,
      첫번째 경우는 reference로 매개변수를 받았기 때문에 함수가 종료되어도 매개변수 val 라는 레퍼런스만
      없어지는 것이지 그 메모리 공간까지 사라지는 것은 아니기 때문에 이상이 없는 것이고
      두번째 경우는 함수 호출시 val이라는 새로운 메모리를 stack에 할당받아 거기에 같은 복사하여 사용하고
      ref는 val를 레퍼런스하는데 함수 종료시 val은 할당해제가 되고 컴파일러에 의해서 거기에 다른 변수가
      할당이 될수 있으므로 ref로 해당 메모리를 참조하는 시점에 그 데이터 값은 보장할 수가 없게 된다.
    - 쉬운 내용인데 설명만 길어지고 어려워져서... -_-;;;; 암튼 지역변수는 절대 레퍼런스로 리턴해선 안되고,
      이렇게 하는것은 포인터 변수 생성만 하고 초기화나 할당없이 참조하는것과 똑같다고 보면 된다.

5. new와 delete
  1) 일단 아래처럼만 알아두자
    - int *val = new int;
    - int *arr = new int[size];
    - delete val;
    - delete []arr;
by sminchoi 2008. 8. 27. 17:40

1. printf와 scanf를 대신하는 입출력 방식
  1) 구버전/신버전의 헤더 파일
    - #include <iostream.h> : 구버전의 헤더 파일
    - #include <iostream> : 신버전의 헤더 파일, std::cout, std::cin, std::endl 처럼 써야 한다
  2) 출력
    - count<<”문자열”<<endl;
    - std::cout<<”문자열”<<std::cout::endl;
    - count<<정수<<’문자’<<”문자열”<<endl; 도 가능, 자료형에 상관없이 출력이 가능하므로 편리함
  3) 입력
    - cin>>입력받을변수>>입력받을변수…;
  4) 기타
    - C에서와는 다르게 함수의 시작 부분에서 뿐만 아니라 어디서든 변수 선언이 가능 (for문 안에서 선언과 초기화 동시도 가능)

2. 함수 오버로딩 (Function Overloading)
  1) 함수 오버로딩이란 : 동일한 이름을 가지면서 매개변수의 개수 혹은 타입을 다르게 가지는 함수를 중복해서 정의하는 것
  2) C : 컴파일러에서 함수의 이름만으로 참조, 호출하므로 오버로딩이 불가능
  3) C++ : 함수이름과 매개변수의 타입까지 참조하므로 함수 오버로딩이 가능하다
  4) 매개변수의 개수가 다르거나 타입이 다른 경우만 허용하며, 리턴값의 타입이 다른 경우는 오버로딩이 허용되지 않는다

3. 디폴트 (Default) 매개 변수
  1) 디폴드 매개 변수란 : 함수 선언시 전달되지 않은 인자에 자동으로 입력되도록 디폴트 값이 정의되어 있는 매개 변수
  2) example

    위와 같은 함수에서 function()으로 매개 변수가 생략되어 호출되는 경우에 a는 자동으로 디폴트 값 0을 가지게 됨
  3) 기타
    - 함수 오버로딩과 디폴트 매개 변수가 중복되는 경우 컴파일 에러 발생하므로 주의 필요

4. 인-라인 (in-line) 함수
  1) C : C에서는 #define을 이용한 매크로로 전처리기에 의해 인-라인화
  2) C++ : 함수의 선언시에 inline 선언을 하면 함수가 자동으로 인라인화 되고, 컴파일 타임에 컴파일러는 inline 할지를 판단하여 처리한다
  3) 장점
    - 사용법이 간단하고 구현이 용이함
    - 매크로 함수의 장점을 반영하면서, 컴파일러에 의한 최적화가 가능

5. 이름 공간 (namespace) 에 대한 소개
  1) namespace : 큰 프로젝트 등에서 동일한 함수 이름의 사용으로 인한 오류를 막기 위해 공간에 이름을 부여하는 것
  2) 기타
    - :: 범위지정연산자
    - ::val 과 같이 사용하여 전역 변수에 접근이 가능
    - using 을 이용하여 namespace를 생략하고 사용이 가능하나 namespace의 기본 필요성을 고려해서 사용이 필요

by sminchoi 2008. 8. 20. 20:15
| 1 |