이 블로그는 애드센스 수익으로 운영되고 있습니다.
광고차단앱을 해제해주시면 블로그 운영에 큰 도움이 됩니다.

'c++'에 해당되는 글 3건

  1. C++ STL 2013.03.25
  2. C++ 템플리트(template) 2013.03.25
  3. C++ static과 friend 2013.03.19

C++ STL

from Programing/C++ 2013. 3. 25. 20:35

■ STL(Standard Template Library)


- 프로그래머가 자료구조와 알고리즘을 알지 못해도 사용할 수 있도록 한 라이브러리

- 표준 STL은 std namespace 안에 있다.


- 컨테이너(Container) : 특정한 타입의 원소(또는 객체)들을 담아 다루기 위한 객체

ex) list, vector, map, deque, multimap 등


- 반복자(Iterator) : 컨테이너 내부 원소를 순회할 수 있는 객체이며 컨테이너의 특정 위치를 나타냄

- 반복자에 사용되는 멤버함수

begin() : 컨테이너의 첫번쨰 위치를 가리키는 반복자

end() : 컨테이너의 마지막 위치를 가리키는 반복자를 반환하며

         이것은 컨테이너의 마지막 원소 ' 다음의 위치를 말한다.

- 반복자에 사용되는 연산자

* 연산자 : 지금 현재 위치의 원소를 반환

++ 연산자 : 다음 원소를 가리키는 역할

-- 연산자 : 이전 원소를 가리키는 역할

= 연산자 : 반복자가 참조하는 원소의 위치를 할당

==,!= 연산자 : 두 반복자가 같은 위치인지를 반환하는 연산자


- 알고리즘(Algorithm) : 컨테이너 객체의 원소를 다루기 위한 여러 알고리즘으로 검색, 정렬, 수정등의 역할


❉ STL : 컨테이너 + 반복자 + 알고리즘


■vector

- vector는 자신의 원소를 동적 배열을 이용하여 관리

- vector는 데이터 추가와 삭제는 빠르지만 삽입은 비교적 늦은


■vector와 list 멤버 함수

- size() : 원소의 개수를 반환하는 함수

- empty() : 컨테이너가 비었는지를 알려줌

- max_size() : 컨테이너가 가질 수 있는 최대 원소의 개수를 반환

- reserve() : 용량을 재할당하는 함수

- insert() :  반복자 위치에 데이터를 삽입

- push_back() : 큰 부분에 데이터를 추가

- pop_back() : 마지막 원소를 제거

- erase() : 반복자 위치의 원소를 제거

- clear() : 모든 원소를 제거

- resize() : 원소릐 개수를 변경

- sort() : 오름차순으로 정 렬


- 백터에 데이터 입력과[]연산자를 이용한 요소의 접근 

#include <iostream>

#include <vector>



using namespace std;



int main(int argc, const char * argv[])

{

    vector<int> Vector;

    

    for(int i = 0; i < 7 ; i++)

        Vector.push_back(i);  //

    

    for(int i = 0; i < Vector.size() ; i++)  //size()원소의 개수를 반환

        cout<<Vector[i]<<" ";


    Vector.clear();


    return 0;

}

결과:

0 1 2 3 4 5 6  




















- 반복자

 #include <iostream>

#include <vector>



using namespace std;



int main(int argc, const char * argv[])

{

    vector<int> Vector;

    vector<int>::iterator pos;

    

    for(int i = 8; i >= 0 ; --i)

        Vector.push_back(i);  //

    

    for(pos = Vector.begin() ; pos!=Vector.end() ; pos++)  //begin() 컨테이너의 첫번째 위치를 가리키는 반복자

        cout<<*pos<<" ";


    Vector.clear();


    return 0;

}

결과:

8 7 6 5 4 3 2 1 0 






















■list

- list는 이중 링크드 리스트(double linked list)

- <list> 헤더를 포함

- 원소를 검색, 처음부터 검색하게 되어 다른 vector에 비해 시간이 다소 걸림

- 빠른 삽입과 삭제는 vector보다 훨씬 빠르다.

- vector의 [] 연산자를 제공하지 않는다.


- 1~10까지 데이터 입력 및 제거 그리고 검색

 #include <iostream>

#include <list>



using namespace std;



int main(int argc, const char * argv[])

{

    int nNum;

    list<int> nLinkedList;

    

    for(int i = 0 ; i< 10 ; i++)

        nLinkedList.push_back(i);

    

    cout<<"리스트에 입력된 값은 다음과 같다"<<endl;

    list<int>::iterator pos;

    for(pos = nLinkedList.begin() ; pos != nLinkedList.end() ; pos++)

        cout<<*pos<<" ";

    

    cout<<endl<<"0~9까지의 값중에서 삭제할 값은?:"<<endl;

    cin>>nNum;

    

    for(pos = nLinkedList.begin() ; pos !=nLinkedList.end() ; pos++)

    {

        if(*pos == nNum)

        {

            nLinkedList.erase(pos);

            break;

        }

    }

    

    cout<<endl<<"삭제한 결과"<<endl;

    for(pos = nLinkedList.begin() ; pos != nLinkedList.end();pos++)

        cout<<*pos<<" ";

    

    nLinkedList.clear();

    

    return 0;

}

결과:

리스트에 입력된 값은 다음과 같다

0 1 2 3 4 5 6 7 8 9 

0~9까지의 값중에서 삭제할 값은?:

8


삭제한 결과

0 1 2 3 4 5 6 7 9 









































- 오름차순 내림차순 정렬

#include <iostream>

#include <list>



using namespace std;



int main(int argc, const char * argv[])

{

    list<int>nLinkedList;

    

    for(int i = 10; i>0 ; --i)

    {

        nLinkedList.push_back(i);

    }

    

    nLinkedList.sort();

    

    list<int>::iterator pos;

    for(pos = nLinkedList.begin(); pos!=nLinkedList.end();pos++)

        cout<<*pos<<" ";

    cout<<endl;

    

    nLinkedList.reverse();

    for(pos = nLinkedList.begin(); pos!=nLinkedList.end();pos++)

        cout<<*pos<<" ";

    cout<<endl;

    

    nLinkedList.clear();


    return 0;

}

결과:

1 2 3 4 5 6 7 8 9 10 

10 9 8 7 6 5 4 3 2 1 






























■알고리즘

- min_element() : 최소값을 검색하며 반복자 위치를 반환

- max_element() : 최대값을 검색하며 반복자 위치를 반환

- find() : 값으로 검색하며 있으면 반복자 위치를 반환하고 없으면 범위의 끝을 반환

- reverse() : 역순으로 배열

- sort() : 오름차순으로 정


- vector에 알고리즘 적용

 #include <iostream>

#include <vector>

#include <algorithm>



using namespace std;



int main(int argc, const char * argv[])

{

    int nSearch;

    vector<int> Vectors;

    

    vector<int>::iterator pos;

    

    Vectors.push_back(3);

    Vectors.push_back(7);

    Vectors.push_back(8);

    Vectors.push_back(10);

    Vectors.push_back(6);

    Vectors.push_back(1);

    Vectors.push_back(4);

    Vectors.push_back(2);

    

    for( pos = Vectors.begin() ; pos != Vectors.end() ; pos++)

        cout << *pos << " " ;

    

    cout << endl << "최소값 : " << *min_element(Vectors.begin(), Vectors.end()) << endl;

    cout << "최대값 : " << *max_element(Vectors.begin(), Vectors.end()) << endl;

    

    sort(Vectors.begin(), Vectors.end());

    

    cout << "정렬 : ";

    

    for( pos = Vectors.begin() ; pos != Vectors.end() ; pos++)

        cout << *pos << " " ;

    

    cout << endl << "찾을 값을 입력 :" ;

    cin >> nSearch;

    

    pos = find(Vectors.begin(), Vectors.end(), nSearch);

    if( pos != Vectors.end() )

        cout << "검색값이 있음" << endl;

    else

        cout << "검색값이 없음" << endl;

    

    cout << "내림차순으로 정렬" << endl; reverse(Vectors.begin(), Vectors.end());

    cout << "정렬 : ";

    for( pos = Vectors.begin() ; pos != Vectors.end() ; pos++)

        cout << *pos << " " ;


    return 0;

}

결과:

3 7 8 10 6 1 4 2 

최소값 : 1

최대값 : 10

정렬 : 1 2 3 4 6 7 8 10 

찾을 값을 입력 : 8

검색값이 있음

내림차순으로 정렬

정렬 : 10 8 7 6 4 3 2 1 
















































-list에 알고리즘 적용

 #include <iostream>

#include <list>

#include <algorithm>



using namespace std;



int main(int argc, const char * argv[])

{

    list<int> LinkedList;

    list<int>::iterator pos;

    

    int nSearch;

    

    LinkedList.push_back(10);

    LinkedList.push_back(7);

    LinkedList.push_back(3);

    LinkedList.push_back(1);

    LinkedList.push_back(12);

    LinkedList.push_back(5);

    LinkedList.push_back(2);

    for( pos = LinkedList.begin() ; pos != LinkedList.end() ;

        pos++) cout << *pos << " " ;

    

    cout << endl << "최소값 : " << *min_element(LinkedList.begin(), LinkedList.end()) << endl;

    cout << "최대값 : " << *max_element(LinkedList.begin(), LinkedList.end()) << endl;

    

    LinkedList.sort();

    

    cout << "정렬 : ";

    for( pos = LinkedList.begin() ; pos != LinkedList.end() ; pos++)

        cout << *pos << " " ;

    cout << endl << "찾을 값을 입력 : " ;

    cin >> nSearch;

    

    pos = find(LinkedList.begin(), LinkedList.end(), nSearch);

    if( pos != LinkedList.end() )

        cout << "검색값이 있음" << endl;

    else

        cout << "검색값이 없음" << endl;

    cout << "내림차순으로 정렬" << endl;

    

    reverse(LinkedList.begin(), LinkedList.end());

   

    cout << "정렬 : ";

    

    for( pos = LinkedList.begin() ; pos != LinkedList.end() ; pos++)

        cout << *pos << " " ;

    

    return 0;

}

결과:

10 7 3 1 12 5 2 

최소값 : 1

최대값 : 12

정렬 : 1 2 3 5 7 10 12 

찾을 값을 입력 : 7

검색값이 있음

내림차순으로 정렬

정렬 : 12 10 7 5 3 2 1 


,

C++ 템플리트(template)

from Programing/C++ 2013. 3. 25. 12:55

■템플리트

- 어떤 타입이라도 클래스 또는 함수 안에서 사용할 수 있게 하는 역할을 한다

- 타입을 찍어내는 틀

- 기본 형식

template<class T>

template<class T1, class T2>

- class는 일반적인 클래스 키워드가 아니라 사용자가 지정해야 할 데이터 형을 의 미

- 한 개의 형(type) 지정 예제


#include <iostream>


using namespace std;

template <class T>void Swap(T& a, T& b)

{

    T c = a;

    a = b;

    b = c;


}


int main(int argc, const char * argv[])

{

    int nVar1, nVar2;

    float fVar1, fVar2;

    nVar1 = 7;

    nVar2 = 12;


    fVar1 = 3.14f;

    fVar2 = 0.5f;

    

    Swap(nVar1, nVar2); 

    cout<<"nVar1:"<<nVar1<<'\t'<<"nVar2:"<<nVar2<<endl;

    

    Swap(fVar1, fVar2);

     cout<<"fVar1:"<<fVar1<<'\t'<<"fVar2:"<<fVar2<<endl;

    

    return 0;

}

결과:

nVar1:12 nVar2:7

fVar1:0.5 fVar2:3.14

 






























- 여러 개의 형(type)지정

#include <iostream>


using namespace std;

template <class T, class U, int i>void Func(T str)

{

    U buffer[i];

    strcpy(buffer, str);

    cout<<buffer<<endl;

}


int main(int argc, const char * argv[])

{

    Func<char* , char, 12>("C++");

    return 0;

}

결과:

C++



















■템플리트 클래스

- 클래스 안에서 사용하려는 형을 템플리트로 지정

- 템플리트를 사용하는 멤버 함수의 구현을 외부에 할 때에는 클래스에서 정의한 템플리트를 모든 함수의 구현 부분에 지정해야 한다.


- 클래스에서 한 개의 템플리트 형을 사용하는 경우


 


#include <iostream>


using namespace std;


template<class T> class A

{

private:

    T m_Var;

public:

    void Print();

    void Set(T Var);

    T Get(){return m_Var;}


};


template<class T>void A<T>::Set(T Var)

{

    m_Var = Var;

}


template<class T>void A<T>::Print()

{

    cout<<m_Var<<endl;

}


int main(int argc, const char * argv[])

{

    A<char> test1;

    A<int> test2;

    A<int*> test3;

    

    test1.Set('a');

    test1.Print();

    

    test2.Set(10);

    test2.Print();

    

    int k = 7;

    test3.Set(&k);

    cout<<*test3.Get()<<endl;

    


}

결과:

a

10

7









































- 클래스 안에서 두 개의 템플리트 형을 사용하는 경우


 


#include <iostream>


using namespace std;


template<class T, class U> class A

{

private:

    T m_Var1;

    U m_Var2;

public:

    void Print();

    void Set(T Var);

    void Set(U Var);



};


template<class T, class U>void A<T, U>::Set(T Var)

{

    m_Var1 = Var;

}


template<class T, class U>void A<T, U>::Set(U Var)

{

    m_Var2 = Var;

}


template<class T, class U>void A<T, U>::Print()

{

    cout<<m_Var1<<'\t'<<m_Var2<<endl;

}


int main(int argc, const char * argv[])

{


    A<int, char>test;

    test.Set(300);

    test.Set('a');

    test.Print();

    

    return 0;


}

결과:

300 a








































- 템플리트 클래스 객체가 포인터인 경우


 


#include <iostream>


using namespace std;


template<class T> class A

{

private:

    T m_Var;


public:

    void Print();

    void Set(T Var);

    T Get();



};


template<class T>void A<T>::Set(T Var)

{

    m_Var = Var;

}



template<class T>void A<T>::Print()

{

    cout<<m_Var<<endl;

}


template<class T>T A<T>::Get()

{

    return m_Var;

}


int main(int argc, const char * argv[])

{

    A<int> *pTest = new A<int>;

    pTest->Set(12);

    pTest->Print();

    delete pTest;


    return 0;


}

결과:

12






































- 템플리트 클래스 객체에 생성자가 있고 매개변수가 있는 경우


 


#include <iostream>


using namespace std;


template<class T> class A

{

private:

    T m_Var;


public:

    A(T Var):m_Var(Var) {}

    void Print();

    void Set(T Var);

    



};


template<class T>void A<T>::Set(T Var)

{

    m_Var = Var;

}



template<class T>void A<T>::Print()

{

    cout<<m_Var<<endl;

}



int main(int argc, const char * argv[])

{

    A<int> test(12);

    test.Print();

    

    A<int> *pTest;

    pTest = new A<int>(7);

    pTest->Print();

    delete pTest;


    return 0;


}

결과:

12

7








































- typedef를 템플리트에 활용


 


#include <iostream>


using namespace std;


template<class T> class A

{

private:

    T m_Var;


public:


    void Print();

    void Set(T Var);

    T Get();



};


template<class T>void A<T>::Set(T Var)

{

    m_Var = Var;

}



template<class T>void A<T>::Print()

{

    cout<<m_Var<<endl;

}



typedef A<int> intA;


int main(int argc, const char * argv[])

{

    intA test;

    test.Set(12);

    test.Print();

    

    return 0;


}

결과:

12




































- 템플리트에 기본 값을 적용


 #include <iostream>


using namespace std;


template <class T,int m = 12>class A

{

private:

    T* m_pBuffer;

public:

    A(){m_pBuffer =new T[m];}

    ~A(){delete [] m_pBuffer;}

    

    void Set(int nIndex, T Var)

    {

        m_pBuffer[nIndex] = Var;

    }

    

    void Print(int nIndex)

    {

        cout<<nIndex<<":"<<m_pBuffer[nIndex]<<endl;

    }

};


int main(int argc, const char * argv[])

{

    

    A<int> test1;

    test1.Set(0, 3);  //0번째 배열에 3 넣음

    test1.Print(0);   //0번째 배열을 출력

    

    A<int, 20> test2;

    test2.Set(19, 100);  //19번째 배열에 100 넣음

    test2.Print(19);     //19번쨰 배열을 출력


    return 0;

}

결과:

0:3

19:100




,

C++ static과 friend

from Programing/C++ 2013. 3. 19. 20:38

■정적(static) 클래스와 지역 정적(static)클래스

- static class의 특징

한번 생성과 초기화

프로그램이 종료될 때 까지 소멸되지 않는다.


- 형식(1) : 기본 생성자만 있는 경우


class A{};


class B{

public:

    static A Test;

};


A B::Test;  //클래스의 초기화


int main()

{

  //생략

} 













- 형식(2) : 생성자에 초기화가 있는 경우


class A{

public:

    A(int nVar){}

};


class B{

public:

    static A Test;

};


A B::Test(10);  //클래스의 초기화


int main()

{


} 















- 예


#include <iostream>



using namespace std;


class A{

private:

    int m_nVar;

public:

    A(int nVar){

        m_nVar = nVar;

        cout<<"A 생성자 호출"<<m_nVar<<endl;

    }

    void Print(){cout<<m_nVar<<endl;}

    ~A(){cout<<"A 소멸자 호출"<<endl;}

};


class B{

public:

    static A ClassA;

    

    B(){cout<<"B 생성자 호출"<<endl;}

    ~B(){cout<<"B 소멸자 호출"<<endl;}

};


A B::ClassA(10);  //클래스의 초기화


void Set(int nVar)

{

    static A test(nVar);

    test.Print();

}


int main()

{

    

    Set(7);

    Set(12);

    

    B test1, test2;

    test1.ClassA.Print();

    test2.ClassA.Print();

    return 0;

}

결과:

A 생성자 호출10

A 생성자 호출7

7

7

B 생성자 호출

B 생성자 호출

10

10

B 소멸자 호출

B 소멸자 호출

A 소멸자 호출

A 소멸자 호출 














































■정적 멤버변수

- 모든 같은 클래스 안에서 공유하는 변수

- 클래스의 전역변수 역할

- 클래스 외부에서 한번은 초기화해야 한다.

- 초기화할 때는 ::을 이용하여 소속을 지정


■정적 멤버변수의 특징

- 클래스를 생성하지 않아도 정적 멤버변수를 사용할 수 있다.

- 형식


class A{

private:

    static int m_nVar;

};


int A::m_nVar =0; 


 

 


 


#include <iostream>



using namespace std;


class A{

private:

    static int m_nVar;

public:

    static int m_nPublicVar;

    void Set(int nVar){m_nVar = nVar;}

    void Print(){cout<<m_nVar<<endl;}

};


int A::m_nVar = 0;

int A::m_nPublicVar = 0;


int main()

{

    cout<<"public 정적 멤버 변수:"<<A::m_nPublicVar<<endl;

    

    A test1, test2, test3;

    

    test1.Set(12);

    test1.Print();

    test2.Print();

    test3.Print();

    

    A::m_nPublicVar = 7;

    cout<<test1.m_nPublicVar<<'\t'<<test2.m_nPublicVar<<'\t'<<test3.m_nPublicVar<<endl;

    cout<<A::m_nPublicVar<<endl;

    

    return 0;

}

결과:

public 정적 멤버 변수:0

12

12

12

7 7 7

7 






































■정적 멤버함수

- 정적 멤버변수에만 접근하는 함수

- 함수 안에 this 사용 불가


■정적 멤버변수의 특징

- 클래스를 생성하지 않아도 정적 멤버함수를 사용할 수 있다.



#include <iostream>



using namespace std;


class A{

private:

    static int m_nVar;

public:

    static int m_nPublicVar;

    void Set(int nVar){m_nVar = nVar;}

    void Print(){cout<<m_nVar<<endl;}

    static void Add(int nVar){m_nPublicVar += nVar;}

};


int A::m_nVar = 0;

int A::m_nPublicVar = 0;


int main()

{

    A::Add(12);

    cout<<A::m_nPublicVar<<endl;

    

    A test1, test2;

    

    test1.Add(7);

    

    cout<<test1.m_nPublicVar<<'\t'<<test2.m_nPublicVar<<endl;

    

    return 0;

}

결과:

12

19 19 



 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

■friend

- 일반 함수가 클래스의 모든 멤버에 접근할 수 있도록 한다.


■friend 사용 용도

- 클래스 안에 멤버 함수를 두지 않고 외부에 두고자 하는 경우

■friend 참고 사항

- 상속되지 않는다.

-  형식


class A{

private:

    int m_nVar;

public:

    friend bool IsEqual(A& a, A& b);


};


bool IsEqual(A& a, A& b)

{

    if(a.m_nVar ==b.m_nVar)

        return 1;

    else

        return 0;

} 














- friend 함수 예



#include <iostream>



using namespace std;


class A{

private:

    int m_nVar;

public:

    A(int nVar) : m_nVar(nVar){}

    friend bool IsEqual(A& a, A& b);


};


bool IsEqual(A& a, A& b)

{

    if(a.m_nVar ==b.m_nVar)

        return 1;

    else

        return 0;

}



int main()

{

    A test1(7), test2(12);

    if(IsEqual(test1, test2) ==1)

        cout<<"같은 "<<endl;

    else

        cout<<"다른 "<<endl;

    

    return 0;

} 


결과:

다른


 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 


 


#include <iostream>



using namespace std;


class B; //class B 있다는 것을 알림


class A{

private:

    int m_nVar;

public:

    A(int nVar) : m_nVar(nVar){}

    friend bool IsEqual(A& a, B& b);


};


class B

{

private:

    int m_nVar;

public:

    B(int nVar) : m_nVar(nVar){}

    friend bool IsEqual(A& a, B& b);

    

};


bool IsEqual(A &a, B &b)

{

    if(a.m_nVar == b.m_nVar)

        return 1;

    else

        return 0;

}



int main()

{

    A test1(12);

    B test2(12);

    

    if(IsEqual(test1, test2) == 1)

        cout<<"같은 "<<endl;

    else

        cout<<"다른 "<<endl;

    

    return 0;

} 


■friend 클래스

- friend 클래스로 선언된 클래스는 자신이 속한 클래스 안의 모든 멤버에 대한 접근 권한을 가지게 된다

- private 권한과 상관없이 멤버를 사용할 수 있다.


■friend 클래스 형식

■friend 클래스 예



#include <iostream>



using namespace std;



class A

{

private:

    int m_nVar;

    friend class B;

public:

    A():m_nVar(12){}


};


class B

{

public:

    void Print(A& Ref){cout<<Ref.m_nVar<<endl;}

};


int main()

{

    A test1;

    B test2;

    test2.Print(test1);

 

    return 0;

} 



,