工業製造
産業用モノのインターネット | 工業材料 | 機器のメンテナンスと修理 | 産業プログラミング |
home  MfgRobots >> 工業製造 >  >> Industrial Internet of Things >> 埋め込み

組み込みCを理解する:構造とは何ですか?

構造を紹介した後、この強力なデータオブジェクトの重要なアプリケーションのいくつかを見ていきます。次に、C言語の構文を調べて、構造を宣言します。最後に、データアライメントの要件を簡単に紹介します。メンバーの順序を並べ替えるだけで、構造のサイズを縮小できる可能性があることがわかります。

この記事では、組み込みCプログラミングの構造に関する基本的な情報を提供します。

構造を紹介した後、この強力なデータオブジェクトの重要なアプリケーションのいくつかを見ていきます。次に、C言語の構文を調べて、構造を宣言します。最後に、データアライメントの要件を簡単に紹介します。メンバーの順序を並べ替えるだけで、構造のサイズを縮小できる可能性があることがわかります。

構造

互いに論理的に関連している同じタイプの変数の数は、配列としてグループ化できます。独立変数のコレクションではなくグループで作業することで、データを整理してより便利に使用できます。たとえば、音声入力をデジタル化するADCの最後の50サンプルを格納するために、次の配列を定義できます。

  uint16_t voice [50];  

uint16_t 正確に16ビットの幅を持つ符号なし整数型です。これは、C標準ライブラリ stdint.h で定義されています。 、システム仕様に関係なく特定のビット長のデータ型を提供します。

配列を使用して、同じデータ型の多数の変数をグループ化できます。 異なるの変数間に接続がある場合はどうなりますか データ型?これらの変数をプログラムでグループとして扱うことはできますか?たとえば、 音声を生成するADCのサンプリングレートを指定する必要があるとします。 上記の配列。サンプルレートを格納するためにfloat変数を定義できます:

  float sample_rate;  

変数は 音声ですが および sample_rate は相互に関連しており、2つの独立変数として定義されています。これらの2つの変数を相互に関連付けるために、構造と呼ばれるC言語の強力なデータ構造を使用できます。構造により、さまざまなデータ型をグループ化し、それらを単一のデータオブジェクトとして処理できます。構造体には、他の構造体、関数へのポインター、構造体へのポインターなど、さまざまな種類の変数タイプを含めることができます。音声の例では、次の構造体を使用できます。

  struct record {uint16_t voice [50]; float sample_rate;};  

この場合、 record という構造があります。 2つの異なるメンバーまたはフィールドがあります。最初のメンバーは uint16_t の配列です。 要素であり、2番目のメンバーはfloat型の変数です。構文はキーワード struct で始まります 。 structキーワードの後の単語は、後で構造体を参照するために使用されるオプションの名前です。構造の定義と使用に関するその他の詳細については、この記事の残りの部分で説明します。

構造が重要な理由

上記の例は、構造の重要なアプリケーションを示しています。つまり、異なるタイプの個々の変数を相互に関連付けることができるアプリケーション依存のデータオブジェクトを定義しています。これにより、データを効率的に操作できるだけでなく、データ構造と呼ばれる特殊な構造を実装することもできます。

データ構造は、2つの組み込みシステム間のメッセージングや、センサーから収集したデータを連続していないメモリ位置に保存するなど、さまざまなアプリケーションに使用できます。

図1。 構造を使用して、リンクリストを実装できます。

さらに、構造体は、プログラムがメモリマップドマイクロコントローラペリフェラルのレジスタにアクセスする必要がある場合に役立つデータオブジェクトです。次の記事で構造アプリケーションについて見ていきます。

図2。 STM32MCUのメモリマップ。 ARMを備えた組み込みシステムの画像提供。

構造体の宣言

構造を使用するには、最初に構造テンプレートを指定する必要があります。以下のサンプルコードを検討してください:

  struct record {uint16_t voice [4]; float sample_rate;};  

これは、このタイプの将来の変数を作成するためのレイアウトまたはテンプレートを指定します。このテンプレートには、 uint16_t の配列が含まれています およびfloat型の変数。テンプレートの名前は record 、これはキーワード struct の後にあります 。構造テンプレートを格納するためのメモリ割り当てがないことは言及する価値があります。メモリ割り当ては、このレイアウトに基づく構造変数が定義された後にのみ発生します。次のコードは、変数 mic1 を宣言します。 上記のテンプレートの:

  struct record mic1;  

これで、メモリのセクションが変数 mic1 に割り当てられます。 。 4つの uint16_t を保存するスペースがあります 配列の要素と1つのfloat変数。

構造体のメンバーには、メンバー演算子(。)を使用してアクセスできます。たとえば、次のコードは、配列の最初の要素に100を割り当て、 sample_rate の値をコピーします。 fs 変数(float型である必要があります)。

  mic1.voice [0] =100; fs =mic1.sample_rate;  

構造を宣言する他の方法

前のセクションで構造を宣言する1つの方法を見ました。 C言語は、このセクションで確認する他のいくつかの形式をサポートしています。プログラム全体で1つの形式に固執する可能性がありますが、他の形式に精通していると役立つ場合があります。

構造体のテンプレートを宣言するための一般的な構文は次のとおりです。

  struct tag_name {type_1 member_1; type_2 member_2; …type_nmember_n;} variable_name;  

tag_name および variable_name オプションの識別子です。通常、これら2つの識別子の少なくとも1つが表示されますが、両方を削除できる場合もあります。

構文1: 両方の場合 tag_name および variable_name が存在する場合、テンプレートの直後に構造変数を定義しています。この構文を使用して、前の例を次のように書き直すことができます。

  struct record {uint16_t voice [4]; float sample_rate;} mic1;  

ここで、別の変数( mic2 )を定義する必要がある場合 )、書くことができます

  struct record mic2;  

構文2: variable_name のみ 含まれています。この構文を使用して、前のセクションの例を次のように書き直すことができます。

  struct {uint16_t voice [4]; float sample_rate;} mic1;  

この場合、テンプレートの直後にすべての変数を定義する必要があり、プログラムの後半で他の変数を定義することはできません(テンプレートには名前がなく、後で参照できないため)。

構文3: この場合、 tag_name はありません。 または variable_name 。このように定義された構造テンプレートは、匿名構造と呼ばれます。匿名構造体は、別の構造体または共用体内で定義できます。例を以下に示します:

  struct test {//匿名構造体struct {float f; char a; };} test_var;  

上記の匿名構造のメンバーにアクセスするには、メンバー演算子(。)を使用できます。次のコードは、1.2をメンバー f に割り当てます。

  test_var.f =1.2;  

構造は匿名であるため、メンバー演算子を1回だけ使用してそのメンバーにアクセスします。次の例のような名前の場合、メンバー演算子を2回使用する必要があります。

  struct test {struct {float f; char a; }ネストされた;} test_var;  

この場合、次のコードを使用して、1.2を f に割り当てる必要があります。

  test_var.nested.f =1.2;  

ご覧のとおり、匿名構造を使用すると、コードが読みやすくなり、冗長性が低くなります。 typedefキーワードを構造体と一緒に使用して、新しいデータ型を定義することもできます。この方法については、今後の記事で説明します。

構造体のメモリレイアウト

C標準は、構造体のメンバーが、構造体内で宣言された順序で次々にメモリ内に配置されることを保証します。最初のメンバーのメモリアドレスは、構造体自体のアドレスと同じになります。次の例を考えてみましょう:

  struct Test2 {uint8_t c; uint32_t d; uint8_t e; uint16_t f;} MyStruct;  

変数c、d、e、およびfを格納するために、4つのメモリ位置が割り当てられます。メモリの場所の順序は、メンバーを宣言する順序と一致します。cの場所のアドレスが最も低く、次にd、e、最後にfが表示されます。この構造を格納するために何バイトが必要ですか?変数のサイズを考慮すると、この構造を格納するには、少なくとも1 + 4 + 1 + 2 =8バイトが必要であることがわかります。ただし、このコードを32ビットマシン用にコンパイルすると、驚くべきことに、 MyStruct のサイズがわかります。 8バイトではなく12バイトです!これは、構造体のさまざまなメンバーにメモリを割り当てるときに、コンパイラに特定の制約があるためです。たとえば、32ビット整数は、アドレスが4で割り切れるメモリ位置にのみ格納できます。データアライメント要件と呼ばれるこのような制約は、プロセッサが変数に効率的にアクセスできるようにするために実装されています。データの整列により、メモリレイアウトにスペース(またはパディング)が無駄になります。このトピックはここでのみ紹介されています。このシリーズの次の記事で詳細を説明します。

図3。 データの配置により、メモリレイアウトにスペース(またはパディング)が無駄になります。

データアライメントの要件を認識していると、構造内のメンバーの順序を並べ替えて、メモリの使用効率を高めることができる場合があります。たとえば、上記の構造を次のように書き直すと、32ビットマシンではそのサイズが8バイトに減少します。

  struct Test2 {uint32_t d; uint16_t f; uint8_t c; uint8_t e;} MyStruct;  

メモリに制約のある組み込みシステムの場合、特にプログラムがこれらのデータオブジェクトの多くを必要とする場合、データオブジェクトのサイズを12バイトから8バイトに減らすことで大幅な節約になります。

次の記事では、データアライメントについて詳しく説明し、組み込みシステムで構造を使用するいくつかの例を検討します。

概要

私の記事の完全なリストを表示するには、このページにアクセスしてください。


埋め込み

  1. 高融点金属とは何ですか?
  2. 二つ折りヒンジとは何ですか?
  3. デッキネジとは何ですか?
  4. ばね式シールとは何ですか?
  5. 木ネジとは何ですか?
  6. 鋼合金とは何ですか?
  7. データをどうすればいいですか?!
  8. Java-データ構造
  9. IIoTとは何ですか?
  10. メンテナンスデータとは?
  11. 木工を理解する