masa_beginner
@masa_beginner

Are you sure you want to delete the question?

Leaving a resolved question undeleted may help others!

構造体変数宣言とヒープについて(苦しんで覚えるC言語)

解決したいこと

私は現在苦しんで覚えるC言語というサイトで学習を理解できない箇所がありますのでご教示くださいませ。
下記URLの3問目です。
https://9cguide.appspot.com/19-q.html

下記コードのint main(void)のすぐ下にある、
People *data;
は何を表しているのでしょうか?
(ヒープのように使われていますが、、、)

①構造体を実体化するために構造体変数宣言であるPeople data;
がなぜ記述されていないのでしょうか?

②動的配列を格納するためのヒープを int *heap;
などの記述もされてい内容ですが、構造体型のヒープなども存在するのでしょうか?

該当するソースコード

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

typedef struct {
    char name[256];
    int age;
    int sex;
} People;

void InputPeople(People *data);
void ShowPeople(People data);

int main(void){
    int i,count,datasize;
    //ココ
    People *data;
    //ココ
    datasize = 10;
    data = (People*)malloc(sizeof(People) * datasize);

    count = 0;

    while (1) {
        InputPeople(&data[count]);
        if (data[count].age == -1) break;
        count++;

        if (count >= datasize) {
            datasize += 10;
            data = (People*)realloc(data,sizeof(People) * datasize);
        }
    }

    for (i = 0;i < count;i++) {
        ShowPeople(data[i]);
    }

    free(data);

    return 0;
}

void InputPeople(People *data){
    printf("名前:");
    scanf("%s",data->name);
    printf("年齢:");
    scanf("%d",&data->age);
    printf("性別(1-男性、2-女性):");
    scanf("%d",&data->sex);
    printf("\n");
}

void ShowPeople(People data){
    char sex[16];

    printf("名前:%s\n",data.name);
    printf("年齢:%d\n",data.age);

if (data.sex == 1) {
    strcpy(sex,"男性");
} else {
    strcpy(sex,"女性");
}

    printf("性別:%s\n",sex);
    printf("\n");
}

自分で試したこと

このコードできちんと動作することは確認済みです。

0

1Answer

まず大前提として、「型」というのはメモリー空間をどのように扱うかを示すものであるということです。「構造体型」も型である以上同じです。

int a;

これは自動変数領域にメモリーを確保してint型として扱うことを意味しました。

C99
#include <stdlib.h>

int* p = malloc(sizeof(int));

これはmallocが確保したint型と同じ大きさのメモリー領域をint型の領域として扱うこととし、その領域へのポインタをpに格納することを意味したわけです。

構造体が出てきても同じです。

typedef struct {
   int a;
} foo_t;
foo_t foo;

これは自動変数領域にメモリーを確保してfoo_t型として扱うことを意味します

C99
#include <stdlib.h>
typedef struct {
   int a;
} foo_t;

foo_t* p = malloc(sizeof(foo_t));

これはmallocが確保したfoo_t型と同じ大きさのメモリー領域をfoo_t型の領域として扱うこととし、その領域へのポインタをpに格納することを意味します


①構造体を実体化するために構造体変数宣言であるPeople data;
がなぜ記述されていないのでしょうか?

実体化というのはおそらくメモリー領域が確保され操作できる状態を指すのだと思いますが、その方法は多様であり、自動変数領域に確保するお示しの記法のみではない、が回答となります。

②動的配列を格納するためのヒープを int *heap;
などの記述もされてい内容ですが、構造体型のヒープなども存在するのでしょうか?

同様にして、すくなくともCにおいて、型が何であるかと、どこにその実体があるかはあまり関係がありません。

0Like

Comments

  1. @masa_beginner

    Questioner

    回答いただきありがとうございます!
    People *data; で構造体型を指すポインタ変数dataを宣言しているということなのですね!

    ①の回答について質問なのですが、
    メモリ領域が確保され操作できる状態にするための方法は多様であるとのことですが、
    質問のコードの場合は、

    People *dataが下記2つの役割を同時にこなしていると考えていいのでしょうか?
    ・構造体型を指すポインタ変数dataの宣言
    ・構造体型の変数dataの宣言

    僕の認識としては
    ・構造体型を指すポインタ変数dataの宣言(あくまでも構造体型のアドレスを格納するためのポインタ変数)
    としての役割しかなく、下記のように格納するものを別に作らないといけないのかなと思っていたのですが、
    People data;
    People data_p;
    datasize =10;
    data_p = (People)malloc(sizeof(People) * datasize);

    People *data;が
    People data; とPeople *data_p;の2つの役割を担っていると考えて問題ないでしょうか?

    可能であれば回答お願い致しますm(_ _)m
  2. > People *data; で構造体型を指すポインタ変数dataを宣言しているということなのですね!

    細かいようですが大事なことなので言いますが、ポインタは型を指しません、任意のデータ領域を指し示します。ポインタの型は元となる型から派生してつくられます。データがどうであるかとその型がどうであるかは明確に分離して考えてください。

    >People *dataが下記2つの役割を同時にこなしていると考えていいのでしょうか?
    ・構造体型を指すポインタ変数dataの宣言
    ・構造体型の変数dataの宣言

    いいえ

    mallocが確保したPeople型と同じ大きさのメモリー領域がdatasize個並んだメモリー領域ををPeople型の配列領域として扱うこととし、その領域へのポインタをdataに格納することを意味します

    >構造体型を指すポインタ変数dataの宣言(あくまでも構造体型のアドレスを格納するためのポインタ変数)
    としての役割しかなく、下記のように格納するものを別に作らないといけないのかなと思っていたのですが

    ここはあってます。しかし「格納するもの」の認識が誤っています。

    mallocが確保したPeople型と同じ大きさのメモリー領域は立派な「格納するもの」です。

    格納するものをを作る、言い換えるとメモリ領域が確保され操作できる状態にするための方法は複数あると書きましたが

    ```c
    People data;
    malloc(sizeof(People));
    ```

    これはその一例にすぎません。
  3. @masa_beginner

    Questioner

    回答頂きありがとうございます!
    まだ自分の知識不足で理解が追いついていない部分もありますが、なんとなく理解ができました!

Your answer might help someone💌