[ C# 스터디 ]

자료출처 : C# Programming Bible
출판사 : 영진닷컴


★ C# 식별자와 키워드 ★

식별자 ( Identifier )란 클래스 , 인터페이스 , 변수 , 메서드 , 배열 , 문자열 등을
구분할 때 사용되는 문자열을 지칭하는 말입니다.

C# 식별자는 길이 제한이 없고 , 유니코드 ( Unicode ) 문자를 사용하기 때문에
한글/영어/한문 등 다양한 언어를 사용할 수 있습니다. 식별자는 대 . 소문자를
구분하여 사용되며 , 몇 가지 관례에 따라 만들어집니다. ( 강제적으로 지킬 필
요는 없음 ) 예를 들어 클래스 이름은 대문자로 시작한다거나 메서드 , 변수 등
의 시작 문자는 소문자로 한다는 식별자 관례를 갖고 있습니다. 또한 C#이 예
약한 키워드는 식별자로 사용할 수 없습니다.

올바른식별자 잘목된식별자
User_name : 대문자 시작 User name : C# 식별자 내에 공백
user_name : 소문자 시작 사용자 이름 : C# 식별자 내에 공백
_User_name : _로 시작 #User_name : 첫 글자에 # 사용
$User_name : $ 로 시작 !User_name : 첫 글자에 ! 사용
사용자이름 : 한글 사용 ( 유니코드 ) 7User_name : 첫 글자에 숫자 사용
한문도 사용 가능 delegate : C# 키워드 사용


컴퓨터가 사용하는 대표적인 문자셋으로 아스키코드와 유니코드가 있습니다. 아스키
( ASCII : American Standard Code for Information Interchange )는 컴퓨터 정보 교
환을 위해 미국에 제정한 표준 문자셋으로 한 문자를 표현하는데 7비트를 사용합니다.
아스키가 표현 가능한 문자수는 총 128 ( 7비트 27 ) 개로 영문과 숫자 그리고 몇몇 특수
문자들을 표현할 수 있습니다. 그러나 컴퓨터 프로그래밍 분야에서는 128자 표현이 가
능한 표준 아스키코드보다는 1비트를 추가해 총 8비트를 사용하면서 256자를 표현할 수
있는 확장 아스키코드가 주로 사용되었습니다. C/C++ 등의 프로그래밍 언어는 한 문자를
표현하는데 8비트를 사용하는 확장 아스키코드 기반의 대표적인 언어들입니다.

그러나 확장 아스키도 표현 가능한 문자가 256개로 제한되기 때문에 한글 , 일본어 중국어
등 영어 이외의 문자를 다루는 일이 수월하지 않았습니다. 만약 C/C++ 언어에서 한글을
표현하려면 8비트 문자 두개를 조합해 16비트 기반의 완성형 또는 조합형 문자셋을 만들
어 사용해야 했습니다.

이러한 작업은 프로그램 개발에 많은 어려움과 제약을 가져왔습니다. 그러나 다국어 표현
의 어려움은 유니코드를 사용하는 새로운 컴파일러와 운영체제의 등장으로 자연스럽게
해결되었습니다. 물론 , 유니코드를 사용하게 되면 8비트로도 충분히 표현 가능했던 영
문이나 숫자 등을 16비트로 표현해야 하기에 , 아스키코드에 비해 상대적으로 메모리
효율이 떨어지는 단점도 있지만 국제적인 통용성과 개발의 편의성을 생각할 경우 , 프로
그램 개발에 있어 많은 이득을 얻게 됩니다.

C#은 16비트 유니코드를 사용하는 대표적인 컴파일러로 한글 , 한문 , 일어 , 아랍어와
같이 확장 아스키로 표현이 불가능했던 다국어를 쉽게 표현할 수 있습니다. 유니코드에
대한 자세한 사항은 www.unicode.org 에서 확인할 수 있습니다. 유니코드는 총
65536 개의 글자를 코드화해서 사용할 수 있습니다. 유니코드의 첫머리 256개의 글자
는 이전 문자셋과의 하위 호환성을 유지하기 위해 확장 아스키코드로 채워져 있습니다.

C# 키워드

C# 키워드
abstract const extern int out short typeof
as continue false interface override sizeof uint
base decimal finally internal params stackalloc ulong
bool default fixed is private static unchecked
break delegate float lock protected string unsafe
byte do for long public struct ushort
case double foreach namespace readonly switch using
catch else goto new ref this virtual
char enum if null return throw volatile
checked event implicit object sbyte true void
class explicit in operator sealed try while

컨텍스트 키워드
partial get set value where yield


키워드는 C# 프로그램에서 미리 정의한 단어입니다. 키워드는 예약어로 불리며 ,
C# 문법에 관련된 다양한 기능을 갖고 있습니다. C# 키워드는 80여개로 , 다른 언어의
비해 다소 많은 감이 있지만 다양한 기능을 수행하는 키워드를 이용해 더 유연하고 효과
적인 코드 작성이 가능합니다 이 책에서는 자주 사용되지 않는 몇몇 키워드를 제외한 대부
분의 키워드 용법에 대해 살펴볼 것입니다.

C# 키워드의 정확한 의미와 사용법을 숙지하고 있어야만 닷넷 기반 프로그램을 빠르고 효
율적으로 개발할 수 있습니다. C# 키워드 다른 말로 , C# 문법 익히기라고 말할 수 있습니
다.


★ 변수와 상수 ★


< 변수 >

변수는 다음 규칙을 따라 정의합니다.

○ 변수는 유니코드 문자를 사용합니다.
○ 변수 이름은 _ , $로 시작할 수 있습니다.
○ 변수 이름은 숫자로 시작하거나 특수 문자로 시작할 수 없습니다.
○ 변수는 대소문자를 구분합니다.
○ C# 키워드는 변수 이름으로 사용할 수 없습니다.

C#에서 사용하는 변수는 크게 두 가지로 나뉩니다. 값에 의한 호루 ( call by value ) 기반
의 기본 자료형과 참조에 의한 호출 ( call by reference ) 기반의 참조 자료형이 바로 그것
입니다. 기본 자료형 변수는 문자 , 논리 값 정수 , 실수 등을 표현할 때 사용되며 , 참조
자료형 변수는 클래스 , 인터페이스 , 배열 등을 표현할 때 사용됩니다. 기본 자료형은 모
두 13가지 종류가 있으며 크게 정수형 , 실수형 , 문자형으로 구분됩니다. 기본 자료형
은 다음 장에서 자세히 살펴보겠습니다.

변수를 사용하기 위해서는 우선 변수를 선언해야 합니다. 변수 선언은 닷넷 가상 머신
( CLR ) 에 데이터를 저장하기 위한 메모리 공간을 할당하도록 지시하는 것입니다.

변수 선언은 다음 형태를 따릅니다.

데이터형 변수이름 ;


예를 들어 int a ; 라는 문장이 있다면 , 컴파일러는 이 문장을 해석해 메모리 임의의 영역에
a라는 이름으로 접근 가능한 32비트 ( int 데이터형 ) 영역을 할당합니다.


< 상수 >

상수를 선언할 때는 const 키워드를 사용합니다.

const [ 변수타입 ] [ 상수이름 ] = 초기값 ;

상수는 선언과 동시에 반드시 초기 값을 할당해야 합니다. 프로그래밍 관례에 따라 상수
이름은 보통 대문자로 선언합니다. 물론 , 상수 이름을 소문자로 선언해도 상관없지만 가
급적이면 프로그래밍 전통에 따라 대문자 형태로 사용하는 것이 좋습니다.

class ConstExam1
{

public static void Main ( void )
{

const int value1 = 1 ;
const int VALUE2 ;  // => 에러 발생
VALUE2 = 2 ;

System . Console . WriteLine ( " value 1 = " + value1 ) ;
System . Console . WriteLine ( " value 2 = " + VALUE2 ) ;

}

}

위 예제 처럼 상수를 사용하는 프로그램을 작성할 경우 " 상수는 선언과 동시에 초기화를
해야 한다. " 는 C# 문법을 따라야 합니다. VALUE2는 선언과 동시에 초기화를 하지 않았기
때문에 " const 필드에 값을 입력해야 합니다 " 라는 컴파일 에러 메시지가 출력됩니다.

C#에서 상수를 사용하려면 const 키워드를 사용해 상수 선언과 동시에 값을 초기화해야
한다는 사실을 꼭 기억해야 합니다.

class ConstExam2
{

public static void Main ( void )
{

const int VALUE = 1 ;
System . Console . WriteLine ( " [ 1 ] VALUE = " + VALUE ) ;
VALUE = 2 ;  // => 에러발생
System . Console . WritenLine ( " [ 2 ] VALUE = " + VALUE ) ;

}

}


C# 문법 중에 " 상수는 한번 선언하면 도중에 그 값을 바꿀 수 없다 " 라는 불변의 진리가
있습니다. 이 규칙에 따라 , 초기 값이 1로 설정된 상수 VALUE는 프로그램 중간에 값을
변경 하면 안됩니다. 위 예제는 값을 1로 초기화시킨 상수 VALUE에 새로운 값을 대입하려
고하기 때문에 컴파일 에러가 발생합니다.


< 리터럴 ( Literal ) >

리터럴은 소스코드 안에서 데이터형을 명확히 표현하기 위해 사용되는 문자입니다. 다음은
C#이 제공하는 13가지 기본 자료형에 대한 리터럴입니다.

데이터형 리터럴 데이터형 리터럴
bool true , false long L , l
byte - ulong L , l
sbyte - float F , f
short - double

D , d

ushort - decimal M , m
int - char '\u'
uint -    

리터럴 기호는 변수에 값을 할당할 때 컴파일러에게 더 명확한 의미를 전달하는
용도로 사용 됩니다. 예를 들어 숫자 앞에 0x를 붙이면 이 값은 16진수라는 뜻을 갖게
됩니다. 또한 숫자 뒤에 L을 붙인다면 이 값은 int 형이 아닌 long 형 데이터를 뜻하는 것입니다.

bool  a = true ;  // true 형 값을 갖고 있음
int  a = 100 ;  // 정수 100
int  a = 0x64 ;  // 16진수는 0x를 앞에 붙임
int  a = 0144 ;  // 8진수는 0을 앞에 붙임
long  a = 100L ;  // long은 int와 구분하기 위해 L 붙임
float  a = 100.0f ;  // float은 f를 붙임

class Literal
{

static void Main ( void )
{

float f = 1.0 ;  // 잘못된 곳 ( float f = 1.0f 로 수정 )
System . Console . WriteLine ( " f 의 값은 " + f ) ;

}

}


위 예제는 float 형 변수 f 를 선언하고 1.0으로 초기화하는 간단한 예제입니다. 그러나 예
제를 컴파일하면 컴파일 오류가 발생합니다. 컴파일러와 프로그래머 간의 의사소통이 명
확하지 않기 때문입니다. 다음 문장은 언뜻 오류가 없어 보입니다.

float f = 1.0 ;

프로그래머는 float 형 변수 f 가 메모리 임의의 영역에 1.0으로 초기화되어 선언되기를 바
랄 것입니다. 그러나 컴파일러 입장에서 생각하면 1.0은 double 형 자료로 판단하게 됩니
다. 따라서 float 형 변수 f 에 double 형 값을 대입하려 하기 때문에 컴파일러 입장에서는
float f = 1.0은 오류를 갖는 문장으로 해석됩니다. 따라서 1.0을 float 형태로 사용하려면
F 접미사를 사용해 1.0이 float 형 데이터임을 명시적으로 알 수 있도록 코드를 수정해야
합니다.

float f = 1.0 F ;

혹은

float f = 1.0 f ;

변수 f에 대입되는 값이 float 형이라는 것을 알리기 위해 1.0에 f 혹은 F 리터럴 문자를 붙
여 사용해야 합니다.

프로그램을 작성하다보면 C# 키워드 자체를 식별자로 사용해야 하는 경우도 있습니다.
C# 키워드를 식별자로 사용하려면 키워드 앞에 @를 붙이면 됩니다. 이 때 @를 문자열 리
터럴 ( string literal )이라고 부릅니다. @가 앞에 붙는 순간 뒤에 나오는 식별자 또는 키워
드는 모두 문자열로 처리됩니다. 다음 예제를 실행하면 " int 값 = 20 " 이 출력됩니다.
int 는 C# 키워드지만 앞에 @를 붙였기 때문에 컴파일러는 int를 문자열로 인식합니다.

class KeywordLiteral
{

static void Main ( void )
{

int @int = 20 ;  // int 키워드를 식별자로 사용함
System . Console . WriteLine ( " int 값 = " + @int ) ;  // @int는 문자열로 // 처리됨

}

}

▶ 실행 결과

int 값 = 20


★ 문장과 블록 ( Statement and Block ) ★

문장이란 어떤 작업을 처리하는 최소 단위입니다. C#에서 한 문장은 세미콜론 ( ; ) 으로
종료됩니다. 문장은 원칙적으로 한 줄에 하나씩 기술합니다 세미콜론을 사용해 한 줄에
여러 문장을 연속으로 기술할 수 있지만 , 코드의 가독성이 떨어지므로 " 문장은 한 줄에
하나씩 기술한다. " 는 원칙을 따르는 것이 좋습니다.

int kor = 100 ; // 한 줄에 한 문장 기술

int kor ; kor=100 ; System.Console.WriteLine ( kor ) ; // 한 줄에 여러 문장 기술

=> 가독성을 높이기 위해 한 줄에 한 문장씩 기술하는 형태로 바꿔야 함

int kor ;
kor=100 ;
System.Console.WriteLine ( kor ) ;


블록이란 문장들을 묶어놓은 단위입니다. 블록은 중괄호 '{ , }' 를 사용해 설정하며 , 블록
안에 서 또 다른 블록을 설정할 수 있습니다.

{

int a=100 ; // 1번
{  // 2번

int b=20 ;  // 3번

} // 4번

}


변수 a는 1번에서 4번까지 사용가능하며 , 변수 b는 3번에서 4번에서만 사용됩니다.
블록의시작과 끝은 중괄호 ( { ~ } )로 구분합니다.

변수의 유효 범위는 블록 설정과 밀접한 관계가 있습니다. 어떤 블록 내에 선언된 변수를
지역 변수라고 부르며 , 지역 변수 값은 블록 내에서만 유효합니다. 블록 밖에서는 블록
안에 선언된 지역 변수를 호출할 수 없습니다.

class BlockExam
{

static void Main ( void )
{ // 1번

int a=100 ;  // 2번
{  // 3번

int b=10 ;  // 4번
System . Console . WriteLine ( " 변수 a= " + a + " 변수 b = " + b ) ;  // 5번

}  // 6번

// System . Console . WriteLine ( " 변수 a = "+ a +" 변수 b = " + b ) ;  7번

}  // 8번

}

▶ 실행 결과

변수 a=100 변수 b=10

변수 a와 b가 서로 다른 블록에 정의되어 있습니다. 두 변수는 같은 자료형이지만 사용되는
범위가 다릅니다. 변수 a는 1번부터 8번까지 사용이 가능하지만 변수 b는
3번부터 6번까지만 사용할 수 있습니다. 만약 7번에 있는
// System . Console . WriteLine ( " 변수 a = "+ a +" 변수 b = " + b ) ;
이 부분에서 주석 ( // )을 풀고 컴파일하면 " b 이름이 현재 컨텍스트에 없습니다. "
라는 컴파일 에러가 발생합니다. 변수 b는 3번부터 6번까지 사용이 가능한데 7번에 있는
변수 b를 호출하게 되면 변수의 유효 범위를 벗어나는 변수 b를 컴파일러는 인식할
수 없게 됩니다.


★ 닷넷 프레임워크에서 지원되는 데이터형 ★

닷넷프레임워크는 CTS ( Common Type System ) 데이터형을 제공합니다. CTS는
닷넷 환경에서 작동하는 모든 프로그래밍 언어들이 사용하는 범용 데이터 형식입니다.
CTS 데이터 타입은 System 네임스페이스에 정의되어 있습니다.

CTS가 지원하는 데이터 형식은 값 형식과 참조 형식으로 나뉩니다. 값 형식 변수는 문자 ,
정수 실수 , 논리 값 등의 널 ( null )을 갖지 않는 데이터들입니다. 참조 형식은 힙 ( Heap )
에 할당되는 값으로 object , string , 클래스 및 인터페이스 등이 있으며 , 이들은 널
( null ) 값을 가질수 있는 데이터입니다.


< 문자 형식 >

키워드 CTS 형식 설명 초기 값
char System . Char 16비트 유니코드 문자
( ' \u0000 ' ~ ' \uffff ' )
'\u0000 '
string System . String 유니코드 문자열  

C#은 문자를 표현하는데 System . Char 와 System . String CTS 형식을 사용합니다.
System . Char는 char 키워드와 동일하게 취급되며 , 16비트 유니코드 문자를 표현할
때 사용됩니다.

유니코드에는 0x0000 ~ 0x007F 사이에 아스키 문자가 0x0080 ~ 0x00FF 까지는 ISO-
8895-1 문자가 포함되어 있으며 , 한글 11172자가 0xAC00 ~ 0xD7A3 영역에 들어
있습니다. char의 초기 값은 '\u0000 ' 이며 문자 값을 직접 대입할 경우 작은따옴표로
문자를 묶어 줘야 합니다. char 자료형에 값을 입력할 때 \( escape 문자 )를 이용해
특수한 기능을 지시할 수 있습니다.

◎ \t : TAB 키
◎ \n : Line Feed ( 줄 바꾸기 )
◎ \r : Carrage Return ( 첫 칸으로 이동하기 )
◎ \b : Backspace ( 바로 앞 글자 지우기 )
◎ \f : Form Feed ( 페이지 넘기기 )
◎ \숫자 : 8진수로 표현
◎ \u숫자 : 16진수 유니코드 표현
◎ \\ : 역슬래시를 나타낼 때
◎ \ : 연결자
◎ \' : 작은따옴표를 나타낼 때
◎ \" : 큰따옴표를 나타낼 때

char는 유니코드 , 아스키코드 , 문자 형식으로 사용합니다. 아래 예제는 char에 소문자
a를 유니코드 , 아스키코드 , 문자 형식으로 대입합니다. 유니코드는 '\u0061' 처럼
\u로 시작하며 , 작은따옴표로 묶어 표현합니다. 아스키코드는 문자에 해당되는 아스키
숫자를 그대로 입력해 사용합니다. 정수 형태를 char 자료형에 그대로 대입하면 컴파일
에러가 발생하므로 대입하고자 하는 정수 앞에 ( char ) 형태로 형 변환 연산자를 넣어야
합니다. 형 변환에 대해서는 이번 장 후반 부에서 살펴보겠습니다. 아래 예제는 작은따옴표
( \" ) , 역슬래시 ( \\ ) , 탭 ( \t ) , 줄 바꾸기 ( \n ) 등의 기호를 출력하기 위해
\ ( escape 문자 ) 를 사용하고 있습니다.

class Char
{

static void Main ( void )
{

char ch1 = '\u0061 ' ;  // 유니코드 형식
char ch2 = ( char )97 ; // 숫자 형식
char ch3 = 'a' ; // 문자 형식
System . Console . WriteLine ( " \' 출력[ 1 ] \' 문자열 >> " + ch1 + "\t" ) ;
System . Console . WriteLine ( " \' 출력[ 2 ] \' 문자열 >> " + ch2 + "\t" ) ;
System . Console . WriteLine ( " \\' 출력[ 3 ] \\' 문자열 >> " + ch3 + "\n" ) ;

}

}

▶ 실행 결과

'출력[ 1 ]' 문자열 >> a "출력[ 2 ]" 문자열 >> a \출력[ 3 ]\ 문자열 >> a=100 변수 b=10


닷넷 프레임워크가 제공하는 CTS 타입은 C# 에서는 키워드로 대체해 사용할 수 있습니다.

System . Char str = 'a' ;  => CTS 타입
char str = 'a' ;  => 키워드 형태


CLR은 문자변수 str을 선언할 때 System . Char나 char 모두 동일하게 처리합니다. char
라고 데이터 타입을 쓰면 , CLR은 내부적으로 System . Char로 변환해 데이터를 처리합
니다. 키워드를 이용해 CTS 타입을 대체하면 , 코드를 더 간결하게 작성할 수 있습니다.


< 불린 ( 논리 ) 형식 >

키워드 CTS 형식 설명 초기값
bool System . Boolean 참 . 거짓 형태의 논리 데이터 처리 false

bool 형식은 논리 형식을 나타냅니다. bool 키워드는 true , false 값 중 하나를 갖습니다.
bool 데이터는 1바이트 크기를 갖고 있으며 , 앞으로 살펴볼 연산자와 제어문에서 애용
됩니다.

class Bool
{

static void Main ( void )
{

bool bn = true ;  // 혹은 System . Boolean bn = true ;

if ( bn )
System . Console . WriteLine ( " select => True " ) ;

else
System . Console . WriteLine ( " select => False " ) ;

}

}

▶ 실행 결과

select => True