6 분 소요

실습 17

문제 설명 정수 n이 주어질 때, n이하의 짝수를 모두 더한 값을 return 하도록 solution 함수를 작성해주세요.

제한사항 0 < n ≤ 1000

입출력 예 n result 10 30 4 6

문제 설명

정수 n이 주어질 때, n이하의 짝수를 모두 더한 값을 return 하도록 solution 함수를 작성해주세요.

제한사항

0 < n ≤ 1000

입출력 예

n result
10 30
4 6

내가 제출한 코드

#include <string>
#include <vector>

using namespace std;

int solution(int n) {
    int answer = 0;

    for (int i = 1; i <= n; i++)
    {
        if (i % 2 == 0)
        {
            answer += i;
        }
    }
    return answer;
}

교수님 코드

#include <string>
#include <vector>

using namespace std;

int solution(int n) {
    int answer = 0;

    for (int i = 2; i <= n; i++)
    {
        answer += i;
    }

    return answer;
}

실습 18

문제 설명

우주여행을 하던 머쓱이는 엔진 고장으로 PROGRAMMERS-962 행성에 불시착하게 됐습니다. 입국심사에서 나이를 말해야 하는데, PROGRAMMERS-962 행성에서는 나이를 알파벳으로 말하고 있습니다. a는 0, b는 1, c는 2, …, j는 9입니다. 예를 들어 23살은 cd, 51살은 fb로 표현합니다. 나이 age가 매개변수로 주어질 때 PROGRAMMER-962식 나이를 return하도록 solution 함수를 완성해주세요.

제한사항

age는 자연수입니다.
age ≤ 1,000
PROGRAMMERS-962 행성은 알파벳 소문자만 사용합니다.

입출력 예

age result
23 “cd”
51 “fb”
100 “baa”

내가 제출한 코드

#include <string>
#include <vector>

using namespace std;

string solution(int age) {
    string answer = "";
    for (int i = age; i > 0; i /= 10)
    {
        int temp = i % 10;
        char alpha = temp + 'a';
        answer = alpha + answer;
    }
    return answer;
}

교수님 코드

#include <string>
#include <vector>

using namespace std;

string solution(int age) {
    string answer = "";

    for (int i = age; i > 0; i /= 10)
    {
        answer = ('a' + i % 10) + answer;
    }
    return answer;
}

타입 캐스팅

형변환 타입 캐스팅이란 우리가 기본적으로 컴퓨터는 2진수를 처리한다. 물리적으로 보면 10101을 다룸. 문제는 그거를 어떻게 해석할지에 따라서 의미가 달라진다. 예를 들어서 동그라미를 숫자 0으로 해석할수도 있고, 알파벳 o라고 해석할 수 도 있고, 한글 ㅇㅇ로 해석할 수 있다. .규칙으로 해석하냐에 따라서 다르게 해석한다. 예는 숫자야 그럼 0(영)으로 해석한다. 명시적 타입 캐스팅: 해석 방법을 명시적으로 알려준다. 암묵적 타입 캐스팅: 컴파일러가 눈치껏알아서 스스로 해석 결정. 컴파일러의 스스로의 해석이 우리가 충분히 예측가능한 범위일대는 컴파일러 해석을 믿어도 된다. 프로그래밍ㅇㄹ 하다보면 언제나 헷갈릴때가 있다. 컴파일러가 어떤 식으로 해석할지 헷갈림. 헷갈림을 두지 말고, 최대한 괄호를 쓰고 모호함을 줄인다. 모호함을 줄이게 되면 에러의 발생이 줄어들 수 있다.

Chap 8. Technicalities: Functions, etc.

Language technicalities

우리가 태어나서 처음으로 배우는 말이 아니다. 프로그래밍 언어는 모호하지 않고, 예외가 없다. 인공적 언어이므로 의도적으로 모호성을 허용하지 않기 때문이다.

여기서 의도적으로 만들어둔 중요한 문법으로는 Function과 Class가 있다.

지금은 언어를 배울 때, 너무 디테일까진 외울 필요가 없다. 디테일은 구글링하면 되는데, 배우는 언어에 대해서 중요한 갠며적 이해가 필요하긴 핟. 그 언어의 중요한 개념과 철학을 이해 해야 된다.

Declarations

컴파일러가 검사하는 문법은 Known 심볼(if, for 문법 등), user define 문법이 섞여 있는 변수와 함수 가 있다. 사실 컴파일러 입장에서는 known 심볼의 경우는 이미 정해져 있는 규칙이므로 틀린 문법이 들어온다면 이를 인지할 수 있다.

하지만 사용자 정의 변수 및 함수의 경우는 컴파일러는 아무것도 모른다. 따라서 이 변수나 함수를 쓰기 전에는 선언 을 해주어야 된다. 선언을 통해서 변수의 경우는 데이터 타입을 알려주고, 함수의 경우는 리턴 타임, 함수 이름, 매개 변수 개수, 매개 변수의 데이터 타입을 알려준다.

  • 선언은 동일한 선언을 해도 문제가 발생하지는 않는다. 다만 같은 변수 이름의 다른 데이터타입을 선언하게 되면 문제가 발생한다.

    int i;
    int i = 0;
    

    ❓교수님은 동일한 선언을 해도 상관 없다고 했는데 VSCode 상에서는 note: ‘int i’ previously declared here 라고 뜨는데?

    내꺼는 에러라고 뜨지만 두 번 정의할 수 있단다.

    ❌ ⏬

    int i;
    float i;
    

    모호성이 발생하게 되므로 컴파일러는 에러를 발생시킨다.

CPP에서도 변수는 똑같은 이름, 다른 타입인 경우는 여전히 모호하다고 판단한다.

하지만 다형성이 등장하였으므로 함수의 경우는 달라졌다. 함수의 매개 변수 개수나 타입이 다르면 모호하지 않다고 판단을 하였기 때문이다.

Declaration과 Definition은 엄밀히 말하면 살짝 다르다. Declaration은 컴파일러에게 이런 변수나 함수를 사용할 것이고, 그 변수와 함수의 데이터 타입에 대해서 알려주는 것이다.

Definition의 경우는 메모리를 잡는 것을 말한다. 변수의 경우는 선언과 정의가 무조건 동시에 발생한다. 하지만 함수의 경우는 함수의 리턴 타입, 함수 이름, 매개 변수까지만 적어준 것이 선언, 구현부까지 구현을 했으면 정의라고 표현을 한다. 함수는 초기화라는 표현은 하지 않는다.

사용자 정의 변수와 함수의 심볼은 메모리에 대한 이름 이다. 명령어에서는 메모리 이름은 address이다. 변수와 함수는 단순히 High language에서 생산성을 높이기 위해서 사용이 되는 것이고, Low language에서는 이 변수와 함수에 대한 주소를 내부적으로 처리되도록 만들었다.

변수, 함수: 심볼 / 그 심볼에 대한 실제값: 주소값

메모리에서 내부적으로 심볼과 주소값을 매핑시켜준다. 여기서 심볼에 대한 규칙만 알려주는 것이 declaration, 메모리까지 잡는 것을 definition이라고 한다.

  • 변수
    int a; -> declaration + definition (무조건 동시에, 굳이굳이 extern 키워드를 사용해서 선언만 가능하긴 함)
  • 함수
    definition은 구현부까지 있어야 정의라고 함. 구현부 없이 리턴 타입, 함수 이름, 매개 변수까지만 있으면 명시적 선언 즉 declaration이라고 한다. 이때는 메모리를 잡지는 않는다.

definition은 중복 허용 X, declaration은 중복 허용 O

You can’t define something twice / You can declare something twice

모든 프로그램이 declare, define이 필요한 것은 아니다. 인터프리터 언어의 경우는 define이 필요 없다. 선언 없이 바로 정의를 해버리는 구조이다.

Kinds of declarations

Namespaces: 다형성 구현.

[교수님 예]

중국성이라는 이름이 대학교 앞, 고등학교 앞 둘다 있을 때, 중국성이라고만 장소를 공지를 하면 대학교 앞인지 고등학교 앞인지를 정확히 몰라 namespace를 알아야 모호성을 줄일 수 있어. 함수 이름 같이 쓰자 = 다형성 => 여기서 보호성 발생 => namespcae를 사용해서 해결

여기서 default로 사용할 수 있는 namespace가 필요하다. 이를 using namespace를 통해서 해결했다.

Header Files and the preprocessor

헤더 파일: 선언을 잔뜩 모아놓아. 옛날에는 오픈 소스가 활발하지 않았기 때문에 내 코드는 알려주지 않고(define은 알리지 않고) 사용을 할 수 있도록(declaration만 알려주어서) 사용을 했다.

즉, definition을 공유한다는 말은 low lv까지 공유를 한다는 것이고 declaration의 경우는 high lv만 공유를 한다는 것이다. 이런 선언만 모아둔 것이 헤더 파일이다.

# 이라는 것은 preprocessor로서 컴파일러 모르게 그 전에 처리를 해준다. 복붙을 통해서! 그 다음 컴파일러로 들어가기 때문에 컴파일러는 # 이라는 문법을 모른다.

Source files

실제 프로그래밍에서는 여러 파일을 통해서 하나의 프로젝트를 만들게 된다. cpp 파일로 나누어서 구현을 했다고 했을 때,

컴파일러는 언제나 하나의 파일만 열 수 있다. A.cpp를 컴파일할 때는 A에 대한 정보단 안다. 나머지 B.cpp, C.cpp에 있는 정의된 변수 또는 함수에 대해서는 모른다. 여기서 A.cpp에서 사용된 모든 심볼에 대한 정의가 필요하다.

컴파일러 -> 문법 검사(Known 심볼 / User define 심볼) / 번역을 하는데 사용자 정의 심볼을 사용하기 위해서는 Declaration이 필요하다.

각각의 cpp -> obj -> obj * n -> exe 실행 파일

Scope

  • Global scope

    C에도 있는 것

    보이느냐 보이지 않느냐 이 차이 중에서 어디에서나 보이고 프로그램의 수명과 동일함. 모든 곳에서 모든 funct에서 다 보여!

    컴파일러가 어느 위치에 있는지를 인식

    • 단:

      모든 곳에서 보여서 안정성이 떨어짐. 모든 곳에서 access 할 수 있어서 어디에서 에러가 발생한지를 몰라 / 메모리 사용이 커져. 프로그램이 종료될 때까지 살아 있으니까.

      따라서 global 변수는 권장하지 않는다. 자바는 global scope에 대한 범위가 없다. global scope 대신 class scope 권장. 클래스 내부에서만 접근할 수 있는 것을 말함.

  • Class scope

    class를 아직 배우지 않은 관계로 패스,,

  • Local scope

    C에도 있는 것

    function 내에서만 유효하게 사용 가능, 메모리 유지에 용이(function과 삶을 같이 하기 때문) 언어가 진화하면서 scope에 대한 범위를 점점 짧게 정의하고 잇다. 모든 변수 정의는 funct 처음만 가능(무조건 함수 도입부에서는 변수 정의 필요)에서 함수 내부 어느 곳에서든 선언이 가능하도록 만들어 졌다.

    이렇게 되면서 변수의 수명이 함수의 수명과 완전히 동일하게 되지는 않았다. 변수가 정의된 위치에서 가장 가까운 {}가 끝날때까지만 살아있을 수 있도록 하였다.

    정의된 위치에서 가까운 {}가 사라질 때, 변수도 사라진다.

  • Statement scope

    for 때문에 등장하게 되었다. 옛날 코드

    int i
    for (i = 0; i < n; i++)
    {
        ...
    }
    

    이렇게만 했어야 되었는데, 진화를 해서

    for (int i = 0; i < n; i++)
    {
        ...
    }
    

    가 되도록 하였다. 여기서 i는 중괄호가 아니라 반복문에 따른 하나의 state에서만 유지가 된다. for문 뒤에 나오는 하나의 state 명령어에서만 사용이 가능하다. 원래는 for문과 if문 다음에는 한 줄의 명령어만 가능했는데 그러나 {}를 사용하면 중괄호 안에 있는 코드는 모두 한 줄로 보기로 함. 이런 경우 i를 statement scope라고 부른다.

int x;
int y;

int f()
{
    int x;
    x = 7;
    {
        int x = y;
        ++x;
    }
}

에러 아님. 중괄호 안에 있는 x는 새로 정의된 다른 x이다.

동일한 scope내에서 동일 이름 사용 안됨.

동일하지 않은 scope 내에서 동일 이름 사용 가능 대신 가까운 변수가 명령어 수행.

댓글남기기