• ベストアンサー

構造体の宣言について

今解析しているC言語のプログラムで以下の様な構造体の宣言があります。 typedef struct { unsigned char :3; unsigned char aaa :1; unsigned char bbb :1; unsigned char ccc :1; unsigned char ddd :1; unsigned char eee :1; } tTSR ; :3や:1の部分の意味がわかりません。 御存知の方ご回答よろしくお願いします。

質問者が選んだベストアンサー

  • ベストアンサー
  • Oh-Orange
  • ベストアンサー率63% (854/1345)
回答No.4

★『ビットフィールド』と呼びます。 ・意味は回答者 No.1 さんを参考にして下さい。 ・あと解析しているC言語のプログラムはちょっとだけ問題があります。  問題とは『ビットフィールド』は unsigned int 型のみしか正式にはサポート  していません。『unsigned char』型や『unsigned long』型はコンパイラ  さんが自動的に『unsigned int』型に変換しているため動くと思われます。 ・よって正しくは『unsigned int』型に記述しなおしましょう。  特に自分でプログラミングをする場合は注意して下さい。 最後に: ・質問内容としては次のようになります。  (1)識別名がない無効なビット(3ビット)  (2)識別名が『aaa』のフラグ(1ビット)  (3)識別名が『bbb』のフラグ(1ビット)  (4)識別名が『ccc』のフラグ(1ビット)  (5)識別名が『ddd』のフラグ(1ビット)  (6)識別名が『eee』のフラグ(1ビット) ・構造体の意味は何かのフラグ情報(aaa~eee)でしょうね。  識別名がないと単に未使用なビットとして宣言されます。 ・さらに『:0』とすると次の『unsigned int』型にビットを割り当てる事になります。 ・構造体『tTSR』は『3+1+1+1+1+1』=8ビットのフラグ情報を管理している構造体です。 ・以上。おわり。

参考URL:
http://www.doumo.jp/postgretips/tips.jsp?tips=28
HERLOCK777
質問者

お礼

この様な使い方がある事を知りませんでした。 御回答頂きありがとうございました。

その他の回答 (3)

  • Interest
  • ベストアンサー率31% (207/659)
回答No.3

ビットフィールド(bit field)で検索してみてください。 ビットフィールドを使うと、構造体や共用体のメンバに対してビット幅を指定することが出来ます。メモリ割付にはちょっとだけ注意が必要です。<コンパイラによって構造体メンバの埋め方が違うことがあるので > typedef struct { > unsigned char :3; > unsigned char aaa :1; これは、 構造体の先頭から 3bit は使用しない。 4bit目に aaa を充てる。 という意味です。 ビットの指定が悪いとメモリ上に隙間が空いてしまうこともあります。

HERLOCK777
質問者

お礼

御回答頂きありがとうございました

  • jacta
  • ベストアンサー率26% (845/3158)
回答No.2
HERLOCK777
質問者

お礼

御回答頂きありがとうございました。

noname#26650
noname#26650
回答No.1

> :3や:1の部分の意味がわかりません。 ビット長を表わします。

HERLOCK777
質問者

お礼

御回答頂きありがとうございました。

関連するQ&A

  • 配列から構造体へデータコピー

    配列から構造体へデータのコピーをしたいのですが、 構造体のメンバがビットフィールドで構成されている時の処理がわかりません。 --------test.c----------- #include <stdio.h> #include <string.h> typedef struct{ unsigned char aaa :1; unsigned char bbb :1; unsigned char ccc :1; unsigned int ddd :13; unsigned char eee :2; unsigned char fff :2; unsigned char ggg :4; }test_t; int main(void) { test_t test_t; unsigned char data[]={0x5F, 0xFE, 0x1C}; memcpy(&test_t, data, 4); printf("aaa = %X\n", test_t.aaa); printf("bbb = %X\n", test_t.bbb); printf("ccc = %X\n", test_t.ccc); printf("ddd = %d\n", test_t.ddd); printf("eee = %X\n", test_t.eee); printf("fff = %X\n", test_t.fff); printf("ggg = %X\n", test_t.ggg); return 0; } ------期待出力--------- aaa = 0 bbb = 1 ccc = 0 ddd = 1FFE eee = 0 fff = 1 ggg = 12 「test.c」を実行した時に「期待出力」のような出力を期待していたのですが、実際には aaa = 1 bbb = 1 ccc = 1 ddd = 1 eee = 0 fff = 0 ggg = 0 と表示されてしまいます。 ビットフィールドで構成された構造体に、配列の値をそのままあてる事は出来ないのでしょうか? 出来るだけ、マスクやシフト演算を使用しないで、配列からビット単位で値を抽出したいのですが・・・

  • structをポインタ宣言時の領域

    struct test{     char* aaa;     int bbb;     long ccc;     char ddd[10]; }; というような構造体があるとします。 これを test* AAA = 0; と宣言した時点でデータ領域は確保されているのでしょうか?

  • 入れ子の構造体について

    例えば、入れ子の構造体を1つ使いたい場合、 struct bbb{ int b; }; typedef struct aaa{ struct bbb a; }AAA; AAA dt; と書くと、「dt.a.b = 10」とやれば、値等を設定できると思いますが、 入れ子の構造体を2つ使いたい場合も、同じように書けるのでしょうか? struct ccc{ int c; }; struct bbb{ struct ccc b; }; typedef struct aaa{ struct bbb a; }AAA; AAA dt; dt.a.b.c = 10; と書けるのでしょうか?こんがらがってしまって、どう書いていいのか・・。 2つでも出来るのであれば、コードの書き方を教えて頂けませんか?

  • 動的な構造体配列の初期化

    以下のように構造体を new で動的に確保したときに 構造体の中身(char bbb[10], int ccc)をゼロで初期化したいのですが ZeroMemory を使用するとCArrayのAdd()を使用したときにエラーになってしまいました。 何かよい方法がありましたら教えて下さい。お願いいたします。 # 簡単にイメージですが・・・ typedef struct { CString a; CString b; }aaa_t ; struct s_aaa{ char bbb[10]; int ccc; CArray<aaa_t,aaa_t> m_aaaArray ; } s_aaa *StructB; StructB = new s_aaa [10];

  • 基本的な領域確保の仕方について

    下記のような構造体が宣言されている場合、 A.c.e ←を配列扱いにし、 A.c.e[0].g.h ←を配列扱いにし、 A.c.e[0].g.h[0].iにデータを設定するには、 どのように領域を確保すれば良いのでしょうか? eee型はポインタ宣言のみされていて配列宣言されて いません。(Max10配列) typedef struct { int len; char *i; } hhh; typedef struct { int number; hhh *h; } ggg; typedef struct { fff f; ggg g; } eee; typedef struct { int number; eee *e; } ccc; typedef union { aaa a; bbb b; ccc c; ddd d; } A;

  • 静的構造体の初期化について

    struct XXX{ MYSQL *MMM; char a[32]; char b[32]; char c[32]; char d[24]; } static struct XXX YYY[] = { {NULL, "AAA", "BBB", "CCC", "DDD"}, {NULL, "AAA", "BBB", "CCC", "DDD"}, {NULL, "", "", "", ""} } main(){ for(i=0; YYY[i].a[0]; i++){ MMM = ... } 上記のように、YYY[]分MMMの値を設定します。 この設定はうまくMMMが取得できるのですが、 実際にはMMMを1つの構造体の中に10個分用意したいです。 つまり、イメージは struct XXX{ MYSQL *MMM[10]; ... } このような形です。 ただし、初期化の仕方がわからずコンパイルが通りません。 またこのようなやり方ができるのかもわかりません。 どなたかご教授ください。 他にいいやり方があるのであればそれも教えて下さい。

  • 構造体の型について

    ある構造体をxxxと名づける以下のプログラムを作成しました。 ーーーーーーーーーーー #include <stdio.h> #include <string.h> main() { typedef struct { char variable[64]; char type[64]; char value[512]; } xxx; xxx aaa; strcpy(aaa.variable,"bbb"); printf("%s\n",aaa.variable); } ーーーーーーーーーーー これは動き、bbbと表示されます。 しかしながら、構造体のポインタを使用した 以下のプログラムではコンパイルはとおりますが実行時にコアダンプして落ち ます。 ーーーーーーーーーーーーーーーーーーーー #include <stdio.h> #include <string.h> main() { typedef struct { char variable[64]; char type[64]; char value[512]; } xxx; xxx* aaa; strcpy(aaa->variable,"bbb"); printf("%s\n",aaa->variable); } ーーーーーーーーーーーーーーーーーーーーーーー 両プログラムの意図はまったく同じなのに何故いけないのでしょうか。

  • 構造体の宣言方法について

    構造体の宣言で ヘッダーファイルに struct RAM rom_AAA[20] を宣言 Cソースファイル(上記のヘッダーファイルをインクルードする)に struct RAM { struct BBB *CCC } を宣言 とした時 rom_AAA[20]と*CCC(BBBアドレス)はリンクしてる状態になるのでしょうか? 構造体の一部の定数テーブルを参照するために 間単にポインタ使ってグルグル回したいのですが、同じものをアクセスしてる事にならないでしょうか?

  • C言語の構造体のサイズについて

    いつもお世話になっていります。 早速ですが、C言語の構造体のサイズについて教えてください。 typedef struct B { short code; char name; float price; } B; typedef struct A { B bbb[10]; double sougaku; } A; A aaa; といった構造体があった場合に、 sizeof(aaa.bbb.code) + sizeof(aaa.bbb.name) + … + sizeof(aaa.sougaku) という風に一つ一つサイズを取得し、合計して構造体のサイズを取得した場合と sizeof(aaa) という風に構造体のサイズを取得した場合のサイズの値が異なるといった現象が起きます。 その原因が分からなくて困っております。 そこで考えられる要因をお教えください。 因みに実際の構造体はサイズで言えば2500バイトくらいあります。 froat/char/double/short 型を使用しております。 よろしくお願いします。

  • 構造体 アドレス

    VC++6 こんにちは。構造体のアドレスを文字列ポインタで操作することに悩んでいます。下にソースの一部を書きます。 typedef struct{   char code[100];   int type; }AAA; typedef struct{   double method[4][3];   int area; }BBB; 複数の構造体があり、 BOOL CTestApp::File_Check(){  AAA aaa; ~  db.DB_regi(2, (char *)&aaa); ~ } void CData::DB_regi(int key, char *buff) {  switch(key){ ~  case 2:   sss.push_back(buff);  //vector<char *> sss;   break; } で、データを登録し、 int CTestApp::Data_Check() { ~  AAA aaa;  db.DB_get(2, (char *)&aaa); ~ } void CData::DB_get(int key, char *buff) {  switch(key){ ~  case 2:   buff = sss[i];   break; ~ } で、構造体のアドレスを取得しようと思ったら、取得できませんでした。 //DB_getの中では、aaa = (AAA *)buff;とすれば指定の構造体を取得できる。 DB_get関数をどのようにしたら、Data_Check()で、登録した構造体を取得できるのか教えてください。長くなってすみません。

専門家に質問してみよう