자료형 bool


C++에서는 참(1)과 거짓(0)을 의미하는 키워드 true false를 지원한다. true와 false는 1과 0이아니지만 , 정수출력시 1과 0으로 변환하여 나타내진다. 

이때 , 키워드 true와 false의 자료형이 bool이다.


참조자(Reference)


변수는 할당된 메모리공간에 붙여진 이름이다. 이름을통해 해당 메모리공간에 접근이 가능하다. 이때 , 하나의 할당된 메모리공간에 두개의 이름을 부여하는것이 참조자선언이다.


int num1 = 2018;

int arr[3]={1,3,5};

int * ptr = &num1;

int ** dptr = &ptr;

int &num2 = num1; // num2는 num1의 참조자

int &num3 = num2; // 참조자를 대상으로 참조자를 선언할 수 있다

int &num4 = arr[0]; // 배열요소도 참조자선언이 가능하다

int *(&pref) = ptr; // 포인터변수의 참조자선언

int **(&dpref) = dptr; //이중 포인터변수의 참조자선언


이미 선언된 변수앞에 &연산자가 붙으면 주소값 반환을 명령하는 뜻이지만, 새로 선언되는 변수 이름앞에 붙을땐 참조자의 선언을 뜻하는것이 된다.

함수 내에서 선언된 지역적(local) 참조자 또한 지역변수와 마찬가지로 함수를 빠져나가면 소멸된다. 또한 참조자는 반드시 선언과동시에 변수를 참조하도록 해야한다. 배열요소는 변수로 간주되어 참조자의 선언이가능하다.


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


void Swap( int &ref1, int &ref2) // 매개변수는 함수의 호출시 초기화가 진행되기때문에 , 함수의 호출시 전달되는 인자로 초기화된다.

{

int temp = ref1;

ref1=ref2;

ref2=temp;

}


const참조자


void HappyFunc ( int & ref ){ ... } 으로 선언되어있을때,

int num=20;

HappyFunc(num);

std :: cout<<num<<std :: endl;

은 20이 출력될지 알 수 없다. ( C언어에서는 매개변수에 num값을 전달할때는 num값이 절대 변하지않기때문에 20이 출력됨을 알수있다 )

이때 , 가독성이 떨어지는 단점이있다. 이를 보완하기위해 

void HappyFunc ( const int & ref ){ ... } 로 함수를 선언하게되면 ,ref참조자를 이용해 변수값을 변경하지않겠다는 선언이되어 코드의가독성을 높일수 있다.


반환형이 참조형인경우


int num1=1;

int & RefRetFuncOne( int &ref )

{

ref ++;

return ref;

}

int &num2=RefRetFuncOne(num1);

int num3 = RefRetFuncOne(num1);


이렇게 선언되어있을때 , num2는 num1의 참조자가되고 , 메모리주소값을 공유하게된다. num3는 num1의 참조자가 아닌 별개의 변수가된다.

반환형이 int형인경우엔 int형 자료형 변수에만 저장이 가능하다. ( 반환값이 상수이기때문 )


const 참조자 주의


const int num =3;

const int &ref = num;

const int &ref1= 30; // const 선언된 참조자는 상수도 참조 가능하다


num과같이 상수선언된 변수의 참조자를 선언할때는 const선언을 붙여줘야한다. const 참조자가 상수를 참조할때 C++에서는 임시변수를 만들고 그 장소에 30값을 저장하고선 참조자가 이를 참조하게끔한다.


int adder ( const int & num1 , const int & num2)

{

return num1+num2;

}

std :: cout<<adder (3,4)<<std::endl;


위와 같은 함수를 선언했을때  인자전달을 목적으로 변수를 선언한다는것은 매우 번거로운일인데 , cosnt 참조자의 상수참조를 허용함으로서 간단한 함수호출을 가능케했다.


malloc&free를 대신하는 new&delete


C언어에서 힙영역에 메모리를 할당할때는 malloc&free를 이용했는데 이는 두가지 불편사항이있다.

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

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


C++에서 지원하는 키워드 new와 delete 를 사용하면 이러한 불편함을 해소할 수 있다,


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

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

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

int형 변수의 소멸 delete ptr1;

double형 변수의 소멸 delete ptr2;

int형 배열의 소멸 delete []arr1;


C++에서는 new연산자를 이용해서 할당된 메모리공간도 변수로 간주하기때문에 , 참조자선언이 가능하다.

int *ptr = new int;

int &ref = *ptr; // 힙영역에 할당된 변수에대한 참조자선언

ref =20; // 참조자를이용해 포인터연산없이 힙영역에 접근할수있다


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


c를 더하고 .h를 빼라

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

가급적 C++의 표준헤더를 이용해서 함수를 호출하는것이 좋다

헤더파일 선언문 #include <iostream>


C++ 언어에서 입출력함수는 iostream 표준 헤더파일안에 선언되어있다. 과거의 표준라이브러리 및 헤더는 .h 확장자를 붙이고, 새로운 표준라이브러리 및 헤더는 확장자를 붙이지 않는다.


출력함수 std :: cout 


std :: cout <<"출력대상"<<변수; // << 연산자를 이용해 둘 이상의 출력대상을 연이어서 출력

std :: cout <<"Hello World!"<<num<<std :: end;  // std :: end 를 이용한 개행


입력함수 std :: cin


std :: cin >>변수1>>변수2;

std :: cin >>num1>>num2; // 변수는 자료형에따라 각각 알아서 입력이 진행된다.


C++의 지역변수선언


C++의 지역변수선언은 함수 내 어디든 삽입 가능하다


for(int i= val1+1;i<val;i++)

result +=i;


배열기반의 문자열 입출력


char name[100];

std :: cin >>name;

std :: cout << "이름은"<<name<<"입니다"<<std :: endl;


함수 오버로딩


함수호출시 전달되는 인자를 통해서 호출하고자 하는 함수의 구분이 가능할때, 매개변수의 선언형태가다르다면 동일한이름의 함수를 오버로딩할수있다.

함수를 오버로딩할때는 매개변수의 자료형 또는 개수가 달라야한다. 반환형이다른것은 의미없다.


매개변수의 디폴트값


int MyFuncOne(int num = 7)

{

return num +1;

}

int MyFuncOne(int num1=5,int num2=7)

{

return num1+num2;

}

int MyFuncThree(int num1, int num2 =1, int num3=2)

{

return num1+num2+num3;

}


MyFuncOne은 함수호출시 인자를 전달하지않으면 7이된것으로 간주하고 

MyFuncTwo는 함수호출시 인자를 전달하지않으면 5,7이 , 하나만전달하면 num1에 전달한값, 7이 전달되게된다.

MyFuncThree 처럼, 디폴트값을 부분적으로 설정할수 있는데 이때 , 매개변수를 비울때는 왼쪽에서부터 비워야한다. //  매개변수가 전달될때 왼쪽에서부터 전달되기때문이다 


인라인 ( inline ) 함수


C언어에서 매크로함수의 장점은 일반적인 함수에 비해서 실행속도의 이점이있다는것이고, 단점은 정의하기가 어렵다는것이다.

이를 보완하기위해 정의하기쉽고 일반적 함수보다 실행속도가 빠른 함수를 C++에서 도입했는데 인라인함수가 그것이다.


inline int SQUARE(int x) // 컴파일러가 함수의 인라인화가 오히려 성능에 해가된다고 판단할경우, inline 키워드를 임의로 빼기도한다.

{

return x*x;

}


하지만 inline 함수에는 매개변수에서 자료형을 선언해야하는단점이있다. 매크로함수는 자료형에 의존하지않는 함수이다.


namespace


namespace안에 선언된 변수와 함수들은 다른 namespace 에 선언된 변수와 함수들과 겹치지않고 독립적이다.


namespace BestCom

{

void SimpleFunc(void)

{

std :: cout <<"BestCom이 정의한 함수"<<std ::endl;

}

}

namespace ProgCom

{

void SimpleFunc(void)

{

std :: cout <<"ProgCom이 정의한함수" <<std :: endl;

}

}

BestCom :: SimpleFunc(); // BestCom 네임스페이스에 선언된 SimpleFunc 호출

ProgCom :: SimpleFunc(); // ProgCom 네임스페이스에 선언된 SimpleFunc 호출


함수 선언후 다른소스코드에서 함수를 정의할때는 밑처럼 정의한다.

void BestCom :: SimpleFunc(void)

{

..

}


이름공간은 중첩이가능하다 


namespace BestCom

{

int num; // 1

namespace ProgCom

{

int num; // 2

}

}

BestCom :: num // 1번 num

BestCom :: ProgCom :: num // 2번 num


using을 이용한 이름공간의 명시


using std; // std namespace 안의 cout cin endl 등의 연산자를 std :: endl 이아닌 endl 로 사용 가능하다.

using std :: cout; // cout 호출시 std namespace안의 cout 에서 찾으라는 선언

namespace ABC = AAA::BBB::CCC; // AAA네임스페이스안의 BBB네임스페이스안의CCC네임스페이스를 지칭하는 별칭 ABC 선언


범위지정연산자 :: 의 또다른기능


int val =100;

int main(void)

{

int val =30;

val = 20 // 지역변수 val 의 값 변경

::val =20 // 전역변수 val 의 값 변경

}

전역변수 val 은 지역변수 val 에 가리게되는데 , 범위지정연산자를 사용하면 전역변수 val 에 접근이 가능하다


파일의 분할


외부선언된 변수혹은 함수 이용 : extern


소스코드를 나누어서 작성할때 , 컴파일러는 파일단위로 컴파일을 진행하기때문에 , 같은 파일에 선언되어있지않은 변수나 함수를 이용하려면 extern 키워드를 이용해야한다.


extern int num; // int 형 변수 num 이 외부에 선언되어있다

extern void increment(void) // void increment(void) 함수가 외부에 선언되어있다.


다른파일에서 접근을 못하게 막고싶을때 : static


static 지역변수는 함수를 빠져나가도 사라지지않는 특성 ( 전역변수적 특성 ) 을 가지고있는데 , static 전역변수는 외부파일에서의 접근을 허용하지 않는 특징이 있다 .  

static int num ;// num 변수의 접근범위를 파일 내부로 제한한다.

static void increment(void); // void increment(void) 함수의 접근범위를 파일 내부로 제한한다.


헤더파일의 디자인과 활용


헤더파일을 include 하는 두가지 방법


#include<헤더파일이름>  : 표준헤더파일이 저장되어있는 디렉터리에서 파일을 찾는다.

#include "헤더파일이름"   : 소스파일이 저장되어있는 디렉터리에서 헤더파일을 찾는다. ( 프로그래머가 정의하는 헤더파일을 포함시킬때 사용하는방식)


절대경로지정 ( 기기마다의 호환성 문제로 거의 사용하지않는다)

#include "C:\Cpower\myproject\header.h" //windows 상에서의 절대경로지정 


상대경로지정

#include "Release\header0.h" // 소스파일이 있는 디렉터리의 하위디렉터리인 Release 디렉터리에 존재하는 header0.h를 찾아서 포함

#include "...\CProg\header1.h" //소스파일이 있는 디렉터리의 한단계 상위디렉터리에 존재하는 CProg 디렉터리 안에서 header1.h를 찾아서 포함


헤더파일에 담으면 좋은것


구조체

int num;

int GetNum(void);

# define PI 3.14

등의 선언을 포함시키면 좋다


헤더파일의 중복삽입문제


헤더파일이 중복삽입되었을때 , 문제가되는 코드들이있다. ex) 구조체

조건부 컴파일을 활용하면 중복삽입의 문제를 해결할 수 있다.


#ifndef  __STDIV2_H__

#define __STDIV2_H__

typedef struct div

{

int quotient;

int remainder;

}Div;

#endif



+ Recent posts