2023. 10. 30. 10:47ㆍ프로그래밍 공부/OOP
1.1 C++ 소개
C++ 언어의 기원
C++ 프로그래밍 언어는 클래스(및 기타 현대적 특징)가 추가된 C 프로그래밍 언어로 생각할 수 있습니다.
C++와 객체 지향 프로그래밍
객체 지향 프로그래밍(OOP)의 특징 3가지: 캡슐화(encapsulation), 상속(inheritance), 다형성(polymorphyism)
C++는 클래스(class)를 제공하므로써 OOP를 수용합니다.
C++의 특징
클래스(class)를 가집니다.
함수(function)과 연산자(operator)의 오버로딩(overloading)을 수용합니다.
C++와 C는 연결되어 있습니다.
C++에는 템플릿 기능이 있습니다.
C++에는 여러 네임스페이스를 허용해 클래스와 함수를 재사용할 수 있도록 도와줍니다.
C++의 예외처리기능은 다른 언어와 비슷합니다.
C++의 메모리 관리는 C와 비슷합니다.
C++ 용어
함수(function): 모든 절차(procedure), 메소드(method), 함수(function), 서브프로그램(subprogram)이라고 하는 것들
프로그램(program): C++ 프로그램은 기본적으로 main이라고 불리는 함수일 뿐입니다. 프로그램을 실행하면 런타임 시스템이 자동으로 main이라고 하는 함수를 호출합니다.
샘플 C++ 프로그램
#include <iostream>
using namespacestd;
int main( )
{
int numberOfLanguages; // integer(정수)값
cout << "Hello reader.\n" // string 문자열, C-string: C 문자열 cout: 출력
<< "Welcome to C++.\n";
cout << "How many programming languages have you used? ";
cin >> numberOfLanguages; // cin: 입력
if (numberOfLanguages < 1) //if-else 문
cout << "Read the preface. You may prefer\n"
<< "a more elementary book by the same author.\n";
else
cout << "Enjoy the book.\n";
return 0;
}
샘플 대화 상자 1 (키보드에 0을 입력합니다. 사용자 입력은 굵은 글씨로 표시됩니다.)
Hello reader.
Welcome to C++.
How many programming languages have you used? 0
Read the preface.
You may prefer a more elementary book by the same author.
샘플 대화 상자 2 (키보드에 1을 입력합니다. 사용자 입력은 굵은 글씨로 표시됩니다.)
Hello reader.
Welcome to C++.
How many programming languages have you used? 1
Enjoy the book
main
C++ 프로그램은 실제로 main이라는 이름의 함수에 대한 함수 정의입니다.
프로그램이 실행되면 main이라는 이름의 함수가 호출됩니다.
함수 main의 본문은 괄호 안에 들어 있습니다.
프로그램이 실행되면 brace의 문장이 실행됩니다.
다음 두 줄은 콘솔 입출력 기능이 있는 라이브러리를 프로그램에 사용할 수 있도록 설정합니다.
# include <iostream>
using namespace
int main() -> 매개변수 x이고 정수를 반환하는 함수이다.
return 0; -> 0을 반환하면서 프로그램을 마친다.
1.2 변수, 식 및 할당문
식별자
식별자(identifier): 변수의 이름
첫번째 글자(character)는 문자(letter) or _(underscore) 로 시작 가능하다.
나머지 글자는 문자 or 숫자 or _ 가 가능하다.
대소문자를 구분한다. (case-sensitive)
길이에 제한이 없다.
아래 예시는 가능
x x1 x_1 _abc ABC123z7 sum RATE count data2 bigBonus
아래 예시들은 불가능
12 3X %change data-1 myfirst.c PROG.CPP
키워드(keyword): 예약어(reserved word)라고도 하며 특별한 종류의 식별자이다. 이들은 C++에서 미리 정의된 의미를 가지고 있으며 변수나 다른 어떤 것의 이름으로도 사용할 수 없다.
변수
변수 선언
변수를 사용하기 전에 모든 변수를 선언해야 한다. 변수 선언의 구문은 다음과 같다.
신택스
Type_Name Variable_Name_1, Variable_Name_2,. . .;
예시
int count, numberOfDragons, numberOfTrolls;
double distance;
int: 정수(integer)의 약자
double: 소숫점(decimal point)을 가진 숫자(= floating-point numbers)를 가진 유형
char: 문자(character)형
bool: 부울(boolean) 논리
unsigned: 음수가 아닌 값만 포함하는 유형 (ex. unsigned short, unsigned int 그리고 unsigned long)
| TYPE NAME | MEMORY USED | SIZE RANGE | PRECISION |
| short(also called short int) | 2 bytes | -32,768 to 32,767 | Not applicable |
| int | 4 bytes | −2,147,483,648 to 2,147,483,647 |
Not applicable |
| long(also called long int) | 4 bytes | −2,147,483,648 to 2,147,483,647 |
Not applicable |
| float | 4 bytes | approximately 10^–38 to 10^38 |
7 digits |
| double | 8 bytes | approximately 10^–308 to 10^308 |
15 digits |
| long double | 10 bytes | approximately 10^–4932 to 10^4932 |
19 digits |
| char | 1 byte | All ASCII characters (Can also be used as an integer type, although we do not recommend doing so.) |
Not applicable |
| bool | 1 byte | true, false | Not applicable |
| 여기에 나열된 값은 유형이 어떻게 다른지에 대한 일반적인 생각을 제공하기 위한 샘플 값일 뿐입니다. 이러한 항목의 값은 시스템에서 다를 수 있습니다. 정밀도(Precision)는 소수점 앞의 숫자를 포함하여 의미 있는 숫자의 수를 나타냅니다. float, double, long double 유형의 범위는 양수의 범위입니다. 음수는 범위가 비슷하지만 각 숫자 앞에 음의 부호가 있습니다. | |||
할당문
할당문(Assignment Statements): 먼저 등호의 오른쪽에 있는 식을 평가한 다음 등호의 왼쪽에 있는 변수를 이 값과 동일하게 설정합니다.
SYNTAX
Variable = Expression;
EXAMPLES
distance = rate * time;
count = count + 2;
L값 및 R값
L값(lvalue): 할당 연산자(=)의 왼쪽에 나타날 수 있는 모든 것. 변수의 종류.
R값(rvalue): 할당 연산자(=)의 오른쪽에 나타날 수 있는 모든 것. 값을 평가하는 모든 표현.
string 클래스에 대한 소개
C++는 문자열(텍스트의 시퀀스)을 직접적으로 조작할 수 있는 간단한 데이터 유형이 없지만,
문자열을 지금까지 본 데이터 유형과 유사한 방식으로 처리할 수 있는 문자열(string) 클래스가 있다.
string 클래스를 이용하기 위해서는 프로그램 상단에 아래 코드와 같이 string 라이브러리를 포함시켜야 한다.
# include <string>
string 정의 예시
string fruit;
fruit = "durian";
함정: 초기화하지 않은 변수
프로그램이 값을 지정하지 않으면 변수는 의미 있는 값을 가지지 않는다.
예시)
desiredNumber = minimumNumber + 10;
minimumNumber의 값 지정되지 않고 기존 메모리 어딘가 저장된 garbage값이 지정되어 있음
따라서 desiredNumber 또한 값이 지정되지 않고 minimumNumber보다 10이 큰 쓰레기값이 지정되어 있음.
이러한 사태를 피하기 위해 변수가 정의될 때 변수에 초기값을 지정해놓는다.
int minimumNumber = 3;
선언 시 변수 초기화하기
변수를 선언할 때 동시에 변수를 초기화할 수 있다.
SYNTAX
Type_Name Variable_Name_1 = Expression_for_Value_1,
Variable_Name_2 = Expression_for_Value_2,...;
EXAMPLES
int count = 0, limit = 10, fudgeFactor = 2;
double distance = 999.99;
선언 시 초기화를 위한 대안적인 syntax
SYNTAX
Type_Name Variable_Name_1 (Expression_for_Value_1),
Variable_Name_2 (Expression_for_Value_2),...;
EXAMPLES
int count(0), limit(10), fudgeFactor(2);
double distance(999.99);
TIP: 의미있는 이름을 사용하라
x = y * z;
distance = speed * time;
두 문장 다 같은 것을 달성하지만 첫번째보다 두번째가 더 이해하기 쉽다.
추가 할당문
할당 연산자( = )와 산술 연산자를 결합하여 지정된 값을 더하거나 빼기, 곱하기 또는 분할하여 지정된 값을 변경할 수 있는 축약 표기법이 있다.
Variable Operator = Expression
Variable = Variable Operator (Expression)
| Example | Equivalent to |
| count += 2; | count = count + 2; |
| total -= discount; | total = total - discount; |
| bonus *= 2; | bonus = bonus * 2; |
| time /= rushFactor; | time = time / rushFactor; |
| change %= 100; | change = change % 100; |
| amount *= cnt1 + cnt2; | amount = amout * (cnt1 +cnt2); |
할당 호환성
int intVariable;
intVariable = 2.99;
2.99는 double 값이고 intVariable은 int값이다.
몇몇 compiler은 error값을 보내고 몇몇 compiler은 intVariable = 2를 출력한다.
double doubleVariable;
doubleVariable = 2;
2는 int값이지만 2 = 2.0으로 doubleVarable = 2.0이다.
int a= 'z'
'z'의 아스키 코드가 65이므로 a의 값은 65이다.
일반적인 규칙으로는 한 유형의 값을 다른 유형의 변수로 넣을 수 없지만 예외가 존재할 수 있다.
하지만 규칙을 따르는 것이 따르는 것이 좋다.
integer유형에 bool유형이 할당 가능하고 bool유형에 integer유형이 할당 가능하다.
bool에 할당될 때 0이 아닌 수는 false, 0인 수는 true로 저장된다.
integer에 할당될 때 true는 1, false는 0에 저장된다.
리터럴
리터럴(literal): 특정한 값을 가진 이름, 상수(constant)라고도 한다. int형 상수, double형 상수, char형 상수, bool형 상수가 있다.
과학적 표기법(scientific notation) or 부동 소수점 표기법(floating-point notation)
double형 상수에 대한 더 복잡한 표기법
너무 큰 수나 너무 작은 수를 표기할 때 적합하다.
3.67 * 10^5 = 367000.0 = 3.67e5
5.89 * 10^3 = 0.00589 = 5.89e-3
e: 지수(exponent)를 나타내며 "다음에 나오는 거듭제곱에 10을 곱한다"는 의미이다.
따옴표(quote) 유의
문자열 상수는 큰따옴표 안에, 유형 char의 상수는 작은따옴표 안에 배치된다.
서로 같지 않다는 것에 유의하자
'A': char 문자형의 값"A": string 문자열의 한 글자
큰따옴표로 묶은 문자열은 "Hello"와 같이 종종 C-strings라고 불립니다.
C-string은 앞에서 소개한 문자열 클래스와 같지 않지만
둘 다 텍스트의 시퀀스를 저장하는 데 사용되며 때때로 둘을 교환하여 사용합니다.
이스케이프 시퀀스(Escape Sequences)
이스케이프 시퀀스: 문자 앞에 오는 백슬래시, \ 앞에 오는 백슬래시는 컴파일러에게 백슬래시 뒤에 오는 시퀀스가 문자 자체에서 나타나는 것과 동일한 의미가 아님을 알려줍니다. 시퀀스는 기호 사이에 공백이 없이 두 개의 문자로 입력됩니다.
백슬래시(\)를 입력하고 싶을 때: \\ 를 입력한다.
쌍따옴표(")를 입력하고 싶을 때:\"를 입력한다.
몇몇 이스케이프 시퀀스
| 시퀀스 | 의미 |
| \n | New line |
| \r | Carriage return (Positions the cursor at the start of the current line. You are not likely to use this very much.) |
| \t | (Horizontal) Tab (Advances the cursor to the next tab stop.) |
| \a | Alert (Sounds the alert noise, typically a bell.) |
| \\ | Backslash (Allows you to place a backslash in a quoted expression.) |
| \' | Single quote (Mostly used to place a single quote inside single quotes.) |
| \" | Double quote (Mostly used to place a double quote inside a quoted string.) |
| The following are not as commonly used, but we include them for completeness: | |
| \v | Vertical tab |
| \b | Backspace |
| \f | Form feed |
| \? | Question mark |
상수 네이밍하기
변수의 값을 변경할 수 없도록 변수 선언을 표시하하기 위해 선언 앞에 const(상수의 약어)를 붙입니다.
SYNTAX
const Type_Name Variable_Name = Constant;
EXAMPLE
const int BRANCH_COUNT = 10;
const int WINDOW_COUNT = 10;
const라는 단어는 선언되는 변수를 수정(제한)하기 때문에 종종 수식어(modifier)라고 불립니다.
const 수식어를 사용하여 선언된 변수를 선언된 상수(declared constant)라고 합니다.
C++ 언어에서 선언된 상수를 모두 대문자로 쓰는 것은 필요하지 않지만 C++ 프로그래머들 사이에서는 표준 관례입니다.
산술 연산자와 식
식은 변수, 상수, 연산자(+, -, *, /, %)로 구성
혼합한 형태
int형만 존재 -> 결과: int형
double형만 존재 -> 결과: double형
int형, double형 같이 존재 -> 결과: double형
우선순위 규칙(precedence rule)
연산 순서는 괄호를 삽입하여 산술식으로 지정할 수 있습니다.
괄호를 생략하면 컴퓨터는 덧셈과 곱셈과 같은 연산이 수행되는 순서를 결정하는 우선 순위 규칙이라는 규칙을 따를 것입니다.
이 우선 순위 규칙은 대수학이나 다른 수학 수업에서 사용되는 규칙과 유사합니다.
네이밍된 상수
#include <iostream>
using namespace std;
int main( )
{
const doubleRATE = 6.9;
double deposit
cout << "Enter the amount of your deposit $";
cin >> deposit;
double newBalance;
newBalance = deposit + deposit*(RATE/100);
cout << "In one year, that deposit will grow to\n"
<< "$" << newBalance << " an amount worth waiting for.\n";
return 0;
}
샘플 대화
Enter the amount of your deposit $100
In one year, that deposit will grow to
$106.9 an amount worth waiting for.
정수와 부동 소숫점 나눗셈
double 나눗셈은 흔히 기대하는 나눗셈을 한다. (10/3 = 3.333..., 5/2 = 2.5)
정수 나눗셈은 소수점 이하를 버린다. (10/3 = 3, 5/2 = 2)
% 연산자는 int형에서 나눗셈의 나머지에 대한 정보를 제공한다. (10%3 = 1, 5%2=1)
cout << "17 divided by 5 is " << (17 / 5) << "\n";
cout << "with a remainder of " << (17 % 5) << "\n";
17 divided by 5 is 3
with a remainder of 2
int형의 음의 값과 함께 사용할 경우 연산자 / 및 %의 결과는 C++의 구현에 따라 다를 수 있습니다.
따라서 두 값이 모두 음이 아닌 경우에만 / 및 %를 int 값과 함께 사용해야 합니다.
함정: 전체 숫자에 대한 나눗셈
totalPrice = 5000 * (feet/5280.0);
int feet = 15000
여기서 totalPrice의 타입이 double이면 계산값이 14200이 나오고
totalPrice의 타입이 int이면 계산값이 10000이 나온다.
실제 결과값은 14200이므로 변수의 타입에 오차가 나지 않도록 미리 잘 설정해야 한다!
타입 캐스팅
타입 캐스트(type cast): 유형 캐스트는 한 유형의 값을 다른 유형의 값으로 변경하는 방법
static_cast<Type>(Expression) : 객체의 데이터 형식을 다른 데이터 형식으로 변환할 때 사용한다.
const_cast<Type>(Expression): 상수를 버리기 위해 사용한다.
dynamic_cast<Type>(Expression): 상속 계층에서 하나의 유형에서 하위 유형으로 안전하게 다운캐스트하는 데 사용한다.
reinterpret_cast<Type>(Expression): 다른 데이터 형식으로 포인터나 참조를 변환하는 데 사용한다.
static_cast 예시)
double ans = n/ static_cast<double>(m);
부동 소수점 유형의 변수에 정수 유형의 값을 항상 할당할 수 있습니다.
ex)
double d = 5;
이 경우 C++는 자동 타입 캐스트를 수행하여 5를 5.0으로 변환하고 변수 d에 5.0을 배치합니다.
이러한 자동 변환은 때때로 유형 강요(type coersion)라고 합니다.
증감 연산자
증가 연산자(increment operator): 변수의 값에 1을 더한다. 기호는 ++이다.
감소 연산자(decrement operator): 변수의 값에 1을 뺀다. 기호는 --이다.
int n = 1, m = 7;
n++
cout << "The value of n is changed to " << n << "\n";
m- -;
cout << "The value of m is changed to " << m << "\n";
결과값
The value of n is changed to 2
The value of m is changed to 6
n++ 대 ++n
n++: 변수 n의 값을 평가한 다음 변수 n의 값을 1씩 증가시킨다
++n: 변수 n의 값을 1씩 증가시킨 다음 변수 n의 값을 평가한다.
int n = 2;
int valueProduced = 2*(n++);
cout << valueProduced << "\n";
cout << n << "\n";
결과값
4
3
int n = 2;
int valueProduced = 2*(++n);
cout << valueProduced << "\n";
cout << n << "\n";
결과값
6
3
함정: 평가 순서
n + (++n)
n = 2라고 가정하자.
오른쪽부터 계산하면 5, 왼쪽부터 계산하면 6이다.
그런데 C++에서는 계산순서에 우위가 없으므로 이런 식으로 프로그래밍해서는 안된다.
하지만 &&(그리고), ||(또는) 연산자 및 쉼표 연산자의 경우 C++는 평가 순서가 오른쪽에서 왼쪽으로 유지됨을 보장한다.
ex) (n <= 2) && (++n > 2) => 2 <=2 이고 2+1=3>2이므로 참이된다.
1.3 콘솔 입출력
단순 콘솔 입출력은 객체 cin, cout, cerr와 라이브러리 iostream에서 이루어진다.
입출력을 하기 위해서는 프로그램 시작할 때 아래와 같은 코드를 추가해야 한다.
#include <iostream>
using namespace std;
cout을 이용한 출력
변수 값은 물론 텍스트 문자열도 cout을 사용하여 화면에 출력할 수 있습니다.
예시1)
cout << "Hello reader.\n"
<< "Welcome to C++.\n";
예시2)
cout << numberOfGames << " games played.";
식도 표현할 수 있다.
cout << "The total cost is $" << (price + tax);
두 < 기호는 공백 없이 입력해야 합니다. 화살표 표기 <<는 삽입 연산자라고 불립니다.
공백 기호는 다음과 같이 나타낼 수 있다.
cout << firstNumber << " " << secondNumber;
+기호를 통한 문자열 결합도 나타낼 수 있다.
string day1 = "Monday", day2="Tuesday";
cout << day1 + day2;
결과로 출력
"MondayTuesday"
출력에서 새로운 줄 시작하기
\n은 컴퓨터에 출력 줄을 새로 시작하라고 지시합니다.
비록 두 개의 기호로 입력되었지만, C++는 \n을 새 줄 문자(newline character)라고 불리는 하나의 문자로 간주합니다.
cout << "\n";
이와 동일한 표현은 아래와 같습니다.
cout << endl;
TIP: \n 또는 endl로 각 프로그램 끝내기
모든 프로그램이 끝날 때마다 새로운 줄 명령어를 출력하는 것이 좋습니다.
마지막으로 출력할 항목이 문자열이면 문자열 끝에 \n을 포함하고,
그렇지 않으면 프로그램의 마지막 출력 동작으로 endl을 출력합니다.
소수점이 있는 숫자에 대한 서식 지정
Double 형식의 답 출력
만약 당신이 당신의 프로그램에 다음과 같은 "마법 공식"을 삽입한다면, 모든 타입 더블(또는 다른 타입의 부동소수점 번호)은 다음과 같은 통상적인 표기법으로 출력될 것입니다.
소수점 뒤의 두 자리 수:
cout.setf(ios::fixed);
cout.setf(ios::showpoint);
cout.precision(2);
소수점 뒤에 다른 자릿수를 지정하기 위해 2 대신 음수가 아닌 다른 정수를 사용할 수 있습니다. 2 대신 int 유형의 변수를 사용할 수도 있습니다.
cerr를 이용한 출력
오브젝트 cerr은 cout와 같은 방식으로 사용됩니다.
오브젝트 cerr은 출력을 일반적으로 콘솔 화면인 표준 오류 출력 스트림으로 보냅니다.
이를 통해 두 종류의 출력을 구별할 수 있습니다.
일반 출력의 경우 cout, 오류 메시지 출력의 경우 cerr입니다.
cin을 이용한 입력
cin 문은 키보드에 입력한 값과 같은 변수를 설정합니다.
SYNTAX
cin >> Variable_1 >> Variable_2 >>... ;
예시1)
cin >> numberOfLanguages;
예시2)
cout << "Enter the number of dragons\n"
<< "followed by the number of trolls.\n";
cin >> dragons >> trolls;
동작원리
프로그램이 cin 문에 도달하면 키보드에서 입력을 기다립니다.
첫 번째 변수는 키보드에서 입력한 첫 번째 값과 같게 설정한다.
두 번째 변수는 입력한 두 번째 값과 같게 설정합니다.
그러나 프로그램은 사용자가 Return 키를 누를 때까지 입력을 읽지 않습니다.
이것은 사용자가 입력 라인을 입력할 때 뒷공간을 확보하고 실수를 수정할 수 있게 해줍니다.
입력 구분
화이트스페이스(whitespace): 하나 이상의 공백 또는 줄 바꿈으로 구분하는 문자
cin 문을 사용할 때, 컴퓨터는 다음 입력 값을 찾을 때까지 빈 칸이나 줄 바꿈의 수를 건너뛰게 됩니다.
디스플레이 1.5 문자열에서 cin과 cout을 이용하기
//Program to demonstrate cin and cout with strings
#include <iostream>
#include <string> // Needed to access the string class.
using namespace std;
int main( )
{
string dogName;
int actualAge;
int humanAge;
cout << "How many years old is your dog?" << endl;
cin >> actualAge;
humanAge = actualAge * 7;
cout << "What is your dog's name?" << endl;
cin >> dogName;
cout << dogName << "'s age is approximately " <<
"equivalent to a " << humanAge << " year old human."
<< endl;
return 0;
}
샘플 대화1
How many years old is your dog?
5
What is your dog's name?
Rex
Rex's age is approximately equivalent to a 35 year old human.
샘플 대화2
How many years old is your dog?
10
What is your dog's name?
Mr. Bojangles
Mr.'s age is approximately equivalent to a 70 year old human.
cin이 공간에서 입력을 중지하므로 "Bojangles"가 dogName으로 읽히지 않습니다.
TIP: 입출력에서 줄바꿈
출력과 입력을 동일한 라인에 유지할 수 있으며, 때로는 사용자에게 더 좋은 인터페이스를 제공할 수 있습니다.
예시)
cout << "Enter the cost per person: $";
cin >> costPerPerson;
사용자 입력시)
Enter the cost per person: $ 1.25
1.4 프로그램 스타일
주석(comment)
// : 각 줄 끝날 때 보충 설명
예시)
distance = speed * time; //Computes the distance traveled.
/* */: 이 사이 공간은 전부 주석처리된다.
예시)
/*This is a comment that spans
three lines. Note that there is no comment
symbol of any kind on the second line.*/
1.5 라이브러리와 네임스페이스
라이브러리와 include 지시문
C++의 표준 라이브러리를 프로그램에서 사용할 수 있게 만드는 일반적인 방법은 include 지시문입니다.
#include < Library_Name>
예시)
#include <iostream>
전처리기(preprocessor):C++에는 프로그램의 텍스트가 컴파일러에 전달되기 전에 간단한 텍스트 조작을 처리한다.
컴파일러에서 당신이 프로그램을 컴파일할 때 전처리기가 자동으로 호출된다.
include 지시문은 전처리기에 의해 처리된다.
네임스페이스
네임스페이스(namespace): 이름 정의의 집합
사용할 모든 표준 라이브러리는 std(standard) 네임스페이스에 정의되어 있습니다.
이것을 사용하기 위해 아래의 지시문을 포함해야 합니다.
using namespace std;
따라서 콘솔 I/O를 사용하는 간단한 프로그램이 시작된다.
#include <iostream>
using namespace std;
표준라이브러리에서 cin만 사용하기를 원하면
using std::cin;
표준라이브러리에서 cin, cout, cerr만 사용하기를 원하면
#include <iostream>
using std::cin;
using std::cout;
using std::endl;
함정: 라이브러리 이름에 대한 문제
새 표준에 맞게 아직 수정되지 않은 컴파일러를 사용하는 경우 다른 라이브러리 이름을 사용해야 합니다.
예시)
아래의 구문은 작동한다.
#include <iostream>
이것의 예전 버전인 아래의 구문은 최신 버전의 컴파일러에서 작동하지 않는다.
#include <iostream.h>