自動車エンジニアのアップデート

自動車エンジニアのアップデート

自動車部品メーカー勤務ソフトエンジニアの情報発信ブログ

~ 車載 ソフト エンジニア の 情報発信 ブログ ~

<C言語入門/車載ソフト> 構造体

f:id:Vefortec:20200504201222j:plain

こんにちは、レオハルです。

車載ソフトで利用するC言語入門シリーズ「構造体」です。

※通常のC言語解説とは、異なり組込み・車載ソフトに特化した記載があります。ご注意ください。

構造体とは

構造体とは、種類の違う型のデータを複数集め、まとめてメモリに配置できるオブジェクトです。配列でも同様に複数のデータを扱うことができましたが、配列の場合は、同じ型のデータしか取り扱えません。構造体のメリットは、違う型もまとめて取り扱えることにあります。

構造体の定義方法

型の定義

構造体を利用する場合、まず構造体として取り扱う型の定義を行います。また、構造体で扱うデータのことをメンバと呼びます。構造体を定義する際には、取り扱うメンバの定義も同時に行います。

基本の定義方法は、次のようになります。struct を利用します。

struct 構造体型(タグ)名{
  型 メンバ1;
  型 メンバ2;
        :
};

ここで記述している構造体型のことをタグと呼びます。

構造体の実体定義

上記では、型を定義しただけですので、実体となる構造体変数を定義する必要があり、次のように記述します。

struct タグ名 変数名 ;
typedefを利用した定義方法

既存型名に対して別の型名を付けることができるtypedefを利用した方法がよく利用されます。先ほどの定義方法では、変数実体を定義する際に、structを付ける必要がありましたが、typedefを利用して構造体に別名を付けることで省略することができます。

typedef struct タグ名{
  型 メンバ1;
  型 メンバ2;
        :
}構造体別型名;

構造体別型名 変数名 ; 

また、typedefを使う場合、タグ名の部分は省略することができます。これは、"struct{ 型 メンバ名}”に対して別名の型を定義している形になります。

typedef struct {
  型 メンバ1;
  型 メンバ2;
        :
}構造体別型名;  

構造体別型名 変数名 ; 

また、タグ名を省略して構造体を定義した上記の例の場合、次の定義は出来ません。

struct タグ名 変数名 ; /* コンパイルエラー */
struct 構造体別型名 変数名 ; /* コンパイルエラー */

具体的使用例

次に定義した構造体を例をもとに使い方を見ていきます。

typedef struct {
  s2 s2_gx ;     /* 前後G */
  s2 s2_gy ;     /* 横G */
  s2 s2_yaw ;    /* ヨー */
  u2 u2_ig;      /* IG電圧 */
  u2 u2_pb;      /* バッテリ電圧 */
  u4 u4_mil ;    /* 走行距離 */
  u2 u2_eng ;    /* エンジン回転数 */
  u1 u1_spd ;    /* 車速 */
  s2 s2_str;     /* 舵角 */
}VehicleInfo;
構造体の初期値設定

構造体の変数宣言と同時に、各メンバの初期値を設定することができます。

/* 初期値設定 */
const VehicleInfo str_VcleDefaultData = { 0, 0, 0, 12, 12, 0, 0, 0, 0 };
構造体の配列

構造体も普通の変数と同様に配列で定義することが可能です。

Vehicleinfo str_VcleANow;        /* 現在値 */
Vehicleinfo str_VcleAData[9];    /* 保存データ */
構造体の参照・代入

同じ型の構造体同士であれば、代入処理により、すべての変数を一度に代入することができます。

void init( void ) {
  u1 u1a_cnt ; 

  str_VcleANow = str_VcleDefaultData ;

  for( u1a_cnt = 0 ;u1a_cnt < 10 ; u1a_cnt ++){
    str_VcleAData[u1a_cnt ] = str_VcleDefaultData ;
  }
}
構造体メンバの参照・代入

構造体の中に定義されている各メンバを直接参照したり、代入したりすることが可能です。メンバを指定する場合には、構造体名の後に".(ピリオド)"を付けてメンバ名を続けることで指定できます。

void vog_VcleInfoGet( VehicleInfo * str_input ); /* 車両情報取得処理 */

void main( void ) {
  u1 u1a_cnt ;

  vog_VcleInfoGet(&str_VcleANow );

  for( u1a_cnt = 0 ;u1a_cnt < 10 ; u1a_cnt ++){
    if( 0 == u1a_cnt  ){
        str_VcleAData[u1_cnt].u1_spd = str_VcleANow.u1_spd 
    }
    else{
       str_VcleAData[u1_cnt].u1_spd = str_VcleAData[u1_cnt].u1_spd[ u1_cnt - 1] ;
    }
  }
}
構造体の中の構造体

構造体の中に構造体の型を持つメンバを作ることも可能です。

struct sensor{
  s2 s2_gx ;     /* 前後G */
  s2 s2_gy ;     /* 横G */
  s2 s2_yaw ;    /* ヨー */
};

struct volt{
  u2 u2_ig;      /* IG電圧 */
  u2 u2_pb;      /* バッテリ電圧 */
};

typedef struct {
  struct SENSOR str_sensor : /* センサ値 */
  struct VOLT str_volt; /* 入力電圧 */
  u4 u4_mil ;    /* 走行距離 */
  u2 u2_eng ;    /* エンジン回転数 */
  u1 u1_spd ;    /* 車速 */
  s2 s2_str;     /* 舵角 */
}VehicleInfo;

このように構造体をある意味のある集合体として定義、管理することで、データが使いやすくなったり、可読性を向上させたりすることができます。
ただ、変数を羅列するのではなく、構造を考え、どんなデータをどう持たせるのか考えて、構造体をうまく使っていきたいですね

 

C言語学習におススメの書籍

C言語/プログラミング初心者の方】

スッキリわかるC言語入門

スッキリわかるC言語入門

  • 作者:中山 清喬
  • 発売日: 2018/06/22
  • メディア: 単行本(ソフトカバー)
 

【入門卒業レベルの方】

苦しんで覚えるC言語

苦しんで覚えるC言語

  • 作者:MMGames
  • 発売日: 2011/06/24
  • メディア: 単行本
 
新・明解C言語 入門編 (明解シリーズ)

新・明解C言語 入門編 (明解シリーズ)

  • 作者:柴田 望洋
  • 発売日: 2014/08/09
  • メディア: 単行本
 
独習C 第4版

独習C 第4版

 

 【組込み向け】

組込みエンジニアの教科書

組込みエンジニアの教科書