byte

8비트 부호 없는 정수형 데이터 타입이다.

0 ~ 255까지의 값을 표현할 수 있으며 메모리의 크기가 작아서 주로 이미지나 음악 파일 등의 바이너리 데이터를 다룰 때 사용한다. 

 

또한 비트 연산을 처리할 때에도 byte 데이터 타입이 자주 사용된다.

byte b = 255;
byte b2 = (byte)128;

 

파일이나 이미지 등의 경우 0과 1로 이루어진 이진 데이터이기 때문에 각각의 비트는 0 또는 1의 값을 가진다. 이진 데이터를 다룰 때 byte 단위로 처리해야 하므로 해당 타입이 자주 사용되는 것이다.

 

예를 들어 이미지 파일을 읽어와서 메모리에 저장한다고 할 때 메모리에 저장하기 위해서는 파일의 크기만큼의 바이트 배열을 선언하고 파일에서 바이트 단위로 읽어와서 배열에 저장해야 한다. 이때 각각의 바이트는 0에서 255까지의 값을 가질 수 있기 때문에 byte 타입으로 배열을 선언한다. 

 

using System;
using System.IO;

class Program
{
    static void Main(string[] args)
    {
        // 파일 경로
        string filePath = "C:\\images\\test.jpg";

        // 파일을 바이트 배열로 읽어오기
        byte[] fileBytes = File.ReadAllBytes(filePath);

        // 바이트 배열의 크기 출력
        Console.WriteLine("File size: " + fileBytes.Length + " bytes");

        // 첫 번째 바이트 값 출력
        Console.WriteLine("First byte: " + fileBytes[0]);
    }
}

 

sbyte

부호가 있는 정수형 데이터 타입이다. byte와 달리 부호 비트를 가지기 때문에 음수 값을 표현할 수 있다.

주로 바이너리 파일 처리나 기계어 처리와 같은 곳에서 사용되는데 컴퓨터 메모리의 물리적 한계로 인해 값의 범위가 중요한 상황에서는 sbyte를 사용해서 적절하게 범위를 다룰 수도 있다.

 

C#에서는 보통 byte와 함께 사용하면서 비트 연산을 수행하기도 한다.

728x90
반응형

부동소수점 숫자를 나타내는 데이터 형식 중 하나이다. 

 

float

32비트의 고정된 크기를 가지며 숫자의 소수점 이하 7자리까지 정밀도를 가지고 있다.

실수 리터럴을 표현할 때 컴파일러가 float으로 인식하게 하려면 숫자 뒤에 f 또는 F를 붙여야 한다.

float a = 1.0f
float b = 1.0F

double

float보다 더 큰 범위의 수를 저장할 수 있으며 64비트 부동소수점 형식을 사용하여 약 15~16자리의 정밀도를 가진다. 하지만 이론적으로는 무한한 자릿수까지 표현이 가능하며 더 정밀한 값을 표현하기 위해서는 decimal을 사용해야 한다.

 

* decimal의 경우 높은 정밀도를 제공하지만 128비트 크기로 계산 속도가 느리기 때문에 성능이 중요한 경우에는 사용에 주의가 필요하다.

 

double d = 1.0d;
double e = 1.0;

double을 사용할 때는 접미사 d를 생략할 수 있다. 또한 double 형에 1.0f 처럼 float 값을 넣어도 암시적 형변환이 이루어져 허용이되지만 반대의 경우는 에러가 발생한다.

double d = 1.0f;	// implicitly convert
float a = 1.0d; 	// error

 

float보다 double이 더 많은 소수점 자릿수의 표현이 가능하지만 메모리의 크기가 차이가 나기 때문에 꼭 필요한 상황에서만 double을 사용하며 이외의 소수점을 사용할때는 float을 사용하는 것이 좋다.

 

 

728x90
반응형

class

클래스는 객체 지향 프로그래밍에서 가장 중요한 개념 중 하나로 데이터와 해당 데이터를 다루는 메서드를 하나의 단위로 묶어서 정의한 사용자 정의 데이터 형식이다. C#에서는 기능들의 단위가 클래스로 만들이 지고 사용된다.

 

class는 일반적으로 클래스 멤버로 프로퍼티, 메서드, 이벤트, 인덱서, 생성자, 중첩 클래스 등을 포함할 수 있으며 클래스를 정의함으로써 해당 클래스를 사용해요 객체를 생성할 수 있다. 

 

class MyClass {
    // 클래스 멤버 정의
    private int myField;
    public void MyMethod() {
        // 메서드 구현
    }
}
.
.
.

MyClass myObject = new MyClass();

MyClass는 class의 이름이며 myField와 MyMethod는 클래스의 멤버이다.

myField는 private 접근 제한자를 가지고 있어 클래스 내부에서만 접근이 가능하다. myMethod는 public 접근 제한자로 클래스 외부에서도 해당 클래스의 객체를 통해서 메서드를 호출할 수 있다.

 

myObject는 인스턴스화된 MyClass 객체이다.

클래스명을 타입으로 사용하여 변수를 선언하고 new를 통해서 해당 클래스의 객체를 생성해 할당한다.

myObject 변수를 사용하여 클래스의 멤버에 접근하여 사용할 수 있게된다.

 

 

728x90
반응형

decimal

부동 소수점과 다르게 고정 소수점 숫자를 나타내는 자료형이다. 정확한 소수점 계산이 필요한 금융, 세금, 계산 등과 같은 분야에서는 decimal을 자주 사용한다.

 

최대 28자리의 숫자를 나타낼 수 있으며 부호, 정수, 소수점, 소수점 이하 자릿수를 나타내는 4바이트 정수형 정수부와 소수부를 나타내는 4바이트 정수형 소수부 그리고 소수점 위치를 나타내는 4바이트 정수형 지수부 등으로 구성된다.

 

decimal balance = 100.50m;
decimal withdrawalAmount = 20.25m;
decimal newBalance = balance - withdrawalAmount;
Console.WriteLine($"New balance : {newBalance:C}");
// balance : 기존 잔액
// withdrawalanceAmount : 출금액
// newBalance : 출금 후 잔액

// New balance: $80.25 출력

decimal을 사용할 때는 m으로 끝나는 접미사를 사용해서 변수를 선언해야 한다.

 

소수점 자릿수가 다른 경우의 계산에서는 더 적은 숫자와 같은 자릿수로 맞춘 후 계산이 된다.

 

decimal d1 = 100.123m;
decimal d2 = 10.1m;

// d1 + d2 = 110.223m

만약 자릿수를 맞추어도 계산이 불가능한 경우에는 OverflowException이 발생한다. 따라서 숫자를 계산할 때는 소수점 자릿수를 유의하여 맞추는 것이 좋다.

728x90
반응형

bool

영국의 수학자 겸 논리학자인 조지 불의 이름에서 유래되었다.

bool은 참과 거짓의 값을 저장하는 변수타입으로 논리 자료형이라고도 한다.

 

프로그래밍 언어마다 다르지만 true, false는 정수형 1, 0과도 대응된다.

조건문과 논리 연산자 등에서 많이 사용된다.

 

조건문

bool isDone = true;
if (isDone)
{
	Console.WriteLine("작업 완료");
}

 

논리 연산자

&& (and) : 좌항과 우항이 모두 true일 때 true를 반환한다.

||(or) : 좌항과 우항 중 하나라도 true이면 true를 반환한다.

!(not) : 피연산자의 값을 반대로 반환한다.

 

int x = 10;
bool b1 = ( x > 5 ) && ( x < 20 );	// b1 == true
bool b2 = ( x < 0 ) || ( x > 100 );	// b2 == true
bool b3 = !(x == 10);	// b3 == false

 

bool 타입의 가장 흔하게 사용하는 방식으로 토글이 있다.

 

isDone = !isDone;

 

해당 코드가 실행되면 isDone은 언제나 현재 값의 반대 값을 가지게 되며 이 코드를 통해서 true와 false를 번갈아 가지는 토글 기능을 갖게 된다.

728x90
반응형

volatile

변수의 값을 캐시에 저장하지 않고 항상 메모리에서 값을 읽어오도록 한다.

멀티 스레딩 환경에서 여러 스레드가 동시에 하나의 변수에 접근할 때 캐시에 저장된 값과 메모리의 실제 값이 일치하지 않아서 오류가 발생할 수 있다.

 

int counter = 0;

void IncrementCounter()
{
    for (int i = 0; i < 100000; i++)
    {
        counter++;
    }
}

void DecrementCounter()
{
    for (int i = 0; i < 100000; i++)
    {
        counter--;
    }
}

void Main()
{
    Thread t1 = new Thread(IncrementCounter);
    Thread t2 = new Thread(DecrementCounter);

    t1.Start();
    t2.Start();

    t1.Join();
    t2.Join();

    Console.WriteLine("Counter value: " + counter);
}

 

위 코드에서 counter변수에 서로 다른 스레드에서 거의 동시에 접근하여 값을 변경하고 있다.

이때 counter는 항상 0이 아니며 일정하지 않은 값들로 출력된다.

 

이러한 상황에서 volatile 키워드로 변수를 선언하면 항상 일정한 값이 들어오게 된다.

 

int volatile counter = 0;

 

728x90
반응형

'Program Language > C#' 카테고리의 다른 글

C# 고정소수점 키워드 : decimal  (0) 2023.04.25
C# Yes or No 키워드 : bool  (0) 2023.04.25
C# 안전하지 않은 키워드 : unsafe  (0) 2023.04.25
C# 정적 키워드 : static  (0) 2023.04.25
C# 상속 방지 키워드 : sealed  (0) 2023.04.25

unsafe

뜻 그대로 안전하지 않은 코드를 명시할 때 사용하는 키워드이다.

C#에서 모든 메모리 영역은 가비지 컬렉터에 의해서 관리되는데 관리를 벗어난 영역에 작업을 수행하기 위해서 사용한다.

 

따라서 C#에서 관리하는 기능을 사용하지 않고 직접 관리하는 코드를 사용하겠다는 것을 명시하여 해당 코드를 GC관리로부터 벗어나도록 할 수 있기 때문에 더 자유롭게 메모리 컨트롤이 가능하게 된다. 자유로워진 만큼 메모리 할당과 해제를 모두 직접 구현해야 하며 해당 문제로 에러가 발생하면 메모리 누수, 버퍼 오버플로, 세그먼트 폴트 등 치명적인 결함이 발생하게 된다.

 

발생하는 문제가 치명적인만큼 이를 다루기 위해서 unsafe 키워드를 통해서 반드시 명시된 경우에만 제어권을 얻게 한다. 

기본적으로 unsafe를 사용하게 되면 c# 내부에서는 문제로 인식하고 콘솔에 경고를 보내게 된다.

 

사용처

사용할일이 거의 없는 키워드로 사용하는 상황도 일반적이지 않다.

 

포인터 사용

C#에서는 포인터 사용을 허용하지 않기 때문에 unsafe를 통해서만 직접 사용이 가능하도록 한다.

 

빠른 코드 실행

외부 알고리즘의 경우 빠른 코드 실행이 필요하기도 하는데 이럴 때 unsafe코드를 사용하면 성능을 향상할 수 있다.

 

외부 라이브러리와 상호 작용

일부 외부 라이브러리는 C#의 안전한 기능을 사용할 수 없기도 한데 이때 unsafe코드를 사용하여 외부와 상호 작용이 가능하도록 할 수 있다.

728x90
반응형

'Program Language > C#' 카테고리의 다른 글

C# Yes or No 키워드 : bool  (0) 2023.04.25
C# 변수 동기화 키워드 : volatile  (0) 2023.04.25
C# 정적 키워드 : static  (0) 2023.04.25
C# 상속 방지 키워드 : sealed  (0) 2023.04.25
C# 읽기 전용 키워드 : readonly  (0) 2023.03.30

클래스 멤버를 정의할 때 사용된다.

static으로 정의된 멤버는 객체 인스턴스에 속하는 것이 아닌 클래스 자체에 속하게 된다.

즉, 객체가 인스턴스화되기 전에도 해당 멤버에 접근이 가능한데 클래스 자체에 속하기 때문에 클래스 이름을 통해서 직접 호출이 가능하다.

 

class MyClass
{
	public static int myStaticVariable;
    public static void myStaticMethod(){}
}

class OtherClass
{
	public void SomeFunc()
    {
    	MyClass.myStaticVariable = 10;
    	MyClass.mySaticMethod();
    }
}

 

static 멤버는 모든 인스턴스에 공유되기 때문에 한 객체에서 static 멤버에 대한 수정이 있는 경우 다른 객체에서도 동일한 값을 가지게 된다. 따라서 static 멤버는 클래스의 인스턴스와 관련이 없는 작업을 수행할 때 사용되며 일반적으로 유틸리티 클래스의 메서드나 상수 특정 클래스에서 공통으로 사용하는 변수 등을 정의할 때 static 키워드가 사용된다.

 

주의할 점은 모든 객체에서 공유되므로 서로 다른 스레드에서 동시에 static 멤버를 수정하는 상황이 발생할 수 있는 즉, thread-safe 하지 않기 때문에 멀티스레드 환경에서는 문제가 발생할 수 있다.

 

이러한 특징 때문에 static을 사용할 때는 몇가지 당연한 규칙이 있다.

 

우선 static 클래스의 모든 멤버는 static으로 선언되어야 한다.

클래스가 static이라는 것은 별도의 인스턴스를 생성하지 않아도 해당 클래스를 어디서든 사용이 가능하고 항시 메모리에 올라가 있는 상태라는 뜻이므로 인스턴스가 생성될 때 변수 할당이 이루어지는 일반 변수의 선언은 허용되지 않게 된다.

 

public static class MyStaticClass
{
	// 불가능
    public int number_1;
    // 가능
    public static int number_2;
    static int number_3;
}

 

하지만 반대로 static 클래스가 아니어도 내부의 멤버가 static으로 선언되는 것은 가능하다. 

 

public class MyClass
{
	public static int MyStaticVar = 0;
    public int MyVar = 0;
}

 

정리

static은 처음 선언된 이후 메모리에 상주하기 때문에 언제든 접근 가능하다.

따라서 빈번하게 사용되는 공통적인 변수의 경우 정적으로 선언해서 사용하는 것이 좋을 수 있지만 너무 많은 static을 사용하게 되면 그만큼 상주하는 메모리가 많아지는 것이기 때문에 적절한 사용이 필요하다.

728x90
반응형

sealed

클래스나 메서드를 상속하지 못하도록 하여 오버라이딩을 방지한다.

sealed로 선언된 클래스는 다른 클래스에서 상속받을 수 없으며 메서드의 경우 해당 클래스에서만 사용이 가능하다.

 

sealed 클래스 선언

sealed class MyClass
{
	//
}

이 클래스는 다른 클래스에서 상속받을 수 없으며 이 클래스를 파생 클래스로도 사용할 수 없다.

 

 sealed 메서드 선언

class MyBaseClass
{
	public virtual void MyMethod() {}
}

class MyDerivedClass : MyBaseClass
{
	public sealed override void MyMethod() {}
}

MyMethod 함수는 MyDerivedClass에서 오버라이딩되고 이후 sealed로 선언된다. 따라서 MyDerivedClass를 상속하는 다른 파생 클래스에서 MyMethod를 오버라이딩할 수 없게 된다.

 

일반적으로 클래스를 마지막으로 봉할 때 사용하는 키워드로 최종적인 구현을 제공하는 클래스에서 사용된다.

파생되어 추가되는 내용이 필요하지 않게 하거나 해당 기능을 변경하거나 확장하려는 경우를 방지해 클래스의 안정성을 보장한다.

 

예를 들어 C#의 String 클래스의 경우 sealed로 선언되어 있어 개발자가 해당 클래스를 상속하거나 수정할 수 없도록 만들어 클래스의 안정성을 보장하도록 한다.

728x90
반응형

아시는 분께서 최근에 베트남에 다녀오셨는데 선물로 커피를 받았다. 평소에도 커피를 즐겨 먹어서 반가운 선물이다.

 

베트남 콘삭 커피

 

베트남이 커피로 유명하다는 사실도 이번에서야 알게 되었다.

프랑스의 식민 통제를 대략 100년 정도 받으면서 이때 커피 문화도 발전하게 되었다고 한다

 

패키지에는 제조사의 페이지로 보이는 주소가 적혀있어서 들어가 보았다.

 

CONSOC

 

해당 페이지에는 판매 중인 커피의 종류들이 보인다. 그리고 사이트가 한글을 지원한다는 점에서 한국 소비자층이 꽤나 있구나 싶었다. 

 

제조사는 TRUONG SON COOPERATIVE(쯔엉 성)인 거 같은데 해당 커피에 대해서 더 자세히 찾아보니 해당 커피 제조사와 인터뷰한 기사를 찾을 수 있었다.

 

베트남 콘삭 커피를 만드는 사람들

 

글에서는 해당 커피에 대해서 다루고 있다.

기사에는 이 부분에 대해서도 제조사와 인터뷰한 내용이 있다. 일단 다람쥐똥 커피는 존재하지 않는다 대신 족제비 똥 커피는 존재하긴 하는데 해당 커피와는 관련이 없다. 콘삭커피는 커피를 연구하다가 헤이즐넛 향을 첨가하게 되었고 여기서 특유의 맛을 얻게 되었다고 한다. 그래서 다람쥐가 헤이즐넛을 좋아한다는 점과 귀엽고 친숙하기 때문에 커피 이름을 Con sóc(=다람쥐)이라고 짓게 되었다고 한다. 

 

나도 패키지에서 가장 눈에 띄는 게 커피를 먹고 있는 다람쥐 그림이었는데 그 다람쥐 그림 때문에 루왁커피처럼 다람쥐의 배설물로 만든 것인가 생각했다. 거기다 이름도 다람쥐다 보니 베트남어를 아는 사람이었다면 더 다람쥐똥 커피가 연상되었을 것 같다. 실제로 커피를 검색해 보면 다람쥐똥 커피로 더 알려져 있어서 사람들 생각은 다 비슷하구나 생각했다.

 

필터를 통해서 내려 마시는 방식으로 커피를 내릴 때 풍기는 찐한 향이 좋다. 맛도 굉장히 부드럽고 커피의 향도 많이 느낄 수 있는 맛있는 커피다.

패키지에는 설탕스틱도 있는데 평소에는 커피를 마실 때 추가로 넣어서 먹지 않는데 그래도 있으니 넣고 먹어봤더니 달달하니 맛이 괜찮았다.

 

 

커피를 내려 먹어야 해서 번거로움이 있지만 향이 좋아서 그 과정마저 즐기면서 마실 수 있었다.

향도 좋고 맛도 좋고 패키지도 깔끔하고 귀여운 다람쥐도 있기 때문에 커피를 좋아하는 사람에게는 좋은 선물이라고 생각된다.

728x90
반응형

'Life' 카테고리의 다른 글

사이버 나무  (0) 2023.05.11
오랜만에 만족스러운 영화관람! 슈퍼 마리오 브라더스  (0) 2023.05.08
티스토리 단축키  (0) 2023.03.30
장 줄리앙 전시회 - 그리고 거기  (1) 2023.03.27
재벌집 막내아들  (0) 2023.01.08

+ Recent posts