[Warming up C Programming] Chapter 10 : 구조체

eunee22·2023년 8월 2일

Warming-up C Programming

목록 보기
10/10

제가 대학교 1학년 때 C언어 수업에서 배운 내용을 교재와 ppt를 중심으로 정리한 내용입니다. (2022.3 ~ 2022.6)
당시에 공부를 위해서 HWP 파일로 정리해 놓은 것을 그대로 올립니다.

대학에 처음 들어와 정리한 내용이라 모든 내용을 담고 싶은 욕심에 정리가 많이 지져분하고 어설픈점 양해 부탁드립니다..!

🍑구조체의 기본

구조체의 개념

  • 구조체 : 서로 다른 데이터형의 변수들을 하나로 묶어서 사용하는 기능
  • c 언어에서의 구조체는 사용자 정의형을 만드는 방법임

구조체의 정의

  • struct 태그명 {
    데이터형 멤버명;
    데이터형 멤버명;
    .
    .
    }; 형식으로 정의함.

    • 태그 이름 : 구조체를 구별하기 위한 이름
    • 구조체의 멤버 : 구조체를 구성하는 변수
  • 구조체는 함수 밖에 정의하며, 소스 파일의 시작 부분에 정의하는 것이 좋음

  • 구조체를 정의하면 새로운 데이터형이 만들어짐

  • 구조체형의 변수를 선언해야 구조체 변수가 메모리에 할당된다. 정의했다고 해서 자동으로 구조체 변수가 만들어지진 않음

  • 구조체의 바이트 크기는 멤버들의 바이트 크기를 모두 더한것보다 크거나 같음 → 메모리 정렬과 패딩 때문에

    • 구조체도 데이터형이므로 sizeof 연산자 사용가능
  • 구조체를 사용시 struct 키워드와 태그이름을 함께 사용해야함 (태그 이름만 사용 시 컴파일 에러)

구조체 변수의 선언

  • struct 태그명 변수명; 형식을 통해서 선언
  • 구조체 변수 선언 시 구조체의 멤버들이 선언된 순서대로 메모리 할당
  • 구조체를 정의하면서 구조체 변수를 선언할 수 있음
    • 이때는 태그이름을 생략할수 있지만, 일회성으로만 사용 가능함

구조체 변수의 초기화

  • 구조체 변수는 { } 안에 멤버들의 초기값을 순서대로 나열함으로써 초기화.
  • 초기화 해주지 않으면 쓰레기값을 가짐.
  • { } 안의 초기값이 부족하면 나머지는 0으로 초기화, 더 많으면 컴파일 에러 발생
  • 초기값으로 { 0 }을 지정하면 모든 멤버 0으로 초기화, 모든 문자는 널문자로 초기화

구조체 변수의 사용

  • 멤버 접근 연산자(.) → 구조체의 멤버의 접근할 때 이용

  • 구조체의 멤버도 수식에 사용하거나 함수 호출 시 인자로 사용가능

  • 구조체의 멤버는 항상 구조체 변수를 통해서만 접근 가능

    • 구조체에 속한 변수이므로 구조체 변수 없이 사용시 일반 변수로 간주
  • 구조체 변수를 여러개 선언시 서로 다른 메모리에 할당

  • 구조체의 멤버는 구조체 변수마다 각각 할당

  • 구조체 변수(.앞)를 통해서 멤버(.뒤)에 접근하기에 어떤 변수의 멤버를 사용하는지 구분가능

  • 구조체의 멤버가 배열일 때는 배열이름에 대입할수 없음 → 문자열 처리 함수 이용

구조체 변수 간의 초기화와 대입

  • 같은 구조체형의 변수들끼리 서로 초기화하거나 대입 가능

  • 구조체 변수로 다른 구조체 변수, 같은 구조체 변수를 초기화하면, 같은 멤버들끼리 1:1로 복사해서 초기화 (기본형 뿐만 아니라 배열형의 멤버도 복사)

  • 구조체 변수 선언 이후에 해당 변수에 { }를 이용해서 직접 값을 대입(할당)하는 것은 불가능 (컴파일에러)

  • 구조체 변수끼리는 대입 가능하지만, 구조체의 멤버가 배열인 경우 해당 배열끼리는 대입 불가

    • 각 요소를 대입하거나 문자열 처리 함수 사용

구조체 변수의 비교

  • 구조체 변수에는 관계 연산자를 사용할 수 없음
  • 구조체 변수의 값이 같은지 비교하려면 멤버 대 멤버로 비교해야함
    • 이때 문자열이냐 기본형이냐에 따라 처리 방법 다름

🍑구조체의 활용

구조체 배열

  • struct 태그명 배열의이름[배열의크기] 형식으로 구조체 배열의 선언

  • 구조체 배열의 원소들도 메모리에 연속적으로 할당

  • 구조체 배열을 초기화하려면 { } 안에 배열 원소의 초기값을 나열

  • 구조체 배열을 초기화 할 때 배열의 크기 생략 가능

  • 구조체 배열의 원소에 접근하려면 인덱스를 이용

  • 구조체의 멤버에 접근하려면 배열의 이름[배열의 크기].member으로 접근

  • 구조체 배열에 대해서도 데이터의 탐색과 정렬같은 기능 구현 가능
    ex) 콘텐츠 검색 기능

구조체 포인터

  • 구조체 변수의 주소를 저장하는 포인터
  • 구조체형 테그명 *포인터변수이름 = &구조체변수명 으로 선언
  • 간접 멤버 접근 연산자 : (대신 역참조 연산자*와 멤버접근 연산자. 이용가능)
    • 구조체 포인터로 포인터가 가리키는 구조체 변수의 멤버에 접근하기위해 사용
      ex) 구조체 포인터 ptr이 가리키는 구조체 변수의 멤버에 접근
      ptr→member = (*ptr).member
  • 구조체를 가리키는 포인터로 구조체 변수에 읽기 전용으로 접근하게 하려면 const 포인터로 선언(변경불가)

함수의 인자로 구조체 사용하기

  • 구조체를 함수의 인자로 전달할 때는 값과 포인터에 대한 호출을 둘다 사용가능함.

1. 값에 의한 호출(구조체 복사)

  • 인자를 매개변수로 복사해서 전달
  • 메모리를 복사하는데 시간이 걸리므로 공간적,시간적 성능 저하를 유발
  • 기본형에 비해 크기가 큰 구조체는 복사하는 대신 구조체의 주소를 전달하는 것이 좋음

2. 참조에 의한 호출

  • 구조체를 복사하지 않고 포인터로(주소만) 전달
  • 구조체가 입력 매개변수 일때는 const 포인터로 전달하는 것이 좋고, (변경시 컴파일 에러)
    구조체의 함수가 출력 매개변수이거나 입출력 매개변수 일때는 일반 포인터로 전달
  • 매개변수를 구조체 포인터형으로 선언
  • 함수안에서는 간접 멤버 접근 연산자 사용
  • 구조체를 매개변수로 갖는 함수 호출 시 구조체변수의 주소를 인자로 전달

구조체의 멤버로 다른 구조체 사용하기

  • 구조체 안에 다른 구조체 변수를 멤버로 포함할 수 있음.
  • 큰 구조체 변수안에 작은 구조체의 변수들의 메모리가 할당됨.
  • 초기화 하려면 { } 안에 { }를 씌워서 작은 구조체의 변수에 할당할 값을 순서대로 나열
  • 큰 구조체의 멤버에 접근하려면 멤버 접근 연산자(.)를 이용
  • 멤버의 멤버에 접근할 때 멤버 접근 연산자를 연속해서 사용가능
profile
보안 공부하는 대학교 4학년 / 시리즈에서 더욱 편하게 글을 찾아보실 수 있습니다:)

2개의 댓글

comment-user-thumbnail
2023년 8월 2일

좋은 글 감사합니다.

1개의 답글