코딩 스터디

[241006] C++ 스터디 1주차

jisu0924 2024. 10. 8. 23:47

현재 학교에서 C++ 강의를 수강하고 있어 C++을 중심으로 문제를 풀 예정.

CODE UP 사이트의 C언어 기초 100제 문제를 바탕으로 풀이한다.


 

1005 : [기초-출력] 출력하기05(설명) 

문제는 다음과 같다. 출력하기 01-04는 중복되므로 생략한다.

더보기

이번에는 큰따옴표(double quotation mark)가 포함된 출력문을 연습해보자.

다음 문장을 출력하시오.

"Hello World"
(단, 큰따옴표도 함께 출력한다.)

참고
printf( ) 함수로 큰 따옴표 문자 " 를 출력하기 위해서는 \" 로 출력해야 한다.

예시
printf("\"");

** 주의 : 본 화면에서 복사하여 붙여넣기하면 제대로 되지 않을 수 있으니 직접 작성해야한다.

모든 코딩 문제의 첫 번째 문제라 할 수 있는 ''Hello World'' 출력 문제이기 때문에 문제 자체는 굉장히 쉽다. 그러나 큰 따옴표를 출력하기 위해서 ""안에  "Hello World"만 입력하면 제대로 출력이 되지 않는다. 

#include <iostream>
using namespace std;

int main(){
    cout << ""Hello World"";
}

를 실행하면 다음과 같이 컴파일 에러가 발생한다.

이는 "은 C++에서 문자가 아닌 문자열을 나타내기 위해 쓰는 하나의 도구로 인식하기 때문이다. 따라서 문제를 해결하기 위해서는 "앞에 \를 붙여 \"의 형태로 써 주어야 한다. \를 쓰면 "가 문자로 인식되어 문제에서 요구하는 "Hello World"를 출력할 수 있게 된다.

 

올바른 코드는 다음과 같다.

#include <iostream>
using namespace std;

int main(){
    cout << "\"Hello World\"";
}

 

콘솔창


1010 : [기초-입출력] 정수 1개 입력받아 그대로 출력하기(설명) 

문제는 다음과 같다.

더보기

정수형(int)으로 변수를 선언하고, 변수에 정수값을 저장한 후
변수에 저장되어 있는 값을 그대로 출력해보자.

예시
int main()
{
    int n;
    scanf("%d", &n);
    printf("%d", n);

    return 0;
}

와 같은 형태로 가능하다.

말 그대로 정수형 변수를 선언한 후 값을 출력하면 된다. 예시는 C언어이기 때문에 C++로 출력하기 위해서는 다음과 같은 형식으로 코드를 써야 한다. 우선, C++은 <iostream> 헤더 파일을 사용하는데, 이 헤더파일은 표준 입출력을 위한 객체, 클래스, 변수 등이 선언된다.(cin, <<과 같은)

#include <iostream>

이후 std::cout << ~;와 같은 복잡한 식을 간단히 하기 위해 using 지시어를 사용한 후 namespace 키워드를 사용해 std라는 이름 공간을 생성해 주면 cout만 간단히 입력하여 코드를 작성할 수 있다. main()함수는 C와 동일

#include <iostream>
using namespace std;

int main(){
}

정수를 선언하기 위해서는 정수형 변수를 먼저 선언해 주어야 한다.(C와 동일) 

#include <iostream>
using namespace std;

int main(){
    int n;
}

이후 변수에 들어갈 값을 입력받은 후 이를 출력해 주어야 한다. C에서는 scanf와 printf를 사용하지만 C++에서는 각각 cin, cout을 사용하여 코드를 작성한다. 따라서

#include <iostream>
using namespace std;

int main() {
    int a;  // 정수형 변수 a 선언
    cin >> a;  // 사용자로부터 정수형 숫자를 입력받음
    cout << a;  // 입력받은 숫자를 출력
}

과 같이 작성해 주면 된다.  따라서 답은 위의 코드가 된다. C에서는 정수형 변수기 때문에 %d를 사용하여 출력해야 하는 것과 달리 C++에서는 단순히 선언한 변수만 입력해 주어도 코드가 완성된다.

콘솔창

 

코드를 보면 둘의 연산자가 다른 것을 볼 수 있는데 cin은 스트림 주출 연산자를 사용하는 반면 cout은 스트림 삽입 연산자를 사용하기 때문이다. 또한, return 0;이 필요없는 이유는 컴파일러가 자동적으로 return 0;을 추가해 주기 때문이다.


1014 : [기초-입출력] 문자 2개 입력받아 순서 바꿔 출력하기(설명)

문제는 다음과 같다.

더보기

2개의 문자(ASCII CODE)를 입력받아서 순서를 바꿔 출력해보자.

참고
char x, y;
scanf("%c %c", &x, &y);
printf("%c %c", y, x); //출력되는 순서를 작성
와 같은 방법으로 해결할 수 있다.

문자 두 개를 입력받기 위해서는 C와 동일하게 문자형 변수를 선언해야 한다.

#include <iostream>
using namespace std;

int main(){
    char x;
}

여기서 두 개의 문자를 입력하기 위해서는 C와 동일하게 문자형 변수 x, y를 선언해 주어야 한다. 이후 C에서는 문자 두 개를 입력하기 위해서 %c %c를 동시에 ""안에 넣어 입력할 수 있지만 C++에서는 두 개를 입력하기 위해 다음과 같이 나눠서 작성해야 한다.

#include <iostream>
using namespace std;

int main() {
    char x, y;
    cin >> x;
    cin >> y;
    cout << x;
    cout << y;
}

 

위와 같이 작성 가능하나 하나씩 작성하게 되면 코드가 너무 길어지기 때문에 따로 쓰되 다음과 같이 코드를 붙이는 것이 가능하다.

#include <iostream>
using namespace std;

int main() {
    char x, y;
    cin >> x >> y;
    cout << x << y;
}

그러나 이 코드를 실행하면 띄어쓰기를 했음에도 불구하고 공백없이 문자가 출력되는 것을 볼 수 있다.

콘솔창

따라서 공백을 입력하기 위해서는 cout에서 따로 " " 를 중간에 입력해 주면 된다. 여기서 더 추가되는 것은, 문제를 보면 둘의 순서를 바꾸어서 출력하라 했기에 cout에서 x와 y의 위치를 바꾸어 주면 된다.

#include <iostream>
using namespace std;

int main() {
    char x, y;
    cin >> x >> y;
    cout << y << " " << x;
}

콘솔창


1018 : [기초-입출력] 시간 입력받아 그대로 출력하기

문제는 다음과 같다.

더보기

어떤 형식에 맞추어 시간이 입력될 때, 그대로 출력하는 연습을 해보자.

참고
scanf( ) 함수는 지정한 형식(format)에 따라 입력받는 함수이다.
따라서, 입력받고자 하는 형식으로 표현해주면 된다.

예시
scanf("%d:%d", &h, &m); //콜론(:) 기호를 기준으로 두 수가 각 변수에 저장된다.

C에서는 예시와 같이 정수형 숫자 두 개를 입력하고 가운데에 :를 넣어 구분하여야 하지만 C++는 문자열 변수를 선언하는 string을 사용해 간단하게 풀 수 있다. 방법은 정수형 숫자 하나를 출력하는 것과 같은데, int만 string으로 변경해 주면 된다.

#include <iostream>
using namespace std;

int main() {
    string n;
    cin >> n;
    cout << n;
}

두 개를 입력받지 않고도 한거번에 숫자와 문자를 입력하여 문제를 해결할 수 있다.

콘솔창


마지막 문제는 C++ 수업에서 짠 코드를 복습해 보려 한다. 코드는 다음과 같다.

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

class Circle {
private:
	int radius;
	string color;
public:
	Circle(); //기본 생성자
	Circle(int r) { radius = r; }; //매개변수 생성자
	Circle(int r, string c) { radius = r; color = c; };
	double getArea(); //멤버 함수
	int getRadius();
	string getcolor() {return color;};
	//리턴값 없음
	void setRadius(int r) { radius = r; };
};

//기본 생성자
Circle::Circle():Circle(1) {
	//radius = 1;
}

double Circle::getArea()  {
	return 3.14 * radius * radius;
}

int Circle::getRadius()
{
	return radius;
}

int main() {
	Circle donut; //기본 생성자
	//donut.radius = 1; // donut 객체의 반지름을 1로 설정
	double area = donut.getArea(); // donut 객체의 면적 알아내기
	cout << "donut 면적은 " << area << endl;

	Circle pizza(30); //매개변수 생성자
	//pizza.radius = 30; // pizza 객체의 반지름을 30으로 설정
    area = pizza.getArea(); // pizza 객체의 면적 알아내기
	cout << "pizza 면적은 " << area << endl;
    
	//pizza.getRadius = 28;
	pizza.setRadius(28);
	cout << pizza.getRadius() << endl;

	Circle donut2(5, "YELLOW"); //매개변수Circle(int, string)
	cout << "반지름 : " << donut2.getRadius() << ", 색상 : " << donut2.getcolor();
}

이 코드는 Circle이라는 클래스를 선언한 후 그 안에서 donut, pizza, dodut2라는 객체를 생성하여 면적과 반지름, 색상을 출력하는 코드이다. 클래스를 선언할 때는 main 함수와는 별개로 독립된 class 선언이 필요하며, main 함수와 클래스 선언이 함께 존재해야 한다. 기본 구성은 다음과 같다.

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

class Circle {
}; //';' 필수


int main() {
}

여기서, 접근 지정자를 사용해 클래스 내부에서만 멤버를 사용할 수 있도록 제한할지(private), 모든 클래스에서 접근 가능하도록 할지(public)를 결정해야 한다. 형식은 다음과 같다.

class Circle {
private:

public:

};

 

이제 클래스에 radius와 color라는 멤버 변수를 추가한다.

class Circle {
private:
    int radius;
    string color;
public:

};
  • radius는 원의 반지름을 저장하는 정수형 변수이다.
  • color는 색상을 저장할 문자열 변수이다.

이 두 변수는 private에 속해 있기에 외부에서 직접 접근이 불가능하다. 반지름과 색상을 외부에서 접근하게 하기 위해서는 public에 getRadius()와 같은 함수를 사용해야 하는데 이는 뒤에 가서 설명하겠다. 

 

private에 멤버 변수를 추가해 주었다면 이제 기본 생성자와 매개변수를 받는 생성자를 추가해 주어야 한다. 기본 생성자는 Circle()처럼 () 안에 아무것도 추가하지 않은 생성자를 말한. 매개변수를 받는 생성자는 () 안에 변수를 받는(예: int r) 생성자로, ()에 변수를 선언해 준다.

class Circle {
private:
    int radius;
    string color;
public:
    Circle(); // 기본 생성자
    Circle(int r); // 매개변수 생성자(반지름)
    Circle(int r, string c); // 매개변수 생성자 (반지름, 색상)
};

여기서 radius와 color가 하나의 값을 전달받아 초기화하기 때문에 매개변수 옆에 Circle(int r) { radius = r; }; 과 같이 생성자가 초기화 작업을 해줄 수 있다. 여기서 멤버 변수가 이미 존재함에도 값을 다시 정의하는 이유는 변수가 private으로 선언되어 있기 때문이다. radius는 r로, color는 c로 정의하고 코드를 짜면 다음과 같다.

class Circle {
private:
    int radius;
    string color;
public:
    Circle();
    Circle(int r); { radius = r; };
    Circle(int r, string c); { radius = r; color = c; };
};

 

이제 멤버 변수를 추가해 주었으니 멤버 함수를 만들어 주어야 한다. 면적을 계산해 주는 getArea()함수와 반지름을 출력해주는 getRadius(), 색상을 출력해 주는 getcolor() 함수를 각각 선언해 준다.

class Circle {
private:
    int radius;
    string color;
public:
    Circle();
    Circle(int r); { radius = r; };
    Circle(int r, string c); { radius = r; color = c; };
    double getArea(); // 멤버 함수
    int getRadius();
    string getcolor() { return color; };
};

여기서 getcolor() 함수에서 바로 return color;를 할 수 있는 이유는, getcolor() 함수의 역할이 현재 객체의 color 값을 반환하는 것이기 때문이다. 이제 클래스 외부에서 기본 생성자를 정의해야 한다. 기본 생성자만 따로 정의하는 이유는, 매개변수 생성자는 클래스 내부에서 이미 값을 설정해 주었기 때문이다. 

 

기본 생성자는 다음과 같이 구현 가능하다.

Circle()::Circle() {
    radius = 1;
}

그러나 코드를 조금이라도 간소화하기 위해서는 위임 생성자라는 생성자를 사용하여 다음과 같이 간소화 가능하다.

Circle()::Circle()::Circle(1) {
}

생성자를 외부에 구현해 준 것과 같이 멤버 함수 또한 구현을 해 주어야 한다. 이는

이렇게 생성자에 초록색 밑줄이 그어져 있는 것에 마우스를 가져다대고 저 도구 모양을 눌러 보면 <Circle에서 소스파일' 정의 만들기> 라는 선택창이 뜨는 걸 볼 수 있다. 이것을 클릭하

클래스의 소스 파일 정의를 자동으로 생성할 수 있다. 이를 이용하여 getArea()와 getRadius() 함수의 틀을 구현해 보았다. 

double getArea() //면적을 구하는 식에 3.14와 같은 실수가 들어가기 때문에 double
{
    return 0.0;
}

int getRadius()
{
    return 0;
}

여기서 getArea()는 면적을 가리키고 getRadius는 반지름을 가리키기 때문에 각각 return에 값을 담아주면 다음과 같다.

double Circle::getArea()  {
	return 3.14 * radius * radius;
}

int Circle::getRadius()
{
	return radius;
}

이렇게 하면 Circle 클래스 구현이 완료되었다. 이제 main()함수를 채워 나가야 한다. 우선 첫 번째로 Circle의 객체들을 구현해 주어야 한다. 앞에서 말했듯, donut과 pizza, donut2를 생성해 준다.

int main() {
	Circle donut; //기본 생성자

	Circle pizza(30); //매개변수 생성자

	Circle donut2(5, "YELLOW"); //매개변수 Circle(int, string)
}

이렇게 생성해 준 후 해야 할 일은 Circle 클래스에서 작성한 함수를 main()에 사용해 주어야 하는 것이다. donut/pizza는 면적을, donut2는 반지름과 색상을 출력해 주어야 하는데, donut2는 멤버 함수가 변수 그대로를 나타나기 때문에

int main() {
	Circle donut; //기본 생성자

	Circle pizza(30); //매개변수 생성자

	Circle donut2(5, "YELLOW"); //매개변수 Circle(int, string)
	cout << "반지름 : " << donut2.getRadius() << ", 색상 : " << donut2.getcolor();
}

와 같이 cout만 입력해 주어도 된다. 그러나 면적을 구해야 하는 donut과 pizza는 실수형 변수 area를 추가해 주어 면적을 따로 구해주어야 한다. area는 donut/pizza.getArea() (<- 면적 구하는 식이 담겨 있음) 이기 때문에 식을 완성해 주면 다음과 같다.

int main() {
	Circle donut; 
	//donut.radius = 1; // donut 객체의 반지름을 1로 설정, 이는 위에서 해 주었다.
	double area = donut.getArea(); // donut 객체의 면적 알아내기
	cout << "donut 면적은 " << area << endl;

	Circle pizza(30); 
	//pizza.radius = 30; // pizza 객체의 반지름을 30으로 설정, 위에서 지정해 주었다.
    area = pizza.getArea(); // pizza 객체의 면적 알아내기
	cout << "pizza 면적은 " << area << endl;

	Circle donut2(5, "YELLOW"); 
	cout << "반지름 : " << donut2.getRadius() << ", 색상 : " << donut2.getcolor();

마지막으로, 완성된 코드를 보면

	//pizza.getRadius = 28;
	pizza.setRadius(28);
	cout << pizza.getRadius() << endl;

라는 코드가 추가로 쓰여 있는 것을 볼 수 있다. 이는 피자의 반지름을 수정해 주고 싶을 때 쓰는 코드로, 주석 처리 되어 있는 부분은 pizza의 반지름을 28로 수정해 주고 싶어서 작성하였지만 실행이 되지 않는 코드이다.

빨간줄이 그어지며 '바인인딩된 함수에 대한 포인터는 함수를 호출하는 데에만 사용할 수 있습니다'라 되어 있다.

이는 getRadius는 함수이지 변수가 아니기 때문이다. 함수는 값을 가져오는 역할을 하기에 값을 지정해 주는 기능이 있지 않다. 따라서 새로운 설정자 함수 set.Radius()를 사용하여 함수에 따로 수정할 반지름을 담아놔야 한다. 이는 다시 Circle 클래스의 public칸으로 이동하여 생성해준 멤버 함수 밑에 지정해 준다.

	void setRadius(int r) { radius = r; };

void를 사용하는 이유는 설정자 함수는 값을 반환할 필요가 없고, 그저 값을 다시 설정하는 역할만 하기 때문이다. (반환하는 함수는 getRadius())

추가한 후, main() 함수에서도

pizza.setRadius(28);

라는 코드를 통해 반지름을 28로 수정하고, 이를 출력하기 위해

cout << pizza.getRadius() << endl;

를 해 주면, 실행했을 때 다시 설정한 반지름값을 출력할 것이다. 이제 완성된 코드를 실행해 보면 다음과 같은 실행값을 보여준다.

'코딩 스터디' 카테고리의 다른 글

[250128] C 스터디 2주차  (0) 2025.01.29
[241125] C++ 스터디 5주차  (0) 2024.11.25
[241119] C++ 스터디 4주차  (0) 2024.11.20
[241112] C++ 스터디 3주차  (1) 2024.11.12
[241104] C++ 스터디 2주차  (0) 2024.11.04