타입(Type)
닷넷의 타입은 System 네임스페이스에 구조체나 클래스로 정의되어 있다. 타입에 따라 변수의 크기와 부호 여부가 다르다. 닷넷의 타입은 크게 값(value) 타입과 참조(reference) 타입으로 분류되며 기억장소와 관리 방법이 완전히 다르다.
- 값(value) 타입: 스택(stack)에 할당되며 변수가 직접 값을 가진다. 정수, 실수 등의 내장형과 열거형, 구조체 등이며 크기가 작고 길이가 일정한 값을 저장한다. 선언하는 즉시 기억장소가 할당되어 바로 사용할 수 있다.
- 참조(reference) 타입: 값을 가지지 않고 값이 저장된 위치만 가진다. 선언 후 힙(heap)에 기억장소를 따로 할당해야 사용할 수 있다. 실제값은 힙에 저장되며 가비지 컬렉터가 관리한다. 문자열, 클래스, 배열 등 덩치가 크고 길이가 가변적인 정보를 저장한다.
스택은 크기가 제한적인 메모리 영역이어서 작고 고정적인 값 타입을 주로 저장한다. 반면 힙은 넓고 임의대로 확장할 수 있어 가변 크기의 복잡한 정보도 잘 저장한다.
클래스
클래스는 객체지향 프로그래밍의 중심 개념이며 닷넷의 모든 것이 클래스로 정의되어 있다. 클래스는 간단하게 말하자면 속성을 표현하는 데이터와 동작을 기술하는 함수의 묶음이다. 클래스는 참조 타입이기 때문에 선언만으로 사용할 수 없으며 new 연산자로 할당해야 한다.
using System;
internal class Program
{
static void Main(string[] args)
{
//Now 객체가 생성될 때 호출됨.
Time Now = new Time(12, 30, 45);
Now.OutTime();
}
}
class Time
{
public int hour, min, sec;
public Time(int ahour, int amin, int asec)
{
//생성자 메서드
//객체가 생성될 때 호출된다.
//1. 리턴형이 없다
//2. 클래스의 이름과 동일하다
//3. 일반적으로 필드(멤버변수)를 초기화할 때 사용한다.
hour = ahour;
min = amin;
sec = asec;
}
public void OutTime()
{
Console.WriteLine($"현재 시간은 {hour}시 {min}분 {sec}초이다.");
}
}
생성과 동시에 'Time Now = new Time(12, 30, 45);' 식으로 초기화 하고 싶다면 생성자 메서드를 정의해야 한다. 생성자는 클래스 이름과 같은 이름을 가지며 객체 할당시에 자동으로 호출되어 멤버를 초기화하는 특별한 메서드이다. (코드 참고)
구조체
구조체는 타입이 다른 변수의 집합이다. 멤버의 개수에 제한이 없어 괴장히 커질 수 있지만 그래도 스택에 생성 되는 값 타입이며 구조체 변수끼리 대입도 가능하다. 구조체는 '값 타입' 이기 때문에 구조체 형식의 Int32, Double 등도 모두 값 타입이다. 구조체의 선언은 클래스와 비슷하지만 참조 타입인 클래스와는 다르게 구조체는 값 타입이기 때문에 선언만 하면 곧바로 사용할 수 있다.
using System;
internal class Program
{
private static void Main(string[] args)
{
Book b; //바로 사용 가능
b.Name = "노점상으로 떼돈벌기";
b.Price = 18000;
Console.WriteLine($"제목:{b.Name}\n가격:{b.Price}");
}
}
//구조체
struct Book
{
public string Name;
public int Price;
}
배열
배열은 동일 타입의 변수를 하나의 이름으로 묶어 놓은 것이다. 배열은 '타입[] 변수명;' 형식으로 선언할 수 있다.
ex) int[] array;
[]괄호면 쓰면 1차원 배열, [,]는 2차원 배열이다. 배열의 차수는 [] 안의 콤마수 + 1 이다.
arScore = new int[5];
arSung = new int[2,3];
이라고 선언을 하면 아래 그림과 같은 배열이 할당되는 것이다.
new 연산자를 사용하여 할당을 해야 데이터 저장을 위한 별도의 공간이 힙에 할당된다. 참조 변수는 스택에 저장되어 이 위치만 가리킨다.
중요한 것은 new 연산자를 사용하여 할당하지 않으면 참조 변수는 아무것도 참조하지 않는다는 의미의 null 값을 가지며 이 상태에서 변수를 사용하면 예외가 발생한다.
internal class Program
{
private static void Main(string[] args)
{
//ar 대표이름으로 int 공간을 여러 개 생성하겠다.
//ar은 스택에 존재.
int[] ar;
//힙에 5개의 int 공간을 생성하라
ar = new int[5];
for (int i = 0; i < 5; i++)
{
ar[i] = i * 2;
}
for(int i = 0; i < 5; i++)
{
Console.WriteLine(ar[i]);
}
}
}
-배열의 메서드
배열은 System.Array 클래스로 구현되며 이 클래스에는 배열을 관리하는 멤버가 포함되어 있다. 가장 자주 사용되는 메서드는 배열 요소의 개수를 조사하는 Length 프로퍼티이다.
문자열
마지막으로 살펴볼 것은 문자열이다. 문자열은 참조 타입 이지만 대입과 비교시에 값처럼 동작한다. 참조 타입의 비교는 가리키는 위치에 따라서 결정되는데, 문자열을 비교할 때는 같은 문자열을 가리키는 것을 비교하는 것이 아닌 실제 텍스트가 동일한지를 비교한다. 값 타입 처럼 동작하는 것이다.
internal class Program
{
private static void Main(string[] args)
{
string s1 = "텔레토비";
string s2 = s1;
s2 = "마시마로";
Console.WriteLine($"s1={s1}, s2={s2}");
string s3 = "로보트 태권 V";
string s4 = "로보트 태권 V";
Console.WriteLine("문자열 : " + (s3 == s4 ? "같다" : "다르다"));
//문자열은 힙에 할당되는 참조형이지만 대입과 비교시에 값처럼 동작한다!!!!!!!
}
}
<실행 결과>
위의 s3 와 s4는 서로 다른 참조를 하고 있음에도 불구하고 텍스트가 같기 때문에 같다고 판단한다. 문자열에 대해서만 특별하게 예외를 적용하는 이유는 그게 편하고 상식적이기 때문이다.
이미지 출처: http://soen.kr/
'개발 > C#' 카테고리의 다른 글
[C#] 자습서 6장 - 함수 (0) | 2023.01.11 |
---|---|
[C#] 자습서 5장 - 클래스 (0) | 2023.01.10 |
[C#] 자습서 4장 - 제어문 (1) | 2023.01.05 |
[C#] 자습서 2장 - 입출력 (0) | 2023.01.03 |
[C# ] 자습서 1장 - 닷넷 (0) | 2023.01.02 |