C++

[C++]중간고사 공부 로그

곽가누 2024. 3. 15. 16:36

2024.03.15

1. sizeof 함수

데이터 형식에 대한 크기를 바이트 단위로 출력

 

2. 삼항 연산자 ?

간단한 if 문으로, 식이 참이면 앞의 값을, 거짓이면 뒤의 값을 반환함

사용할 땐 ()를 묶어 줘야 함

#include <iostream>
using namespace std;

int main() {
    cout << "(7 == 5):" << (7 == 5 ? 0 : 1) << endl;

    return 0;
}

 

3. endl

줄바꿈. C++는 python과 다르게 기본적으로 줄바꿈이 적용되지 않는다. 

 

4. float과 나눗셈 

float을 사용해야 나눗셈이 소숫점까지 나옴

#include <iostream>
using namespace std;
int main() {
	int x, y, sum, mult;
	float div;
	cin >> x >> y;
	sum = x + y;
	mult = x * y;
	div = float(x) / float(y);
	cout << x << '\t' << y << endl;
	cout << "x + y = " << sum << endl;
	cout << "x * y = " << mult << endl;
	cout << "x / y = " << div << endl;

}

 

5. 큰따옴표

문장을 쓸땐 무조건 큰따옴표, 작은따옴표는 문자가 하나일 때

 

6. 한 프로젝트에서 여러 개의 main 함수가 있을 때

해당 파일 우클릭 - 속성 - 구성 속성 - 일반 - 빌드에서 제외

 

7. 이렇게 쓰면 계속 F만 출력됨

#include <iostream>
using namespace std;
int main() {
	char grade = 'X';
	int score;
	cout << "Enter your score: ";
	cin >> score;

	if (score >= 0 && score <= 100) {
		if (score >= 90){
			grade = 'A';
		}

		if (score < 90 && score >= 80) {
			grade = 'B';
		}

		if (score < 80 && score >= 70) {
			grade = 'C';
		}

		if (score < 70 && score >= 60) {
			grade = 'D';
		}
		else {
			grade = 'F';
		}

		cout << "Your grade is " << grade << endl;

	}

	else {
		cout << "The score (" << score << ") is invalid" << endl;

	}

	return 0;

}

else가 마지막 if 랑만 묶여서 score이 60~70 사이가 아니면 무조건 F가 나옴

-> else if 써야함

 

2024.04.04

8. 삼항 연산자를 쓸 땐 괄호로 꼭 두번씩은 묶어줄 것 

	cout << ((s1 == "Good-bye") ? true : false) << endl;

 

8-1. 그런데 다음과 같이 써도 상관없다.

cout << (s1 == "good-bye")  << endl

 

9. substr은 index 값 5번째부터 문자 3개를 출력하는 것이고, find는 가장 먼저 나오는 od위치를 찾아줌

s1 = "Good";
s1 = s1 + "-bye";
//Good-bye (string)

cout << s1.substr(5, 3) << endl; //bye
cout << s1.substr(2, 2) << endl; //od
cout << s1.find("od") << endl; // 2

 

10. 9번 응용

cout << s1.find("od", 5) << endl; //1844-
int od_index = s1.find("od");
cout << s1.find("od", od_index + 2); //1844-
cout << (s1.find("korea") == string::npos) << endl; //1

 

첫번째 줄은 od를 5번째 인덱스부터 찾으라는 의미이다.

세번째 줄은 od를 4번째 index부터 찾으라는 의미이다.

string::npos란 undefined된 값 중 가장 큰 값인데, 여기선 아마 1844~ 가 될 것이다

네번째 줄은 s1에서 korea를 찾았으면 그 인덱스를 반환할 텐데 찾지 못할 것이므로 값이 1844~ 로 나올 것이다. 

1844 ~ == 1844 ~ 이므로 값이 true 이다.

 

11. C++에서 true는 1값을 반환하고 false는 0값을 반환한다.

 

12. file 내용 읽는법 : 한 줄씩 읽기와 한 단어씩 읽기 

ifstream fin;
string s1;
fin.open("example.txt");
if (!fin) {
	cout << "Error, no such file exists" << endl;
	exit(100);
}

while (getline (fin, s1)) {
	cout << s1 << endl;
}
while (1) {
	fin >> s1; //fin 내용물을 s1에 할당. 이렇게 할당된 값은 자동으로 띄어쓰기 단위로 출력됨
	if(!fin)
		break;
	cout << s1 << endl; 


}
fin.close();

(while 문이 두개는 실행되지 않아 하나의 while문은 주석처리 해야한다)

 

13. width, precision, fill

width는 매번 지정해야하고

precision과 fill은 한번 저장하면 영구적으로 지정된다. 

(cf.flags는 거의 영구적 지정)

 

width는 출력값 길이를 지정하고

precision은 주요 자리수를 출력한다 

#include <iostream>
using namespace std;

int main() {
	double d1 = 1.23456789;
	double d2 = 123.2121;

	cout << d1 << endl;
	cout << d2 << endl;

	cout.precision(4); //출력값 길이 4으로 지정
	cout << d1 << endl;
	cout << d2 << endl;
	cout << 12.2112 << endl;


}

>>>

1.23457
123.212 (default 값은 6인가보다)


1.235
123.2
12.21

 

14. buffer와 cin

버퍼란, 임시 저장소와 같다. cin으로 입력을 받을 때, 우리가 썼다 지웠다 하는 걸 버퍼는 다 기록한다.

예를 들어, apple 이란 글자를 입력한다고 할 때 a, p, p, l, e, enter 까지 모두 입력이 된다. 

여기서 enter키도 버퍼는 저장하며, space 키 또한 저장된다. 

버퍼가 가득 차거나, 개행문자가 나타나면, 버퍼의 내용을 한번에 전송한다. 

 

cin은 버퍼에 무엇인가가 있는 경우, 입력을 받지 않는다. 

그리고 버퍼는 선입선출이다. 

 

cin.ignore();은 enter가 다음 cin으로 들어가지 않도록 해준다. 

cin.unsetf(ios::skipws);는 white-space를 skip하는걸 끈다. 즉 스페이스바도 잘 저장하겠다는 뜻이다. 

코드로 보면, 

#include <iostream>
using namespace std;

int main() {

	char ch1;
	char ch2;

	// ch1, ch2 : enter “ z”. ( space + z )
    
	cin >> ch1; //spacebar는 default로 저장이 되지 않는다
    //버퍼 상태 :[z][Enter] 
    
	cout << "(" << ch1 << ")" << endl; //[z] 버퍼에서 나감 : 선입선출
    //버퍼 상태 :[Enter] 

	//cin.ignore(); //[Enter] 무시 : 선입선출 
    //버퍼 상태 : None 즉, 입력 받아야함

	cin.unsetf (ios::skipws); //spacebar 저장되게끔 flag 내림
    
    // ch1, ch2 : enter “ z”. ( space + z )
    
	cin >> ch2; 
    //버퍼 상태 : [ ][z]
    
	cout << "(" << ch2 << ")" << endl; //[ ]버퍼에서 나감 : 선입선출 
    

	return 0;

}

 

15. ifstream(읽기전용), ofstream(쓰기전용), fstream(읽기쓰기 둘다 가능)

선언할 땐, ifstream [변수명] 

 

16. 객체지향적 파일 잘 불러왔는지 확인하는 함수

bool getStu(ifstream& fin, int& id, int& exam1, int& exam2, int& exam3) {
	fin >> id >> exam1 >> exam2 >> exam3;
	if (!fin)
		return false;
	return true;
}

 

17. c++의 size와 length는 한국어를 자음 모음 단위로 인식한다.

#include <iostream>
#include <string>

using namespace std;
string keyword = "집밥";
cout << keyword.length();

>>> 6

 

18. 그리고 단어 찾을땐 count 값에다가 단어의 길이를 꼭 더해주어야 한다.

int main() {
	string data = "사랑,프로그래밍,의자,사랑의바보,영통역,천년의사랑,냉장고,객체지향,향";
	string keyword;
	int searchResult; 

	
	cout << "키워드 : ";
	cin >> keyword;
	int count = 0;
	while (count < data.size()) {
		
		
		searchResult = data.find(keyword, count);
		cout << data.length()<<endl;
		//cout << searchResult;
		count += searchResult + keyword.length();


	}

 

2024.04.07

19. file 2개 합병 : while 문 이런식으로 하면 두번 쓸 수 있긴 함 

#include <iostream>
#include <fstream>
#include <string>

using namespace std;

int main() {
	ifstream inputStream;
	ofstream outputStream;
	string line;

	inputStream.open("inputText1.txt");
	outputStream.open("output.txt");

	while (getline(inputStream, line)) {
		outputStream << line << endl;
	}
	inputStream.close();

	outputStream << endl;

	inputStream.open("inputText2.txt");
	while (getline(inputStream, line)) {
		outputStream << line<<endl;
	}
	inputStream.close();
	outputStream.close();

	return 0;
}

 

20. spacebar 반영 여부

while (input >> ch) {
	cout << ch<<endl;
}

이러면 spacebar 반영 안되고 글자만 출력됨

while (input.get(ch)) {
	cout << ch<<endl;
}

이러면 spacebar도 반영됨

 

21. 어려웠던 LAB_07 응용문제 2번 통오답

#include <iostream>
#include <string>

using namespace std;
 
int main() {
	string data = "사랑,프로그래밍,의자,사랑의바보,영통역,천년의사랑,냉장고,객체지향,향";
	string keyword, word;
	string delimeter = ",";

	int cursorIndex = 0;

	//사랑
	cout << "키워드 : ";
	cin >> keyword ;
	cout << endl << "검색결과 : ";
	while ((cursorIndex = data.find(delimeter)) != string::npos) { //1
		word = data.substr(0, cursorIndex);
		data = data.substr(cursorIndex + 1);

		if (word.find(keyword) != string::npos) { //2
			cout << word;
		}
	}

	if (data.find(keyword) != string::npos) { //2
		cout << word;
	}
}

//1. 계산 누가 먼전지 생각하기 싫으면 괄호 바로바로 넣어주기

//2. word에 keyword가 존재한다고 해서 if(word.find(keyword))이렇게 쓰지 말고

if(word.find(keyword) != string::npos))식으로 써주어야 글자가 안 깨진다. 

 

2024.04.11

22. pointer

#include <iostream>
using namespace std;

void swap(int* x, int* y) {
	//x는 주소, *x는 값
	int temp = *x; //temp는 x의 실제값 : 10
	*x = *y; 
	*y = temp;
}

int main() {
	int a = 10, b = 20;
	cout << a << ", " << b << endl;
	swap(&a, &b);
	cout << a << ", " << b << endl;
	return 0;
}

 

23. function pointer - method1

#include <iostream>
using namespace std;

int sum(int x, int y) { return x + y; }
int mult(int x, int y) { return x * y; }



int main() {
	int(*func)(int, int); // 함수 포인터 선언
	func = &sum;
	cout << func(10, 20) << endl;
	func = &mult;
	cout << func(10, 20) << endl;
	return 0;

}

 

24. function pointer - method2

#include <iostream>
using namespace std;

int sum(int x, int y) { return x + y; }
int mult(int x, int y) { return x * y; }

int evaluate(int (*func)(int, int), int x, int y) {
	return func(x, y);
}

int main() {
	cout << evaluate(&sum, 100, 200) << endl;
	cout << evaluate(&mult, 100, 200) << endl;
	return 0;

}

 

25. 다음과 같이 쓰면 함수의 주소 출력됨

cout << &(*func) << endl;

 

26.vector 도는 문법! - 벡터 객체에 전체적으로 접근하려면 반복문 사용해야함

여기선 call by reference를 썼다.

#include <iostream>
#include <vector>
using namespace std;
void print(const vector<int>& v) {//로컬 벡터 
	for (unsigned i = 0; i < v.size(); i++)
		cout << v[i] << "\t";
	cout << endl;
}

int main() {
	vector<int> vec{ 10, 20, 30 };
	print(vec);

	vec[0] = 100;
	vec.at(1) = 200;
	print(vec);
	
	vec.push_back(400);
	print(vec);

	vec.pop_back();
	print(vec);

	cout << endl;

	for (int& elem : vec) {
		cout << "enter an element of vector v: ";
		cin >> elem;
	}

	cout << endl << "[ vector v ]" << endl;

	for (int elem : vec) 
		cout << elem << "\t";
	cout << endl;

	return 0;
}

 

call by reference vs call by pointer

  • 함수 정의나 호출 시 매개변수의 선언을 보면 구분할 수 있습니다. 매개변수가 참조(&)로 선언되어 있으면 "call by reference", 포인터(*)로 선언되어 있으면 "call by pointer"입니다.
  • 함수 내에서 매개변수를 사용하는 방식을 보면 구분할 수 있습니다. 매개변수를 역참조하여 변수를 수정하면 "call by pointer", 직접 사용하면 "call by reference"입니다.

2024.04.18

27. 여기서 vector<int> primes(int lower, int upper)는 함수이다!! 리턴값도 있잖아.. 

#include <iostream>
#include <iomanip>
#include <vector>
using namespace std;

bool is_prime(int num) {
	if (num < 2)
		return false;
	for (int i = 2; i < num; i++) {
		if (num % i == 0)
			return false;
	}
	return true;
}

vector <int> primes(int lower, int upper) {
	vector<int> v;
	for (int i = lower; i <= upper; i++) {
		if (is_prime(i) == true) {
			v.push_back(i);
		}
	}
	return v;
}

int main() {
	int lower = 10, upper = 100;
	vector<int> vec = primes(lower, upper);
	for (int elem : vec) 
		cout << elem << setw(5);
	cout << endl;

	return 0;
}

 

28. 벡터를 call by pointer 하고 싶을 땐 다음과 같이 (*vec)[i] 형태와 같이 써야한다. 

#include <iostream>
#include <vector>
using namespace std;

void function(vector<int>* vec) {
	for (int i = 0; i < 5 ; i++) {
		int temp = (*vec)[i];
		(*vec)[i] = (*vec)[9 - i];
		(*vec)[9 - i] = temp;
	}

}

int main() {
	vector<int> vec(10);
	cout << "기본 Vector 값:" << endl;
	for (int i= 0; i < vec.size(); i++) {
		vec[i] = i+1;
		cout <<" " << vec[i];
	}

	cout << endl;
	function(&vec);

	cout << "함수 실행 후 Vector 값:" << endl;
	for (int i = 0; i < vec.size(); i++) {
		cout << " " << vec[i];
	}

	return 0;

}

2024.04.19

29. Array 동적 할당 

#include <iostream>
#include <vector>
using namespace std;

int main() {
	const int size = 3;
	int list[size] = { 10, 20, 30 };

	int length = 3;
	cin >> length;
	int* list2 = new int[length];
    
	// 메모리 heap에 length만큼의 연속된 정수형 데이터를 위한 공간을 할당하고, 
	// 그 시작 주소를 list2 포인터에 저장합니다.
	
	cout << list2 << endl << &list2;
    //list2는 list2의 첫번째 원소의 주소, &list2는 list2 배열의 주소
    
    delete [] list2;
}

int new를 선언할 때 포인터도 int로 선언했는데, 

배열의 값이 double이면 포인터도 double로 해주어야 한다. 

 

29-1. 그래서 begin, end와 같은 변수를 지정하면 주소와 int의 연산이 가능하다..

#include <iostream>
#include <vector>
using namespace std;

int main() {
	const int size = 3;
	int list[size] = { 10, 20, 30 };

	int length = 3;
	cin >> length;
	int* list2 = new int[length];

	
	int* begin = list2;
	int* end = list2 + length;

	cout << "list2 : " << list2 << " length : " << length << endl;
	cout << "begin : " << begin << " end : " << end;

	
    delete[] list2;
	
	return 0;
}

 

결과 :

5
list2 : 00000274AE2F3310 length : 5
begin : 00000274AE2F3310 end : 00000274AE2F3324

 

30. 동적행렬 만들기

int main() {
	int nRow = 2, nCol = 2;
	int** matrix2;
	matrix2 = new int* [nRow];
	for (int i = 0; i < nRow; i++)
		matrix2[i] = new int [nCol];

	matrix2[0][0] = 1; matrix2[0][1] = 2;
	matrix2[1][0] = 3; matrix2[1][1] = 4;

	print(matrix2, nRow, nCol);

	for (int i = 0; i < nRow; i++)
		delete[] matrix2[i];
	
	delete[] matrix2;

	return 0;

}

 

31. 포인터는 다른 변수의 주소 뿐만 아니라 literal 값의 주소 또한 저장할 수 있다.

#include <iostream>
using namespace std;

int main() {
	const char* phrase = "this is a phrase";
	cout << phrase; //this is a phrase
	cout << &phrase;//this is a phrase가 들어간 주소 ,t의 주소값이 출력되지만 추후 반복문을 사용하게 되면 뒤의 char 주소도 출력 가능
	cout << *phrase;//t
}

 

31-1. 다른 문자열의 주소도 출력하는법

#include <iostream>
using namespace std;

int main() {
    const char* phrase = "this is a phrase";

    // 문자열의 각 문자의 주소를 출력
    for (const char* ptr = phrase; *ptr != '\0'; ++ptr) {
        cout << "Address of '" << *ptr << "': " << (void*)ptr << endl;
    }

    return 0;
}

 

32. 이코드의 문제점 : 변하는 문자열을 elem이라는 새 변수에 할당하면, *s = p로 고정됨

#include <iostream>
#include <vector>
using namespace std;

bool found_char(const char* s, char ch) {
	for (char elem = *s; elem != '\0'; elem++) { //문제의 부분
		if (elem == ch) {
			cout << elem;
			return true;
		}
	}
	return false;
}

int main() {
	const char* phrase = "phrase";

	for (char ch = 'a'; ch <= 'z'; ch++) {
		cout << ch << " is ";
		if (!found_char(phrase, ch))
			cout << "NOT";
		cout << " in (" << phrase << ")" << endl;
	}

	return 0;

 

올바른 코드 : *s를 그대로 받아와야 한다. 

#include <iostream>
#include <vector>
using namespace std;

bool found_char(const char* s, char ch) {
	for (; *s != '\0'; s++) {
		if (*s == ch) {
			return true;
		}
	}
	return false;
}

int main() {
	const char* phrase = "phrase";

	for (char ch = 'a'; ch <= 'z'; ch++) {
		cout << ch << " is ";
		if(!found_char(phrase, ch))
			cout << "NOT";
		cout << " in (" << phrase << ")" << endl;
	}

	return 0;
}

 

2024.04.21

33. cout << array를 하면 디폴트값으로 array의 첫번째 주소값이 나오게 된다. 

code 1

	int list[3] = { 10, 20, 30 }; //Array
	cout << (list + 0) <<'\t' << *(list + 0) << endl;
	cout << (list + 1) << '\t' << *(list + 1) << endl;
	cout << (list + 2) << '\t' << *(list + 2) << endl;

 

code 2

	cout << &list[0] <<'\t' << list[0] << endl;
	cout << &list[1] << '\t' << list[1] << endl;
	cout << &list[2] << '\t' << list[2] << endl;

 

두 코드는 같은 값이 출력된다

cout << array를 하게 되면 array의 주소값이 출력된다. 그리고 이는 첫번째 요소의 주소값과 같다. 

 

2024.04.24

34. 교수님이 구현해보라고 하신 피보나치 수열

#include <iostream>
using namespace std;
long long fibo(int n) {
    long long* arr = new long long[n];
    arr[0] = 1;
    arr[1] = 1;

    for (int i = 2; i < n; i++) {
        arr[i] = arr[i - 1] + arr[i - 2];
    }

    long long result = arr[n - 1];
    delete[] arr;
    return result;
}
int main() {
    int n;
    cin >> n;
    cout << fibo(n);

}

keypoint : long long을 알맞게 쓰는것이 중요하다. 

 

35. 쉼표 만들기 :  locale liabrary 사용 

#include <iostream>
#include <iomanip>
#include <locale>
using namespace std;
int main() {
    int power = 1;
    cout.imbue(locale(""));
    while (power <= 10000000) {
        cout << setw(10) << power << '\n';
        power *= 10;
    }
}

 

36. 조건을 충족시킬때까지 while 문 돌리는 코드

초기조건 설정 : value를 밖에다가 지정해주고 value 값을 바꿀 때까지 while 문을 실행한다. 

#include <iostream>

int main() {
    int in_value = -1;

    std::cout << "Please enter an integer in the range 0-10: ";

    // 입력 값이 0과 10 사이인지 확인
    while (in_value < 0 || in_value > 10)
        std::cin >> in_value;

    // 유효한 값 출력
    std::cout << "Legal value entered was " << in_value << '\n';
    return 0;
}

 

37. switch 

시험에 안 나올거 같긴 한데, switch는 자잘한 케이스들이 많을 때 사용되는 거 같다. 

#include <iostream> 

int main() {
    int value;
    std::cout << "Please enter an integer in the range 0...5: "; 
    std::cin >> value;
    
    switch (value) { 
        case 0:
            std::cout << "zero"; 
            break;
        case 1:
            std::cout << "one"; 
            break;
        case 2:
            std::cout << "two"; 
            break;
        case 3:
            std::cout << "three"; 
            break;
        case 4:
            std::cout << "four"; 
            break;
        case 5:
            std::cout << "five"; 
            break;
        default:
            if (value < 0)
                std::cout << "Too small"; 
            else
                std::cout << "Too large";
    }

    std::cout << '\n';
    
    return 0;
}

 

첨언하자면, case를 붙여 쓰면 같은 상황 취급을 할 수 있다.

 

40. string 함수 정리

다 function이기 때문에 ()와 같이 쓴다. 

 

at : n번째 값을 리턴

length = size : string의 길이 리턴

find : index를 리턴, str.find("is")이런것도 가능

substr : n번째부터 m개의 문자열을 리턴

empty : 배열이 비었으면 true, 뭐라도 있음 false를 리턴

clear : 배열 다지워버림

 

41. Stream Flags 정리

fixed 

scientific

hex 16진수표현

skipws : buffer에서 white space를 무시하지 않음(white space도 잘 입력되게 함)

cin.unsetf(ios::skipws);

 

42. vector 함수 정리

push_back

pop_back 

at

size

empty

clear

 

43. 읽기 목적이면 함수로 벡터 넘길때 const 꼭 붙여줄 것 !!

'C++' 카테고리의 다른 글

[Data Structure] Reviewing Up wrong C++ codes 2  (0) 2024.11.30
[Data Structure] 중간고사 정리  (2) 2024.10.20
[Data Structure] Reviewing Up wrong C++ codes  (1) 2024.10.04
[C++] 기말고사 공부 로그  (0) 2024.05.20
[C++] Vector와 Array  (0) 2024.04.21