Language Grammar/C++

2024 - 02 - 08 C++ 코딩테스트 10주완성 D+3

Jang_^ 2024. 2. 8. 18:17

*메모리와 주소

RAM은 1Byte 단위의 메모리 셀들로 이루어져 있다.

각각의 메모리 셀들은 16진수로 이루어진 주소를 가지고 있다.

각각의 변수를 선언할 시 해당되는 변수의 크기만큼 메모리에 할당이 된다.

변수의 주소는 사용하는 메모리의 첫번째 주소로 할당받음 => 첫번째 주소를 알면 변수의 크기로 변수의 끝주소까지 알기때문

실습코드

int main()
{
    //메모리와 주소
    int i;
    cout << &i << "\n";
}



*포인터

메모리의 주소를 담는 타입

 

실습코드

 

	int main()
    {
        //포인터
        int pointerInt = 4;
        int* pointer = &pointerInt;
    }



*= 에스터리스크

타입에 관계없이 포인터변수의 크기는 32bit 일때 4byte ,64bit 일때 8byte 이다.

실습코드

 

int main()
{
    //포인터
    int pointerInt = 4;
    int* pointer = &pointerInt;
}


*역참조 연산자

포인터 변수안에 담긴 주소로 접근하여 값을 가져오는 연산자

실습코드

 

int main()
{
    //역참조 연산자
    string sa = "hyukjun";
    string* sb = &sa;
    cout << sb << endl;
    cout << sa << endl;
}


*메모리와 포인터

배열의 이름 = 배열이 시작하는 첫번째 주소를 가르킴

포인터변수안에 배열을 할당할경우 주소만 들어가고 배열의 크기정보는 없어짐

실습코드

int main()
{
    //포인터와 배열
    int ar[3] = { 1,2,3 };
    int* c = a;
    cout << c << "\n";
    cout << &ar[0] << "\n";
    //int형 포인터 주소에서 +1을 더하면 int형의 데이터크기만큼 주소를 이동한다.
    //따라서 배열의 다음주소를 가르킨다
    cout << c + 1 << "\n";
    cout << &ar[1] << "\n";
    return 0;
}



*중복된 요소 제거하는 방법과 unique()

범위안의 있는 요소 중 앞에서부터 서로 비교해가며 중복되는 요소를 제거하고 나머지 요소들은 삭제하지 않고 그대로 두는 함수.

실습 코드

int main()
{
    //중복된 요소제거 unique 사용
    for (int i = 1; i <= 5; i++)
    {
    v.push_back(i);
    v.push_back(i);
    // 1 1 2 2 3 3 4 4 5 5
    }

    for (int i : v) cout << i << "";
    cout << "\n";
    // 중복되지 않는 요소로 채운 후, 그 다음 이터레이터를 반환한다.
    auto it = unique(v.begin(), v.end());
    cout << it - v.begin() << '\n';
    // 앞에서 부터 중복되지 않게 채운 후 나머지 요소들은 그대로 둔다.
    for (int i : v) cout << i << "";
    cout << '\n';
    return 0;
}


이중 it - v.begin() 에서 이터레이터인 it 에서 v.begin을 빼는 이유는
unique 는 해당 자료형으로부터 이터레이터를 반환하기때문에 몇번째인지 추려내려면 이 이터레이터에서 배열의 초깃값을 빼주어야 함.

*erase 함수

배열의 특정부분을 지우고 싶을때 사용하는 함수

실습코드

 

int main()
{
    vector<int> v{ 1,1,2,2,3,3 };
    // 중복되지 않은 요소로 채우고, 그 다음 요소들을 삭제하고 싶다면..
    // erase의 첫번째 인자는 지우기 시작하는 시작점 이고 
    // 안에 들어간 첫번째 인자 unique(v.begin(),v.end())는 중복되지 않은 요소 다음 이터레이터를 반환하기때문에
    // 중복되지 않은 요소를 채우고 그 다음 요소들을 삭제할수있다. 
    v.erase(unique(v.begin(), v.end()), v.end());
}



*makePermutation 동작원리

n = 배열의 총 갯수

r = 순열로 뽑을 부분 배열의 갯수

depth = 배열 요소끼리 스왑을 하기 위한 기본 정수형 요소

인수가 3,3,0 이면
printf 조건이 r == depth 일때이므로 depth가 3까지 올라간경우만 생각
Swap 같은 경우 다시 본래자리로 swap을 해주므로 밑 swap 코드는 생각하지않기 
재귀함수의 경우 재귀함수가 리턴을 받을때까지 밑에코드가 진행되지 않는다.

 i = 0 일때
 swap (0,0) => make(3,3,1) => swap(1,1) => make(3,3,2) => swap(2,2) => make(3,3,3) => 1,2,3
 swap (2,1) => a[] = 1,3,2 => make(3,3,3) => 1,3,2


 i = 1 일때
 swap (1,0) => a[] = 2,1,3 => make(3,3,1) => swap(1,1) => make(3,3,2) => swap(2,2) => make(3,3,3) => 2,1,3
 각 swap을 한상태에서 재귀함수가 도는 것이므로 맨앞 배열순서를 제외한 나머지 두개가 바뀐다.

 i = 2 일떄
 swap (2,0) => a[] = 3,1,2 => make(3,3,1) => swap(1,1) => make(3,3,2) => swap(2,2) => make(3,3,3,) => 3,1,2
 각 swap을 한상태에서 재귀함수가 도는 것이므로 맨앞 배열순서를 제외한 나머지 두개가 바뀐다.