TIL(1) - Struct

jaepal·2022년 6월 24일
1

TIL

목록 보기
1/5
post-thumbnail

🗃 구조체란?

구조체를 설명하기 전 , 기존에 배웠었던 배열을 알 필요가 있는데
배열은 자료형(int,char,float 등)이 같은 데이터가 하나로 묶여있는 집합체라면,
구조체는 설계자가 자료형이 다른 데이터를 하나로 묶어 설계한 집합체라고 한다.

즉, 구조체는 사용자가 새로운 자료형을 정의 한다고 볼수도 있다.
아래 표를 통해 간단히 차이점을 알아보자.

목록배열구조체
자료형의 종류무조건 동일 해야한다.다르게 구성할 수 있다.
선언의 차이int a[3]; struct a { int num; char array; float num2; }

구조체의 선언 🗂️

구조체 선언은 struct란 명렁어를 이용해 구조체 선언을 한다.

다음코드와 같다.

struct 구조체이름 /* 태그라 칭한다. */ {
    
    자료형(int,char) 변수이름; /* 필드(or 멤버)라 칭한다. */
    자료형(int,char) 변수이름;
    자료형(int,char) 변수이름;
                .
                .
                .
    }; /* 구조체 선언의 끝을 알림을 나타내는 세미콜론을 붙여줘야 한다. */

구조체의 요소들을 사용할 때 유의 사항 ⚠️


요소내용
형틀(선언)어떤 변수나 배열을 실제로 메모리에 만드는 것이 아닌 ,
구조체를 설계하는 지침만 컴파일러에게 통보한다.
태그(이름)구조체의 대표하는 태그로 중복되게 선언할 수 없다.
필드(멤버)기억 클래스를 지원하지 않는다.
기억 클래스)구조체 형틀이 선언되어 있는 위치와 관계가 없다.
연산자. & = 연산자, sizeof의 피연산자, 함수의 매개변수와
반환값으로 사용될 때를 제외하고는,
구조체 전체 단위로 이루어지는 연산은 허용되지 않는다.

구조체의 초기화

구조체의 초기화는 배열과 비슷하게 정의하고, 구조체 멤버에 해당하는 요소의 초기값을 자료형 형식에 맞춰서 ,
중괄호 { } 안에 선언하면 된다.

다음 코드와 같다.

int main(void){
  struct score student_1 = { 20220101, "이재찬", 88 , 91 , 97 , 76 , 44 } /* 구조체의 초기화 */
  . . .
}

구조체 변수 선언

  • 위에 코드와 같이 score 구조체를 선언한 후에 사용하기 위해서는 구조체 변수를 선언 해줘야한다.

  • 구조체 변수는 구조체에서 선언한 모든 속성을 사용할 수 있다.

  • 구조체 변수를 선언하는 방법은 이와 같다.

  • struct score student_Kim && struct score student_Lee
  • score 구조체의 변수 student_Kim을 선언하면 구조체 형식에 맞춰 해당 필드의 자료형이 그대로,
    상속되어 메모리에 할당되도록 컴파일러에게 알려준다.

    여기서, 반드시 구조체를 먼저 선언한 후 구조체 변수를 따로 선언해야 하는것은 아니나

    다음과 같이 구조체와 구조체 변수를 한꺼번에 선언할 수도 있다.

    
    struct score { /* 구조체 선언 */
            int student_number;
            char student_name[10];
            int testKorScore;
            int testEngScore;
            int testMathScore;
            double scoreAvg;
    }student_Lee; /* 구조체의 선언과 동시에 구조체 변수인 student_Lee 선언. */
    

구조체 필드(멤버) 연산자 ➗

  • 앞서, 구조체를 정의하고 구조체 변수를 선언한 이유는 바로 구조체 멤버를 참조하기 위한 것 이다.
  • 구조체 멤버는 멤버 연산자인 dot.을 사용하여 다음과 같이 사용한다.
    student_Lee.student_number = 20220101; // 구조체 필드 참조
  • 구조체 멤버가 문자 배열(char)일 경우, student_name = "이재찬"과 같이
    선언하는 것은 허용되지 않는다. 반드시 strcpy()함수를 이용해 구조체 를 접근해줘야 한다.
    strcpy(student_name , "이재찬"); // 문자 배열에 대한 구조체 필드 참조

구조체 배열 📜

구조체 배열 초기화

  • 구조체 배열의 초기화는 중괄호{}를 사용하여 배열의 요소를 초기화한다.

  • 구조체 배열을 초기화하는 방법은 다음과 같다.

       struct student MyClass[3] = {
               { "Sam" , "Man" , 20 },
               { "Lee" , "Woman" , "23 },
               { "Ryu" , "Man" , 28 }
          };
  • 다음과 같이 구조체 배열을 초기화 할때엔, 콤마,를 사용하여 배열 요소를 확실하게 구분해야 하며
    마지막 배열 요소에는 콤마를 생략한다.

구조체 포인터 ☝️

구조체에서 사용하는 포인터

  • 구조체를 가리키는 포인터를 사용하는 형식
  • 포인터를 구조체 멤버로 사용하는 형식 먼저 구조체와 포인터를 사용하기 위해 구조체를 선언한다.
    struct gameID {   /* gameID 구조체 선언 */
            char id[10];
            char nickname[8];
            int level;
    };

구조체를 가르키는 포인터의 사용

  • 선언한 구조체를 가르키는 포인터를 사용하는 형식은 다음과 같다.
struct gameID admin = { "adminUser" , "GameManager" , "100" };
struct gameID *p;     /*  gameID 구조체를 가르키는 포인터 선언 */

p = &admin;           /*  구조체 주소를 포인터에 대입한다. */

printf("%s , %s , %d \n" , (*p).id, (*p).nickname , (*p).level);

이와 같이, 구조체를 가르키는 포인터를 사용할 경우에 구조체 필드에 접근하기 위해서는
(*p).id과 같이 선언하면 된다.

여기서 한가지 짚어가야 할 점은 (*p).name 이와 같이 선언한 이유는
연산자 우선순위를 정해주기 위함이다.

만약 *p.name 이처럼 선언하게 되면 포인터보다
p.name가 먼저 수행되어 결과가 달라질 수 있다.

만약 이런 코드가 번거롭다면 간접 멤버 연산자인 ->를 사용할 수 있다.

printf("%s , %s , %d \n" , p -> id, p -> nickname , p -> level);

간접 멤버 연산자 사용시 유의사항

  • 간접 멤버 연산자를 사용할 때엔 연산자 왼쪽에 반드시 구조체 포인터수식이 위치해줘야 한다.

마치며,

구조체 기능은 매우 편리한 기능이라 생각하고,

객체지향 언어에서의 class와 비슷한 점이 많다고 느꼈다.

다만 포인터를 활용하게 된다면 난이도가 올라가는게 문제라 포인터 부분 공부를 반복하여,

포인터를 다루는 실력을 늘려야겠다고 생각한다.

0개의 댓글