강의

멘토링

커뮤니티

Cộng đồng Hỏi & Đáp của Inflearn

Hình ảnh hồ sơ của maritime233292
maritime233292

câu hỏi đã được viết

(2026) Đỗ kỳ thi Kỹ sư Xử lý Thông tin phần thực hành chỉ trong một tuần

Cấu trúc

아 진짜 구조체 이해 안되는데요

Đã giải quyết

Viết

·

48

0

아니 구조체 포인터는 뭐고 구조체 포인터 사용하여 함수호출은 뭐고.. 하.. 너무 쉽게쉽게 넘어가시는거같아요 저는 빡대가리인데.

pythonjavac정보처리기사

Câu trả lời 3

0

maritime23님의 프로필 이미지
maritime23
Người đặt câu hỏi

AI보다 정확하고 쉬운 설명 감사합니다. 이해가 너무 잘되었습니다.

weekendcode님의 프로필 이미지
weekendcode
Người chia sẻ kiến thức

앞으로도 계속 어려울 수 있습니다.

많은 질문 부탁드립니다.

0

weekendcode님의 프로필 이미지
weekendcode
Người chia sẻ kiến thức

안녕하세요, 많이 어려우시죠.

아예 코드를 처음 배우시는 분들이라면 C언어 자체가 어려울 수 있습니다.

컴퓨터공학과 1학년 때 C언어를 6개월 간 배웠던 저도 그랬고요.

옆에서 붙어서 과외처럼 가르쳐주지 않는 한, 원래 어려운 것이 맞습니다.

 

우선 문법은 둘째치고,

개념 자체가 어려우신 것 같습니다.

첫번째는 포인터 개념이고 두번째는 "함수를 호출한다"라는 개념입니다.

8:14에 나온 코드 기준으로 좀 더 구체적으로 설명해볼게요.

#include <stdio.h>

#include <string.h>

// 구조체 정의

struct Bag {

  char brand[50]; // 브랜드명을 저장할 문자열 배열
  int year; // 제작 연도를 저장할 정수형 변수
  float price; // 가격을 저장할 실수형 변수

};

// 구조체 포인터를 인수로 받아서 출력하는 함수 정의

void printBag(struct Bag * bag) {
  printf("Brand: %s\n", bag -> brand);
  printf("Year: %d\n", bag -> year);
  printf("Price: %.2f\n", bag -> price);
}

int main() {

  struct Bag myBag; // 구조체 변수 선언
  struct Bag * bagPtr = & myBag;
  // 구조체 포인터 선언 및 초기화

  // 포인터를 통해 값 할당
  strcpy(bagPtr -> brand, "Gucci");
  bagPtr -> year = 2021;
  bagPtr -> price = 1500.50;
  printBag(bagPtr);

  // 구조체 포인터를 사용하여 함수 호출
  return 0;

}
weekendcode님의 프로필 이미지
weekendcode
Người chia sẻ kiến thức

포인터 — 상자의 "주소"를 적어둔 메모지

포인터가 어려운 이유는, 값 자체가 아니라 "값이 있는 위치(주소)" 를 다루기 때문입니다.

비유해볼게요.

친구가 "내 가방 어디있어?" 라고 물었을 때,

가방을 직접 들고 와서 주는 것 → 변수 (값 자체) "거실 테이블 위에 있어"라고 위치를 알려주는 것포인터 (주소)

코드로 보면:

int year = 2021;        // 상자에 값을 넣음
int *ptr = &year;       // ptr이라는 메모지에 year의 주소를 적어둠

여기서 기호 두 개만 기억하세요.

&year -> year의 주소를 가르쳐달라는 뜻
*ptr -> ptr이 가리키는 곳의 값을 꺼내라는 뜻

정리: 포인터는 그냥 "다른 변수의 주소를 저장하는 변수"입니다. 그게 전부예요.

weekendcode님의 프로필 이미지
weekendcode
Người chia sẻ kiến thức

구조체 — 여러 상자를 하나로 묶은 가방

변수 하나에는 값 하나만 넣을 수 있잖아요?

그런데 현실에서는 하나의 물건에 여러 정보가 있죠.

 

예를 들어 가방 하나에 대해:

  • 브랜드명 (글자)

  • 제작연도 (숫자)

  • 가격 (소수점 숫자)

이걸 따로따로 만들면 너무 번거롭습니다.

(이게 Java로 가면 Class라는 개념으로 확장됩니다. 여러 데이터를 하나로 묶는다는 점에서 둘 다 비슷한 개념입니다.)

// 이렇게 하면 변수가 너무 많아져요...

char brand[50] = "Gucci";
int year = 2021;
float price = 1500.50;

그래서 하나로 묶은 게 구조체인 것입니다.

struct Bag {
    char brand[50];   // 브랜드명
    int year;         // 제작연도
    float price;      // 가격
};

 

이렇게 하면 앞으로 저 Bag라는 것 자체를 단위로 쓸 수 있습니다.

근데 아직 우리는 Bag라는 개념만 정립한 것이고 실제 변수로 쓰려면 앞에 struct라는 키워드를 붙여서 main 함수에서 써야합니다.

 

struct Bag myBag;   // 설계도(Bag)를 바탕으로 실제 가방(myBag)을 하나 만듦

그림으로 보면:
myBag (구조체 변수 = 큰 상자)
┌─────────────────────────────┐
│  brand: "아직 비어있음"      │
│  year:  아직 비어있음        │
│  price: 아직 비어있음        │
└─────────────────────────────┘

 

저 변수에다가 변수를 넣은 것이 아래처럼 한 것입니다.

strcpy(myBag.brand, "Gucci");  // 문자열은 strcpy로 복사
myBag.year = 2021;
myBag.price = 1500.50;
weekendcode님의 프로필 이미지
weekendcode
Người chia sẻ kiến thức

자, 이제 maritime님이 질문하신 구조체 포인터를 설명하겠습니다.

앞에서 배운 포인터를 그냥 구조체에 적용한 거에요. 그렇게 받아들이시면 됩니다. 더 어려운 것 없습니다. 진짜 그게 끝입니다.

struct Bag myBag;              // 실제 가방
struct Bag *bagPtr = &myBag;   // 가방의 주소를 적어둔 메모지
```

그림:
```
bagPtr (메모지)              myBag (실제 가방)
┌──────────┐                ┌─────────────────────┐
│ 0x2000   │ ─────────────→ │  brand: ""          │
└──────────┘                │  year:  0           │
 "myBag의 주소를             │  price: 0.0         │
  들고 있음"                 └─────────────────────┘

 

여기서의 차이가 있다면,

구조체를 직접 쓸 때는 .(점)으로 접근하고 포인터로 접근할 때는 -> 화살표를 씁니다.

// 직접 접근 (점 사용)
myBag.year = 2021;

// 포인터로 접근 (화살표 사용)
bagPtr->year = 2021;

 

이렇게 하면 저 포인터라는 녀석을 파라미터로 해서 함수를 만들 수 있습니다.

그게 void printBag(struct Bag * bag) 이 부분의 함수입니다.

void printBag(struct Bag *bag) {
    printf("Brand: %s\n", bag->brand);
    printf("Year: %d\n", bag->year);
    printf("Price: %.2f\n", bag->price);
}
```

이건 "구조체 포인터를 받아서, 그 안의 내용을 출력해주는 일꾼"입니다.

하나씩 뜯어볼게요:
```
void printBag(struct Bag *bag)
 │      │           │
 │      │           └─ "나한테 Bag의 주소를 알려줘, bag이라고 부를게"
 │      └─ 함수 이름
 └─ 돌려줄 값 없음 (그냥 출력만 할 거야)

 

 

weekendcode님의 프로필 이미지
weekendcode
Người chia sẻ kiến thức

자 이제 전체 흐름을 main 함수에서부터 읽어봅시다.

이제 전체 코드의 실행 순서를 따라가봅시다.

 

① 프로그램 시작

컴퓨터는 항상 main부터 실행합니다.

int main() { 부분에 가서 어떤 변수가 어떻게 만들어지는 지 보기

 

② 빈 가방을 하나 만들기

struct Bag myBag;

myBag (아직 비어있는 구조체)
┌──────────────────────────┐
│  brand : ???             │
│  year  : ???             │
│  price : ???             │
└──────────────────────────┘

 

③ 가방의 주소를 메모지(bagPtr)에 적어둠

struct Bag *bagPtr = &myBag;


bagPtr (메모지)            myBag (실제 가방)
┌────────────┐            ┌──────────────────────────┐
│  0x2000    │ ─────────→ │  brand : ???             │
└────────────┘            │  year  : ???             │
                          │  price : ???             │
                          └──────────────────────────┘

 

④ 포인터를 통해 가방에 값을 채워넣음

strcpy(bagPtr->brand, "Gucci");

bagPtr->year = 2021;

bagPtr->price = 1500.50;

bagPtr->brand은 "bagPtr이 가리키는 곳의 brand"이니까,

결국 myBag의 brand에 "Gucci"를 넣는 것입니다.

 

(메모리 주소는 임의로 쓴 것이니까 무시하세요.)


bagPtr (메모지)            myBag (값이 채워진 가방)
┌────────────┐            ┌──────────────────────────┐
│  0x2000    │ ─────────→ │  brand : "Gucci"         │
└────────────┘            │  year  : 2021            │
                          │  price : 1500.50         │
                          └──────────────────────────┘

 

⑤ printBag 함수를 호출

printBag(bagPtr); 이 한 줄이 실행되는 순간 일어나는 일:


main 함수
    │
    │  "야 printBag아, 가방 주소(bagPtr) 줄게. 출력 좀 해줘"
    │
    │  bagPtr (주소값 0x2000) 을 넘겨줌
    │
    ▼
printBag 함수가 받아서 실행
    │
    │  받은 주소를 bag 이라는 이름으로 사용
    │
    │  bag->brand  →  주소 따라가서 brand 읽음  →  "Gucci"
    │  bag->year   →  주소 따라가서 year 읽음   →  2021
    │  bag->price  →  주소 따라가서 price 읽음  →  1500.50
    │
    ▼
화면에 출력

 

⑥ 최종 출력결과

Brand: Gucci
Year: 2021
Price: 1500.50

 

⑦ 프로그램 종료

    return 0;
}

return 0은 "프로그램이 정상적으로 끝났어"라는 뜻입니다.

0

안녕하세요, 인프런 AI 인턴입니다. maritime23님.

구조체와 관련된 개념들이 처음에는 다소 복잡할 수 있습니다. 구조체 포인터와 이를 통한 함수 호출에 대해 간단히 설명드리고, 관련된 유용한 링크를 제공해 드리겠습니다.

구조체 포인터란?

  • 구조체 포인터는 구조체 자체가 아닌, 구조체가 저장된 메모리의 주소를 가리키는 포인터입니다. 즉, 구조체의 값이 아닌, 그 위치를 참조할 때 사용되는 도구입니다.
  struct Person {
      int age;
      float salary;
  };

위와 같은 구조체가 있으면, 구조체 포인터는 다음과 같이 선언할 수 있습니다:

  struct Person person1;
  struct Person* ptr = &person1;

여기서 ptrperson1의 메모리 주소를 가리킵니다.

구조체 포인터를 사용하여 함수 호출

  • 구조체 포인터를 함수에 전달하면, 함수가 구조체 자체가 아닌, 메모리 주소를 참조하게 됩니다. 이는 대용량 데이터를 다룰 때 복사 시간과 메모리를 절약하게 해줍니다.
  void updatePerson(struct Person* p) {
      p->age = 30;
  }

함수가 구조체 포인터를 매개변수로 받아들일 때는 접근 연산자로 ‘->‘를 사용하여 구조체 멤버에 접근합니다.

관련 내용을 더 살펴보시려면 다음 링크를 참고해 보세요:

  • C언어 구조체 관련 질문: 구조체 포인터와 사용 방법에 관한 설명이 담겨 있습니다.
  • 구조체 접근?: 구조체와 포인터를 활용하는 방법에 대한 다른 질문과 설명이 제공되어 있습니다.

이해에 어려움을 겪고 계신 점 충분히 이해합니다. 해당 링크에서 다양한 예제와 설명을 통해 개념을 더욱 쉽게 이해하실 수 있을 것입니다.

저는 질문자님의 이해를 돕고자 지식공유자님의 기존 답변을 참고하여 유사한 답변 링크를 추천해드리고 있습니다.
현재 베타 기능으로 답변이 만족스럽지 않을 수 있는 점 양해 부탁드립니다. 🙏
추가적으로 궁금한 점이 있으시면, 이어서 질문해 주세요. 곧 지식공유자께서 답변해 주실 것입니다.

Hình ảnh hồ sơ của maritime233292
maritime233292

câu hỏi đã được viết

Đặt câu hỏi