Unity 내일배움캠프 TIL 1109 | STL과 함수 인자 | 표준 입출력

cheeseonrose·2023년 11월 9일
0

Unity 내일배움캠프

목록 보기
75/89
post-thumbnail

[바킹독의 실전 알고리즘] 0x02강 - 기초 코드 작성 요령 II

💡 STL과 함수 인자

🎅 함수 인자

// 01
void func(int a) {
	a = 5;
}
int main(void) {
	int t = 0;
	func(t);
	cout << t;
}

// 출력
// 0
  • 값이 복사되어 전달되므로 함수 내부에서 값을 바꿔도 원본은 변하지 않음

// 02
void func(int arr[]) {
	arr[0] = 10;
}
int main(void) {
	int arr[3] = {1, 2, 3};
	func(arr);
	cout << arr[0];
}

// 출력
// 10
  • arr의 주소를 넘겨주게 되므로 arr[0]의 값도 바뀜

// 03
struct pt{
	int x, y;
};
void func(pt a) {
	a.x = 10;
}
int main(void) {
	pt tmp = {0, 0};
	func(tmp);
	cout << tmp.x;
}

// 출력
// 0
  • 값이 복사되므로 원본에 영향을 주지 않음



🦌 참조자(Reference)

void swap1(int a, int b) {
	int tmp = a;
	a = b;
	b = tmp;
}
  • 복사된 값을 바꾸므로 원본은 바뀌지 않음

void swap2(int* a, int* b) {
	int tmp = *a;
	*a = *b;
	*b = tmp;
}
  • 포인터를 보내서 두 변수의 값을 바꿈

void swap3(int& a, int& b) {
	int tmp = a;
	a = b;
	b = tmp;
}
  • C++에서의 해결법인 참조자
    • a와 b는 int reference
  • 참조자는 C의 포인터와 거의 비슷한 기능을 하지만, 포인터에서 Null 포인터에 값을 넣거나 type이 다른 것을 마음대로 캐스팅하는 등의 문제들을 방지해줌



🎄 STL(Standard Template Library) - vector

  • C++에는 미리 다양한 알고리즘과 자료구조가 STL에 직접 구현되어 있어서, 필요한 자료구조를 직접 구현할 필요 없이 바로 가져다 사용 가능
  • vector STL
    • 원래 C++에서는 배열을 선언할 때 크기를 명시해야 함
    • vector는 일종의 가변 배열로 크기를 마음대로 늘렸다 줄였다 할 수 있음
    • vector 헤더에 선언되어 있음

vector<int> v(100);
v[20] = 10;
v[60] = -4;
void func1(vector<int> v) {
	v[10] = 7;
}

int main(void) {
	vector<int> v(100);
	func1(v);
	cout << v[10];
}

// 출력
// 0
  • STL도 구조체와 비슷하게 함수 인자로 보낼 때 복사본을 만들어서 보내므로, 함수 내에서 값을 바꿔도 원본 값에 영향을 주지 않음

bool cmp1(vector<int> v1, vector<int> v2, int idx) {
	return v1[idx] > v2[idx];
}
  • 두 vector의 크기가 N일 때, 이 함수의 시간 복잡도는 O(N)임
    → 원본으로부터 복사본을 만드는 비용
    → v1과 v2의 값만 복사하는데 O(N)의 비용이 드는 것은 비효율적

bool cmp2(vector<int>& v1, vector<int>& v2, int idx) {
	return v1[idx] > v2[idx];
}
  • 위 코드처럼 참조자를 사용하면 복사본을 만들지 않고 참조 대상의 주소 정보만 넘어가기 때문에 시간 복잡도가 O(1)임






💡 표준 입출력

🎁 scanf/printf와 cin/cout

  • C에서는 scanf/printf
  • C++에서는 cin/cout

int main(void) {
	string s = "potato";
	printf("s is %s\n", s);
}

// 출력
// s is     ?
  • scanf/printf에서는 C++ string을 처리할 수 없음

    • C에서는 char*로 문자열을 다루기 때문

    • C++ string을 활용하고 싶다면 char*로 입력 받고 string으로 형 변환을 한 뒤, 작업을 다 끝낸 뒤에 c_str() 메서드를 이용해 출력

      int main(void) {
      	char a[10];
      	printf("input : ");
      	scanf("%s", a);
      	string s(a);    // 혹은 string s = a;
      	printf("a is %s\n", a);
      	printf("s is %s\n", s.c_str());
      }
      
      // 출력
      // a is test
      // s is test

  • scanf와 cin 모두 공백 전까지만 입력을 받는 문제

    int main(void) {
    		char a[10];
    		printf("input : ");
    		scanf("%s", a);
    		printf("a is %s\n", a);
    }
    
    // input : hi hello
    // 출력
    // a is hi
    int main(void) {
    		string s;
    		cout << "input : ";
    		cin >> s;
    		cout << "s is " << s;
    }
    
    // input : hi hello
    // 출력
    // s is hi
    • 이에 대한 해결책은 3가지

      // 1. scanf의 옵션
      char a[10];
      scanf("%[^\n]", a1);
      
      // 2. gets 함수 (보안상의 이유로 C++ 14 이상에서는 제거됨)
      char a2[10];
      gets(a2);
      puts(a2);
      
      // 3. getline 함수
      string s;
      getline(cin, s);
      cout << s;

  • cin/cout에서는 입출력으로 인한 시간 초과를 막기 위해서 다음을 실행시켜야 함
    ios::sync_with_stdio(0)
    cin.tie(0)
    • 하지 않으면 입출력이 많을 때 시간 초과가 날 수 있음
    • sync_with_stdio(0) : C stream과 C++ stream의 동기화를 끊어서 실행 시간을 줄임
      • 동기화를 끊으면 cout과 printf를 섞어서 쓰면 안 된다는 것에 주의!!
    • cin.tie : cin 명령을 수행하기 전 cout 버퍼를 비우지 않도록 하는 코드
      • 입력을 받고 출력을 하기 전 버퍼에 넣어뒀다가 출력하는데, 이 과정에서 입출력 순서가 꼬일 수 있어서 항상 cin 명령 수행 전에 cout 버퍼를 비움
      • 하지만 코딩 테스트 채점에서는 출력 결과만 보기 때문에 입출력 순서가 꼬이더라도, 출력 순서만 맞으면 정답 처리 되므로 굳이 버퍼를 비우지 않도록 하는 것

  • endl
    • 개행문자(”\n”)을 출력하고 출력 버퍼를 비우는 명령어
    • 코딩 테스트에서는 중간 중간 버퍼를 비우라고 명령을 줄 필요가 없음
    • 줄바꿈이 필요하면 그냥 개행 문자를 사용하자!



위 모든 내용은 코딩 테스트 문제 풀이 요령이라는 것에 주의하자!!!



언어 공부할 생각에 신이 난다 ... . .. .

끗 ..

0개의 댓글