728x90

1. 함수 오버로딩 개념

함수의 기능은 동일한데 매개변수만 다른 경우! (리턴형의 차이는 해당되지 않음)

 

*함수 오버로딩이 제대로 작동하지 않고 에러 나는 경우

1) 함수의 리턴형만 다른 경우

2) 이상의 함수에 대응되는 경우

 

2. 코드

#include <iostream>
using namespace std;

int sum(int, int);
float sum(float, float);

int main() {
    //함수의 오버로딩 = 함수의 다형(다양한 형태를 지닌)
    //"여러 개의 함수를 같은 이름으로 연결한다"
    //구분 기준: 입력 매개변수의 형태
    const int a = 1;
    const int b = 2;
    const float c = 1.5;
    const float d = 2.3;
    cout <<sum(a,b)<<endl;
    cout <<sum(c,d)<<endl;

    return 0;
}

int sum(int a, int b) {
    return a+b;
}

float sum(float c, float d) {
    return c+d;
}

3. 에러 슈팅

처음에는 main 함수를 이하와 같이 작성하였더니 에러가 발생하였다.

int main() {
    cout <<sum(1,2)<<endl; //ok
    cout <<sum(1.5, 2.3)<<endl; //에러 발생
    return 0;
}

위 코드를 이하와 같이 고쳤더니 해결되었다.

const int a = 1;
const int b = 2;
const float c = 1.5;
const float d = 2.3;
cout <<sum(a,b)<<endl;
cout <<sum(c,d)<<endl;

결국 함수 오버로딩의 핵심은 매개변수의 형태가 다른 것이다.

 

바뀐 코드에서는 const int와 const float 형태의 변수 a, b, c, d를 사용하여 함수 sum을 호출하고 있다.

이러한 형태로 함수 호출을 하면 컴파일러가 적절한 sum 함수를 선택할 수 있게 된다.

 

따라서 함수 오버로딩을 실행하기 전, 매개변수의 자료형을 미리 선언(int float 변수를 사용)해야 한다.

즉, 미리 변수에 값을 입력해두고, 해당 변수를 함수의 입력으로 사용하는 것이다.

 

원래 발생했던 에러의 이유는 매개변수의 형태가 충돌하고 있었기 때문이다.

728x90
728x90

 

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

class Printer {
private:
    char inputs[30];
public:
    void SetString(char* sentence);
    void ShowString();
};

inline void Printer::SetString(char* sentence){
    strcpy(inputs, sentence);
}

inline void Printer::ShowString() {
    cout << inputs << endl;
}

int main(){
    Printer pnt;
    pnt.SetString("Hello world!");
    pnt.ShowString();

    pnt.SetString("I love C++");
    pnt.ShowString();
    return 0;
}

 

질문

디테일이긴 하지만, strcpy에서 char* sentence -> sentence를 입력하는 이유는 무엇인가?


1. strcpy 함수는 source에서 destination으로 문자열을 복사하고, 복사 작업은 source에서 NULL 문자('\0')를 만날 때까지 계속됨

복사가 완료된 후 destination을 반환함.

destination은 충분한 크기로 선언되어야 하며, 복사할 문자열의 길이에 맞게 할당되어야 함.

 

2. strcpy 함수에는 두 개의 매개변수가 있음

  • destination (대상 문자열):  문자열을 복사한  결과가 저장될 대상 문자열을 가리키는 포인터

- destination char 배열 또는 char 포인터 선언

- 복사된 문자열은 destination 저장됨

- destination 충분한 크기로 선언되어야 하며, 복사될 문자열의 길이에 맞게 할당되어야

  • source (원본 문자열):

- 이 매개변수는 복사하려는 원본 문자열을 가리키는 포인터

- source const char 배열 또는 const char 포인터 선언

- source 가리키는 문자열이 destination 복사됨

 

3. 이 코드에서 char* sentence 대신 char sentence로 매개변수를 변경하면 컴파일 오류가 발생

char* sentence문자열을 가리키는 포인터를 받는 것이며, char sentence는 문자 하나를 저장하는 데 사용되는 단일 문자 변수임

 SetString 함수가 입력으로 받는 것은 문자열임. 문자열은 여러 문자로 구성되어 있으므로 문자열을 다루기 위해서는 문자열을 가리키는 포인터(char*)를 사용해야 함.

(char 변수 하나로는 문자열을 저장하고 복사하는 데 충분하지 않음)

 

 

 

728x90
728x90

1) c++ 클래스 디자인하기

#include <iostream>
using namespace std;

class Calculator {
private: //멤버변수
//    double a;
//    double b;
// 얘네들은 함수의 입력으로 바로 정의되는 거지, 멤버함수에서 생성하거나 입력하는 것이 아님

    int add; //멤버변수는: Class의 함수를 통해 직접 생성하거나, 값을 입력하거나, 조작할 대상
    int min;
    int mul;
    int div;

public: //멤버함수
    void Init();
    double Add(double a, double b);
    double Min(double a, double b);
    double Mul(double a, double b);
    double Div(double a, double b);
    void ShowOpCount();
};

inline void Calculator::Init(){
    add = 0;
    min = 0;
    mul = 0;
    div = 0;
}

inline double Calculator::Add(double a, double b){
    add ++;
    return a + b;}

inline double Calculator::Min(double a, double b){
    min ++;
    return a - b;}

inline double Calculator::Mul(double a, double b){
    mul ++;
    return a*b;}

inline double Calculator::Div(double a, double b){
    div ++;
    return a / b;}

inline void Calculator::ShowOpCount() {
    cout<<"덧셈: "<<add<<" "<<"뺄셈: "<<min<<" "<<"곱셈: "<<mul<<" "<<"나눗셈: "<<div<<endl;
}

int main(){
    Calculator cal;
    cal.Init();
    cout <<"3.2 + 2.4 = "<<cal.Add(3.2, 2.4)<<endl;
    cout <<"3.5 / 1.7 = "<<cal.Div(3.5, 1.7)<<endl;
    cout <<"2.2 - 1.5 = "<<cal.Min(2.2, 1.5)<<endl;
    cout << "4.9 / 1.2 = "<<cal.Div(4.9, 1.2)<<endl;
    cal.ShowOpCount();
    return 0;
}

/*3.2 + 2.4 = 5.6
3.5 / 1.7 = 2.05882
2.2 - 1.5 = 0.7
4.9 / 1.2 = 4.08333
덧셈: 1 뺄셈: 1 곱셈: 0 나눗셈: 2*/

 

2) 멤버변수 개념 다시 ~!

멤버변수는: Class의 함수를 통해 직접 생성하거나, 값을 입력하거나, 조작할 대상 (e.g. int add;)

- 함수의 입력으로 바로 정의되는 변수는, 클래스의 멤버변수로 선언하지 않음 (e.g. double a;)

 

3) 디자인 개괄 보기

(1) 클래스

class 클래스명 {

private:

      멤버변수 정의

public:

      멤버함수 정의 //이때 함수 정의까지 포함하면 클래스 구조가 너무 길어질 수 있으므로, 상속을 유지하되 inline 통해 클래스 밖으로 빼기

      //말 그대로 '선언;'만 하기

}

 

(2) 클래스 함수 - inline으로 정의

inline 자료형 클래스명::멤버함수(  ) {

함수 정의 ~ ~ ~ }

 

** 클래스 정의할 때는 괄호 따로 쓰지 않음

** 함수 정의할 때는 괄호 따로 씀. input이 반드시 있어야 하면, "자료형 input명"의 형태로 채우고, 아니면 공란으로 비워둠.

728x90
728x90

1. 인라인 함수의 사용

#include <iostream>

// 인라인 함수 정의 // 앞에 inline이 추가됨
inline int add(int a, int b) {
    return a + b;
}

int main() {
    int result = add(5, 3); // 인라인 함수 호출
    return 0;
}

 

2. 인라인 함수를 사용하지 않은 경우

#include <iostream>

// 일반적인 함수 정의
int add(int a, int b) {
    return a + b;
}

int main() {
    int result = add(5, 3); // 함수 호출
    return 0;
}

두 예시의 가장 중요한 차이점은: 함수 호출 방식 (inline 키워드)

- inline O : 함수 호출 대신 함수 내용이 호출 지점에 직접 삽입

함수 호출 오버헤드가 사라지고 코드 실행 속도가 향상

따라서, 인라인 함수는 그 함수 호출이 아주 많은 경우 성능 향상에 유용함!

  코드 삽입이기 때문에 재귀가 불가능!

 

↔️ inline X : 함수 호출이 발생하며, 함수 호출 및 복귀 주소 저장을 위한 스택 프레임이 생성됨

     → 작은 함수에서도 오버헤드 발생 (여러 번 호출될 시 성능 저하 가능)

 

**

어떤 함수가 특정 구조체에 의존적일 때, 해당 함수를 구조체 내부에서 상속하여 정의할 수 있음.

단, 구조체 코드에 대한 가독성을 높이기 위해서, 상속을 유지하되 구조체 정의 코드 밖으로 빼낼 수 있음.

이때 inline과 :: 코드를 활용함.

 

struct Car
{	int curSpeed;
	void Accel(); //함수 원형을 구조체 내부에 상속시켜 정의하되
    }

inline void Car::Accel() //구조체 코드 바깥으로 함수 정의를 빼냄 //이때 inline & :: 를 사용
{
	//~~~~ }

 

728x90
728x90

"Call by value"와 "call by reference"는 함수 호출 방식을 나타내는 용어

이 두 가지 방식의 주요 차이점: 함수에 인수를 전달하는 방법 & 함수가 인수를 처리하는 방법

 

1. Call by Value (값에 의한 호출):

  • 함수에 매개 변수로 ‘값’을 전달합니다.
  • 함수 내에서 매개 변수는 별도의 변수로 취급되며, 인수의 값이 복사되어 매개 변수에 저장됨
  • 따라서 함수 내에서 매개 변수의 값을 변경하더라도 호출자(caller/원본)의 변수는 영향을 받지 않음
  • C++에서 함수의 기본 호출 방식은 "call by value"
void modifyValue(int x) {
    x = x + 10;
}

int main() {
    int num = 5;
    modifyValue(num);
    std::cout << "num: " << num << std::endl; // 출력 결과: num: 5
    return 0;
}

 

2. Call by Reference (참조에 의한 호출):

 

"주소/참조 값을 전달받아서, 함수 외부에 선언된 변수직접 접근하는 형태의 함수 호출"

- 함수 입력으로 주소/참조 값이 전달되었다는 사실이 중요한 게 아니라

- 입력된 주소/참조 값을 통해 직접 외부 변수를 참조하여 모종의 행위(읽기/조작 등)을 했을 때 call-by-reference라 칭할 수 있음

  • 함수에 매개 변수로 ‘변수의 참조/주소’를 전달
  • 함수 내에서 매개 변수는 원래 변수와 동일한 메모리 위치를 참조하므로,
    함수에서 매개 변수를 수정하면 호출자(원본)의 변수가 직접 영향을 받음
  • C++에서는 매개 변수를 참조로 전달하려면 참조자(reference) 또는 포인터(pointer)를 사용해야 함

(1) 포인터 *를 활용 (주소)

void modifyValueByPointer(int* x) {
    *x = *x + 10;
}

int main() {
    int num = 5;
    modifyValueByPointer(&num);
    std::cout << "num: " << num << std::endl; // 출력 결과: num: 15
    return 0;
}

- 늘 느끼는 건데.. (?) 주소값은 메모리가 할당된 위치이고, 이 주소값 자체는 변하지 않고 고정됨.

반면, 해당 주소에 저장된 value 자체는 변형&조작의 대상이 됨.

 

- 단, 이하와 같은 방식으로, 포인터를 통해 value를 직접 조작하는 것을 막을 수 있다.

const int* ptr1 = &num; //ptr1를 이용해서 num의 value를 바꿀 수 없음 //*ptr1를 상수화시켰다는 의미

*주의할 점은, ptr = 2; ptr이 const 변수이기 때문에 컴파일 에러가 발생 하지만

 num = 2; num이 non-const 변수이기 때문에 정상이다. 즉, 포인터 변수가 가리키는 num 자체가 상수화가 되는 것이 아니다.

https://easycoding91.tistory.com/entry/C-%EA%B0%95%EC%A2%8C-const-%EC%9C%84%EC%B9%98%EC%9D%98-%EC%9D%98%EB%AF%B8%EC%99%80-%EC%82%AC%EC%9A%A9-%EB%B0%A9%EB%B2%95

 

 

- (완전 별개의 이야기지만) 포인터 주소값 자체를 상수화시킬 수도 있다.

int* const ptr2 = &num; // num의 주소값인 ptr2 자체가 상수화됨

 

 

 

(2) 참조 &를 활용 (별명)

void modifyValueByReference(int& x) {
    x = x + 10;
}

int main() {
    int num = 5;
    modifyValueByReference(num);
    std::cout << "num: " << num << std::endl; // 출력 결과: num: 15
    return 0;
}

 

- int& x에서 &는 C++에서 "참조자"를 나타내는 연산자

- 자료형 바로 뒤에 &가 붙음!!! (변수명 앞에 &가 붙는 게 아니라 ~~~.)

- 참조자는 변수에 대한 별명(alias)이며, 원본 변수를 직접 참조하게 함.

이것은 값(value) 자체가 아니라 변수에 대한 참조(reference)를 함수에 전달함을 의미함

- int& x에서 x는 참조자의 이름이고, int는 참조할 변수의 데이터 타입을 나타냄 (int& x: "정수형 변수에 대한 참조를 받는다")

 

 

참조자를 사용할 때의 특징

  • 원본 변수의 별명: 참조자는 원본 변수의 별명으로 동작함, 따라서 참조자를 통해 값을 읽거나 수정하면 원본 변수에도 동일한 작업이 반영됨.
  • 포인터와 다른 점: 참조자 != 포인터.
    포인터는 메모리 주소를 저장하고 간접 참조를 통해 값을 읽고 쓰고 조작할 수 있지만,
    참조자는 변수에 직접적으로 연결되어 있으므로 포인터보다 사용하기 간편
  • 전달이 아닌 참조 전달: 함수에 참조자를 매개 변수로 전달하면 함수 내에서 원본 변수를 직접 조작할 있으며, 호출자의 변수도 변경됨( 성질은 포인터에서도 동일~)
728x90
728x90

실행중인 프로그램은 운영체제로부터 메모리 공간을 할당받는데, 프로그램이 실행 중인 동안 사용되는 메모리는 일반적으로 세 가지 주요 영역으로 나뉨

: 데이터, 스택, 힙. 각 영역에는 다음과 같은 형태의 변수나 데이터가 할당됨.

 

간단히 말해 데이터 영역은 전역 변수와 정적 변수를 저장하고, 스택 영역은 함수 호출 관련 데이터를 저장하며,  영역은 동적으로 할당된 변수와 데이터를 저장함. 이러한 영역은 각각의 역할을 수행하여 프로그램의 메모리 사용을 관리하고, 변수  데이터의 수명을 결정함.

 

1. 데이터(Data) 영역:

- 전역 변수(Global Variables): 프로그램 전체에서 접근 가능한 변수로, 초기화된 데이터를 저장. 이러한 변수는 프로그램이 시작될 메모리에 할당되고 프로그램이 종료될 때까지 유지됨.

- 정적 변수(Static Variables): 함수 내부에서 선언되지만, 프로그램이 실행될 메모리에 할당되며 함수가 호출될 변수 값이 초기화됨. 함수가 종료되더라도 메모리에 남아있는 특성을 가짐.

 

#include <iostream>

// 전역 변수 (global variable)
// globalVar는 프로그램 전체에서 접근 가능하며 초기화된 데이터를 저장
int globalVar = 10;

int main() {
    // 정적 변수 (static variable)
    // staticVar는 main 함수 내에서 선언되었지만 프로그램이 시작될 때 메모리에 할당되며, 프로그램이 종료될 때까지 유지됨
    static int staticVar = 5;
    
    std::cout << "전역 변수: " << globalVar << std::endl;
    std::cout << "정적 변수: " << staticVar << std::endl;

    return 0;
}

 

2. 스택(Stack) 영역

- 지역 변수(Local Variables): 함수 내부에서 선언되며 함수가 호출될 메모리에 할당됨. 함수가 종료되면 해당 변수도 소멸됨. 스택은 함수 호출과 관련된 데이터 함수의 호출 복귀 정보를 저장하는 사용됨.

#include <iostream>

int add(int a, int b) {
    int result = a + b; // 지역 변수 (local variable)
    return result;
    // add의 지역변수 ; 함수가 호출될 때 메모리에 할당되고 함수가 종료될 때 소멸
}

int main() {
    int x = 5; // 지역 변수 (local variable)
    int y = 3; // 지역 변수 (local variable)
    // main의 지역변수 ; 함수가 호출될 때 메모리에 할당되고 함수가 종료될 때 소멸

    int sum = add(x, y); // add 함수 호출

    std::cout << "합계: " << sum << std::endl;

    return 0;
}

 

3. 힙(Heap) 영역:

- 동적 할당된 변수(Dynamically Allocated Variables): 프로그램 실행 중에 필요한 메모리를 동적으로 할당하고 해제하는 사용됨. 이러한 변수는 개발자가 메모리 할당 해제를 관리해야 . 예를 들어, new (C++) 또는 malloc (C) 함수로 메모리를 할당하고 delete (C++) 또는 free (C) 함수로 메모리를 해제함.

 

#include <iostream>

int main() {
    int* dynamicVar = new int; // 동적 할당된 변수 (dynamically allocated variable)
    *dynamicVar = 7;

    std::cout << "동적 할당된 변수: " << *dynamicVar << std::endl;

    delete dynamicVar; // 메모리 해제

    return 0;
    
    // 프로그램 실행 중에 메모리를 할당하고 new 연산자를 사용하여 초기화함
    // 이 변수는 개발자가 명시적으로 메모리를 해제해야 하며, delete 연산자를 사용하여 메모리를 해제함
}
728x90
728x90

1. 함수와 배열

c++에서, 배열 이름을 그 배열의 첫번째 원소의 주소로 인식함
// arr == &arr[0]

#include <iostream>
using namespace std;

const int SIZE = 8;
int sumArr(int arr[], int n);
int sumArr2(int*, int*);
void sizeArr(int* arr);

/*c++에서, 배열 이름을 그 배열의 첫번째 원소의 주소로 인식함*/
// arr == &arr[0]
int main()
{
    int arr[SIZE] = {1,2,3,4,5,6,7,8};

    int total = sumArr(arr, SIZE);
    cout << "This is total1: " << total << endl;
    // This is total1: 36
    int total2 = sumArr2(arr, arr+SIZE);
    cout << "This is total2: " << total2 << endl;
    // This is total2: 36


    cout << "size of arr[SIZE]: " << sizeof arr << endl;
    // size of 'arr[SIZE]': 32 //argument
    sizeArr(arr);
    // size of 'arr': 8 //parameter
}

/*배열을 전달받을 때에는 배열 전체가 들어오는 것이 아닌, 첫번째 원소의 주소값이 들어옴*/
int sumArr(int arr[], int n) { //int* arr라고 써도 무방
    int total = 0;
    for (int i=0; i<n; i++)
        total += arr[i]; //배열의 원소에 접근하는 대괄호는 배열이든 포인터든 사용가능
    return total;
}

int sumArr2(int* begin, int* end) {
    int total = 0;
    for (int* pt = begin; pt != end; pt++)
        total += *pt;
    return total;
}

void sizeArr(int* arr) {
    //int arr[] 일 때와 int* arr 일 때 결과가 동일함
    cout << "size of array as parameter: " << sizeof arr << endl;
    // size of array in sumArr(): 8
    // 32가 아닌 8이 나옴
}

 

2. 함수와 구조체

구조체와 함수
- 함수 통해 구조체 자체를 직접 리턴할 수 있고
- 함수의 인풋으로 구조체 형식을 사용할 수도 있음
 
구조체 규모가 너무 커질 때, 함수는 구조체의 원본이 아닌 복사본으로 작업하기에
- 이때 구조체를 포인터로 사용할 시 훨씬 효율적이게 됨
- 이 경우 원소에 접근하려면 화살표를 사용함

#include <iostream>
using namespace std;
const int MINUTES = 60;
int totalmin(int hour, int minute);

struct Time{
    int hour;
    int minute;
};

Time sum(Time*, Time*); //구조체와 구조체를 더하여서 구조체를 Return하는 함수
void showTime(Time);

int main()
{
    Time market;
    market.hour = 2;
    market.minute = 20;
    Time library = {1, 11};

    cout << "Total minutes to market: " << totalmin(market.hour, market.minute) << endl;
    cout << "Total minutes to library: " << totalmin(library.hour, library.minute) << endl;

    Time total = sum(&market, &library);
    showTime(total);
}

/*
Total minutes to market: 140
Total minutes to library: 71
총 3시간 31분 걸렸습니다.
 */

함수 쪼개서 보기 - totalmin

int totalmin(int hour, int minute)
{
    return hour * MINUTES + minute;
};

함수 쪼개서 보기 - sum

- 구조체를 return하는 함수

- 입력으로 구조체를 받음

- 이때 구조체의 주소값을 입력으로 받음

**당연하지만, 입력으로 Pointer를 지정해놓으면, 실제 함수 입력으로도 주소값을 넣어야 함(앞에 & 붙여서~)

Time sum(Time* a, Time* b) {
    //구조체의 값에서 멤버(원소)로 접근할 때: . (dot)
    //구조체의 주소에서 멤버(원소)로 접근할 때: -> (arrow)

    Time total;

    total.minute = (a->minute + b->minute) % MINUTES;
    total.hour = (a->hour + b->hour) + ((a->minute + b->minute) / MINUTES);

    return total;
}

void showTime(Time t){
    cout << "총 " << t.hour << "시간 " << t.minute << "분 걸렸습니다." << endl;
}

 

3. 재귀함수

재귀호출: 함수가 자기 자신을 호출할 수 있음
재귀함수: 재귀호출을 하는 함수 - 종결을 위해 보통 If문을 사용

  void recurs(argumentList)
   //code #1
   if (재귀호출조건)
       recurs(argumentList)
   //code #2

   이때 재귀호출이 연쇄적으로 일어나는 동안에는 code#2가 실행되지 않고 유보됨
   연쇄가 끊이면, 가장 마지막에 호출된 code#2부터 쭈욱 실행되어 마지막에 최초 code#2를 실행

 

#include <iostream>
using namespace std;

void countDown(int);

int main()
{
countDown(5);
}

void countDown(int n)
{
    cout << "Counting..." << n << endl;
    if (n > 0)
        countDown(n-1);
    cout << n << " 올라간다~" <<endl;
}

/*
Counting...5
Counting...4
Counting...3
Counting...2
Counting...1
Counting...0
0 올라간다~
1 올라간다~
2 올라간다~
3 올라간다~
4 올라간다~
5 올라간다~*/

 

4. 함수를 지시하는 포인터

함수를 지시하는 포인터
-> 어떠한 함수에 함수의 주소를 매개변수로 넘겨주는 경우, 유용하게 사용할 수 있다.

1. 함수의 주소를 얻는다 (그냥 '함수명'만 입력해주면 됨)
2. 함수를 지시하는 포인터를 선언한다. 이때 함수 포인터 선언 형태가 특이함 
    

    1) 반환형 (*포인터명)(매개변수) = 함수명; OR
    
    2)반환형 (*포인터명)(매개변수);
       포인터명 = 함수명
    
3. 함수를 지시하는 포인터를 사용하여 그 함수를 호출한다.

 

#include <iostream>
using namespace std;
int func(int);

//함수 포인터에서 괄호를 빠뜨리지 말 것 !

int main() {
    int (*ptr_func)(int) = func;
    cout << ptr_func(10) << endl; //1000
    cout << (*ptr_func)(10) << endl; //1000

    int (*ptr_func2)(int);
    ptr_func2 = func;
    cout << ptr_func2 << endl; //1
    cout << (*ptr_func2)(10) << endl; //1000
}

int func(int a)  {
    return a*100;
}

//함수의 주소는 함수 당 하나밖에 없음! 입력이 어떻든, 함수마다 고유한 값~

 

728x90
728x90

1. 함수 기본

/*
 * 1. 함수 정의 제공
 * 2. main 앞에, 함수 원형 명시 ; (1)함수 데이터형 (2)함수 이름 (3)(매개변수);
 * 3. 함수 호출
 * */

/* 함수의 두 타입
 * 1. 리턴값이 있는 타입: 함수가 리턴하는 값의 데이터형으로 선언 & return 뒤 변수 있음
 * 2. 리턴값이 없는 타입: void로 선언 & return 뒤 변수 없음 */
#include <iostream>
using namespace std;

const float PIE = 3.14;
/* main 함수 이전에 함수 원형 명시 */
//물론 원형 명시와 함께 함수를 정의하는 것도 가능
void cheers(int n);
float circle(int x);

int main(){

    int a;
    cout << "하나의 수를 입력하십시오." << endl;
    cin >> a;
    cheers(a);

    int b;
    cout << "원의 반지름을 입력하십시오." << endl;
    cin >> b;
    float c = circle(b); //입력과 리턴 모두 자료형과 함께 미리 선언해주어야 함
    cout << "원의 넓이는 " << c << "입니다." << endl;

}
/* main 함수가 끝날 때 함수 정의 */
void cheers(int n) {
    for (int i = 0; i < n; i++) {
        cout << "cheers!" << endl;
    }
}

float circle(int x) {
    return x * PIE;
}

→ 당연히, main 함수 안에, 내가 따로 선언해준 함수를 명시해서 사용해주어야 한다!

 

2. 매개변수와 전달인자

#include <iostream>
using namespace std;
void helloCPP(int, int);

int main() {
    int n; //파라미터(매개변수)
    int m; //파라미터(매개변수)
    cout << "n: " << endl;
    cin >> n; //파라미터(매개변수)
    cout << "m: " << endl;
    cin >> m; //파라미터(매개변수)
    helloCPP(n, m); //전달인자(argument)
}

void helloCPP(int n, int m) {
    for (int i=0; i < n; i++)
        cout << "Hello n" << endl;

    for (int i=0; i < m; i++)
        cout << "Hello m" << endl;
}

함수의 인자를, 우리의 입력 내용에 따라 정해줌

매개변수와 전달인자 간 자료형이 일치해야 함

 

 

 

728x90
728x90

1. if, else if, if 조건문

#include <iostream>
using namespace std;

int main(){
    //분기 구문: if & switch
    /*if(조건)
     *  코드*/
    if (true) {
        cout << "참";
        cout << "입니다." << endl; }
    if (false)
        cout << "거짓" << endl;

    // if - else if - else 구문은 하나의 덩어리로 인식함
    if (false)
        cout << "거짓" << endl;
    else {
    cout << "참이라구요~!" << endl;}

    // if 하나에 else 여러 개 가능
    // 이때 else: 앞단 것의 차집합이 연쇄로 계산됨
    // 양끝 말고는 else if를 사용하는 게 더 나을 듯.
    
    cout << "종료됨" << endl;
    /*
    참입니다.
    참이라구요~!종료됨*/
    
    }

2. 논리연산자

#include <iostream>
using namespace std;

int main(){

    /*논리 표현식: 논리합, 논리곱, 논리부정 연산자*/
    //논리합(or): 좌항 || 우항
    //논리곱(and): 좌항 && 우항
    //논리부정 연산자: !(표현식)
        //e.g. !(True) => False
    cout << "당신의 나이는?" << endl;
    int age;
    cin >> age;
    if (age<0 || age>100)
        cout << "거짓말 마세요!" << endl;
    else if (age>=20 && age<30)
        cout << "20대시군요!" << endl;
    else
        cout << "당신의 나이를 모르겠어요."<< endl;
}

3. switch, break, continue

#include <iostream>
using namespace std;

int main(){
    /*switch 구문*/
    //선택할 수 있는 경우의 수가 3개 이상으로 넘어가면, if-else보다 switch 구문이 훨씬 효율적.!
//    integer-expression에 해당하는 값의 case로 이동 -> 해당 값에 있는 코드가 실행됨
//    e.g.
//     switch (integer-expression) {
//        case label1:
//            code1 / break;
//        case label2:
//            code2 / break;
//     ... }
    int a;
    cin >> a;
    switch(a){
        case 1:
            cout << "1\n";
            break; //switch 구문을 바로 종료시킴 //*break* 는 모든 반복문에서 사용 가능
        case 2:
            cout << "2\n";
            continue; //이하 코드를 무시하고, 다음 loop를 돈다 //*continue* 는 반복문에서만 사용가능하다
        case 3:
            cout << "3\n";
            break;
        default:
            cout << "case 이외의 수를 입력하셨습니다.\n";
    }
    cout << "switch 구문이 끝났습니다.";
    //지정한 case 이외의 경우는,
    //default 지정 시 해당 구문이 실행되거나, 그렇지 않을 경우 별다른 실행 없이 종료됨.

}

4. 예제

#공백 제외한 글자 수 세기

#include <iostream>
using namespace std;
const int SIZE = 30;

int main(){
    char line[SIZE]; //문자 배열, string의 끝에는 개행문자 \0가 포함돼있음
    cin.get(line, SIZE); //get을 통해 입력 받기

    int word_cnt = 0;
    for(int i = 0; line[i]!='\0'; i++){
        if(line[i]==' ')
            continue;
        word_cnt++;
    };

    cout << "공백 제외 총 글자 수는 " << word_cnt <<"입니다~";
    //영어로 하니까 괜찮은데 한글은 개수 처리가 애매하다, 다른 설정이 필요한 듯.

}

reference:https://inf.run/4ttD

728x90
728x90

0. 증가/감소 연산자

/*잠깐
     * - 증가연산자
     * - 감소연산자
     * => 반복문의 카운터에 구현하면 유리함*/

    int a = 10;
    int b = 10;
    cout << "a는 " << a << " b는 " << b << endl;
    cout << "a++는 " << a++ << endl; //변수의 값을 판단한 후 증가시킴 -> 10 출력
    cout << "++b는 " << ++b << endl; //증가시킨 후 변수의 값 판단 -> 11 출력
    cout << "다시 a는 " << a << endl; //11

    for(int j = 5; j>0; j--){ //부등식은 관계표현식의 일종
        cout << j << endl;
    }

1. 반복문 for

#include <iostream>
using namespace std;

int main(){
    /*반복문 for*/
    for(int i = 0; i < 5; i++) {
        cout << i << "번째" << endl;
    }
    /*반복문의 네 가지 규칙
     * 1. 반복문에 사용할 카운터(반복 횟수에 대한 변수)의 값을 초기화 (여기서 i=0)
     * 2. 반복문을 진행할 것인지 '조건 검사' (여기서 i < 5)
     * 3. 반복문 몸체를 수행
     * 4. 카운터의 값을 변화시킴(여기서 i++) */}

 

2. 반복문 while, do while

#include <iostream>
using namespace std;

int main(){
    /*반복문 while
     * while(조건) {카운터변화}
     * 조건에 true나 false와 같은 bool형도 들어갈 수 있음
     * while로 짠 것을 for문으로도 짤 수 있고, vice versa, 둘 사이 복잡도 차이도 없음
     * 단, while문은 bool데이터만으로, 관계표현식 없이도, 실행할 수 있음
     * 또한, for문은 카운터 초기화, 카운터 변화 모두 for문 행에서 한꺼번에 정의할 수 있는데
     * while문은 카운터 초기화를 while문 바깥에서 미리 선언해야 하며, 이는 while문을 벗어나서도 해당 변수를 사용할 수 있음을 의미.
     *
     */

    int k = 0;
    while (k<3) {
        cout<<k<<"번째"<<endl;
        k++; //while문 내부에 반드시 '카운터변화' 행을 포함해야 함
    }

    string str = "panda"; //string은 명시적으로 개행문자'\0'를 포함
    int l = 0;
    while (str[l] != '\0'){
        cout << str[l] << endl;
        l++;
    }

    //일반 while문: 조건 검사 후 -> 반복 실행
    //do while문: 반복을 실행 후 -> 조건 검사 //따라서 어떤 조건이든 최소한 1회는 실행 됨
    int m = 0;
    do{
        cout << "while문 입니다.\n";
        m++;
    } while (m < 3);
}

3. 예제

3-1. 배열과 반복문

#include <iostream>
using namespace std;

int main(){
   /*배열 기반 반복문*/

    int a[10] = {1, 3, 5, 7, 9};

    //1: index로 배열 원소 접근
    for (int i = 0; i<5; i++){
        cout << a[i];
    } //13579
    cout << "\n";

    //2: 배열 자체로 원소 접근 //for (int 원소: 배열 이름) {}
    //간결하지만, 실제 원소 개수보다 선언한 원소 개수가 많을 경우, 0으로 채워져 선언한 만큼 출력됨
    for (int k : a) {
        cout << k;
    } //1357900000


}

3-2. 중첩 Loop

#include <iostream>
using namespace std;

int main(){
   /*중첩루프
    * 2차원 배열에서 많이 활용됨*/

   int temp[4][5] = {
           {1,2,3,4,5},
           {11,22,33,44,55}

   }; // 배열[행개수][열개수]
   // 2차원 배열 생성 시 {{}}의 이중 중첩 활용 & 행 간 콤마로 연결

   for (int row = 0; row < 4; row++) {
       for (int col = 0; col < 5; col++) {
           cout << temp[row][col] << " ";
       } cout << endl;
   }
/*
1 2 3 4 5 
11 22 33 44 55 
0 0 0 0 0 
0 0 0 0 0 */

reference:https://inf.run/4ttD

728x90

+ Recent posts