본문 바로가기
공부/C#

이것이 C#이다 Chapter 02 처음 만드는 C# 프로그램

by bokob 2024. 2. 10.

using System;

using System;

'using'은 C#의 키워드 중 하나.
뒤에 따라 나오는 것을 사용하겠다는 것이다. 여기에서는 'System'을 사용하겠다는 것
'System'은 C# 코드에 기본적으로 필요한 클래스를 담고 있는 네임 스페이스
위의 코드는 System 네임스페이스 안에 있는 클래스를 사용하겠다고 컴파일러에게 알리는 역할
';'은 문장의 끝을 알리는 기호

using static System.Console;

using 키워드만 사용하면 네임스페이스 전체를 사용한다는 의미
using static은 어떤 데이터 형식(예: 클래스)의 정적 멤버를 데이터 형식의 이름을 명시하지 않고 참조하겠다고 선언하는 기능

전역 using

전역 using(또는 global using)은 소스 파일 한 곳에서만 네임스페이스를 참조하면 프로젝트 내 모든 파일에서 별도의 using 문 없이 해당 네임스페이스를 참조할 수 있도록 한다. using 앞에 global 키워드를 붙여주면 된다.

global using System;
global using static System.Console;

namespace

네임스페이스는 성격이나 하는 일이 비슷한 클래스, 구조체, 인터페이스, 대리자, 열거 형식 등을 하나의 이름 아래 묶는 일을 한다.

namespace 네임스페이스_이름
{
    // 클래스
    // 구조체
     // 인터페이스 등...
}
namespace Hello
{
    class MainApp
    {

    }
}

파일 범위 네임스페이스

namespace Softwares
{
    // ...
}

대부분의 경우 파일 하나에 네임스페이스가 하나씩만 선언된다는 점이다. 이 부분에서 착안해서 C# 10에서는 파일 범위 네임스페이스(File Scoped Namespace)라는 새 기능이 도입
파일 범위 네임스페이스는 다음과 같이 namespace 선언 뒤에 {} 대신 세미콜론(;)을 붙이면 그 파일의 모든 코드는 해당 네임스페이스 소속으로 들어가게 만든다.

namespace Devices;

class

클래스는 C# 프로그램 (C#으로 만드는 프로그램) 을 구성하는 기본 단위
데이터와 데이터를 처리하는 기능(메소드), C# 프로그램은 최소한 하나 이상의 클래스로 이루어진다.

class MainApp
{
    // 프로그램 실행이 시작되는 곳
    static void Main(string[] args)
    {
        if(args.Length == 0)
        {
            Console.WriteLine("사용법 : Hello.exe <이름>");
            return;
        }
        WriteLine("Hello, {0}!", args[0]);
    }
}

주석

// 주석
/*
주석이다.
*/

static void Main(string[] args){}

이 메소드는 프로그램의 진입점(Entry Point) 으로서 프로그램을 시작하면 실행되고, 이 메소드가 종료되면 프로그램도 역시 종료된다.
모든 프로그램은 반드시 Main 이라는 이름을 가진 메소드를 하나 가지고 있어야 한다.

class MainApp
{
    // 프로그램 실행이 시작되는 곳
    static void Main(string[] args)
    {
        if(args.Length == 0)
        {
            Console.WriteLine("사용법 : Hello.exe <이름>");
            return;
        }
        WriteLine("Hello, {0}!", args[0]); // 프로그램 출력
    }
}

다른 언어에서는 메소드를 서브루틴(Subroutine)이나 함수(Function)로 부르기도 한다.
메소드라는 용어는 객체지향 프로그래밍 세계에서 함수를 일컫는 말

static void Main(string[] args)
{

}

'static'은 한정자(modifier)로서 메소드나 변수 등을 수식.
C# 프로그램의 각 요소는 코드가 실행되는 시점에 비로소 메모리에 할당된다.
반면, static 키워드로 수식되는 코드는 프로그램이 처음 구동될 때부터 메모리에 할당된다는 특징이 있다.
프로그램이 실행되면 CLR(Common Language Runtime)은 프로그램을 메모리에 올린 후 프로그램의 진입점을 찾는데, 이때 Main() 메소드가 static 키워드로 수식되어 있지 않다면 진입점을 찾지 못했다는 에러 메시지를 남기고 프로그램을 종료시킨다. (실제로는 컴파일러가 static 으로 한정된 Main() 메소드가 없는 경우를 판단하여 컴파일 에러 메시지를 출력).
'void'는 메소드의 반환 형식이다.
'Main'은 메소드 이름

CLR에 대하여

C#으로 만든 프로그램은 CLR 위에서 실행


CLR은 자바의 실행 환경인 자바 가상 머신과 비슷한 역할
CLR은 .NET 라이브러리와 함께 OS 위에 설치
네이티브 코드로 작성된 프로그램들은 운영체제가 직접 실행할 수 있지만
컴파일러가 만들어낸 실행 파일은 하드웨어가 이해할 수 없는 코드로 구성되어 있기 띠문에 실행할 수 없다.

C# 컴파일러는 C# 소스 코드를 컴파일해서 IL(Intermediate Language) 이라는 중간 언어로 작성된 실행 파일을 만들어낸다.
사용자가 이 파일을 실행시키면, CLR이 중간 코드를 읽어들여 다시 하드웨어가 이해할 수 있는 네이티브 코드로 컴파일한 후 실행시킨다.
이것을 JIT(Just In Time) 컴파일 이라고 부른다. JIT 컴파일이란, 실행에 필요한 코드를 실행할 때마다 실시간으로 컴파일해서 실행한다는 뜻

왜 두 번씩이나 컴파일하는 복잡한 과정을 거칠까?
C#이 동작하는 환경이자 엔진인 CLR은 C#뿐만 아니라 다른 언어도 지원하도록 설계되었다.
서로 다른 언어들이 만나기 위한 지점이 바로 IL 이라는 중간 언어이고, 이 언어로 쓰인 코드를 CLR이 다시 자신이 설치된 플랫폼에 최적화해 컴파일한 후 실행하는 것이다

이 방식의 장점은 바로 플랫폼에 최적화된 코드를 만들어낸다는 것이고 단점은 실행 시 이루어지는 컴파일 비용의 부담이다.

CLR은 단순히 C# 이나 기타 언어들을 동작시키는 환경 기능 외에도, 프로그램 오류(정확히는 '예외' 라고 한다)가 발생했을 때 이를 처리하도록 도와주는 기능이다.
언어간 상속 지원, COM과의 상호 운용성 지원, 그리고 자동 메모리 관리 등의 기능을 제공한다. 이 기능을 가비지 컬렉션(Garbage Collection)이라고 하는데, 프로그램에서 더 이상 사용하지 않는 메모리를 쓰레기(Garbage)로 간주하고 수거(Collection)하는 기능이다.