데이터의 형식
- 기본 데이터 형식 : C#에서 기본으로 제공하는 데이터 형식(int, double 등)
- 복합 데이터 형식 : 구조체, 클래스, 배열 등
- 값 형식 : 변수가 값을 담는 데이터 형식
- 참조 형식 : 변수가 값 대신 값이 있는 주소를 담는 데이터 형식
힙과 스텍 메모리의 차이
값 형식으로 데이터를 지정한 경우
- 스택 영역에 코드 블록 안에 선언된 값 형식 변수를 메모리 상에 저장함
- 코드 블록이 끝나면 스택 영역에 저장된 변수들은 모두 삭제됨.
참조 형식으로 데이터를 저장한 경우
- 참조 형식으로 변수를 선언하는 경우 힙 영역에 실제 값 저장, 스텍 영역에는 영역값의 주소가 저장됨 ex) c : &03
- 아무 변수도 특정 힙 영역의 변수를 참조하지 않을 경우 가비지 컬렉터(garbage collector)에 의해 힙 영역의 변수가 삭제됨.
기본 데이터 형식 (primitive data type)
- byte, sbyte : 1바이트 정수
- short, usrhot : 2바이트 정수
- int, uint : 4바이트 정수
- long, ulong : 8바이트 정수
- char : 유니코드 문자 (2바이트)
- float : 4바이트 부동 소수점
- double : 8바이트 부동 소수점
- 주로 int, double, char 사용
- char은 따옴표, string은 쌍따옴표를 사용 (서로 섞어서 사용하면 무조건 오류)
- bool : 1바이트 논리 형식 (true, false를 가짐) → [논리 형식]
- object : 모든 데이터를 담을 수 있는 부모 형식
형 변환
- 암시적 형변환 : 더 큰 데이터 타입으로의 형변환은 자동으로 일어남.
- 명시적 형변환 : float → int, long → int 등 큰 범위에서 작은 범위로의 형변환은 (Type) 을 이용해 주어야 함.
1
2
3
4
5
| int a = 100;
long b =a; //암시적 형변환
int c = b; //에러 발생
int d = (int) b; //명시적 형변환
int? e = b as int?; // 후술
|
Nullable type
- 값 형식의 데이터들은 null이 들어갈 수 없기 때문에 nullable 연산자로 Nullable <> 를 사용하거나 int? 를 사용하여 null이 포함될 수 있게 함.
- 값 형식의 데이터는 반드시 어떤 값으로 할당하여야 함. 실제로 할당하지 않아도 특정 값을 초기화 되어 있음.
- 참조형, 즉 T? 형태로 선언하면 null, 할당하지 않을 수 있음.
1
2
3
4
5
6
7
8
| Nullable<int> a = null;
int? b = null;
if (b.HasValue) {
//if 문을 통과하지 못함.
}
Console.WriteLine(a.Value); //값이 없으므로 예외 출력
//그냥 Console.WriteLine(a) 로 사용하게 될 경우 a=null에서 빈 화면을 출력함.
|
1
2
3
4
| long a = 100;
object b = 100;
int? c = a as int?; //오류 출력
int? d = b as int?; //object → int? 로 변환.
|
as로 변환하는건 애초에 object 외 형식이면 변환 안되는 것 같음값변수 + nullable 에서는 int를 int?로 변환한다는 의의가 존재?
예제
1
2
3
4
5
6
7
8
| {
int a = 100;
long b = a; //암시적 형 변환
int c = b; //에러 발생
int d = (int) b; //명시적 형변환
int? e = b as int?;//e=null;
int? f = a as int?; //f=100;
}
|
1
2
3
4
5
| {
float a = 1.123456f;
double b = (double) a; //명시적 형변환
float c = 0.1f;
double d = c as double; //as 키워드는 참조형식 or nullable만 변환가능} → 에러발생
|
double, float → int로의 변환 (부동 소숫점 → 정수형)
1
2
3
4
5
6
| {
float a = 1.1f;
int b = (int)a; // b = 1
float c = 0.9f;
int d = (int)c; // d = 0
}
|
문자열 → 숫자 형 변환
- (int) 명시적 형 변환 연산자는 숫자를 제외한 형 변환을 가지고 있지 않음. 즉 문자열을 숫자로 변환 불가.
- T.Parse(“string”) 이용.
1
2
3
4
5
6
7
8
| {
string a = "1234";
int b = (int) a; //string → int 변환하는데는 명시적 변환 연산자 사용 불가
int c = int.Parse(a); //.Parse("string") 이용하여 파싱 함.
float d = float.Parse("1.234");
string e = "1.234";
int f = int.Parse(e); //1.234는 int가 아니므로 오류 반환
}
|
숫자 → 문자열 형 변환
- 모든 데이터 형식 (object)는 ToString method를 가지고 있음
- 기본 데이터 형식일 경우 ToString Method를 통해 문자열 객체로 변경가능
예제
1
2
3
4
5
6
7
8
9
10
| {
int a = 123;
float b = 1.234f;
string c = a.ToString();
string d = b.ToString();//c, d 모두 정상적으로 "123", "1.234" 가짐
string e = (string) a; //명시적 형변환 사용 불가.
string f = a as string;
// 명시적 형변환이 안되므로 당연히 불가능, 문법 자체는 string?이 아닌 string 이 맞음
//(string에는 null이 들어가므로)
}
|
상수 (constant)
- Const 키워드를 이용하여 상수를 선언할 수 있음. 단, 한번 선언 후 변경 불가능
- 대표적인 상수들의 값들은 지원 함. MaxValue, MinValue 등
예제
1
2
3
4
5
6
| {
string a = "123";
Console.WriteLine(a);
Console.WriteLine($"{a}");
Console.WriteLine("{0}, {1}", a, a);
}
|
- 상수형을 다른 값으로 할당하는 것은 상관 없으나, 상수 변수 자체를 바꿀 수는 없음.
출력방식
1
| { string a = "123"; Console.WriteLine(a); Console.WriteLine($"{a}"); Console.WriteLine("{0}, {1}", a, a);}
|
오류의 종류
- Runtime 오류 : 명시적 형변환에서 범위 외의 값을 대입하는 등 컴파일러는 알 수 없지만 실행해보면 오류가 나는 경우
- Compile 오류 : 코드 상에서 컴파일러가 컴파일하면서 발견하는 오류들 ex) 형식 잘못 넣거나 등.
열거형 (enumerator)
- 개발자의 편의를 위해 열거형 지원
- 열거형 중복되지 않는 값을 갖고 있다는데 의미가 있음 실제 A=90, B=90으로 배정하여도 오류는 발생하지 않음
- 원하는 숫자(정수)로 할당 가능
1
2
3
4
5
6
7
8
9
10
11
12
13
14
| class Program
{
enum Rank { A=10,B=20,C=30,D} //namespace 내부에만 있으면 enum 사용 가능
static void Main(string[] args)
{
Rank john = Rank.D;
Rank bob = Rank.A;
Console.WriteLine(john+", " + bob); //D, A 출력
int a = (int) bob; // Rank.A의 값은 10이므로 a=10
int b = (int) john;// Rank.D는 C 다음의 값이므로 b=31
// 값이 지정되지 않은 enum의 경우 시스템상에서는 문자열이 아닌 정수형으로 저장함.
// 값이 지정되지 않은 경우 마지막으로 지정되었던 값 + n 꼴로 들어감.
}
}
|
Nullable 형식
1
2
3
4
5
| {
int a = null;
float b = null; //nullable이 아닌 변수에 null을 할당하면, 즉 할당하지 않으면 에러 발생
}
|
var를 이용한 데이터의 선언
- C#은 데이터의 형식에 매우 깐깐한 언어임 (프로그래머의 실수를 줄이기 위함)
- var 키워드를 통하여 약한 형식 검사를 하는 편리함을 제공함.
- var는 지역 변수로만 사용할 수 있으며, 반드시 선언과 동시에 초기화 해주어야 함.
- stack 영역에 저장하는 변수이므로 코드블럭 내에서만 사용이 가능하고 초기화 필수.
- var는 값 형식임에 반해 object는 참조 형식
예제
1
2
3
4
5
6
| {
var a = 1;
var b = "hello";
var c; //오류 발생시킴
var d=null; // 오류 발생시킴, (null로 만들 수 없음)
}
|
산술 연산자
- +(덧셈), -(뺄셈), * (곱셈), / (몫), % (나머지)
- 모든 수치 데이터 형식에 적용 가능, 몫, 나머지의 경우 수치 데이터 형식에 따라 반환 값이 다름
ex)
1
2
3
4
5
6
7
8
9
| {
double a = 2/3;
double b = 2.0/3;
double c = 2/3.0;
double d = 2.0/3.0;
double e = (int) (2.0/3.0);
Console.WriteLine("{0}, {1}, {2}, {3}, {4}", a, b, c, d, e);
//0,.667,.667,.667,0이 나옴.
}
|
증감 연산자
- 증가 감소 연산자는 모든 수치 연산자와 열거(enum) 형식과 사용이 가능.
- 변수의 위치에 따라 그 결과가 다르게 나옴.
- ++, –
ex)
1
2
3
4
5
6
7
8
9
| {
int a = 1;
a++;
Console.WriteLine(a); //2
Console.WriteLine(a++); //2
Console.WriteLine(a); //3
Console.WriteLine(--a); //2
Console.WriteLine(a);//2
}
|
관계 연산자
- 출력 형식이 bool, 즉 참과 거짓의 논리 연산자의 결과값으로만 나옴.
- <, >, <=, >=, ==, !=가 존재.
- 모든 수치형식과 열거 형식에 사용 가능.
조건 연산자
- A ? B : C 형태로, A에 bool이 들어가 bool이 참일 경우 “B”, 거짓일 경우 “C”값 출력
예제
1
2
3
4
5
| {
int a = 10;
string b = (a==10) ? "true", "false";
Console.WriteLine(b); //true
}
|
할당 연산자
- 변수 또는 상수에 피연산자 데이터를 할당하는 기능.
- 왼쪽 피연산자와 오른쪽 피연산자를 연산한 뒤 왼쪽 피연산자에 결과값을 할당.
| =, +=, -=, *=, /=, %=, &=, | = 등 존재 |
연산자의 우선순위
- 증감 연산자 (후위, a++, a–)
- 증감 연산자 (전위, ++a, –a)
- 산술 연산자 ( * , / , % )
- 산술 연산자 ( + , - )
- 시프트 연산자 (» , «)
- 관계 연산자 (> , < , <= , >=, is , as)
- 관계 연산자 (== , !=)
- 조건 연산자 ( ? : )
| 할당 연산자 (= , *=, /=, +=, -=, «=, »=, &=, ^=, | = 등) |