C# - 구조체 1

2025. 6. 17. 20:08Programming Language/C#

반응형

구조체

C#에서 구조체는 값 형식(Value Type)의 사용자 정의 타입으로 타입에 무관하게 관련있는 데이터를 묶어서 하나의 단위로 표현할 수 있게 해준다.

작고 단순한 데이터를 담을 때 유용하고 클래스와 비슷하나 메모리 관리 방식과 동작에서 차이가 존재한다.

 

구조체의 정의

struct 구조체명
{
    데이터형식 변수명1;
    데이터형식 변수명2;
    ....
}

이렇게 구현된 구조체명은 새로운 데이터의 타입이 되고 변수를 선언할 때 구조체명으로 변수를 선언할 수 있게 된다.

그래서 이 구조체를 사용자 정의 데이터 타입이라고도 한다.

유의해야할 점은 C#에서 구조체는 메서드 안에서는 정의할 수 없다

메서드의 내부에 생성하는 경우 에러를 발생

그렇기에 메서드의 외부에서만 정의가 가능하다.

 

예시를 하나 보자면 학교의 학생에 대한 구조체를 하나 만들어본다고 하자.

그러면 그 구조체는 아래와 같은 형식으로 구현되게 될것이다.

 

구조체의 접근제한자

위에서 만든 구조체를 사용하기 위해서 요소에 값을 할당해보면

이렇게 할당이 되지 않는것을 볼 수 있다.

 

이는 struct의 내부에 있는 요소들에게는 접근제한자라는 것을 붙일 수 있는데 기본적으로 struct에서 요소에 아무것도 붙이지 않고 선언을 하게 되면 각 요소는 private라는 접근제한자로 설정이 되게 되고 외부에서는 해당 요소들에 직접 접근이 불가능하다.

 

그래서 사실 구조체 자체도 클래스 내부에 선언되어 있어 기본적으로 private라는 접근제한자로 생성이 된 상태로 클래스의 외부의 다른 공간에서 구조체에 접근하고자 한다면 찾을 수 없다는 에러를 벹는다

 

이런 접근 제한자의 종류로는 public, private, internal, file이 있다.

 

1. private

구조체의 내부에서만 접근이 가능하게하는 접근제한자로 외부에서 직접 접근하지 못하도록 값을 숨긴다.

구조체의 필드, 메서드, 속성등에 사용이 가능하다.

보통 아무것도 붙지 않으면 private로 선언이 된다.

 

private는 위에서 봤던것 처럼 같은 스코프 내부가 아닌 상태라면 접근이 불가능하다

대신 같은 스코프에 위치해 있다면 해당 구조체에 접근이 가능하다.

 

그리고 구조체가 생성이 가능하다 하더라도 구조체 내부의 요소들 또한 private로 선언되어 있다면 내부의 요소에 대해서 접근이 불가능하다.

대신 요소들이 존재하는 구조체의 내부에서는 해당 구조체에 접근이 가능하다.

2. public

public 접근 제한자는 제한을 두지 않겠다는 의미로 어디서든 접근이 가능하다.

이 용도는 구조체나 구조체의 멤버를 외부 코드에서 사용할 수 있도록 공개하는 것으로 구조체 선언, 멤버 필드, 프로퍼티, 메서드등에 모두 사용이 가능하다.

 

위에서 봤던 구조체에 public 접근제한자를 부여하면

이렇게 외부의 다른 클래스에서 사용이 가능하게 된다.

 

그리고 구조체의 요소에 대해서도 접근제한자를 설정해주지 않는다면 접근할 수 없게 되어 있다.

이 또한 public으로 선언해주면 접근이 가능해진다.

 

3. internal

같은 어셈블리(프로젝트) 안에서만 접근이 가능하고 이는 라이브러리 외부에는 숨기고 내부 구성요소끼리는 공유하고 싶을때 사용한다.

C#같은 경우는 같은 솔루션 내부에서 서로 연관성이 있는 프로젝트가 여러개가 생기게 되어 이들간의 접근을 제한하기 위한 접근제한자이다.

 

여기서 어셈블리 라는 것은 C#에서 빌드를 진행하면 생성되는 실행파일(exe파일) 혹은 라이브러리 파일(dll)을 이야기 하는것으로 C#에서는 이들 자체가 결국 하나의 프로젝트에 해당하기 때문에 어셈블리를 프로젝트로 이해하고 있어도 될듯 하다.

 

internal로 선언은 구조체 선언, 멤버 모두 가능하다.

 

한번 이게 어떤 영향을 주는지 테스트해보자.

먼저 솔루션탐색기에서 우리 솔루션을 우클릭 > 추가 > 새 프로젝트를 눌러서 프로젝트를 하나 추가해주자

 

프로젝트 명칭은 원하는대로 아무렇게나 만들어주자.

 

먼저 구조체 및 요소들은 public으로 모두 변경해보자.

그러면 보다 싶이 ConsoleApp1 프로젝트 내부에서는 접근이 가능한 상태임을 알 수 있다.

 

그렇다면 ConsoleApp2 프로젝트 내부에서는 어떨까?

먼저 다른 프로젝트에서 해당 프로젝트의 클래스, 구조체등을 사용하기 위해서는 프로젝트를 참조시켜줘야만 한다.

이런 내용들은 나중에 더 알아보긴 하겠다만 지금은 단순하게 ConsoleApp2에게 ConsoleApp1프로젝트의 public 클래스, 구조체, 함수들을 사용할 수 있도록 알려주는 방법이다.

 

프로젝트 참조시키는 방법은 참조를 시도하고 싶은 프로젝트 우클릭 > 추가(D) > 프로젝트 참조(R)... 을 눌러주고

 

열리는 참조관리자 팝업에서 왼쪽 사이드 메뉴에서 프로젝트 > 솔루션으로 들어가서

참조하고자 하는 프로젝트를 체크하고 확인해주면 된다.

 

물론 이렇게 참조를 하더라도 클래스 내부에 public 구조체에 접근하기 위해서는 클래스 또한 public으로 외부에 공개가 되어 있어야만 접근이 가능하다.

 

ConsoleApp1의 클래스를 public으로 선언해주고 나서 

다시 확인해보면

접근이 가능한 상태임을 확인할 수 있다.

 

그러면 이제 internal 접근 제한자를 구조체에 걸어보면

이렇게 접근제한이 걸리는 것을 볼 수 있다.

 

이게 internal의 접근 제한 범위이다.

 

4. file( C# 11이상)

같은 소스 파일 내에서만 접근이 가능하게 하는 접근제한자로 아주 제한적인 사용 범위를 설정하는 방법이다

보통 테스트용 타입이나 내부 유틸 클래스등에 사용되기도 한다.

file 접근제한자는 클래스 자체, 구조체 자체, 레코드 자체에만 붙일 수 있고 내부 요소(멤버필드, 메서드)에는 붙일 수 가 없다.

또한 file 접근제한자는 최상위 타입에만 선언이 붙을 수 있기에 구조체가 클래스 내부에 있다면 접근제한자를 설정할 수 없다.

 

file에 대해서 확인해보기 위해서 먼저 cs 파일을 하나 추가로 생성해보자.

프로젝트 우클릭 > 추가 > 새 파일(Ctrl + Shift + A) 을 눌러 

 

새항목을 추가해주자.

 

그리고 새로 만들어진 클래스 내부에 함수 하나를 생성해주고 이 안에서 한번 구조체를 선언해보자.

 

기존에 public으로 존재하기에 접근이 가능한 상태임을 확인할 수 있다.

 

이제 이 구조체에 file 접근제한자를 붙이면

file접근제한자가 붙은 구조체는 최상위에 존재해야한다고 나온다.

 

그러니까 구조체를 클래스 외부로 빼주자.

이러고 새로 만든 파일에서 보면

이렇게 접근이 가능한것을 볼 수 있다.

 

그러면 이제 file로 접근제한자를 변경해보면

아예 찾지를 못하게 된다.

 

이게 구조체에 붙는 접근제한자이다.

 

구조체의 사용

구조체안에 있는 멤버 필드에 접근하기 위해서는 아래와 같은 방식을 사용한다.

구조체명 구조체변수명; // 구조체의 선언
구조체변수명.멤버필드명 = 값; // 구조체의 멤버필드에 값 할당
구조체변수명.멤버필드명 // 구조체의 멤버필드 값 사용

===============================================================

public Struct Student // 구조체의 정의
{
    public int id;
}

static void Main(string[] args)
{
    Student s; //구조체의 선언
    s.id = 20; //구조체 멤버필드에 값 할당
    Console.WriteLine(s.id) //구조체 멤버필드 값 사용
}

 

구조체의 멤버에 접근하기 위해서는 . 연산자를 사용해서 접근이 가능하다.

 

구조체의 배열

구조체의 배열은 특별하게 다른점은 없다.

배열의 타입을 구조체로 선언을 하고 new 연산자를 사용해서 인스턴스화를 하면 된다.

기본적인 구조체 배열의 사용 법은 아래의 구조와 같이 선언이 가능하다.

구조체명[] 배열명 = new 구조체명[size];

 

 

이렇게 선언된 구조체 배열에는 기존 배열에 값을 할당하는 방법 + 구조체의 멤버필드를 사용하는 방법을 연결해서 사용하면 된다.

 

한번에 할당하는 방법은 조금 다른데 구조체의 모든 요소를 한번에 할당할때에는 new 키워드를 사용해서 구조체를 인스턴스화하여 전체를 교체해줘야한다.

그 이유는 우선 구조체 배열의 요소에 넣으려는 전체 값이 {}중괄호로 값을 전달하는 경우는 컴파일러에서 이 값이 구조체의 타입으로 되어 있는지 인식할 수 없어 우선 저장 자체를 못하게 된다.

 

여기서 구조체 배열의 경우는 선언이 되는 순간 모든 배열의 요소에 구조체가 인스턴스화 됨에도 불구하고 

이렇게 할당이 되지 않는 이유는 구조체 배열의 경우는 값 전체를 만들어 할당할때({}중괄호를 사용해서 할당할때) 만들어진 구조체 인스턴스 자체를 교체해야하기 때문이다.

 

그래서 결국 new 키워드를 사용해서 직접 구조체를 인스턴스화 해서 그 자리에 있던 빈 구조체를 가득 채워놓은 만들어진 구조체로 덮어쓰기 한다고 생각하면 편할듯 보인다.

 

 

함수의 매개변수로 구조체를 사용

함수의 매개변수로 구조체를 전달할때는 특별할건 없고 그냥 매개변수를 구조체 타입으로 선언해두면 된다.

 

 

반응형

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

C# - 열거형  (0) 2025.06.21
C# - 구조체2  (0) 2025.06.21
C# - 닷넷API  (0) 2025.06.17
C# - 함수  (1) 2025.06.15
C# - 배열  (0) 2025.06.15