• ベストアンサー

構造体にたいして、ビット演算はできるのか

struct test {   int i[2]; }; struct test t; と、定義した構造体に対して、 t <<= 8; t = ~t; などの様にまるごとビット演算を行うことはできますか。

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

  • ベストアンサー
回答No.1

できません。 struct型に対するシフト命令や反転命令は未定義のはず unsigned int *p = t; t[0] <<=8; t[0] = ~t[0]; とかならできます。

その他の回答 (7)

  • titokani
  • ベストアンサー率19% (341/1726)
回答No.8

構造体に対してのビット演算は、「できない」というよりも、「定義されていない」です。 なので、その動作はjohnsmith_さんが定義する必要があります。 他の誰も「正解」は持ち合わせていません。 void shift_left(struct test *pt,int s); struct test t; t.i[0]=1; t.i[1]=2; shift_left(&t,8); printf("%d\n",t.i[0]); printf("%d\n",t.i[1]); とした場合に、どういった結果が欲しいのかでshift_leftの中身を決定する形になります。

johnsmith_
質問者

お礼

定義されてないのですね。 ありがとうございました。

回答No.7

具体的に、何がしたいかにもよりますが、 long long 型が使用可能であれば、 long long t; で、不通に乗り切れるという可能性もあるかと思います。

johnsmith_
質問者

お礼

ありがとうございます。 説明が不足していました。 やりたかったことは任意の内容、大きさの構造体にたいしてのビット演算処理です。 すみませんでした。

回答No.6

Cではできないのはすでに回答にあるとおりですが、気になる点が。 >ここで******さんが直接正解を教えてくださる方が、 >これから私が自分で体感するよりもよほど手っ取り早いと思います。 いいえ。 「自分で実行し理解する」ということを放棄した時点で逆です。 その考え方がある時点で「上辺だけわかったつもり」になっておしまいです。 また、「質問すればスグ回答がつく」とも限りません。 QAサイトを「便利な魔法の箱」とでも考えてませんか?

johnsmith_
質問者

お礼

回答ありがとうございます。 >「自分で実行し理解する」ということを放棄した時点で逆です。 >その考え方がある時点で「上辺だけわかったつもり」になっておしまいです。 つまり、できるかできないかは自分で実行して理解するべきであるということですね。 「構造体にたいして、ビット演算はできるのか」というのはC/C++の仕様の問題なので定義されているか、されていないかはっきりと決まっているものと思って質問させていただきました。 私は、この様に白か黒か(できるかできないか)はっきり決まっているだろうことがらというのは、「知る」ものであって、自分で実行して「理解」するというようなものではないと思っております。(個人的な意見ですが) >また、「質問すればスグ回答がつく」とも限りません。 >QAサイトを「便利な魔法の箱」とでも考えてませんか? 教えて!gooのC/C++コーナーでは、今までにあった質問の一覧を見ればわかるとおり難しい質問でなければ、質問してからかなりの短時間で回答をいただくことができます。 とくに、私の質問はC/C++の基本的な仕組みに関する初歩的なものなのですぐに回答してくださる方がいるだろうと思って質問しました。(実際すぐに回答をいただきました) QAサイトは「魔法の箱」とまではいきませんが、便利なサービスだとは思っています。

回答No.5

 こんばんは。  以下で良ければ参考程度に。 template<typename __Tp = int, size_t __N = 1> struct test_t { typedef test_t<__Tp, __N> _Self; enum { Count = __N }; __Tp i[__N]; _Self& operator <<= (const __Tp& shl) { for(int n = 0; n < __N; ++n) this->i[n] <<= shl; return *this; } _Self& operator >>= (const __Tp& shr) { for(int n = 0; n < __N; ++n) this->i[n] >>= shr; return *this; } const _Self operator ~() const { _Self tmp = *this; for(int n = 0; n < __N; ++n) tmp.i[n] = ~tmp.i[n]; return tmp; } }; template<typename __Tp>struct test_t<__Tp, 0>;//error //int[2]の配列にする typedef test_t<int, 2> Test; int main() { Test a = {1, 2}; a = ~a; ::printf("[operator ~()]\n"); for(int i = 0; i < Test::Count; ++i) { ::printf("[%d] = %d\n", i, a.i[i]); } Test b = {1, 2}; b <<= 8; ::printf("[operator <<=()]\n"); for(int i = 0; i < Test::Count; ++i) { ::printf("[%d] = %d\n", i, b.i[i]); } Test c = {0xffff, 0xffffff}; c >>= 8; ::printf("[operator >>=()]\n"); for(int i = 0; i < Test::Count; ++i) { ::printf("[%d] = %d\n", i, c.i[i]); } return 0; }

johnsmith_
質問者

お礼

Thank you for giving me a detailed source code for my question. Now, I can't understand it perfectly because I'm not very experienced in programming a computer program with C++ language yet. So I will learn that more.

  • kmee
  • ベストアンサー率55% (1857/3366)
回答No.4

t <<= 8; がどんな仕様なのか、で作り方が違います。 t.i[0] <<= 8 ; t.i[1] <<= 8 ; とも考えられますし、 t.i[0]とt.i[1]をintの倍のビット幅として、全体を <<= 8 とも考えられます。

johnsmith_
質問者

お礼

すみません。説明不足でした。 やりたかったことは、「全体を<<=8」のほうです。

  • asuncion
  • ベストアンサー率33% (2126/6288)
回答No.3

>まるごとビット演算を行うことはできますか。 できるかできないか、という話でしたら、 サンプルコードを書いてみて「ご自分で」体感された方が、 こういうところで質問するよりもよほど手っ取り早いと思います。 いかがでしょうか。

johnsmith_
質問者

お礼

回答ありがとうございます。 確かにそうですが、もう質問してしっまたからには ここでasuncionさんが直接正解を教えてくださる方が、 これから私が自分で体感するよりもよほど手っ取り早いと思います。 いかがでしょうか。

  • kmee
  • ベストアンサー率55% (1857/3366)
回答No.2

Cならできません。 何度も使うようなら、関数やマクロを使いましょう。 C++なら、演算子のオーバーロードを利用すればできます。 struct test t;って書きかたしてるのでCだと思いますが。

johnsmith_
質問者

お礼

ありがとうございます。 C、C++どちらでもいいので、やり方を教えていただけるとありがたいです。

関連するQ&A

  • 構造体メンバ 構造体ポインタ 値代入

    typedef struct _test_t{ int aaa; int bbb; } test_t; typedef struct _globalData{ int xxx; test_t* pTestData[256]; } globalData_t; globalData_t globalData; int main(){ test_t testData1 = {1,1}; test_t testData2 = {2,2}; *globalData.pTestData[1] = testData1; /* (1) */ globalData.pTestData[2] = &testData1; /* (2) */ } 上記のようなグローバルデータの構造体globalData のメンバの構造体配列にtest_t型の構造体を格納し保持するには、 (1)、(2)のどちらが正しいでしょうか?

  • ポインタを使って構造体の配列を戻り値にするには

    関数の戻り値を構造体の配列(アドレスを受け渡しを利用して)にしたいのですがうまくゆきません。 以下のプログラムではコンパイルはできるのですが、 a0 = 2 a1 = 4198512 a2 = 4329332 と表示されてしまいa1,a2がうまくゆきません。 ********************************************* #include<stdio.h> struct test{ int a; }; struct test *func(void); void main(void) { struct test *data;//構造体ポインタ int i; data = func(); //ポインタにtest関数の戻り値(アドレス)を代入 for(i=0;i<=2;i++){   printf("a%d = %d\n",i,(data+i)->a); //構造体要素を表示 } } struct test *func(void) { struct test data[3]={1,2,3}; //構造体配列を定義 return (&data[0]); //構造体配列の先頭アドレスを返す } ************************************************* test関数から受ける取ったアドレス(&data[0])をポインタ(data)に代入して1づつずらして表示させれば a0=1,a1=2,a=3 となると思ったのですがどこが間違っているのでしょうか? よろしくお願いします。

  • 異なる複数の構造体のスマートな使用方法

    構造体のビットフィールドを複数作成し、 条件によってどの構造体を使用するかを決定し データ取得しようとしています。 同じ型の構造体の配列はできますが、 異なる構造体が複数ある場合、配列のように 参照する方法はないでしょうか? スマートなやり方があれば、ご教授お願い致します。 以下、やろうとしていることの簡易版、 /* ----例----------------------------------*/ int test = 1; if( test == 1){ /* 構造体test01を使用し値参照 */ } else if( test == 2){ /* 構造体test02を使用し値参照 */ } else if( ........ /* 以下同じような処理 */ struct test01{ unsigned int bit01: 1; unsigned int bit02: 15; } struct test02{ unsigned int bit01: 2; unsigned int bit02: 14; } struct test03{ unsigned int bit01: 3; unsigned int bit02: 13; } /* 同様の構造体がつづく*/ /* --------------------------------------*/

  • 構造体で・・・・

    構造体は配列を使用せずメモリ領域を獲得する関数を使用すること、 *構造体内部のメンバ名には配列を用いて良い。  という、条件があるのですが場合はどのようにすればよろしいでしょうか? どなたか教えてください。 構造体は以下のようになってます。 /*構造体の定義*/ struct seiseki{   char name[20];   int eig;   int suu;   int kok;   char rank[3]; };

  • 構造体について

    私は今プログラミング(C++)を勉強しているのですが、構造体に苦戦しています。分からないことがいくつかあります。もし知っていたらどれでもいいですので、よろしければ教えてください。 1、たとえば構造体を宣言するときに struct abc{ int s; struct abc xx; struct abc yy; }; と宣言するときがあります。でも上記の例と下記の例との違いが分かりません。 struct abc{ int s; struct abc xx; struct abc yy; }abc; 2、たとえばメインの最初にこのように宣言されているとします。 int j, i; struct abc *kk, *nn, *mm; これはここに宣言したものがローカルで、1のときに宣言したものがグローバルと考えていいのでしょうか? 3、メインの中に次のようなプログラムがあったとします。 kk->xx = j; kk->yy = j; nn->yy = NULL; i = kk->xx; i = kk; これらがそれぞれどのような意味があるのでしょうか。 これらでわかることがあればぜひ教えてください。よろしくお願いいたします。

  • 構造体の入れ子が構造体の場合のextern宣言について

    えーと、題名の通りで、単に構造体の場合はextern出来たのですが、構造体の入れ子が構造体の場合は上手くextern出来ないのです;;; typedef struct __test001 { int arg; } _test001; typedef struct _body { _test001 test001; } body; body useful; この場合、他のファイル(例えばtest.cpp)でusefulを使いたい場合、どのようにexternさせれば宜しいでしょうか?

  • 構造体について

    凄く初歩的な質問で申し訳ありませんが… 入門書の構造体のところで 以下のようなプログラムの例がありました。 #include <stdio.h> struct seiseki { /* 構造体の宣言 */ int no; char name[20]; double average; }; int main(void) { int i; struct seiseki seito1, seito2[20]; /* 構造体変数と構造体配列の宣言 */ >char name[20] というのは、NAMEの領域を20文字 確保すると言うことですよね? >struct seiseki seito1, seito2[20] ここの箇所が分からないのですが seito2[20]の20というのは どうして20なのですか? NAMEだけではないので もっと大きな数字になるような気がするのですが… またseito1の方は どうして数字が何もないんですか? 考え違いをしているところを ご指摘して頂ければ幸いです。

  • C++:構造体:newで入れ子:deleteは?

    C++で以下のような構造体を使っています。(本当は他にもメンバが有ります) // ----- typedef struct{  int *npMember; }Test_t; // ----- これをクラスのメンバ変数で // ----- Test_t *m_tpTestStruct; // ----- とし、関数の中で // ----- m_tpTestStruct = new Test_t[10]; for (int i = 0; i < 10; i++) {  m_tpTestStruct[i].npMember = new int[100]; } // ----- というようにメモリを割り当てています。 これを解放する時は、 // ----- for (int i = 0; i < 10; i++) {  delete [] m_tpTestStruct[i].npMember; } delete [] m_tpTestStruct; // ----- で、良いのでしょうか? それとも、他の書き方が必要なのでしょうか?

  • 構造体の宣言

    下記のように構造体の宣言をした所、 struct B_PARAM test; 「`test' の領域サイズがわかりません」というエラーになってしまいました。この構造体を宣言し、値を入れていこうとしています。 ヘッダファイルに構造体の形は定義してあるのですが、 構造体の中に構造体があるからでしょうか? またこの構造体を正しく宣言するにはどうすればいいのでしょうか?

  • 構造体の使い方

    構造体が定義されている場所では、 struct runqueue{ task_t としかないのに、実際の関数の部分では task_t *p = current というように、変数として宣言されている部分があるのですが、これにはどういった意味があるのでしょうか?

専門家に質問してみよう