U E D R , A S I H C RSS

CS/5월11일


1. 개요

  • 시작합니다!

3. 진행 시간

  • 수요일 오후 7시 ~ 오후 9시
    • 역시 이 스터디에는 고정된 시간이란 없는 것 같아요.

4. 진행 예정 내용

  • 다소 중요하다고 생각된 내용은 보라색 볼드(굵게) 처리하였습니다.

  • #1. 닷넷 프레임워크 살펴보기
    • 닷넷 응용 프로그램의 기본 구조
    • CLR과 IL/MSIL(CIL)
    • 닷넷 호환 언어
    • CTS와 CLS
    • 메타데이터, 닷넷 응용 프로그램 속의 메타데이터
    • 어셈블리, 모듈
    • CLI와 CTS, CLI와 닷넷 프레임워크
    • 닷넷 프레임워크 구성 요소
    • 기존 윈도우 프로그램과 닷넷 응용 프로그램의 대응 관계
    • 모노(Mono) 프레임워크
    • C#과 닷넷 프레임워크
    • Naming Convention

  • #2. C#의 타입과 문장(Statement), 배열
    • 자료형과 기본 자료형
    • C#에서의 정수 타입, 실수 타입, 문자 타입. 상수
    • C#에서의 변수 초기화
    • C#에서의 Escape Sequence
    • 형변환
    • 예약어와 식별자
    • 값 형식과 참조 형식
    • 배열, 다차원 배열, 가변 배열
    • 논리 연산자, 관계 연산자, 조건 연산자
    • C#의 조건문과 반복문, 점프문

  • 만약 시간이 된다면 #3까지도 예정중입니다.
    • 이것저것 하다보니 시간이 거의 딱 맞아서 진행하지는 않았습니다.

5. 진행

5.1. 내용 요약

5.1.1. 1. 닷넷 프레임워크 살펴보기

  • C#을 쓰기 위해서는 .NET Framework가 필요합니다.
  • .NET Framework는 일종의 Process Virtual Machine(가상머신) 입니다.
  • 일반적인 네이티브 언어로 만들어진 프로그램들이 기계어를 통해 곧바로 운영체제에서 실행될 수 있는 것과 달리, C# 프로그램은 C# 컴파일러에 의해 중간에 어떤 코드(IL)로 바뀌었다가 .NET Framework(정확히는 CLR)가 대신 실행해줍니다.

  • .NET을 깔면 자동으로 CLR(Common Language Runtime)이 설치됩니다. 사실 C#소스를 컴파일한뒤 CLR에 던져서 실행하는 구조입니다.
  • 중간에 거쳐가는 파일은 IL(Intermediate Language:중간언어)로작성된 파일입니다.
  • 즉, C# 컴파일러는 C# Source를 IL로 바꿔주는 것 뿐이고, 실행 시 CLR이 IL을 기계어로 바꾸면서 실행을 하게 됩니다.
  • IL 역시 하나의 언어에 속하기 때문에, 별도로 ILASM.exe라는 컴파일러도 존재합니다.

  • 일반적인 exe와는 다르게 .NET exe/dll(닷넷 응용 프로그램)에는 CLR 로더가 포함되어 있습니다.(생각해보면 CLR이 없으면 프로그램이 굴러가지 않겠죠?)

  • CLR은 프로세스가 실행되면 로더에 의해 메모리에 함께 적재되어 실행됩니다.

  • .NET Compliant Language (.NET 호환언어) : 어떤 언어든지 IL코드로만 바꿀 수 있다면 CLR에서 작동하지 않을까? 라는 생각에서, 컴파일러가 소스 코드의 결과물을 IL코드로 바꿀 수 있는 언어를 말합니다.

  • 대표적인 .NET CL의 공식적인 종류로는 C++/CLI, F#, VB.NET C# 등이 있습니다. (Ruby, Python, Lisp, COBOL, PHP들도 비공식적으론 읍읍..)

  • 닷넷 IL은 CIL이라 부르기도 하고, MSIL이라고 부르기도 합니다. (자바 IL은 바이트 코드라고 하죠?)
  • IL 코드는 CPU에 독립적이기 때문에, 모든 닷넷 호환 언어는 소스 코드를 IL 코드로 컴파일한 뒤 CLR이 실핻될 때 IL 코드를 CPU의 기계어로 최종 번역하게 됩니다.

  • CTS(Common Type System, 공용 타입 시스템)은 .NET호환언어가 지켜야할 표준 규격을 정의한 것입니다.
  • .NET 호환 언어는 CTS를 넘어서서 구현할 수 없지만, 꼭 CTS를 전부다 구현해야 할 필요도 없습니다.
    • 예를 들어, CTS에서는 클래스 상속을 하나만 허용하기 때문에, 클래스 다중 상속을 지원하도록 만들 수는 없습니다.
    • CTS에서는 접근 제한자로 public, private 등을 지원하지만 필요에 따라 public만 지원하도록 만들 수도 있습니다.

  • CLS(Common Language Specification)은 CTS와는 다르게 .NET 호환 언어가 지켜야 할 최소한의 언어 사양을 정의한 것입니다.

  • 서로 다른 닷넷 호환 언어끼리 호출해야 하는 경우에는, 그 기능에 한해서 CLS를 만족시키도록 작성해야 합니다.
    • 예를 들어, C#에서는 unsigned 를 지원하지만, CLS에서는 unsigned 타입을 강제화하지 않으므로 만약 다른 닷넷호환언어에서 unsigned를 지원하지 않는다면 문제가 생깁니다.

  • 메타데이터(metadata)는 데이터를 위한 데이터로써, 예를 들면 그림의 속성을 나타내고 있는 데이터들이 메타데이터입니다.
  • 프로그래밍 언어에서는 개발자가 구현한 코드가 데이터에 해당하고, 해당 코드의 성격을 설명해주는 클래스, 메서드 등을 메타데이터라고 합니다.

  • exe 또는 dll을 만들게 되면 CLR에서는 자기서술적인 데이터(META data)로써 프로그램의 함수, 클래스들의 목록을 기록합니다. (즉, 그에 대한 메타데이터를 생성합니다.)
  • Reflection 기술을 활용하면 exe이나 dll안에 서술된 메타데이터를 읽어 어떤 클래스나 메서드가 제공되는지 확인할 수 있습니다.

  • CLI(Common Language Infrastructure)는 MS가 ECMA에 제출한 표준형식으로, CTS 명세나 중간 언어(IL)에 대한 코드 정의, 메타데이터와 그것을 포함하는 바이너리 파일들의 구조가 명세되어 있습니다.
  • 따라서 CLR은 CLI를 구현하고 있으며, CLI를 구현한다면 .NET과 호환됩니다. (ex) Mono는 CLI의 구현체

  • 어셈블리(Assembly): .NET에서는 exe나 dll 같은 실행 파일을 어셈블리라고 합니다.
  • 모듈(Module): 하나의 어셈블리를 여러개의 모듈(Module)(.netmodule)로 쪼갤 수 있습니다. 모듈 하나당 한 개의 파일이 대응됩니다. 단, 어셈블리안에 존재하는 모듈 중 하나는 반드시 다른 모듈들의 위치를 기술(기능은 없고, 단순히 위치를 기술함)하고 있어야 하는데, 이 모듈의 확장자가 바로 exe 또는 dll이 됩니다. 하지만 Visual Studio에서도 지원하지 않습니다(개념적인 내용)

  • CLR(Common Language Runtime)에는 중간 언어를 기계어로 변환해주는 JIT(Just-In-Time)컴파일러와 GC(Garbage Collector)가 들어가있습니다.

  • .NET 호환 언어를 Managed(관리)언어라고도 합니다.
  • CLR 자체를 관리 환경(Managed Environment)라고도 하고, CLR이 로드되는 프로세스를 관리 프로세스라고도 합니다.

  • 기존 프로그램에 CLR loader를 넣어주면 .NET호환언어를 구동시킬 수 있는 프로그램이 됩니다.
    • 예를 들어, IE(Internet Explorer)안에는 CLR loader가 들어가 있어서, .NET 호환 언어로 만들어진 컨트롤을 웹 브라우저에서 실행시킬 수 있습니다.

  • MS에서는 CLR, BCL(Base Class Library, 표준라이브러리), GAC(Global Assembly Cache)를 묶어서 '.NET Framework'라고 배포합니다.
  • GAC는 컴퓨터에서 실행되는 닷넷 응용 프로그램이 어셈블리 파일을 공통적으로 찾을 수 있는 전역 저장소입니다.

  • C#은 .NET Framework의 발전에 빠르게 대응해줍니다.

  • .NET Framework를 설치하면 기본적으로 CSC(C# Compiler)가 설치됩니다.
    • 요즈음의 MS는 CSC를 따로 배포하므로 C# 6.0을 컴파일하려면 설치해서 쓰세요. 하지만 VS를 쓴다면?


  • 주로 프로그래밍 언어에서 변수명 이름을 지을 때는 Camel Case. Pascal Case, Snake Case, Screaming Snake Case를 주로 사용합니다. C#에서는 Snake Case와 Screaming Snake Case를 관례적으로 사용하지 않습니다.
    • Camel Case : intValue
    • Pascal Case : IntValue
    • Snake Case : int_value
    • Screaming Snake Case : INT_VALUE

  • C#에서 변수는 Camel Case로 작성하고, 그 외(함수, 클래스, 메소드)에는 Pascal Case로 작성하는 것이 관례입니다.

5.1.2. 2. C#의 타입과 문장, 배열


  • 숫자형 sbyte(부호 있는 8비트), byte(부호 없는 8비트), short, ushort, int, uint, long, ulong

예약어 크기 대응되는 닷넷 프레임워크 내 타입
sbyte 부호 있는 8비트 System.SByte
byte 부호 없는 8비트 System.Byte
short 부호 있는 16비트 System.Int16
ushort 부호 없는 16비트 System.UInt16
int 부호 있는 32비트 System.Int32
uint 부호 없는 32비트 System.UInt32
long 부호 있는 64비트 System.Int64
ulong 부호 없는 64비트 System.UInt64

  • int a = 10000000000; 이런거하면 Compile Error 납니다.
    • 즉, 범위를 넘어가는 값을 대입할 수 없습니다.

  • C#은 Value type과 Reference type이 나눠져있습니다.

  • 실수형

예약어 크기 대응되는 닷넷 프레임워크 내 타입
float 4바이트 System.Single
double 8바이트 System.Double
decimal 16바이트 System.Decimal

  • 리터럴에 U를 붙이면 uint, UL을 붙이면 ulong, L을 붙이면 long, m을 붙이면 decimal, f를 붙이면 float가 됩니다.

  • 문자형

예약어 크기 대응되는 닷넷 프레임워크 내 타입
char 유니코드 4바이트 System.Char
string 유니코드 문자열 System.String
  • ex) char a = '빵'; ( sizeof(a) = 4, 유니코드이기 때문에 )
  • string b = "Hello!";

// b[3] => 'l' 처럼 직접접근도 가능합니다.

  • char c = '\u2023' 같은것도 가능
  • 반대로 char \u2023 = 'c' 도 가능합니다. (char 빵 = '빵' 되듯이..)

  • uint와 char는 바이트 크기는 같지만, uint는 수를 담기 위한 타입으로 정해져 있고 char는 문자를 담기 위한 타입으로 약속되어있습니다.
    • 이 때문에, char에 사칙연산을 적용하려고 하면 오류가 발생합니다.

  • string str = "\tHello World\n!"; Console.WriteLine(str); 이라 하면 콘솔에 'Hello World!"라고 뜨지만
  • string str = @"\tHello World\n!"; 이렇게 하면 Escape Sequence를 따지지 않고 콘솔에 "\tHello World\n!"라고 뜹니다.
    • 즉, 이스케이프 시퀀스로 간주하지 않고 순수한 문자로 취급할 수 있습니다.

  • 예약어를 식별자로 사용할 수 없지만, 식별자로 사용해야 한다면 '@' 문자를 접두어로 사용하여 C# 컴파일러가 예약어가 아닌 식별자로 인식하게 할 수 있습니다.
    • char int = 'a'; // int는 예약어라서 못쓰지만
    • char @int = 'a'; // 이렇게하면 가능합니다.

  • 논리형에는 bool이 존재하며, System.Boolean을 줄인 예약어 입니다.


  • C#에는 값형식과 참조형식이 존재합니다.
    • 값 형식(Value Type)은 스택(Stack)에 저장되고
    • 참조 형식(Reference Type)은 힙(Heap)에 저장됩니다.

  • 윈도우 프로그램은 기본적으로 하나의 스레드를 갖습니다. 이 때, 개별 스레드마다 전용으로 사용할 수 있는 저장소가 메모리에 할당되는데, 그 영역을 스택이라고 합니다.
  • 힙은 프로그램에서 필요에 의해 메모리를 사용하겠다고 요청했을 때 사용할 수 있는 저장소로, 특별히 닷넷에서는 CLR이 직접 프로그램에서 사용될 힙을 관리한다.
  • Heap에 저장된 데이터는 원래 자동으로 해제되지 않습니다. 하지만 C#에는 GC가 있으므로, 자동으로 할당 해제합니다.

  • C#의 값형식은 정수형,실수형, char, bool, struct 등이 있습니다.
  • C#의 참조형식은 배열, 클래스, string, object 등이 있으며, 값 형식과는 달리 변수의 타입에 해당하는 값을 별도의 힙 메모리를 할당하여 담고 스택의 변수 값은 그 힙의 데이터 주소를 가리키게 됩니다.

  • int b; 이렇게 선언만 해놓고 초기화를 안하면 b에는 0이 들어갑니다. 하지만 C#은 오류로 판단하여 못쓰게 합니다. 따라서 int b = 0; 이런식으로 명시적으로 초기화를 하세요.
  • C#에서는 항상 자료형에 대한 메모리를 할당하면 해당 영역을 0으로 초기화합니다. (bool형은 false)

  • 상수는 const int b = 5; 이런식으로 합니다. 즉, 변수 정의시 const 예약어를 붙여줍니다.
    • 상수는 반드시 컴파일 시에 값이 결정되어야 합니다.

  • string s = "a"; 하게 되면 stack에는 's'변수가 할당되고, heap에는 실제 데이터가 할당됩니다.

  • C#에서 참조형은 'new'키워드를 사용하여 할당합니다.

  • 배열은 동일한 타입의 공간을 지정된 수만큼 힙 메모리에 연속적으로 할당합니다. 배열도 참조 타입이기 때문입니다.
  • 한번 정해진 배열의 크기는 고정됩니다. 참조 변수의 특성상 가리키는 대상이 변할 수 있기 때문에 변경된 크기의 배열을 다시 가리키는 것은 가능하나, 처음에 있었던 배열의 크기가 변경되는 것은 아닙니다.

  • 배열을 선언하는 경우 기본적으로 모든 값은 타입에 따른 초기화 값을 갖습니다. 즉, 값 형식 배열일 경우 기본값인 0에 준하는 값을 가지며 참조 형식 배열이라면 개별 요소가 null로 초기화가 됩니다.


  • 배열

  int[] arr1 = new int[5] { 0, 1, 2, 3, 4 }; // 배열의 수를 명시적으로 지정했으므로 초기화 시 반드시 그 수만큼 요소를 나열해야 한다.
  int[] arr2 = new int[] { 0, 1, 2, 3, 4 }; // 컴파일러가 배열의 수를 자동으로 계산한다.

  • 다차원 배열

  int arr[2][3] (C style)
  int[][] arr = new int[2][3]; (Java style)
  int[,] arr = new int[2,3]; (C# sytle)

  // 이것도 가능하겠죠?
int[,,] arr2 = new int[2, 3, 4]
            {
                { { 1, 2, 3, 4 }, { 5, 6, 7, 8 }, { 9, 10, 11, 12 } },
                { { 13, 14, 15, 16 }, { 17, 18, 19, 20 }, { 21, 22, 23, 24 } }
            };

* 가변배열
  int[][] arr = new int[5][];  // 가변배열이면 반드시 '[][]'로 써야됩니다.
  arr[0] = new int[4];
  arr[1] = new int[5];

  • 논리연산자 (C랑 동일합니다)
  • 관계연산자 : < > <= >= != ==
  • 비트연산자 : & | ^ !(bool NOT) ~(Integer NOT)

  • 삼항 연산자도 존재합니다.
    • (condition) ? (true): (false)

  • switch/case구문
    • break가 강제 입니다. (단, caase 레이블에 아무 내용이 없다면 break를 생략할 수도 있습니다.)
    • case에는 정수 상수, Enum 열거값, String 값이 들어올 수 있습니다.

  • 전치,후치연산 가능합니다 (++, --)

  • int n = 50;
    int x = 100;
    if( x > 10 || n++ > 0 ) 이런식으로 하면, 절대 n++은 되지않습니다.

  • while, for, do-while, foreach 가능합니다.
  • foreach (타입 변수명 in 표현식 ) : 표현식에 들어올 수 있는 변수는 IEnumerable 인터페이스를 구현해야 합니다.
    • 일단은 배열이나 컬렉션 계열의 변수가 들어올 수 있다고만 알아둡시다.

  • break, continue, throw, goto 가능합니다.


5.2. 그 외

  • 자기소개, 강사소개 및 각자 C#을 배우고 싶은 이유에 대해서 말했습니다.
  • 다음 주에는 강사님이 훈련을 갑니다 => 휴강으로 결정
  • 미처 전달하지 못한 내용은 다음을 참고해주세요.

6. 덧글


Valid XHTML 1.0! Valid CSS! powered by MoniWiki
last modified 2021-02-07 05:22:43
Processing time 0.0580 sec