初歩的な質問をご容赦ください。

typedef struct tagStruct {
____int a: 2;
____int b: 2;
} STRUCT;

STRUCT st = {1, 2};
/*ビットフィールドをすべてクリア*/
(*int)st = 0;

みたいなことはできないのでしょうか。
コンパイラに、intは必要ありません、と言われて削除すると*演算子の使い方が違う、と怒られてしまいます。
言語仕様レベルで不可能なことなのでしょうか?

A 回答 (6件)

*(int *)&st = 0;



これでintサイズに0を代入できる。
アドレスを(int *)にキャストしたアドレスの値はint。
    • good
    • 0
この回答へのお礼

ありがとうございます。
これぞ求めていたコードです。
多用しないほうがよい、アクロバティックなコードなのでしょうか?気になるところではあります。

お礼日時:2005/04/19 21:14

>具体的なコード


ということで、サンプルをば
#include <stdio.h>

typedef union tagStruct {
struct {
unsigned a:2, b:2;
} bit;
unsigned bitall;
} STRUCT;
void main(void){
STRUCT st;
st.bit.a=1;
st.bit.b=2;
printf("%d, %d\n", st.bit.a, st.bit.b);
st.bitall = 0;
printf("%d, %d\n", st.bit.a, st.bit.b);
}
int a
の部分をunsignedに変えているのは、
%dでintに格上げされたときに、マイナスになってしまうのをそうしないためです。
ビットで操作する場合には、特別なんでも構いません。
    • good
    • 0
この回答へのお礼

ご丁寧にありがとうございます。なるほど、ビットフィールドに別名をつけるやり方ですね。変数名が長くなってしまうのは好みではないですけど、参考になりました。

BLUEPIXYさんをはじめ、rentaheroさん、SSBBGLUVさんの皆さんには、丁寧なお付き合いをいただき、本当に感謝しております。この場をお借りして、お礼申し上げます。これからもどうかよろしくご教授くださいませ。

お礼日時:2005/04/20 01:23

union(共用体)にすればいいかと思います

    • good
    • 0
この回答へのお礼

ご回答ありがとうございます。
unionは使ったことがないのでそんな使い方があるとは!驚きです。union型にキャストして代入するのですか?具体的なコードをぜひご教示ください。

お礼日時:2005/04/19 21:07

ん~。

「言語仕様レベルで不可能か」という質問に対してなので、可能と答えましたが、#3の方の意見も確かにもっともなので(モトローラ系のCPUではバスエラーの危険性は否定できない)、その場合は

memset(&st, 0, sizeof(STRUCT));

となります。
    • good
    • 0
この回答へのお礼

早速のご回答本当にありがとうございます。
丁寧に何度もお答えくださり、勉強中の私には参考になることばかりです。ビットフィールドはint型と決めうちしたコードは危険なのですね。
ありがとうございました。

お礼日時:2005/04/19 20:40

構造体の型によってはメモリバウンダリエラーが発生するかもしれないので、stをintと見なすより素直にmemsetで0クリアするほうが安全だと思いますよ(この例だと大丈夫だと思いますが)。

    • good
    • 0
この回答へのお礼

すばやいご回答、ありがとうございます。
メモリ境界値が調整されていないとアーキテクチャによってはエラーが発生するというのを聞いたことがありますが、その関連のお話でしょうか?
SSBBGLUVさんはお笑いになるかもしれませんが、私はCライブラリを一切使いたくないのです。わがままですよね?

余計なことを言いました。ご回答、ありがとうございました。

お礼日時:2005/04/19 20:47

テストプログラムを一応だしときます。




#include <stdio.h>

struct tagStruct
{
signed a: 2;
signed b: 2;
};
typedef struct tagStruct STRUCT;

int main()
{
STRUCT st = {1, 2};
printf("%d, %d\n", st.a, st.b);
*(int *)&st = 0;
printf("%d, %d\n", st.a, st.b);
return 0;
}


結果
1, -2
0, 0
    • good
    • 0

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!

このQ&Aを見た人はこんなQ&Aも見ています

このQ&Aを見た人が検索しているワード

このQ&Aと関連する良く見られている質問

Qパソコンの初期化の仕方を教えて下さい。

パソコンの初期化(買った時の状態に戻す)をしたいんですが、初期化するCDがありません。
他社の初期化CDならあるのですが、それで初期化できますか??

Aベストアンサー

>他社の初期化CDならあるのですが、それで初期化できますか??

できません。

最近のPCはリカバリーCDがなく、
HDD上にリカバリーイメージを持っているモデルが多いです。
買ったときに付いてきた、取扱説明書に
リカバリーの方法についての記述があるはずですので
まずは確認してみてください。

CDを無くしたということなら、メーカーサポートに連絡です。

Qint select(int n, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout)について

見当違いな質問かもしれませんがお願いします。

複数のソケットを監視する際にselectを使う場合のことですが、
selectの動作と戻り値について疑問があります。

http://www.linux.or.jp/JM/html/LDP_man-pages/man2/select.2.html
ここを参照すると、selectの戻り値は
「更新された 3 つのディスクリプタ集合に含まれているディスクリプタの数 (つまり、 readfds, writefds, exceptfds 中の 1 になっているビットの総数) を返す。」
とあります。
私の中でselectは登録してあるFDのうち、一つでも動きがあれば即座にselectを抜けるもの、という認識です。
この認識だとreadfds,writefdsが引数として与えられているとしても、
どちらかのfd_setのうち、一つでも動きがあればselect文は
抜けてしまうことになります。とすると、戻り値として
「readfds, writefds, exceptfds 中の 1 になっているビットの総数」
は常に1ということになってしまいます。しかし、総数というからには
複数同時に1になることもあるはずです。

私の認識が間違っているとは思うのですが、どう間違っているのかわかりません。
select文の動きについて詳しく教えていただけないでしょうか。
または良いページがあれば教えてください。

見当違いな質問かもしれませんがお願いします。

複数のソケットを監視する際にselectを使う場合のことですが、
selectの動作と戻り値について疑問があります。

http://www.linux.or.jp/JM/html/LDP_man-pages/man2/select.2.html
ここを参照すると、selectの戻り値は
「更新された 3 つのディスクリプタ集合に含まれているディスクリプタの数 (つまり、 readfds, writefds, exceptfds 中の 1 になっているビットの総数) を返す。」
とあります。
私の中でselectは登録してあるFDのうち、一つでも動きが...続きを読む

Aベストアンサー

>私の中でselectは登録してあるFDのうち、一つでも動きがあれば即座にselectを抜けるもの、という認識です。
この認識はあっています。
しかし、selectを呼び出す以前にOKになっているFDがあれば、それらは全てビットがONになります。

話しを簡単にする為に、受信のみのソケットを3つ作成したとします。
これらの3つのソケットに向けて相手が電文を送ったとします。
その状態でまだ、こちらはselectを呼び出さずにいます。しばらくしてから、selectを呼び出すと、selectは即座にリターンし、3つのビットが一度にONになっているはずです。
一方、相手が、一切電文を送ってない状態で、selectを呼び出した場合は、何れかのビットがONになればリターンするので、そのときは、貴方が想像しているように
ビットの総数は1になる可能性が高いです。
従って、相手が電文を送る前にselectを呼び出すか、送った後にselectを呼び出すかは、その時のタイミングにより異なります。従って、ビット数の総和が常に1であるとは、考えない方が無難です。(1つのソケットしか使用しない場合は別ですが・・・)

>私の中でselectは登録してあるFDのうち、一つでも動きがあれば即座にselectを抜けるもの、という認識です。
この認識はあっています。
しかし、selectを呼び出す以前にOKになっているFDがあれば、それらは全てビットがONになります。

話しを簡単にする為に、受信のみのソケットを3つ作成したとします。
これらの3つのソケットに向けて相手が電文を送ったとします。
その状態でまだ、こちらはselectを呼び出さずにいます。しばらくしてから、selectを呼び出すと、selectは即座にリターンし、3つのビ...続きを読む

Qパソコンを初期化する質問煮について

パソコンを初期化すると良く質問されてますが人間がするなら好きな事出来るのでその初期化で良いのですが問題は量産タイプのPCご購入時に戻る訳でして初期化という意味ではないと思います。
何処の時点が初期化なのか解る人居れば、例えば組み立てただけの時点なのかOS入れた時点なのか?解る人居れば教えて頂ければ幸いです、お願い申し上げます、初期化の意味を?

Aベストアンサー

メーカーパソコンはOSとサービスソフトが何十本も入っているので

起動ディスクを使ってリカバリーディスク1枚~2枚と必要です。

起動ディスクを使っていたのはWindows 95~98のときで

今はリカバリーディスクとアプリケーションディスクが2枚~3枚です。


今は現在はDVDが有りますので自作PCはリカバリではなく

OSWindows 7のDVDを使ってOSのインストールも初期化も

OSWindows 7のDVD1枚で両方をまかなうことが出来ます。

Qvoid (*signal(int signum, void (*handler)(int)))(int);

の解釈を教えてください
最後の「(int)」については詳しくお願いします

Aベストアンサー

signalが

(1)1つ目の引数の型:int
(2)2つ目の引数の型:引数がintで戻り値がvoidである関数へのポインタ
(3)戻り値の型:引数がintで戻り値がvoidである関数へのポインタ(2と同じ)

を満たす関数である事を宣言しています。最後の(int)はsignalの戻り値の
関数ポインタがint型の引数を持つ事を示しています。

「引数がintで戻り値がvoidである関数へのポインタ」の型をHANDLERと表すと

HANDLER signal(int signum, HANDLER handler);

となります。

Q初期化でパソコンのパフォーマンスはよくなりますか?

最近、パソコンの動作が鈍くて困っています。特にネットの反応が悪くイライラすることがしばしばです。ある人から、初期化すればパソコンのパフォーマンスが良くなると聞きました。本当でしょうか。また、初期化は、私のような初心者でもできるものでしょうか。初期化の方法も合わせて教えていただいたら幸いです。

Aベストアンサー

パフォーマンスが向上することはありません。
パフォーマンスが元に戻ると思ってください。

初期化…いわゆるリカバリのことです。
インターネット上を検索すると具体的な方法を示したサイトを見つけることができますが、
普通にパソコンメーカーに問い合わせるかパソコンの取扱説明書を読みましょう。
「自分は初心者だから」と言うのは免罪符にはなりませんので、
取扱説明書を読んでも分からないのでしたら、リカバリは止めておきましょう。
余計に問題を大きくしてしまいます。


そんなわけで、
 1.パフォーマンス向上アプリを使用する。(お店で購入しましょう。フリーソフトなんて考えちゃダメ)
 2.諦めてそのまま使用する。
 3.新しいパソコンを購入する。
 4.初期化すればパフォーマンスが良くなると言った人に頼んでやってもらう。
って選択かな?

(とりあえずハードディスクのデフラグくらいはやってもいいと思うんですけどね。)

Q{x = x>y ? x:y; return x;}

#include <iostream>
using namespace std;

inline int max(int x, int y){x = x>y ? x:y; return x;}

int main()
{
int num1, num2, ans;

cout << "2つの整数を入力して。\n";
cin >> num1 >> num2;

ans = max(num1, num2);

cout << "最大値は" << ans << "です。\n";

return 0;
}
の{x = x>y ? x:y; return x;}の部分の意味が解りません。

Aベストアンサー

inline int max(int x, int y){x = x>y ? x:y; return x;}
これを普通に関数で書くと

int max(int x, int y)
{
x = x>y ? x:y;
return x;
}

です。

x = 部分は右辺の結果が代入されます。これはわかりますよね。
x>y?x:y;
と書くと?より左にある条件式を判定し、その結果が真である場合は:で区切られた左側の値を、偽である場合は右の値を帰します。
x>yが真であればxを、偽であればyを返します。
それが、左辺値xに代入され、関数の戻り値として帰ります。

従って、2つの値をこの関数に入れると、大きいほうの値が帰ることになります。

Qパソコンの初期化(今すぐ回答ください)

私のパソコン(vista2007)が悪質ウィルスにかかってしまい、パソコンの初期化を決心しました。
初期化の方法を教えてください。 

※なぜかシステムの復元ができなくなっているので、その対処法、もしくは他の初期化方法を教えて頂きたいです。

宜しくお願い致します。

Aベストアンサー

PC付属のリカバリディスクがあるのなら、これをCD/DVDドライブに挿入し再起動させメーニューに従い実行すれば出来ますよ(正規製品版も同様)。

PCにより、リカバリシステムが内臓のものもありますので、こちらはPCマニュアルを参照のこと。
マニュアル紛失の場合はメーカHPのサポートページからダウンロードしてみてください。

リカバリ実行前にリカバリディスクの「コンピュータを修復する」を選択し、システムの復元、メモリ診断なども実行されてみてはいかがでしょうか。

なをリカバリを実行すると、Officeや後でインストールしたアプリケーションソフト、作成したデータファイル、お気に入りやメール等は消滅しますのでバックアップ保存は忘れないように。

Qtypedef struct OBJECT NODE; の意味を教えてください。

C言語において、

typedef struct OBJECT NODE;

に、コメント文を付けるとしたらどのようになりますか??
よろしくお願いします。

Aベストアンサー

意味は「これから NODE って出てきたら struct OBJECT と同じことだからね」ということです。

コメントに関してですが、言語に親しんだ人であれば難なく理解できる個所にはコメントを書かないのが良いマナーであると思います。
過剰なコメントは可読性を損ねますから。

この場合はコメントをつけないのが正解だと思いますよ。

Qパソコンの完全初期化

今回パソコンが不要になったのでオークションに出そうと思っているのですが、パソコンってリカバリなどの初期化で完全に中のデータは消されるんでしょうか。。。
会社で使っていたパソコンで色々なデータが入っていたので少し不安です。
もし完全に初期化できていないのなら完全に初期化する方法も教えてください。

Aベストアンサー

通常、ハードディスクをフォーマットしても、見出しの部分が消えて、中身が一見消去されているように見えるだけで、実際のデータは残っています。100%ではありませんが、残っているデータを修復されてしまう可能性があります。パソコン技能に秀でている人には可能ですし、中古のパソコンのデータを修復させて悪用することを専門に行っている人もいると聞きます。
できれば有償のデータ消去用のソフトを利用して完全にデータを消去した方が安全ですね。
http://it.jeita.or.jp/perinfo/committee/pc/HDDdata/refer.html
上記のサイトが参考になると思います。

なお完全消去用のソフトは色々あります。
http://www.finaldata.jp/product/terminator5_1.html
など。ご参考まで。

Q「void ( *signal(int sig, void (*func)(int)) ) (int)」の (int)

signal関数の書式についてですが、

  void ( *signal(int sig, void (*func)(int)) ) (int);

最後に付く(int)は一体何でしょうか?
このような関数の書式ははじめて見ました。
UNIX系の何かでしょうか。
回答よろしくお願いします。

Aベストアンサー

typedef void (*sighandler_t)(int);
sighandler_t signal(int signum, sighandler_t sighandler);
より後半部分のtypedefを置き換えると
sighandler_t signal(int signum, void (*sighandler)(int));
つぎに戻り値の部分のtypedefを置き換えると
void (*signal(int signum, void (*sighandler)(int)))(int);
となります。
(
sighandler_t signal(int signum, void (*sighandler)(int));
の「signal(int signum, void (*sighandler)(int))」をAと置き換えて
sighandler_t A;
からtypedefを置き換えると
void (*A)(int);
となり、Aを戻すと
void (*signal(int signum, void (*sighandler)(int)))(int);
となる。
)

typedef void (*sighandler_t)(int);
sighandler_t signal(int signum, sighandler_t sighandler);
より後半部分のtypedefを置き換えると
sighandler_t signal(int signum, void (*sighandler)(int));
つぎに戻り値の部分のtypedefを置き換えると
void (*signal(int signum, void (*sighandler)(int)))(int);
となります。
(
sighandler_t signal(int signum, void (*sighandler)(int));
の「signal(int signum, void (*sighandler)(int))」をAと置き換えて
sighandler_t A;
からtypedefを置き換...続きを読む


人気Q&Aランキング