C 언어(25) - 구조체 포인터

C 언어 강의, 구조체 포인터와 -> 이해

Featured image

🔚 짧게 하는 복습

✅ 1. 구조체의 정의, 선언을 할 수 있다.

✅ 2. 구조체의 메모리상 저장 방법과 패딩 최적화를 안다.

✅ 3. 구조체 원소의 간접 참조, 직접 참조

혹시 기억이 안 난다면, 다시 돌아가자


저번에는 구조체에 대해서 정의, 선언, 수정에 걸쳐 메모리 구조까지 파악하는 시간을 가졌다.

구조체야말로 C언어 기본 강의에서 배우는 자료구조의 꽃이다..

이는 앞으로 배울 객체 지향 프로그래밍이라는 것으로도 넘어가기 때문에, 구조체를 잘 숙지하는 것이 좋다.

일단, 구조체의 큰 특징 중 하나인 패딩은 꼭 잘 알아두는 것이 좋다.

또한, 아직은 참조 연산자인 .은 잘 사용하는 것이 불편할 텐데 익숙해지는 것이 좋다.

오늘은 구조체에서 다루는 마지막 특징인 구조체 포인터를 알아보겠다.


구조체 포인터란?

저번에 배열 포인터, 포인터 배열 등을 다룰 때 뒤에 오는 것이 근본이라는 것을 배웠다.

구조체 포인터, 역시 구조체가 메인이 아니라 포인터가 메인이다.

포인터는 포인터인데 구조체를 가리키는 포인터이다.

구조체 포인터는 다른 포인터들처럼 선언 및 초기화를 할 수 있고, 특히 저번 시간에 배운 것처럼 주소연산자를 통해 초기화할 수 있다.

아래 코드를 주의 깊게 보자.

분명 이론상, 포인터가 구조체를 가리키고 있으니 간접 참조 후. 연산자를 통해서 하면 될 것 같다.

사실 전자의 코드도 논리상 큰 문제가 없다. 저번 강의에도 나왔지만. 연산자의 경우 주소 연산직접 참조가 동시가 되기 때문이다.

하지만 코드가 복잡해지는 것을 막기 위해 구조체 포인터를 통해 값을 간접 참조하고 싶을 때는, -> 연산자를 이용한다.

이를 통해서, 아래와 같은 코드도 가능하다.

p_minsu->age = 30;
p_minsu->stu_score.math = 80;
p_minsu->stu_score.english = 80;
p_minsu->stu_score.korean = 80;
//간접 참조를 통한 구조체 값 변경.

참고로 현재의 코드에서는 name은 변경이 불가하다.(const)

문자열이 배열의 관점이 아니라 리터럴의 관점으로 선언되었기 때문이다.


구조체 배열 및 구조체 포인터 배열

여기서 마치긴 아쉬우니, 특별한 자료구조를 더 배워보자.

우선은 구조체 배열구조체 포인터 배열이다.

이제는 익숙할 것이다. 전자는 구조체를 원소로 가지는 배열, 후자는 구조체 포인터를 원소로 가지는 배열이다.

이런 게 왜 필요하나 싶은데, 사실 우리가 컴퓨터를 사용할 때마다 사용하는 운영체제, 네트워크 모두 이러한 자료구조들로 만들어져있다. (읽어볼 거리 참고)

구조체 배열부터 예제를 통해서 한번 보자.

말 그대로 구조체를 연속적인 구조로 사용하고, 배열과 구조체의 특성을 모두 이용할 수 있다.

배열에서 인덱싱할 때는 [], 그 안의 원소에서 값을 참조할 때는. 연산자를 이용하면 된다.

그렇다면 구조체 포인터 배열은 어떨까?

사실 당연하지만, 구조체 포인터의 ->연산과 배열의 []연산을 모두 사용할 수 있다.

아래의 예제를 보자.

위와 거의 같은 코드지만, 간접 참조를 통해서 접근 및 수정하는 것을 확인할 수 있다.


리터럴 문자열 배열

진짜 진짜, 마지막이다.

우리는 구조체가 다양한 원소를 포함할 수 있음과 배열 역시 다양한 자료형을 원소로 가질 수 있음을 알았다.

하지만 딱 하나, 아직 우리가 다루지 않은 것이 있는데 바로 리터럴 문자열 배열이다.

(문자 배열을 이용한 문자열 배열은 char의 2차원 배열과 같기에 생략한다.)

이 문자열 배열의 가장 큰 특징은, 모든 원소가 상수라는 것이다.

즉, 어떤 인덱스로 참조는 가능하나 그 어떤 원소도 수정할 수 없다.

그런 특징 때문에 사실 많이 사용할 일은 없는데, 일단은 예제를 보자.


📖 오늘의 핵심(다 알기 전까지는 넘어가지 말자❗)

✅ 1. 구조체 포인터와 ->연산자를 안다.

✅ 2. 구조체 배열과 구조체 포인터 배열을 안다.

✅ 3. 문자열 배열을 안다.

⚠️ 다시 한번 강조하지만, 리터럴 문자열은 수정할 수 없다.

💣 과제, 이제 모든 자료형을 배웠으니 함수형으로 다루어 보자.

  1. 정수, 문자열, 실수 원소를 매개변수로 입력받아 구조체를 반환하는 함수를 만들어보자.(난이도 中)

  2. 정수, 문자열, 실수 원소를 매개변수로 입력받아 구조체 포인터를 반환하는 함수를 만들어보자.(난이도 中)

  3. 구조체(위와 동일)와 구조체 배열을 매개변수로 입력받아 저장하는 함수를 만들어보자.(난이도 中)

  4. 구조체(위와 동일)와 정수 배열을 매개변수로 입력받아 기존 구조체 원소에 배열의 정수 원소를 더해서 새로운 구조체 배열을 반환하는 함수를 만들어보자.(난이도 中)

🔜 더 공부해보기,

  1. 읽어볼 거리(1) - 운영체제에서 사용하는 구조체