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

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

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

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

<C言語入門/車載ソフト> ポインタ

f:id:Vefortec:20200504201222j:plain

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

車載ソフトで利用するC言語入門シリーズ「ポインタ」です。

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

ポインタとは

C言語を学んでいく中で難しいと言われるポインタです。
ポインタとは、"アドレスを入れる変数"と解釈できます。 

f:id:Vefortec:20200606103609p:plain

上記のようにアドレス100Aにu2g_dataAという変数が割り当てられ、1002というデータが入っている状態をイメージしてください。
ポインタを利用すると、100Aというアドレスを参照したり、100Aのアドレスに入っている1002というデータにアクセスすることができるようになります。

 

ポインタの定義方法

定義

ポインタの定義方法は、次のようになります。
変数の前に「* (アスタリスク)」をつけることで、ポインタとして扱う定義になります。

型 *変数名;

上記では、「*変数名」になっていますが、「型*」のように型側に*をつけることも可能ですが、変数を1行に複数定義する場合には、2個目以降の変数は、ポインタ変数とならないので注意が必要です。
組織でプログラミングする場合であれば、ルールが決まっていることが多いと思いますので、確認するようにしましょう。

アドレスの代入

ポインタ変数に別の変数のアドレスを代入する場合は、次のようになります。
通常の変数に「&(アンパサンド)」を付けることで、その変数のアドレスを取得することができます。

ポインタ変数 = &変数;

アドレス先の値の参照

ポインタ変数に設定されたアドレス先に入っている値を参照したい場合、次のようになります。ポインタ変数の前に「*」を付けることで参照できます。

変数 = *ポインタ変数;

 

具体的使用例

u2 u2g_dataA ;
u2 u2g_dataB ;

void init(void){
  u2g_dataA = 0x1002 ;
  u2g_dataB = 0x1000 ;
}

void main( void ){
  u2 *u2a_ptr ;
  u2 u2a_result1 ;
  u2 u2a_result2 ;
  u2 u2a_result3 ;
  u2 u2a_result4 ;
 
  u2a_ptr  = &u2g_dataA ;
  
  u2a_result1 = u2a_ptr ;
  u2a_result2 = *u2a_ptr ;

  u2a_ptr ++ ;

  u2a_result3 = u2a_ptr ;
  u2a_result4 = *u2a_ptr ;
}

ポインタ変数 u2a_ptr の使い方を見ていきます。
まず、u2g_dataAのアドレスを設定し、u2a_result1、u2a_result2に代入しています。
このときの代入結果は、次のようになります。
  u2a_result1には、「*」なし : 0x100A  ⇒  u2g_dataAのアドレス
  u2a_result2には、「*」あり : 0x1002 ⇒ u2g_dataAの値
「*」の有り無しで、参照される値が異なります。

次にu2a_ptrをインクリメントしている箇所があります。
ポインタ変数をインクリメントした場合、u2a_ptrに設定されているアドレスの値がインクリメントされます。そのため、u2a_result3、u2a_result4には、u2g_dataBのアドレスと値が設定されます。
ポインタ変数をインクリメントするなどして、連続したアドレスのデータへアクセスする手段はよく利用されます。

構造体・共用体のポインタ

通常の変数と同様に、構造体・共用体のポインタを定義することも可能です。

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

構造体のポインタを利用して、メンバへアクセスする場合、通常の構造体とはアクセス方法が異なります。構造体ポインタのメンバアクセスは、「-> (アロー演算子)」を使ってアクセスします。

pstr_Reference->s2_gx
pstr_Reference->s2_gy
pstr_Reference->s2_yaw

関数ポインタ

ポインタは、変数だけでなく、関数に対しても適用することができます。
関数ポインタの宣言は、次のようになります。

 (*関数名)(引数);

 

関数ポインタを利用することで、動的に実行する関数を変えることが可能になります。
通常関数の呼び出しは、コンパイル時に固定されますが、関数ポインタを利用すれば、入力された値に応じて、呼び出す関数を変えることができるのです。

次に関数ポインタを利用したソース例を記載しておきます。

void vog_funcA;
void vog_funcB;
void vog_funcC;

void vog_funcSelect( u1 u1_input ){
  void (*ptr_func[])() = { vog_funcA,  vog_funcB, vog_funcC } ;

  (*ptf_func[ u1_input ] )( ) ;

}

 

 

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

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

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

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

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

【入門卒業レベルの方】

苦しんで覚えるC言語

苦しんで覚えるC言語

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

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

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

独習C 第4版

 

 【組込み向け】

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

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