C言語基礎知識43(構造体を複数ファイルで構造体内のポインタを使用) - Project_OKI’s diary

Project_OKI’s diary

エンジニアの勉強ブログ

C言語基礎知識43(構造体を複数ファイルで構造体内のポインタを使用)

 

1.目的

  • 構造体を作成し、構造体内でポインタを使用して宣言した場合の振る舞いについて確認する。
  • 複数ファイルで使用する場合の使い方について確認する。

 

目次

 

 構造体の関連記事:

 ・C言語基礎知識7(構造体1) - Project_OKI’s diary

 ・C言語基礎知識17(構造体とポインタとアロー演算子の使い方) - Project_OKI’s diary

 ・C言語基礎知識26(構造体の配列) - Project_OKI’s diary

 ・C言語基礎知識27(構造体を複数の別ファイルで使用する) - Project_OKI’s diary

 ・C言語基礎知識28(構造体の中で構造体を宣言する) - Project_OKI’s diary

 ・C言語基礎知識39(構造体、typedefを使う際の注意点) - Project_OKI’s diary

 ※基本的な使い方は構造体と同じ為、他の使い方については構造体の記事を参照

 

2.構造体を使った配列の使い方

基本的な書き方:
typedef stract{
     構造体メンバ;
}構造体タグ名;

typedef stract{
構造体タグ名(型) *ポインタ名
}構造体タグ名;

 

3.プログラムの作成(構造体とポインタを複数ファイルで使用する)

//main.cファイル
#include <stdio.h>
#include "main.h"
#include "set.h"

//構造体宣言
TTest gtest;

// プロトタイプ宣言
void Init();

int main(void) {
    Init();
    printf("gtest.mode=%d\n",gtest.mode);
    printf("gtest.state=%d\n",gtest.state);
    printf("gtest.setf=%d\n",gtest.setf);
    
    Set();
    printf("gset.num=%d\n",gset.setnum);
    printf("gtest.mode=%d\n",gtest.mode);
    Set2();
    printf("gtest.mode=%d\n",gtest.mode);

    return 0;
}

//TTest構造体初期化
void Init(){
    gtest.mode = MODE1;
    gtest.state = STATE1;
    gtest.setf = false;
}

 

//main.hファイル
//多重インクルード防止
#ifndef MAINH
#define MAINH

typedef enum {
    MODE1,
    MODE2,
    MODE3,
    MODE4
}MODE;

typedef enum{
    STATE1,
    STATE2,
    STATE3,
    STATE4
}STATE;

typedef enum{
    false,
    true
}BOOL;

// TTest構造体の作成
typedef struct {
    MODE mode;
    STATE state;
    int setf;
} TTest;

extern TTest gtest;

#endif

 

//set.cファイル
#include <stdio.h>
#include "main.h"
#include "set.h"

TSet gset;

//gset構造体のTTest構造体を使用
void Set(){
    printf("Set関数実行\n");
    //アドレスの設定をしないとセグメンテーション違反になる。
    gset.ptest = &gtest;            //gtestのアドレスを設定
    gset.setnum = 10;
    gset.ptest->mode= MODE2;
    gset.ptest->state= STATE2;      
//    gtest.mode = MODE4;           //これでも可
}

//Set関数の構造体で入れた方法の短縮版
void Set2(){
    printf("Set2関数実行\n");
    gset.ptest = &gtest;            //gtestのアドレスを設定
    TTest *ptest = gset.ptest;      //ptestにgset.ptestを設定
    ptest->mode = MODE3;
    ptest->state = STATE3;
}

 

//set.hファイル
//多重インクルード防止
#ifndef SETH
#define SETH

// 設定用構造体
typedef struct {
    int setnum;
    TTest *ptest;
} TSet;

extern TSet gset;       //TSet構造体のグローバル宣言

extern void Set();
extern void Set2();

#endif

結果:https://paiza.io/projects/6GQfesLsKej2ww9K65cWCA?language=c

 

4.プログラムの説明

 ・構造体の中で、ポインタを使用した場合、複数の構造体で1つの値を共有することが可能。

 ・set.hファイルのTSet構造体にてTTest構造体のポインタを指定している。

 ・Set関数では、TSet構造体のptestポインタをgset.ptest = &gtest;で読みだしている。

 ・gset.ptest->mode= MODE2;でTTest構造体のメンバ(modeやstate)にアクセスが可能。

 

 ・Set2関数も、基本的な動きは同じ。

 ・TTest *ptest = gset.ptest;を使用することにより、ptest -> メンバ で、TTest構造体のメンバにアクセスが可能。

 

関連記事

過去の記事:

知らないと損するお金の話(ふるさと納税、確定申告とワンストップ納税どっちが得?) - Project_OKI’s diary

C言語基礎知識6(関数) - Project_OKI’s diary

C言語基礎知識7(構造体1) - Project_OKI’s diary

C言語基礎知識8(enum:列挙型) - Project_OKI’s diary

C言語基礎知識9(typedef) - Project_OKI’s diary

C言語基礎知識10(extern宣言) - Project_OKI’s diary

C言語基礎知識11(#define) - Project_OKI’s diary

 

組み込みC言語