강께르의 개발일지

[수업] 20210913_1일차 본문

프로그래밍/C#

[수업] 20210913_1일차

강께르 2021. 9. 14. 01:33

1. 용어 정리

- 키워드(예약어, reserved word)

컴파일러에게 하나의 기능을 사용하기 위해서 알려주기 위한 약속된 단어

example) class, static, void, int 등...

 

- 식별자(identifier)

프로그래밍을 하면서 임의로 선택해서 프로그래머가 이름을 지을 수 있는 단어

example) 변수 이름, 클래스 이름, 함수 이름 등...

 

식별자 이름 짓기 규칙은 C++에서 쓰던 거랑 유사하다.

1. 시작 문자 숫자 X

2. 언더바만 특수문자 중 유일 사용 가능

3. 유니코드 범위 내의 문자 사용가능, 한글 가능 but, 사용 지양

4. 예약어와 이름을 같게 할 수 없다.

등이 있다.

 

- 리터럴(literal)

소스 코드의 고정된 값을 대표하는 용어"

"문자 그대로의" -> 숫자, 문자 등의 값 그대로를 의미하는 문법 요소

고정된 값, 값 그대로라는 특성으로 상수와 유사하다.

각 리터럴은 각자마다 고유 데이터형을 보유하고 있다.

 

- 구두점

연산자 외의 기호문자들을 의미

중괄호, 대괄호, 소괄호나 쉼표, 세미콜론을 구두점이라고 한다.

 

- 연산자

단항, 이항, 삼항 연산자라는 항의 개수와 더불어 사용하는 목적에 따라

산술, 증감, 조건, 관계, 논리 등 여러 가지 연산을 가능케 제공하는 것을

연산자이다.

 

- 주석

C++의 주석과 유사하게 사용한다

 

- 공백에 대해

컴파일러는 공백을 모두 없애고 컴파일한다.

공백의 종류로 띄어쓰기, 탭, 줄 바꾸기 등이 있다.

 

2. .NET 프레임워크

마이크로 소프트에서 개발한 프레임워크

윈도우용 프로그램 개발 및 실행 환경

웹/윈도우 기반 응용프로그램을 개발할 수 있다.

-> 이 .NET 표준을 따르는 프로그래밍 언어 중 하나가 C#

 

.NET 프레임워크만 설치되어 있으면 C#뿐만이 아니라 다른 언어들로 개발된 프로그램들도 실행이 가능하다.

 

Common Language Runtime(CLR)

.NET 언어로 작성된 프로그램을 실행하고 관리하는 실행환경

 

.NET에 동작하는 프로그램을 적재, 프로그램의 동적 컴파일, 프로그램의 실행, 가비지 컬렉터, 프로그램의 예외 처리, 언어 간의 상속 지원 등 .NET 표준을 따르는 언어들은 CLR을 통해 프로그램을 실행 가능케 한다.

 

Intermediate Language(중간 언어, IL)이라는 기계어 전의 변환하기 쉬운 중간 단계의 언어를 만들어 어떤 플랫폼이든 기계어로 바꾸는 번역기만 있으면 실행 가능케 하기 때문에 위의 내용이 가능하다. 

 

그 말은 운영체제가 바뀌어도 .NET 프레임워크가 운영체제와 통신하고 HW의 자원을 요청하기에 언어에서 신경쓰지 않아도 된다.

 

3. object 데이터형

C#에서 모든 자료형은 object형에서 파생되었다.

사용자가 만드는 모든 데이터형의 최상위 부모 클래스가 될 것이다.

기본 데이터형도 하나의 구조체 혹은 클래스로 사용된다.

example) int a = new int(5);

기본 데이터형 int를 인스턴스를 생성해서 대입해준다.

 

4. 선언에 대해

멤버변수, 멤버함수 하나 하나에 접근 제어 지시자를 붙인다.

example) public void Convert (int unit) { }

 

접근 제어 지시자를 따로 붙이지 않으면 private가 기본

생성자에도 접근 제어 지시자를 붙인다.

반환형은 없고 클래스랑 이름은 똑같이

 

C#에서는 데이터형에 따라서 정적 할당 혹은 동적 할당을 쓰게 된다.

 

멤버 변수의 다른 이름 : 필드

멤버 함수의 다른 이름 : 메소드

new의 리턴값 : 객체 혹은 인스턴스라고 지칭

 

static 멤버 <-> 인스턴스 멤버

static 멤버 : 클래스에 위치하여 객체, 인스턴스들이 공유하는 멤버

인스턴스 멤버 : 객체마다 가지고 있는 멤버(객체마다 이 멤버의 값을 다르게 가지고 있을 수 있다.)

 

지역 변수 : 한 스코프 안에서 살아있는 변수

멤버 변수(필드) : 한 클래스, 객체 내에서 살아있는 변수

 

암시적 변수 선언

-> var 키워드(지역 변수에만 사용가능)

변수를 선언할 때, 이 키워드를 붙여서 초기화하면 초기화한 값으로 결정되는 변수로 만드는 키워드이다.

강타입 언어 : 타입 검사를 빡세게 하는 언어 -> 변수 선언 시에 결정된 타입을 그대로 쓴다.

써도 성능에 아무런 문제가 없으니 써도 상관없다.

컴파일 타임에 정해지는 변수

 

배열도 new로 만들 수 있으면 자료형으로 따로 구분해서 선언해야한다.

example)

int[] a = new int[] { 0,1,2 };

var rectMatrix = new int[,]
{
    { 0, 1, 2 },
    { 3, 4, 5 }
}

var rectMatrix = new int[][]
{
   new int[] { 0, 1, 2 },
   new int[] { 3, 4, 5 }
}

 

5. 값 형식과 참조 형식

데이터는 두 가지 영역에 나뉘어서 저장된다.

하나는 정적 할당이라고 칭하며, 스택 영역에 저장된다.

하나는 동적 할당이라고 칭하며, 힙 영역에 저장된다.

 

스택 영역에 정적 할당된 데이터의 예로는 object형과 string형을 제외한 나머지 기본 데이터형이 있다.

힙 영역에 동적 할당된 데이터의 예로는 object형과 string형을 포함하여 사용자 정의 데이터형이 있다.

 

위의 데이터를 값 형식 타입, 아래 데이터는 참조 형식 타입이라고 말한다.

 

값 형식의 타입은 코드 영역이 끝나면, 자신이 선언된 스코프가 끝나면 자동으로 메모리 영역이 해제된다.

참조 형식의 타입은 원래 사용자가 명시적으로 해제해줘야하는 타입이다.

하지만 C#에서는 .NET 프레임워크가 메모리 관리라는 기능을 수행한다고 위에서 이야기했다.

 

보통 프로그래머가 명시적으로 해제해주지 않고 레퍼런스를 잃어버리는 경우, 그 접근할 수 없는 영역을 가비지라고 말한다.

이런 경우, 프로그래머가 다시 접근하여 해제해줄 방법이 없기 때문에 계속 메모리를 잡게 되어 메모리 누수 현상이 일어나는 것이다.

 

이를 .NET 프레임워크에서는 발생하지 않게 관리해준다는 것이다. 가비지가 발생하면 그 메모리를 정리하는 역할인 가비지 컬렉터 기능을 수행하는 것이다.

 

이 두 형식의 복사를 살펴보자.

값 형식일 때는 깊은 복사를 수행해서 값이 그대로 복사된다.

참조 형식으로 복사를 하면 값이 복사되는 게 아니라 참조하고 있는 인스턴스의 참조 값을 복사하게 된다.

그래서 참조 형식은 하나의 인스턴스로 두 변수가 참조하게 되어 같은 인스턴스의 멤버 변수 값을 가질 수도 있다.

 

참조형의 특징으로는 null을 대입할 수 있다.

이 의미는 값이 null이라기 보다는 참조하고 있는 대상이 없음을 의미하는 것이다.

하지만 null로 대입한 참조형 변수를 사용하면 런타임 에러가 발생하니 유의

 

이런 참조형은 쓰기는 편하나 명시적으로 해제할 방법은 없기에 단점일 수 있으나

하드웨어 발전 속도를 많이 이룬 현재에는 크게 메모리 관리면에서 퍼포먼스가 떨어지지 않는다.

 

6. 연산자

연산자는 MSDN을 한 번 쓱 보는 것을 추천!

연산하는 것과 연산하고난 그 결과인 return까지가 연산자가 고려하는 요소이다.

 

예를 들어 증감연산자의 순서로 연산하고난 값을 리턴하는 것인지 연산하기 전의 값을 리턴하는 것인지 차이가 있을 수가 있다. 이것이 연산자가 고려하는 요소인 것이다.

 

연산자마다 피연산자의 데이터형에 따라 고려하는 요소가 있다.

정수에서는 int형 아래로의 데이터형의 연산을 지원하지 않는다.

그렇기에 int형으로 형 변환을 하여 연산한다.

 

비트별로 동작하는 연산자인 비트연산자가 있다.

2진수로 음수를 표현할 때는, 2의 보수를 취한다.

쉬프트 연산자와 &, |, ^ 연산자는 한번씩 훑어보기만 하자.

 

쉬프트 연산자에서 새로 알게 된 점은

쉬프트하고나서 새로 채워지는 비트에 관한 이야기다.

<< 연산자 사용 시 오른쪽에 채워지는 비트는 무조건 0으로 고정이다.

>> 연산자 사용시 왼쪽에 채워지는 비트는 최상위 비트의 값에 따라 다르다.

왜냐하면 최상위 비트는 부호비트이기 때문에 이를 따라가는 것이다.

 

7. 실수형 데이터

실수형에서 새로 알게 되는 것

실수형에서는 0으로 나눌 수 있다.

런타임 에러는 나지 않고, 그 값을 나누는 값에 따라 다른 특별한 값을 가진다.

0 / 0 = nan

double / 0 = positive infinity

double / -0 = negative infinity

 

실수형 데이터에서 중요한 것!

실수는 태생적 한계를 지니고 있다.

1.0과 0.0 사이의 수가 몇 개 있는지 셀 수 있냐고 물어볼 때,

이야기하기 어렵듯이 한 가지 데이터형으로 표현할 수 있는 소수점 아래 자릿수의 한계가 있다는 것이다.

그럼에도 이를 타협하면서 사용하는 편이다.

 

그래서 원래는 float보다는 double이 표현할 수 있는 범위나 정확성 면에서 많이 쓰이는 편이지만

게임 프로그래밍에서는 실수들의 연산을 하는 단위가 float여서 double보다는 더 많이 쓰는 편이다.

 

실수형을 정수형처럼 비교하면 안된다. 물론 상수와 상수끼리의 비교는 아래 비트들까지 전부 똑같을 수 있으니

비교가 가능하겠지만, 변수에 대입한 실수형 데이터는 실수형의 근삿값으로 비교될 수 있으니 지양해야 한다.

 

보장되는 자릿수가 같으면 그 근삿값으로 비교로 사용하든지 판단을 똑디 하자.

 

8. bool형 데이터

bool형의 == 연산자는 같은 데이터형 안에서만 사용 가능하다.

값 형식 변수끼리의 비교는 같은 값인지 비교하는 것이다.

참조형 변수끼리의 비교는 같은 인스턴스인지 비교하는 것이다.

 

9. 문자열

string은 참조형이어서 힙 영역에 할당되지만 동작은 값 형식처럼 한다.

string도 new로 인스턴스를 생성한다.

== 연산자에서 인스턴스 비교를 수행하지 않고 값 비교를 수행한다.

= 연산자에서 인스턴스 복사가 아니라 값 복사를 수행한다.

 

C#은 문자 취급을 무조건 유니코드로 한다.

 

유니코드란 무엇인가?

국제적인 문자 표준이다.

컴퓨터에는 문자 데이터를 저장할 땐 정수로 데이터로 저장하고

읽을 때 문자 테이블을 거쳐서 출력하는 방법을 사용한다.

 

그 때, 이 문자 테이블이 유니코드에 해당하는 것이다.

문자에는 완성형과 조합형이 있는데 유니코드는 완성형으로 모든 국제적인 언어가 개별문자로 저장되어있다.

 

유니코드말고 다른 문자 테이블은 멀티바이트가 있다.

각각 나라 언어마다 다른 문자 테이블을 갖고 있기에 같은 정수라도 다른 테이블이기에 다른 문자가 출력되는 문제가 발생할 수 있다.

 

아래는 string에 대한 메소드들에 대해 훑어볼 것이다. 하지만 MSDN을 참조하고 다양한 것을 써볼 자세를 가지자.

 

문자열 사이에 줄 바꿈이 있으면 안된다. 하지만 문자열 앞에 @을 접두사로 붙이면 ""안에 있는 문자열에 어떤 것을 쓰든지 다 문자열화해버린다.

그래서 코드를 넣거나 파일 경로를 문자열에 넣을 때, @을 사용한다.

이 때 줄 바꿈이 있어도 괜찮다. 하지만 "는 두 번 연속 찍어야 하나로 인정된다.

 

$는 문자열 안에 있는 중괄호를 특별하게 취급한다.

런타임 중에 결정되는 것들을 문자열과 함께 출력할 때 사용한다.

보통은 string에서 제공하는 메소드인 Format을 활용한다.

printf와 쓰이는 모양새는 유사하며, 문자열에 있는 {0}, {1}... 중괄호들이 뒤에 따라오는 인자들과 매칭되어 문자열을 반환한다.

$을 사용하는 것은 문자열 보간이라고 한다.

따로 Format을 사용하지 않고 문자열 안에서 해결하는 것이다.

$"문자열 { num } " 형식으로 쓸 수 있다는 것이다.

중괄호 안에 두번째 인자로 정렬을 사용할 수 있다. 음수는 왼쪽 정렬, 양수는 오른쪽 정렬로 기준으로 수를 입력하면 그 수만큼 공간을 확보하고 정렬할 것이다.

:X2를 붙이면 두자리 16진수로 변환한다는 서식 변환 문자도 추가할 수 있다.

 

string 클래스는 생성자가 다양하니 한번씩 보시고...

빈 문자열 ""과 null을 다르게 취급한다.

빈 문자열은 리터럴로 대입하는 것보다 empty 메소드를 쓰는 것을 추천한다.

 

enumable

IEumerator 

열거자를 구현하는 인터페이스를 의미한다.

IEumerable

열거자를 get하는데 필요한 인터페이스를 의미한다.

그래서 이 인터페이스를 상속받아 GetEnumerator()를 재정의하면 순회하는 반복자를 사용할 수 있는 거 같다.

- 다음에 다시 알아볼 것...

 

그래서 string 또한 순회가능한 클래스라는 의미이다.

foreach문을 이용해 IEnumerator를 순회하는 반복을 한다.

 

문자열 메소드를 간단하게 정리해보자

 

IndexOf

문자 혹은 문자열을 string에 포함될 경우 그 위치 값을 Int형으로 return

 

SubString

시작길이부터 인자까지 string으로 return

 

Replace

1번째 인자 값을 2번째 인자값으로 반환

 

Split

주어진 문자, 문자열의 인자값을 갖고 구분자로 나뉘어 string[]으로 return

 

insert

원하는 인덱스에 문자 혹은 문자열 삽입

 

padleft, right

패딩 추가 메소드

 

trim

화이트 스페이스를 제외한 문자열 return

 

concat

문자열 연결 메소드 -> 지양, 스트링 빌더 클래스 이용

 

 

 

StringBuilder 클래스

append로 문자열을 붙여 ToString으로 반환

'프로그래밍 > C#' 카테고리의 다른 글

[수업] 20210916_4일차  (0) 2021.09.17
[문제 풀기] 클래스에 관하여  (0) 2021.09.16
[수업] 20210915_3일차  (0) 2021.09.16
[수업] 20210914_2일차  (0) 2021.09.14
[문제 풀기] 문자열에 대해서  (0) 2021.09.14