C++에서는 함수의 매개 변수에 다음과 같이 값을 대입하는 형태를 취함으로써 디폴트 값이라는 것을 설정할 수 있다. 디폴트 값이라 함은 기본적으로 설정되어 있는 값을 이야기한다.
매개 변수의 선언을 할 때, 값을 대입하는 형태로 선언되어 있는데 이는 다음과 같은 의미를 내포하고 있다.
함수 호출 시 인자를 전달하지 않으면 미리 대입된 값으로 전달된 것으로 간주하겠다.
그렇기 때문에 14번 라인에서 값이 전달되지 않더라도 함수의 정의, 선언 부분에 디폴트로 대입된 값으로 인자가 전달된 것으로 간주하고 함수 실행이 수행된 것이다.
디폴트 값은 함수의 선언 부분에만 표현
main 함수 윗 부분에 함수 정의 및 선언하는 경우
2. 함수의 정의와 선언을 분리하는 경우 -> 선언 부에 디폴트 값을 기재하고 정의에는 기재하지 않음.
부분적인 디폴트 값의 설정
위의 예처럼 매개 변수의 디폴트 값을 부분적으로 채울 수 있는데 중요한 것은 매개 변수의 오른쪽부터 왼쪽으로 차례대로 채워 나가는 형식으로 디폴트 값을 설정해야 한다는 것이다. 이렇게 행하는 이유는 함수에 전달되는 인자는 왼쪽에서 오른쪽으로 채워지기 때문.
함수 오버로딩과 디폴트 매개 변수의 모호성
위와 같은 예는 func라는 함수 이름으로 오버로딩이 적용되고 있으나 6번 라인에서의 디폴트 값 정의, 11번 라인의 인자를 받지 않는 void 형태의 인자 정의로 인해 19번 라인에서 오버로딩 된 func 함수 호출 시 어떤 함수를 호출해야 하는지 알 수 없는 애매한 상황이다. 가급적 이런 경우를 피해서 코딩
어느 정도의 크기를 저장할 것인지 적절한 크기를 결정 EX) (정수) 4바이트 정도, (문자열) 20바이트 길이 정도
예를 들어, 정수를 저장할 것이고, 크기는 4바이트 정도로 할께요 -> int
다음은 자료형의 저장 가능한 타입과 크기, 표현 범위를 나타낸 표이다.
이토록 다양한 자료형을 제공하는 이유는?
데이터의 표현 방식이 정수와 실수로 나뉘므로 최소 두 개의 종류가 보장되어야 한다.
메모리 공간의 효율적인 사용을 위해 같은 데이터 방식(정수 혹은 실수)이더라도, 다양한 크기로 제공되어야 한다.
sizeof 연산자를 이용한 자료형의 크기 확인
다른 자료형에도 마찬가지로 똑같이 적용되고, 10번 라인의 경우처럼 변수의 이름이 전달될 경우 해당 변수의 전체 크기를 계산한 결과를 반환한다. 즉, 배열의 경우 자료형 x 배열의 개수를 구하고, 반환한다는 의미.
정수 표현에서의 일반적인 자료형의 선택
short, char 형으로 선언한 변수를 이용하여 계산을 하였는데도 불구하고(10라인) 덧셈을 한 결과가(11라인) 1바이트, 2바이트가 아닌 4바이트 형태로 계산되었다.
-> CPU가 정수 연산을 할 때 가장 적합한 크기의 정수 자료형을 int 로 정의하였고, 그로 인해 다른 자료형의 연산 속도보다 같거나 빠르기 때문에 int 형 연산으로 변환하면서까지 연산을 진행한다.
-> 연산의 속도는 int형이 효율적이고 빠르지만, 데이터의 크기를 중요시하는 곳에서는 char, short를 사용하는 것이 중요하다.
실수 표현에서의 일반적인 자료형의 선택
실수에서 중요한 요소는 ‘정밀도’이다. 실수에서는 부동 소수점 오차가 발생하기 때문에 정확하게 값을 표현해낼 수 있는 소수점 이하의 자릿수가 존재하는데 이것이 바로 ‘정밀도’ 이다.
다음은 실수 자료형에서 정밀도를 나타내는 표이다.
실수 자료형에서는 double이 int와 같은 역할로 선택되어진다.
Double과 float 자료형 변수를 선언한 후, 값을 각각 입력 받고 출력하는 예제인데 float와 double 자료형의 출력 시 서식 문자는 같음을 알 수 있지만 입력 시 서식 문자는 다름을 확인할 수 있다.
문자의 표현 방식
문자를 표현할 때는 아스키(ASCII) 코드를 이용한다. 즉, 정수 값과 문자를 매칭하여 내부적으로는 정수로 연산하지만 이를 표현할 때에는 해당 정수 값에 맵핑 되어 있는 문자를 출력 및 표현을 한다.
8번 라인을 봤을 때 문자는 작은 따옴표( ‘ )로 감싸져 표현이 되고, 이 때 ch 변수에 값이 저장될 때에는 ‘a’라는 문자 형태의 값이 들어가는 것이 아니라 ‘a’의 아스키 코드 맵핑 값이 저장됨을 10번 라인을 통해 알 수 있다.
unsigned 0과 양의 정수 표현
- 정수 자료형의 이름 앞에만 unsigned를 붙일 수 있다.
- Unsigned 키워드가 붙을 시에는 부호 비트(MSB) 도 데이터를 표현하는데 사용이 된다. (부호가 사라짐)
- 표현할 수 있는 값이 0 이상의 범위로 두 배가 된다.
상수
상수는 이 자료형에 근거하여 선언되며, 리터럴(literal) 상수와 심볼릭(symbolic) 상수로 나뉘어진다. 자료형에 근거 되어 선언되는 이유는 CPU의 연산 대상이 되려면 메모리 상에 적재되어 CPU가 접근할 수 있는 주소를 할당 받아야 하기 때문이다. -> 모든 상수는 메모리에 할당된다.
먼저 이름을 지니지 않는 리터럴 상수이다.
위와 같은 예가 리터럴 상수의 예이다. 8번 라인에서는 10과 20이 int형, 10.1과 20.2는 double형으로 메모리에 적재된다.
앞서 일반적으로 연산 효율이 좋고, 넓은 정밀도로 인해 선택되어 지는 int형과 double형으로 상수의 자료형이 될 수 있고 자료형이 결정되는 요인은 대입 연산자 왼편의 자료형에 따른 것이 아니라 상수 자체의 종류에 따라서 결정되는 것이다.
두 자료형 이외의 값을 이용하여 자료형을 할당하기 위해서는 형 변환 혹은 접미사를 이용한다. 다음은 접미사를 활용하여 상수 자료형을 할당하는 예이다.
다음은 이름을 지니는 심볼릭 상수이다.
심볼릭 상수는 이름이 존재하는 상수이기 때문에 상수가 존재하는 해당 라인을 넘기더라도, 재 사용이 가능하며 이름을 활용하여 대입 연산자를 통해서 값의 변경을 방지하여 값을 변경하면 에러가 발생하도록 하는 특징을 지니고 있다.
심볼릭 상수 선언의 첫 번째 방법은 const 키워드를 이용한 변수의 상수화다.
위와 같이 const 키워드를 이용하여 변수를 상수화 하게 될 경우에는 선언과 동시에 초기화를 해야 하고, 이름을 통한(혹은 그 외의 어떤 방법으로도) 값의 변경은 금지된다.
두 번째 방법은 매크로를 이용한 방법이다.
자료형의 변환
자료형에서 가장 중요한 것은 모든 연산은 완벽하게 같은 자료형끼리 연산이 가능하다는 점이다.특히 대입 연산 시에도 대입 연산자를 기준으로 왼편(l-value)과 오른편(r-value)의 형(type)이 일치해야 한다. 다른 연산자의 경우에도 마찬가지이다. 자료형이 다름에도 불구하고 오류 없이 연산이 가능한 이유는 자료형의 형 변환(자동, 묵시적)이 이루어졌기 때문이다.
자동 형 변환(묵시적 형 변환)
먼저, 대입 연산 시 값을 전달하는 과정에서 자동으로 발생하는 형의 변환이 존재한다.
10번 라인에서 실수형 변수에 정수형 값을 넣었고, 11번 라인에서 정수형 변수에 실수형 값을 넣었다. 다음은 이에 대한 출력 결과이다.
결과에서 알 수 있듯이 11번 라인에서의 대입은 0.14에 해당하는 값이 모두 손실되었다. 정수형 자료형은 실수를 표현할 수 없기 때문이다. 또한, 바이트 크기가 큰 변수를 바이트 크기가 작은 변수로 형 변환하는 경우에는 상위 바이트의 손실로 인해 부호가 변경되거나, 값이 훼손될 수 있다.
다음은 정수의 승격에 의한 자동 형 변환이다. 정수형 연산에서 일반적인 자료형의 선택 시 int형으로 변환되어 연산이 진행되기 때문에 short나 char 등의 자료형으로 연산을 진행하더라도 int 형으로 변환 되어 연산이 진행된 후 다시 원래 자료형으로 다시 변환이 이루어 진다.
다음은 연산 시 피연산자의 자료형 불일치로 발생하는 자동 형 변환이다.
이와 같은 경우에서 double <- int + double의 형태인데 연산을 진행함에 있어서 두 피연산자의 자료형이 서로 다를 때에는 자료형을 통일시켜주어야 하는데 이 경우에 강제적으로 형 변환을 하지 않는 이상 피연산자의 자동 형 변환이 발생한다. 이 때, 어느 자료형을 어떤 자료형으로 변환시켜줄 것인지를 정해야 한다. 변환할 자료형, 변환될 자료형의 선택은 다음과 같은 규칙으로 진행하면 된다.
데이터의 손실을 최소화하는 방향으로 자료형을 선택
int형과 double형이 피연산자로 오는 경우에는 int형을 double형으로 변경하는 것이 데이터의 손실이 최소화하는 방향이다.
그리고 다음은 최소화하는 방향의 우선 순위를 나타낸 것이다.
우선 순위의 기준은 단순히 바이트 크기가 아니라, 정수와 실수 즉 ‘소수부의 손실’을 고려한 순위 기준이다. long long형과 float형을 보면 알 수 있다.
강제 형 변환(명시적 형 변환)
명시적인 형 변환은 형 변환 연산자를 이용하여 강제로 자료형을 변환하는 방법이다.
위와 같은 예에서 num1과 num2의 자료형은 서로 같기 때문에 정수형으로써 나눗셈이 진행되므로 결과 값은 0이 되고 대입 시 일어나는 자동 형 변환으로 인해 실수형 0이 num에 저장된다. 이러한 경우에 강제 형 변환을 이용하게 되면 다음과 같다.
위와 같이 num1을 강제로 double형으로 형 변환시키면 피연산자 불일치와 연산자 변환 우선 순위에 의거하여 num2 또한 double형으로 자동 형 변환이 이루어져 실수 연산이 이루어지고 그 값이 그대로 num으로 대입된다.
C 언어에서는 두 함수를 정의하고 선언하는데 함수의 이름이 같으면 아무리 함수의 내용이 다르다고 하더라도 허용하지 않았다. 위의 예제에서 sum을 호출할 때, 어떤 함수의 정의를 타겟으로 호출했는지 알 수 있다. 이렇게 호출되는 함수 명은 같지만 어떤 함수 정의를 타겟으로 하였는지 알 수 있었던 이유는 함수 호출의 인자와 함수 선언의 매개 변수 정보를 통해서 호출하고자 하는 함수를 구분할 수 있다.
즉, 함수 호출 시 전달되는 인자를 통해 호출되고자 하는 함수의 구분이 가능하기 때문에 C++에서는 함수의 정의에서 매개 변수의 선언 형태가 다르다면 동일한 이름의 함수 정의를 허용할 수 있다. 이를 함수 오버로딩이라 한다.
함수 오버로딩 시 필요한 정보 :함수 이름 + 함수의 매개변수 + const 여부
함수의 이름은 같아야 함수 오버로딩이 적용되고, 함수의 매개변수의 경우 매개 변수들의 타입 혹은 개수 정보가 달라야 오버로딩이 가능하다. 그리고 const 여부의 경우는 추후 내용 기록한다. 중요한 것은 반환 타입은 오버로딩에 필요한 정보가 아니므로 반환 타입이 다르다고 해서 오버로딩이 적용되지 않는다.
개정 C언어와 C++에서는 참과 거짓의 표현을 위한 키워드 true와 false를 정의 하고 있다. 이러한 true와 false 는 단순 1과 0의 값이 아니라, 그 자체로 의미 있는 데이터이기 때문에 이런 유형의 데이터를 저장하기 위한 자료형이 존재한다. true와 false 데이터는 bool형 데이터라고 하고, 이러한 bool형 데이터를 지원하는 기본 자료형 bool이 존재한다.
다음은 bool 자료형을 이용한 예제를 나타낸 소스이다.
사용자로부터 입력 받는 number 변수에 10이 들어가면 true 값을, 그 외의 값이 들어가면 false 값을 반환 한다.
프로그래머가 정의하는 헤더 파일의 선언이 아닌, 표준 헤더파일의 선언에 대해서 확장자를 생략한다.
자유로운 지역 변수의 선언 – 9번 라인
c언어에서와 같이 중괄호의 첫 부분에 지역 변수들의 선언만을 모아서 선언하는 것이 아닌 자유롭게 소스 코드 중간 중간에 선언이 가능하며, for문 내의 초기문에 해당하는 영역에서도 선언이 가능하다. 이 때 선언된 변수는 for문이 유효한 기간동안 생성되어 있다가 for문이 종료될 때 소멸된다.
std라는 이름 공간(namespace) 의 새로운 개념 – 11번 라인
std라는 이름 공간이 존재하고 그 공간 속에 여러 라이브러리 및 변수들이 존재함.
새로운 연산자( <<, >> ) 와 printf와 scanf를 대체하는 cout과 cin – 11번, 12번 라인
std 라는 이름 공간 내에 존재(std::를 이와 같이 해석)하는 cout과 cin 요소들에 각각 <<와 >> 연산자를 사용하여 연 이은 출력 및 입력으로 기존 c언어의 printf와 scanf를 대체한다
다음은 C++에서 C언어의 입 출력 함수를 대체하는 요소들을 정리한 표이다.
endl 연산자 – 16번 라인
마찬가지로 std 이름 공간 속에 존재하는 endl 요소를 출력하여 개행의 효과를 낸다.
위와 같이 문자 배열에 문자열을 입력 받을 때에도 std::cin을 이용하여 입력 받는다. 다음은 그 결과이다.
결과에서 알 수 있듯이 std::cin도 scanf와 마찬가지로 공백을 기준으로 입력을 구분하기 때문에 첫 공백 전인hello까지만 입력으로 들어간 것을 확인할 수 있다.
c언어에서 연산에 사용되는 모든 값은 변수 혹은 상수 등의 형태로 메모리 상에 저장된 후, 연산이 진행됨. (연산이라 함은 단순 사칙연산 뿐만 아니라, 출력, 입력 등도 포함)
위와 같은 예에서 1과 1은 메모리 상에 상수의 형태로 저장된 후, 그 저장된 메모리를 이용하여 연산을 진행 위와 같은 경우에는 값이 고정된 상수이기 때문에 다른 라인에서 값의 변경이 불가능함. -> 변수 개념으로 해결
변수
변수란? 값을 저장할 수 있는 메모리 공간에 붙은 이름, 혹은 메모리 공간 그 자체를 나타낸다.
이러한 변수라는 개념을 이용하여 변수에 값을 저장하고 그 값을 이용하여 연산을 진행한다. 다만, 상수와 다른 점은 변수가 선언된 아래 라인에서 변수가 지는 값을 변경하고, 변경된 값을 토대로 재연산이 가능하다는 점.
먼저, 변수의 선언이다.
자료형 + 변수의 이름
위와 같은 형태로 변수의 선언이 이루어진다. 여기서 자료형에 대한 기재는 내가 생성할 변수에 어떤 타입(Type)의 값이 올 것인지를 컴파일러에게 명시해주는 것이고, 변수의 이름에 대한 기재는 말 그대로 메모리 공간에 붙여줄 이름을 명시해주는 것이다.
자료형의 종류와 변수의 이름을 지을 때의 명명 규칙에 대해 아래에 기재
<자료형>
<명명 규칙>
다음은 변수의 선언 및 초기화이다.
6번 줄부터 9번 줄까지 총 5개의 변수가 선언되었는데, 각각 여러 문법적인 요소를 지닌다. line 7에서는 정수형 자료형으로 변수를 선언하였고, 선언함과 동시에 2라는 값을 대입 연산자(=, 대입)를 통하여 초기화를 시켜주었다. 이를 ‘선언과 동시에 초기화 한다’ 라고 표현한다. 그리고 line 8에서는 선언과 동시에 초기화를 하되, 콤마 연산자( , )를 통하여 정수형 변수 num3과 num4를 한번에 선언하고 동시에 초기화를 진행한다. 또한 line 6에서는 num1을 선언만 하고 초기화는 행하지 않았으나 line 11에서 첫 대입이므로 초기화가 이루어졌고, 그 이후 line 12에서 일반 대입이 이루어졌다. 그리고 마지막 line 9에서는 선언만 진행하고 초기화가 이루어지지 않았는데 이런 경우에는 num4의 메모리 공간에는 쓰레기 값이 자동으로 채워진다. 사실 채워지는 것이 아니라 해당 메모리 공간에 원래 존재하고 있던 어떤 값이 보여지는 것이다.
변수 선언 시 주의 사항 : 중괄호 내에 변수를 선언할 경우에는 중괄호의 앞부분에 변수의 선언을 위치시킨다.
연산자
키보드로부터 값을 입력 받기
프로그램이 번역된 후 실행하는 중에 값을 변수에 저장할 수 있는 방법.
scanf 함수에서 첫 번째 인자, 큰 따옴표 사이의 Format으로 입력을 받는데, 나타낸 서식 문자 순서대로 이후 인자들에 차례로 값이 저장된다. %c, %d, %f, %lf 는 변수 명 앞에 &를 붙인다. 포인터와 관련된 이야기.
scanf 함수는 스페이스, 엔터 등의 공백으로 입력과 입력을 구분 지으며, 첫 번째 인자로 주어진 형식으로 입력을 받는다. 형식을 지키며 입력하라는 말이다.