16/08/14 00:04:05.53 z6U1tRVC.net
スレを勃てるまでもない低俗なC/C++の質問はここでお願いします。
過去ログ
01 スレリンク(tech板)
02 スレリンク(tech板)
03 スレリンク(tech板)
04 スレリンク(tech板)
05 スレリンク(tech板)
06 スレリンク(tech板)
07 スレリンク(tech板)
08 スレリンク(tech板)
09 スレリンク(tech板)
10 スレリンク(tech板)
11 スレリンク(tech板)
12 スレリンク(tech板)
13 スレリンク(tech板)
14 スレリンク(tech板)
15 スレリンク(tech板)
16 スレリンク(tech板)
17 スレリンク(tech板)
18 スレリンク(tech板)
19 スレリンク(tech板)
20 スレリンク(tech板)
21 スレリンク(tech板)
22 スレリンク(tech板)
23 スレリンク(tech板)
24 スレリンク(tech板)
2:デフォルトの名無しさん
16/08/17 13:13:38.39 rz4OYI8a.net
関数にstaticをつける必要がある場合その関数を仮想関数みたいに使うにはどうすればいいかな?
例えばSetTimerで指定する関数を派生クラス毎の機能にしたい
基底クラスでstatic付きの関数を定義して
その中でpublicな仮想関数を呼ぶとかがスマートなんかな?
3:デフォルトの名無しさん
16/08/17 22:18:06.51 KqRj7kcI.net
基本部分の知識不足か説明不足で要領をえないな
> 関数にstaticをつける必要がある場合その関数を仮想関数みたいに使うにはどうすればいいかな?
そんなことをやろうとしなくても
派生クラス毎にstaticな関数を用意してSetTimerを呼び出すときにそれを登録すればいいだけでは
4:デフォルトの名無しさん
16/08/18 08:40:43.37 nfE+KhhQ.net
>>3
別のstatic関数にthisポインタを保持させておいて
1回目のTimerでその関数を呼んでTimer内のstatic変数に保存したら
publicなら呼べると思ったけど
そうするのがいいんかなありがとう
5:デフォルトの名無しさん
16/08/18 17:06:15.70 9gCEAov3.net
いや言っている意味がよくわからんがこういう感じのじゃダメなの?
やりたいことがわからんからコールバック呼ばれたらKillTimerしちゃってるけど…
それともTimerProcAやTimerProcBでclass A や class B のメンバにアクセスしたいという感じ?
class A
{
private:
static void TimerProcA(HANDLE hwnd, UINT uMsg, UINT idEvent, DWORD dwTime){ KillTimer(NULL,idEvent); }
public:
A(){}
~A(){}
virtual void TimerCall(){ SetTimer(NULL,0,2000,(TIMERPROC)TimerProcA); }
};
class B : public A
private:
static void TimerProcB(HANDLE hwnd, UINT uMsg, UINT idEvent, DWORD dwTime){ KillTimer(NULL,idEvent); }
public:
A(){}
~A(){}
virtual void TimerCall(){ SetTimer(NULL,0,4000,(TIMERPROC)TimerProcB); }
};
6:デフォルトの名無しさん
16/08/18 17:26:00.93 nfE+KhhQ.net
そうそうアクセスしたいという感じ
別のstatic関数ってのはこんな感じでTimerProcからメンバにアクセスするためにクラスポインタを保持させてて
static void *func(void *p) {
static void *q;
if(p != NULL) {
q = p;
}
return q;
}
使う時はこんな感じ
TimerProc() {
static ClassA *classpointer;
if(classpointer == NULL) {
classpointer = func(NULL);
}
// 以下classpointerを使った処理を仮想関数にできればと思った
}
けど基底クラスのTimerProcでは派生クラスの型がわからんし無理だと気付いたごめん
7:デフォルトの名無しさん
16/08/18 17:28:17.52 9gCEAov3.net
あちゃー
クラスBのコンストラクタとデストラクタは脳内で変換しておいてください
それならstd::mapとか使って…
要点だけなのでエラー処理とかは無しだけど
std::map<UINT, void*> mp;
class A
{
public:
A(){}
~A(){}
static void TimerProc(HANDLE hwnd, UINT uMsg, UINT idEvent, DWORD dwTime)
{
KillTimer(NULL,idEvent); A *a=(A*) mp[idEvent]; mp.erase(idEvent); a->TimerCallbackEvent();
}
void TimerCall(){ UINT TimerId = SetTimer(NULL,0,2000,(TIMERPROC)TimerProc); mp[TimerId] = this; }
virtual void TimerCallbackEvent(){ MessageBox(NULL,"Timer A","TEST",MB_OK); }
};
class B : public A
{
public:
B(){}
~B(){}
virtual void TimerCallbackEvent(){ MessageBox(NULL,"Timer B","TEST",MB_OK); }
};
8:デフォルトの名無しさん
16/08/18 17:37:35.78 9gCEAov3.net
別にstd::mapである必要はないし独自のリストを作っても良い
TimerProc() と TimerCall() は基底クラスだけ書く
TimerCallbackEvent()は仮想関数で 派生クラス毎の機能 はここに書く
流れとしてはそれぞれのクラスでTimerCall() を呼び出すとタイマIDとインスタンスをセットで登録
時間経過でTimerProc()が呼ばれるけどその際に登録したタイマIDからインスタンスをゲット
あとはインスタンスの仮想関数 TimerCallbackEvent() を呼び出す
9:デフォルトの名無しさん
16/08/18 18:02:11.11 9gCEAov3.net
あと横着なやり方だと
SetTimerにウインドウハンドル指定すれば第二引数の UINT idTimer を有効に出来る
この idTimer にクラスのインスタンスを指定
コールバック関数 TimerProc では 第三引数の UINT idEvent, をクラスの型にキャストしてインスタンスを取得
class A
{
public:
A(){}
~A(){}
static void TimerProc(HANDLE hwnd, UINT uMsg, UINT idEvent, DWORD dwTime) {
KillTimer(hwnd, idEvent); A *a=(A*) idEvent; a->TimerCallbackEvent();
}
void TimerCall(HWND hWnd){ SetTimer(hWnd,(UINT)this,2000,(TIMERPROC)TimerProc); }
virtual void TimerCallbackEvent(){ MessageBox(NULL,"Timer A","TEST",MB_OK); }
};
class B : public A
{
public:
B() : A(){}
~B(){}
virtual void TimerCallbackEvent(){ MessageBox(NULL,"Timer B","TEST",MB_OK); }
};
10:デフォルトの名無しさん
16/08/18 19:33:04.64 nfE+KhhQ.net
>>7-9
ありがとう
いろいろやり方あるんだな
>>9は目から鱗
アドレスならプロセス内でユニークだしな
その発想は無かったクソやられたw
11:デフォルトの名無しさん
16/08/31 13:39:09.46 HrKErv9D.net
苦C12-2の戻り値になんでcount付くの?
12:デフォルトの名無しさん
16/09/01 12:44:39.61 Cb20qd0C.net
Class A { int a }
Class B { int a }
Class C : A, B { } // A Bを継承
この状態だとCからaにアクセスする場合は
thisじゃどっちのaだよってなるから
A::a, B::aってやる必要があるけど
Class C { A a; B b; } // A Bを宣言
これと違う部分は
名前が衝突するかしないかだけ?
13:デフォルトの名無しさん
16/09/01 14:07:11.55 h0ZxBZjb.net
コンパイルが通る文法でやり直し
14:デフォルトの名無しさん
16/09/01 18:20:52.36 9l469SL1.net
>>12
コンストラクタやデストラクタのタイミングから考えれば両者は別物
例えばCの初期化時、CのメンバがAやBにアクセスする場合
前者は問題なくCのメンバは初期化されるが
後者は宣言の位置によって未初期化データにアクセスする危険がある
前者はCをAとしてみることが出来るし、CをBとしてみることも出来る
でも後者においてCはCでしかない
例えばAを必要とする関数とBを必要とする関数がある場合、
前者はそのままCを引数に渡せるが後者は適宜メンバを指定しないといけない
もっともオーバーロードされた関数だとCをAかBにキャストしてやんないと曖昧だと怒られる
もちろん適切に宣言されていることは前提
15:デフォルトの名無しさん
16/09/01 18:26:02.24 9l469SL1.net
>>12
>>14の補足
>後者は宣言の位置によって未初期化データにアクセスする危険がある
Cのメンバを初期化リストで初期化する場合の話ね
コンストラクタ本体部分でメンバに値を代入する場合なら、
Cのメンバはすでに初期化された後なので参照は可能
16:デフォルトの名無しさん
16/09/01 18:51:52.00 Cb20qd0C.net
>>15
詳しくありがとう
17:デフォルトの名無しさん
16/09/01 21:39:05.25 461u96nve
std::tupleの要素取得関数が外部関数である理由が分からないんだが。
こういうの
std::get<0>(tuple)
これじゃだめだったのか
tuple.get(0)
もしくはこれ
tuple.get<0>()
18:デフォルトの名無しさん
16/09/06 13:37:22.26 71dTDxcx.net
int型aに自然数を入力するとする
√aに最も近い分数を表示する(ただし分子分母はそれぞれ5桁以内)
例えば√2の場合は30547/21600
ってプログラム作りたいなと思ったんですけどなかなか上手くいかないです
何かアドバイスありませんか??
19:デフォルトの名無しさん
16/09/06 14:06:14.75 7STKxdhD.net
君がすでに試したことをアドバイスして、もうやりました、と返されるのはばかばしいだろ
本気でアドバイスが欲しければ君がこれまでにやったが満足出来なかったこと
やろうとしたけどうまくできなかったこと、とかをできるだけ多く伝えてからにするんだな
20:デフォルトの名無しさん
16/09/06 21:30:24.59 Phz+5l1v.net
分母を1から99999まで回して√2に掛け小数点を切り上げた時と切り捨てた時で最も誤差が小さくかつ1から99999の範囲にある値を分子にする
21:デフォルトの名無しさん
16/09/07 09:32:39.46 mdJXQRTa.net
sqrt(2)は、66922/47321じゃない?
22:デフォルトの名無しさん
16/09/07 13:34:29.16 r09HpaM4.net
sqrt(n)の結果を分数に変換すれば良いならググれば出てくると思うが。
割と簡単だぞ。
23:デフォルトの名無しさん
16/09/07 14:15:36.07 M2bjXbVq.net
>>21
47321 / 33461 じゃないんか?
URLリンク(ideone.com)
24:デフォルトの名無しさん
16/09/07 19:10:24.68 9ei6Qh2k.net
>>18 の問題は、平方根の近似値を求めることと
桁数制限のある分子・分母による分数で小数の近似値を作ること、
この2つに分解できるのかな。それとも一体なんだろうか。
ちょいと調べたところ「ディオファントス近似」とかいう
数学のキーワードが出てきたから、C/C++のプログラムというより
アルゴリズムの問題なのかもしれないよ。
25:デフォルトの名無しさん
16/11/17 19:27:03.23 /ZwpQAJu.net
URLリンク(www.boost.org)
CUDAの
__host__ __device__
value_type operator()( value_type x) const
{
みたいな書き方で
__host__ __device__
というのはCUDAに限定された書き方で普通のC++では返り値の方の前に
他のもの置けませんよね?
26:デフォルトの名無しさん
16/11/17 19:31:08.07 cH0vE1/X.net
staticとか置けるよ
27:デフォルトの名無しさん
16/11/17 20:52:01.53 klz7wxCT.net
cdeclとかstdcallとか置かない?
28:デフォルトの名無しさん
16/11/17 20:52:40.98 dEDc58kY.net
環境に応じて空白に置換されることもあるマクロとか普通に置けるし
C++11以降なら普通にattributeを置ける
29:デフォルトの名無しさん
16/11/18 09:34:37.20 HWQGR5IS.net
>>27
void __stdcall func();だわ
30:デフォルトの名無しさん
16/12/25 17:25:21.30 +uAMo6Z3.net
c++11 の std::accumulate() を使って CRC32 を計算するプログラムを書いているんだけど、
イテレータの型が不明だから template<> を使わざるおえずヘッダーにしか書けないんだよな。
それは仕方がないとして、参照しているテーブルをヘッダーファイルに
static const uint32_t __CRC32_TABLE__[256] {/* データは省略 */};
って書いてもコンパイル単位で毎回生成されるようなことにはならないのか心配。
自分で調べてみようと思って objdump を使って見てみたんだけどよくわからんかった。
extern で宣言して別ファイルでテーブルの実態を定義してもいいけど、
シンボルを公開したくないんだよね。
31:デフォルトの名無しさん
16/12/25 23:20:51.61 jDrU+LCU.net
staticなグローバル変数なら翻訳単位ごとに毎回定義(生成)されるのが基本だろ
32:デフォルトの名無しさん
16/12/29 11:13:46.10 ddtQH8Am.net
ヘッダーファイルに定義するなら公開しているようなものじゃないかと思うんだけど。
テーブルアドレスを取得する関数を定義して実体を見せないとかじゃだめなんかな?
33:デフォルトの名無しさん
16/12/31 01:03:30.96 WURbgydp.net
ヘッダファイルなんて作らずに main.cpp で他の .cpp ファイルをインクルードしてしまえばいい
フリーダムさが一つの売りな言語だからな
という話ではなくて?
34:デフォルトの名無しさん
16/12/31 05:29:57.12 M5j1RyE5.net
externをヘッダに書かなければ大丈夫
35:デフォルトの名無しさん
16/12/31 13:06:08.73 bmD+g+A2.net
>>30
今更だけど、何か勘違いしているか、ちょっと間違った使い方をしている気がする。
36:デフォルトの名無しさん
16/12/31 14:05:48.22 dE1JGkqW.net
>>33
それってデバッグするとき最悪なことにならない?
37:デフォルトの名無しさん
16/12/31 19:25:36.12 GpynYecu.net
関数のオーバロードってどう思います?
linusさんはC++批判の一つにこれを上げていました。
38:デフォルトの名無しさん
16/12/31 20:17:07.01 Kmz/fYBF.net
オーバーロードがあると、デフォルト引数がある関数で、間違いが起こりやすい
Haxe では、型推論しやすいように、オーバーロードが無い
39:デフォルトの名無しさん
16/12/31 20:27:01.42 GpynYecu.net
やっぱあえて用意しない言語も少なくないんですかね
C++のような用意されている言語でも意図的に使わない人もいるのかな
ところで自分は関数のオーバロードが大好きなのですがwww
C++をオーバロード関数のあるCもとい better C として使うことも少なくないのですがwwww
C言語にもできないかなぁwwww
40:デフォルトの名無しさん
16/12/31 21:17:05.19 WasXuFJU.net
オーバーロードはいいものだ
だが引数の暗黙の型変換はデフォルト禁止すべきだ
41:デフォルトの名無しさん
17/01/01 00:04:27.70 /LG195GI.net
ソースコードを読む側から見るとオーバロードは欠点でしかない
書く側から見ると稀に便利だけど無い方がいい
42:デフォルトの名無しさん
17/01/01 01:06:03.25 y/0zTBoG.net
暗黙の型変換、デフォルト引数、さらに演算子のオーバーロードなどが
ごっちゃになった本当のヤバさを知らない人には好かれる機能かもね。
43:デフォルトの名無しさん
17/01/01 01:47:02.01 3VCNztM8.net
普通は逆だな
ヤバさを知らない人はやらかして痛い目を見る
知ってる人は使い所に気をつけて恩恵のみ得られる
44:デフォルトの名無しさん
17/01/01 07:30:16.72 /Xch0vce.net
確かにヤバさを知ってから使えばあれはいいものだな
45:デフォルトの名無しさん
17/01/01 10:17:30.27 iNYIlr5k.net
ことしもよろしくな
46:デフォルトの名無しさん
17/01/01 11:21:50.54 J8wVTYjO.net
ふぐみたいなものかな
毒のやばさを知らない人は食って死ぬし
毒のやばさを知っている人はうまく料理しておいしい思いをする
47:デフォルトの名無しさん
17/01/01 11:25:10.13 h0NhlmdK.net
料理人はさばくだけで、食った奴が死ぬ。
48:デフォルトの名無しさん
17/01/01 12:11:27.00 1eFWlFaz.net
>>36
オールマクロで書かれたソースよりはマシですよ
49:デフォルトの名無しさん
17/01/01 13:07:41.65 6FLztjP6.net
目くそ鼻くそ
50:デフォルトの名無しさん
17/01/03 18:18:14.49 YaTOHTL4.net
なるほど自分だけはうまく使えてると思い込んでしまうわけだ。
51:デフォルトの名無しさん
17/01/03 19:02:34.22 IwVR3NZn.net
痛い目を見ないで使えているならうまく使えていると言えるんじゃないの
オールマグロは美味しい
52:デフォルトの名無しさん
17/01/08 04:05:56.53 +qBxgbmJ.net
デフォルト引数とオーバーロードのどちらを取るかといわれると
かなり悩むが、個人的にはオーバーロードかなぁ
オーバーロードがないとメタプログラミングも困難になるし
演算子のオーバーロードは行列やベクトルに対しては非常に有用だしな
デフォルト引数は、関数に構造体を渡すようなものであれば
構造体自体に初期値を設定できるから
無くても別に困らないかなぁ
大体からして、引数が10個以上になるとかはナンセンスだし
そういう場合は大抵構造体で渡すからねぇ
53:デフォルトの名無しさん
17/01/08 10:04:57.89 HWfbhIhn.net
関数のオーバーロードがcに備わっていればへんなプレフィックスをつけなくても名前衝突の可能性は減らせるのに。。
54:デフォルトの名無しさん
17/01/09 17:38:25.57 s0WlKSpH.net
>>53
関数のオーバーロードはマングリングの絡みがあって,アセンブラとリンクしがちなCにとっては鬼門なんだと思うんです
55:デフォルトの名無しさん
17/01/13 23:29:25.67 YsOZ3W7e.net
int l = 2;
printf(" P2=(%1.3f, %1.3f)\n", l, P[2][0], P[2][1]);
→P2=(0.000, 0.000)←正解
printf(" P%d=(%1.3f, %1.3f)\n", l, P[l][0], P[l][1]);
→P2=(1.000, -1.000)
こんなことってありますか?
56:デフォルトの名無しさん
17/01/13 23:44:30.08 uIUQJPv6.net
>>55
>int l = 2;
>printf(" P2=(%1.3f, %1.3f)\n", l,
0が表示されるのはおかしいんじゃないかな
57:デフォルトの名無しさん
17/01/13 23:54:16.22 YsOZ3W7e.net
すみません, ソースコードコピペじゃなかったので書き間違えましたが、正しくは
printf(" P2=(%1.3f, %1.3f)\n", P[2][0], P[2][1]);
です。
すみません解決しました。宣言でP[3][2] と書くべきところをP[2][2]と書いていました。
お騒がせしました。
58:デフォルトの名無しさん
17/01/20 09:36:49.73 Nvso2zBq.net
>>53
関数オーバーロードの存在理由は名前を変えたくても変えられない関数のため
59:デフォルトの名無しさん
17/01/21 12:37:42.57 SM6hxokj.net
gdbでデバッグをするとき、
main.cppファイル以外にtest.cppファイルをインクルードして
コンパイルしています。
このとき、test.cpp内の変数の中身を見るためにブレークポイントを
設定したいのですが、具体的にどのように行えばよいのでしょうか?
60:デフォルトの名無しさん
17/01/22 06:49:21.49 hpHPcjfX.net
>>59 俺もgdbに詳しいわけじゃないけど…。
関数内のローカル変数を見られるのは、当然その関数の実行中だけ。
(gdb) break test
(gdb) run
... 関数test()開始時に停止
(gdb) print var
... 関数test()内のローカル変数varが表示される
C++特有の問題として、ファイル内のスタティック変数も
そのファイルの関数を実行してる間しか正しく見られないみたい。
Cで使えた 'file.c'::var (ソースファイル名で修飾した変数名)は
C++のプログラムだとgdbが文法エラーと言ってくる。
61:デフォルトの名無しさん
17/02/01 22:19:47.26 FDjJl8e/.net
すいません。
教えてください。
mainの最後まで実行してもプログラムが終了しません。
mainの最後にcout<<"END"<<endl;を入れていてENDが出力されているので
mainの最後に到達していることは確実です。
mainの中ではifstreamを使って6万行のファイルをgetlineでダンプしています。
ifstreamが悪さをしているのでしょうか?
62:デフォルトの名無しさん
17/02/01 22:33:53.13 V+KME3Sb.net
悪さというか 一度出力をバッファリングしておいて
END表示の後に ifstreamのデストラクタ経由でトリガーされた処理で
実際の出力を行う ということはあり得ます
その場合 直ぐには終了してくれないように見えると思います
外してたらごめんなさいですが このケースじゃないかなと
63:デフォルトの名無しさん
17/02/01 22:54:30.09 FDjJl8e/.net
つまりプログラムが終了するまでじっと待てばいいということでしょうか?
5分くらい待ちましたが終了する気配がありませんでした。
64:デフォルトの名無しさん
17/02/01 23:13:45.79 V+KME3Sb.net
もし>>62の場合に当て嵌るなら
ifstreamをスコープの内側にいれてデストラクタをEND出力の前に
呼ぶことは出来るはずです
int main(int argc, char* argv[]) {
{ // このスコープを追加することで
ifstream ifs(...);
...
} // デストラクタが確実に呼ばれていることを保証
cout << "END" << endl;
}
(↑コンパイル通してないので過信しないでください)
この場合だと、ENDが出力されずにプログラムも終了しない事が観察できるかと思います
しかし、(処理の内容が解らないので断定できませんが)
6万行なら5分で終わらないってこともなさそうな気もしますね……
"getline"でダンプということは読み込んでから出力ですよね
んー 大雑把に考えられるのはデバッグビルドで
重いデバッグ用のコードが追加されてるとかでしょうか
……なんとなくこれは外してる気がします すいません
実際のコードと環境を見てみないとなんともってとこです
65:sage
17/02/01 23:43:55.55 FDjJl8e/.net
再現コードです。
end,end2,end3すべて出力されてから固まってしまいます。
何かわかることありますでしょうか?
#include<fstream>
#include<iostream>
using namespace std;
int main(int argc,char **argv)
{
{
ifstream f("list.txt");
if(!f.fail())
{
int i=0;
char l[1024];
while(f)
{
l[0]='\0';
f.getline(l,1000);
cout<<i<<" "<<l<<endl;
i++;
}
cout<<"end"<<endl;
}
cout<<"end2"<<endl;
}
cout<<"end3"<<endl;
}
66:デフォルトの名無しさん
17/02/02 00:06:13.31 XVpKeu5E.net
list.txtの内容は意図どおり表示されてますかね?
こちらの環境(Linux gcc4.9.4, clang3.9.0)だと70000行のデータで
得に問題なく出力、終了しました
67:デフォルトの名無しさん
17/02/02 00:10:41.68 uXhy1oZf.net
意図通り出力されてます。
環境の問題ですか、うーん厄介ですね。
cygwinとx86_64-w64-mingw32-g++.exeというコンパイラでやってます。
とりあえず、コードに問題はないということで、ありがとうございます。
68:デフォルトの名無しさん
17/02/02 00:24:50.02 XVpKeu5E.net
ああ mingwですね 昔よく使ってました
プログラムは終了してても コンソールが残っちゃうってやつはよくありました
なら"-mconsole"(だったと思う) flagをg++に与えて見てください
その辺のフラグで解消できるものだったような気がします
"-mwindows"ってのもあったので逆だったかもしれないんですが…(曖昧
69:60
17/02/02 00:31:49.82 uXhy1oZf.net
cygwinじゃなくてコマンドプロンプトでやったら終了しましたw
謎すぎw
とりあえず、解決?ということでありがとうございました。
70:デフォルトの名無しさん
17/02/02 00:32:54.78 XVpKeu5E.net
ありゃw 了解です お疲れ様ー
71:デフォルトの名無しさん
17/02/02 20:06:20.90 twb4E7Xn.net
数独を解くプログラムについてなんですが縦、横の検索はできても3x3で区切られたブロック内を列挙する方法がわかりません
どうやって3x3で区切られたブロックを列挙すればいいでしょうか?
72:デフォルトの名無しさん
17/02/02 20:35:41.21 uXhy1oZf.net
for文2重にすればええんちゃう?
73:デフォルトの名無しさん
17/02/02 21:30:56.78 uZGYbIMg.net
素直に2*2の4重ループだろ
外側の縦横2重ループでまず探索するブロックを決めて
内側の縦横2重ループでブロック内の全マスを列挙する
74:デフォルトの名無しさん
17/02/03 00:04:44.30 ITjsij3m.net
列挙対象の座標のリストを作るとかもいいかもね。
それなら縦横ブロックを統一的に扱える。
75:デフォルトの名無しさん
17/02/03 08:10:45.56 ptvBupX8.net
俺なら(x, y)座標を格納する構造体を作って、
それを9つ集めた配列、を9つ集めた配列、でやるかな。
3x3のブロックに0-8の添字をつける感じで。
ブロック番号(0-2)を3倍してブロック内座標(0-2)を足す、で
盤面全体での座標値(0-8)を得られる、X軸とY軸についてそれぞれ算出、
というやり方もあるが、この文面で分かりにくいと感じたら
コードを書いても分かりにくい方法かと。
76:片山博文MZ
17/02/03 08:24:14.76 6yKPOmXk.net
f: (x, y) |-> (x * 9 + y).
g: (n) |-> (n / 9, n % 9)
という2つの1対1写像があるから、それを使えばint a[9][9];でもint b[9 * 9];でも同じ結果が得られる。
77:デフォルトの名無しさん
17/02/04 01:09:26.83 2qbguusO.net
書いたぞ。
#include<iostream>
#include<vector>
using namespace std;
class Point{
public:
int x,y;
Point(int a,int b){x=a;y=b;}};
ostream &operator<<(ostream &o,Point p){o<<"("<<p.x<<","<<p.y<<")";return o;}
vector<vector<Point> > point_list;
init_list(){
vector<Point> l;
for(int x=0;x<9;++x){
for(int y=0;y<9;++y)l.push_back(Point(x,y));
point_list.push_back(l);l.clear();}
for(int y=0;y<9;++y){
for(int x=0;x<9;++x)l.push_back(Point(x,y));
point_list.push_back(l);l.clear();}
for(int X=0;X<9;X+=3){for(int Y=0;Y<9;Y+=3){
for(int x=0;x<3;++x){for(int y=0;y<3;++y){
l.push_back(Point(X+x,Y+y));}}
point_list.push_back(l);l.clear();}}}
int main(){
init_list();
for(int i=0;i<point_list.size();++i){for(int j=0;j<point_list[i].size();++j){
cout<<point_list[i][j]<<" ";}
cout<<endl;}
}
78:デフォルトの名無しさん
17/02/04 01:13:42.21 2qbguusO.net
そういや数独ってNP完全なんだっけ?
単純な消去法以外アルゴリズム思いつかんが。
79:デフォルトの名無しさん
17/02/21 13:16:05.38 PhJVPA+A.net
#include <stdio.h>
#include <string.h>
int main(void)
{
char *p, str[32];
scanf("%s", str);
while ((p = strpbrk(str, "ab")) != NULL) *p = 'c';
printf("%s\n", str);
return 0;
}
"ab"の文字列を"c"に置換したいんだけどaもbも一文字ずつ置換えられて"cc"ってなってしまう
どうすりゃいいんですかね…
80:デフォルトの名無しさん
17/02/21 15:20:35.77 7lKrpDmc.net
strpbrk() は「第2引数の文字列に含まれる文字のどれか」への
ポインタを返すから strpbrk(str, "ab") だと返るのは
文字'a'の位置か文字'b'の位置だよ。
"ab"という部分文字列の位置が欲しいなら strstr(str, "ab") を使うべき。
加えて "ab" を "c" に置換したい場合、置換後の字数が減るのだから、
'a' を 'c' に上書きした後、strの'b'より後ろを1byteずつ詰めなきゃならない。
もっと一般的な文字列置換関数を作るとなると、かなり面倒だわね。
81:デフォルトの名無しさん
17/02/21 15:30:30.87 2UxBH0C2.net
if(strcmp(str, "ab") == 0); strcpy(str, "c");
これじゃあかんの?
82:デフォルトの名無しさん
17/02/21 15:32:19.27 2UxBH0C2.net
0ab0→0c0って事なら忘れて
83:デフォルトの名無しさん
17/03/19 06:58:05.16 o9adXXiq.net
C言語ではないんですが、以下の事について教えて頂けないでしょうか?
"algo": "Lyra2REv2",
"threads": 0,
"cpu-priority": 0,
"cpu-affinity": -1,
"benchmark": false,
"debug": false,
"protocol": false,
"quiet": false
cpuminer-multi-windows の設定をしているのですが
"threads""cpu-priority""cpu-affinity"が何をさしているのか
よくわかりません。
私は8コア16スレッドのCPUを二個搭載しているPCを使っているのですが
CPUをフルに活用できるように設定したいのです。
ご助力頂けると幸いです。よろしくお願いします。
84:デフォルトの名無しさん
17/03/19 07:18:53.13 bkt1N2YW.net
Cのことじゃないなら何のことなのかぐらい書けよ
モナコインか発掘か?だったらそのスレで聞けよ。シネ
85:デフォルトの名無しさん
17/03/19 14:10:20.03 oNRFZCzo.net
俺は煽り・叩きをしない人間だが、今回ばかりは83への同情を禁じ得ない
86:デフォルトの名無しさん
17/03/19 14:43:20.30 o9adXXiq.net
返事ありがとうございます
まず、何の言語かわからなかったのと
モナコインの質問板がなかったの、ここに書き込みました
向こうのどっか適当なところに書き込みします
お騒がせしました
87:デフォルトの名無しさん
17/03/19 15:18:21.74 cwNaGN41.net
何の言語かわからなくても質問できるスレだってあるのににに
88:デフォルトの名無しさん
17/04/13 08:52:14.43 G0/b3aDb.net
class Parent{
int i;
};
class Child : Parent{
char ch;
};
Parent *ptr = new Child();
delete ptr;
こういうことをした時にメモリを確保するときはChildの変数chの分まで多くメモリを確保してると思うのですが
解放するときにちゃんとchの部分も解放されますか?
delete (Child*)ptr;
みたいにしないとダメですか?
89:デフォルトの名無しさん
17/04/13 09:47:58.57 xWAyKptX.net
>>88
デストラクタがvirtualなら必要ないけどこの場合違うからキャストが必要かな
90:デフォルトの名無しさん
17/04/13 09:54:46.51 knppr/uB.net
>解放するときにちゃんとchの部分も解放されますか?
されない
>delete (Child*)ptr;
>みたいにしないとダメですか?
それでも解放はできるけど、それじゃ継承の利点であるポリモーフィズムが台無しになるので
デストラクタを仮想関数にするのが常套手段
class Parent{
int i;
public:
virtual ~Parent(){}
};
class Child : public Parent{
char ch;
};
91:デフォルトの名無しさん
17/04/13 10:33:00.51 G0/b3aDb.net
>>89
>>90
ありがとうございます
92:デフォルトの名無しさん
17/04/13 11:21:16.25 Wi4DC5Bh.net
>>88
当然される
これだけならデストラクタの出番もない
>delete (Child*)ptr;
こういうのはNG
93:デフォルトの名無しさん
17/04/13 11:54:43.94 G0/b3aDb.net
どっちを信じたら良いんですか!?
94:デフォルトの名無しさん
17/04/13 12:59:56.01 knppr/uB.net
基底クラスのデストラクタはvirtualにしておけ
>>92も間違いでは無いが、chの型が変わっただけで前提が崩れる話だよ
95:デフォルトの名無しさん
17/04/13 13:07:52.52 grSNqbAR.net
誰かが答えた後にでてきて何の説明もなくただ前の否定や異なる結論だけを言うやつは
(結果的に正しいことだったとしても)無視すればええんや
96:デフォルトの名無しさん
17/04/13 21:32:13.97 r2gjPspU.net
確かに
97:デフォルトの名無しさん
17/04/13 21:49:16.84 Qxk7VllX.net
せやな
98:デフォルトの名無しさん
17/05/06 11:45:32.33 3nLTZXlU.net
深い階層を表すのに適したデータ構造というかクラスはなんですか?
unordered_mapを使ってキー/値のペアで作ったツリー構造があるんですが、
最適化をオフにすると500くらいの深さでもスタックオーバーフローが起きてしまいます。
Visual Studioを使っているのでReleaseビルャhのC++ライブラリとDebugのものは組み合わせられないし、
かといって常に最適化オンだとデバッグが不便です。
何かいい方法はありませんか?お願いします
99:デフォルトの名無しさん
17/05/06 13:56:44.08 f2NDPPRD.net
それだけじゃ何がしたいかさっぱり分からんけど
Compositeパターンでぐぐって出てくる奴とか参考にならんかね
100:デフォルトの名無しさん
17/05/06 14:11:14.45 yLSgVzXR.net
スタックオーバーフロー?データ構造の問題じゃないと思われ
問題再現できるコードを上げるでもしないと誰も答えられないよ
101:デフォルトの名無しさん
17/05/06 15:30:45.88 DLhZv41T.net
>>98
一般的には木構造で問題ない
ただ自分で実装する時に単純にノードの処理関数を子ノードに対して再帰的に呼び出す実装にしていると
階層が深くなったときはコールスタック不足でスタックオーバーフローになるので
ループで処理するとかの実装にしておく必要がある
102:
17/05/06 15:50:22.00 ZHaoNFoL.net
木構造のループですか‥やってできないことはないだろうけれどもめんどくさいね goto の連発だね
103:97
17/05/06 16:02:38.76 3nLTZXlU.net
遅くなったけどideone用に書き換えたコードがこれです
URLリンク(ideone.com)
やりたいことは単に階層構造のテキストデータを読み取って、置換したり変形することです。
Visual StudioでDebugビルドしたものを実行すると、id: 248 とか表示されるあたりでスタックオーバーフローが起きて停止します。
ちょっと調べたところだと再帰→ループへの展開は定番みたいですね。
そっちの方向で考えてみたいと思います。どうもありがとうございます。
(…でも、250程度の数の階層くらい頭を使わずに書いたコードでも動いてくれという気がスル)
104:デフォルトの名無しさん
17/05/07 09:09:11.08 w48Ptm+H.net
>>103
こっちのVS2015でも再現しました
スタックサイズ1M(デフォルト)→2Mにしたら動いたけど
105:デフォルトの名無しさん
17/05/07 10:23:46.07 czCtMb/5.net
>>103のコードってどこで再帰処理してるの?
106:デフォルトの名無しさん
17/05/07 10:34:34.49 w48Ptm+H.net
>>105
Dataのデストラクタ実行後に(暗黙的に)実行されるsubitemsの解放処理
107:デフォルトの名無しさん
17/05/07 10:58:59.52 czCtMb/5.net
>>106
にゃるほどね
どうもありがとう
108:デフォルトの名無しさん
17/05/09 04:51:17.39 CfLPAbNS.net
C.C++で初めて作ったのってみんな何?
109:デフォルトの名無しさん
17/05/09 05:45:43.95 A9/kHnP9.net
Hello world
110:デフォルトの名無しさん
17/05/09 13:14:48.03 ZO11Ha1i.net
>>106
gcc7.1.0だとdeleteがループ処理になってるな
Clang4.0.0でも同じ
VC2017でもスタックサイズ変更なしで行けた
111:デフォルトの名無しさん
17/05/11 17:34:15.21 9hjkljzx.net
ああ、独り言だしスレ違いだからスルーして。でも、どうしても言いたいし、雑談スレもないから
ここに書かせて。。
俺はC/C++が大好きなんだけど、GtkとかQtとか大好きなんだけど、Pythonが両方バインドしてるから
使ってみたんだけど、import文がある言語(Java、D言語、Python)って脳の向きと逆向きに設計されてね?
すげえ、違和感あって、使ってるとキモくなってくる。その点、include文はいいわ・・。大好き。
112:デフォルトの名無しさん
17/05/11 19:24:16.98 BuwAxFWP.net
JavaとCがそれほど違うようには感じられないけど
113:デフォルトの名無しさん
17/05/11 19:46:38.79 9hjkljzx.net
クラスの構造とかどうしても合わんわ。。あと、普通に文書いてても違和感感じるw
114:デフォルトの名無しさん
17/05/11 20:44:47.50 r6M771XX.net
>>111
前方宣言自動でやってくれてるって思えば他はCと変わらない気がするけど。
どの辺が違うん?
115:デフォルトの名無しさん
17/05/11 22:53:38.75 LJGZTDJk.net
ファイル名に制約がかかる言語なかったっけ?
Java?
116:デフォルトの名無しさん
17/05/11 23:24:48.41 1a/5L+8A.net
javaは知らないがCは制約ある
正確にはファイル名じゃなくてincludeで指定する文字列だけど
117:デフォルトの名無しさん
17/05/12 07:20:43.83 yoAOukLs.net
Cのexport文と一対一になってないというだけの話じゃね
118:デフォルトの名無しさん
17/05/12 07:25:29.38 r7FlYbQi.net
C#のusingも同じなのかな
やっぱいまいちわからん
119:デフォルトの名無しさん
17/05/12 09:45:14.44 gCSxRRWi.net
Cの制約って何だ?
vs2015だが、ファイル名全角スペースでもエラーでない
120:デフォルトの名無しさん
17/05/12 12:06:01.20 OCYL1E3A.net
>>115
Javaは何だっけ。。。
publicだかmainのあるクラスと同じファイル名じゃないととか、importの階層と同じだけフォルダ掘らないととかあった希ガス。
121:デフォルトの名無しさん
17/05/12 13:40:23.46 FoBe9UZW.net
C++から3年ほど遠ざかっていた俺に最近のC++の何か凄いテクニックを教えてくれ。
122:デフォルトの名無しさん
17/05/12 13:51:20.92 YITQwMx2.net
c++1zで使えるようになるvariantとかどうかね
(記述の見掛け上という意味で)継承を使わず 多態を実現できる
現状はboostでお試し可能
123:デフォルトの名無しさん
17/05/12 16:47:43.02 FoBe9UZW.net
>>122
サンキュー
ググってみるわ
もう浦島太郎状態
124:デフォルトの名無しさん
17/05/12 19:18:49.01 fokGnnSL.net
>>119
vcがそう実装してるだけで、他の処理系も同じようにエラーがでない保証はない
最低限のラインは、8文字+「.」+1文字で英数字のみ、ただし先頭は英字のみ、大文字小文字を区別する保証なし
規格上、inludeの文字列とファイル名が一致するかも定かでないから、気にしても無駄だけど
125:デフォルトの名無しさん
17/05/12 19:23:40.34 WYsaiAgn.net
たぶんCに制約はないだろ
126:デフォルトの名無しさん
17/05/12 20:53:24.64 37oyzgXT.net
ファイル名に「<」や「>」とか含んでいると困るの
127:デフォルトの名無しさん
17/05/13 07:23:06.14 bjLbBbns.net
ファイル名に制約という提起で
まさかファイル名や#includeに使えない文字の話になるとは思ってなかった
128:デフォルトの名無しさん
17/05/13 08:04:09.13 DnMUFoIp.net
2chだからな
129:デフォルトの名無しさん
17/05/14 16:50:22.30 gwLsZ5pp.net
あるアルゴリズムをメソッドとして実装したクラスがあって、
そのアルゴの中で20個くらいの定数を用いる。
そのアルゴリズムの亜種をサブクラスとして作りたいが、その亜種の中では定数の値を親クラスの値とは違う値にしたい。
こういう時、定数群はどうやって定義するのがいいでしょうか。
メンバ変数として全部const intで持っておいて、
コンストラクタの初期化の文法で各クラス固有の値を入れればいいでしょうか。
できれば外部ファイルにjasonとかで持たせられないかとも思ってもいますが、それだとコンストラクタ内のconst intの初期化より先には読み込めないですよね。
浅学で恐縮です。よろしくお願いします。
130:デフォルトの名無しさん
17/05/14 16:59:28.84 C90eDFbL.net
亜種が定数が違うだけならコンストラクタでええんでない?
アルゴリズムも似てるだけで少し違うとかなら使えんかも知らんけど
131:デフォルトの名無しさん
17/05/14 17:42:51.46 abQtpPi4.net
>>129
定数ではなくメンバ変数でいいじゃないの?
外部から変更されたくないなら読み取りプロパティにすればよいし
亜種はサブクラスのインスタンス作成時にファイルを読み込むようにして
親クラスのメンバ変数を上書きするようにする。
132:デフォルトの名無しさん
17/05/19 19:46:36.77 BDF1+v1a.net
コピーコンストラクタのところでエラーがでます。
>オブジェクトにメンバー 関数 "A::getFileName" と互換性のない型修飾子があります
>C2662 'const std::string &A::getFileName(void)': 'const A' から 'A &' へ 'this' ポインターを変換できません。
どう直せばいいのですか?
class A {
public:
A() {}
A(const A &a) {
this->setFileName(a.getFileName()); //ここでエラー
}
void setFileName(const std::string& fn) {
this->m_fileName = fn;
}
const std::string& getFileName() {
return this->m_fileName;
}
private:
std::string m_fileName;
};
133:デフォルトの名無しさん
17/05/19 20:33:23.63 iLAnMNZa.net
linux mint18 32bit
python3をF5で実行できるエディターは無いでしょうか?
Geany 1.27ではpython2.7なので、python3.5を使用したいと思ってます
PC自体にはpytho3.5と2.7が入ってます
134:デフォルトの名無しさん
17/05/19 20:34:44.55 iLAnMNZa.net
間違えました
135:デフォルトの名無しさん
17/05/19 21:14:19.37 gHk1Pzkh.net
>>132
A::getFileNameがconstメンバ関数ではないから
const std::string& getFileName() const {
136:デフォルトの名無しさん
17/05/19 22:24:40.24 BDF1+v1a.net
>>135
そういうこと
ありがとう
137:デフォルトの名無しさん
17/05/25 22:25:27.96 QzzPv//a.net
クラスのメンバ関数のポインタはすべてのインスタンスに共通で
例えばvectorに自作クラスを入れといてあとから要素の挿入・削除をして
インスタンスのメモリ上の位置が変わっても関数のポインタは変わらない
って理解であってますか?
138:デフォルトの名無しさん
17/05/25 23:22:02.15 WUcUkfwI.net
はい
関数の配置アドレスが実行時に変わるなんてことは起きないので
ちなみに同じインスタンスなのにメモリ上の位置が変わるなんてこともないと思うが
139:デフォルトの名無しさん
17/05/28 16:14:14.69 yvANlV24.net
Eigenに
operator*
でなくて逆向きかけ算の関数rdotを追加したい
つまり
some_object * eigen_matrix
するために
Eigen::EigenBase<Derived>::rdot
を追加して
eigen_matrix.rdot(some_object);
で計算できるようにしたい
しかし
no member function declared in class
というエラーになる
どうやったら後付けでmember function追加できるんだ?
Eigenの中はいじりたくない
140:デフォルトの名無しさん
17/05/28 21:29:06.26 p7YrRaRu.net
元のクラス定義を変更せずにクラスにメンバ関数を追加することはできない
141:デフォルトの名無しさん
17/05/28 23:55:15.37 T1SZ8kqz.net
継承したらダメなんか?
142:デフォルトの名無しさん
17/06/01 07:42:47.62 SDX804Eo.net
Eigen3の実装みてるんだけど
class Matrix{
operator * const ...
}
でほとんどの関数がconstで統一されてるのに
transposeだけconstついたのと,ついてないの2つあるのは何故?
143:デフォルトの名無しさん
17/06/01 10:34:56.04 tub0QHg4.net
そのほうが便利だ(と作者が思った)からだろう
const版
返されたtransposeはconstで変更不能
非const版
返されたtransposeは変更可能
変更すると間接的に元のmatrixも変更される
144:デフォルトの名無しさん
17/06/02 21:10:48.66 hdQ1KfrD.net
プログラミング言語C++第4版の本を今頑張って読んでいます。
その中で、サンプルコードは著者のサイトでとURLが乗っているのですが、
これがトップページのURLしか書いてなくてどこからダウンロードできるかわからない状態です。
いろいろ調べたら、グーグルコードのサイトに飛ぶ場所を見かけたのでDLできるかと思いましたが、
グーグルコードは去年の一月には廃止されていて、ダウンロードができない状態です。
ほかにサンプルコードダウンロードできるような場所はあるのでしょうか。
色々と探しても同じような人は見当たりませんし、困っています。
どなたかご存知の方いらっしゃらないでしょうか。
145:デフォルトの名無しさん
17/06/02 22:06:31.65 uqHV+hQL.net
本持ってないけどこのページ上のリンクからダウンロードできるやつではないの?
URLリンク(code.google.com)
146:デフォルトの名無しさん
17/06/03 13:03:58.47 7x/augC4.net
>>145さん
返信ありがとうございます。
ダウンロードばかり気にしていたのかソースというところに気が付きませんでした。お恥ずかしい。
普通にダウンロードできまして、ソースも確認できました。
testingのソースコードが本に書いてあるコードと大体同じように書かれてたのでこれだと思います。
ただ、入門書ってわけじゃないからなのか、洋書だからなのかわかりませんが、
本で書かれているコードだいぶ端折っているなっていう感じなので、正確にこのサンプルで問題ないのかがわからないです。
147:デフォルトの名無しさん
17/06/03 13:12:54.00 7x/augC4.net
143,145です。
すいません。145はなんか途中で書き込みをしてしまいました。
話を戻しまして、
でも、問題ないかがわからないのは、本もまだほとんど読めてないのと、C++も入門書を一回軽く読んだ程度の知識しかないので、わからないだけだと思いますので
本(サンプルも)を参考に自分でソースコードを記述していきたいと思います。
>>145さんのおかげで、ソースも手に入り、教えてもらったことで、モチベーションもあがりました(^^♪)
次に進めそうです。本当にありがとうございました。
148:デフォルトの名無しさん
17/06/09 00:20:22.42 8CSNtvHv.net
他の言語結構熟練してたらべつだけど、
cプラにほとんど慣れてない状態で
この本を読んでも効率わるいだけとおもうがねぇ。
149:デフォルトの名無しさん
17/06/09 00:30:02.53 8GQEdlWI.net
勉強してる気になれるからいいんだよ
150:デフォルトの名無しさん
17/07/01 12:35:47.56 ID6W3bit.net
スタティーック!
151:デフォルトの名無しさん
17/08/08 00:05:19.81 O9M7bV7S.net
C言語の関数ポインタというものは関数ポインタとして作られたのか通常のポインタの改良なのかどちらなのでしょうか?
関数ポインタの引数の仕組みがよく分からなかったので質問してみました
よろしくお願いします
152:デフォルトの名無しさん
17/08/08 00:42:15.53 m8GLf68F.net
言ってる意味が良くわからないが
ポインタの性質は「型」で決まる
あるデータをどのように見なすか
それだけ
32bitだか64bitだかのデータを、文法上どう見なすかってだけ
関数ポインタの場合は関数のエントリーポイントと見なす
引数の数や種類や呼び出し方などは、型が知っている
型に基づいて呼び出すだけ
153:デフォルトの名無しさん
17/08/08 02:23:09.82 SgAIOr6T.net
>>151
極論言えば、配列のポインタも関数のポインタもただのポインタ。
対象が配列だから配列的にも振る舞える。
関数だから関数的にも振る舞える。
ただそれだけやね。
型は配列的とか関数的とかに振る舞う時のルール引数得るのに何回スタックからpushするかとかを教えるヒントにすぎない。
この辺はアセンブラ知ってると理解しやすいかもね。
154:デフォルトの名無しさん
17/08/08 02:24:25.91 SgAIOr6T.net
あ、スタック「から」だとpopやった。。。
155:デフォルトの名無しさん
17/08/08 22:52:38.23 O9M7bV7S.net
変数のポインタはint *i;でアドレスだけを保持していて
関数ポインタはint (*func)(int i);でアドレスと引数リストを保持しているように思えます
引数が必要なのは分かりますが(int i)を勝手に付け足しても良いものなのかなと思いまして
156:デフォルトの名無しさん
17/08/08 23:34:37.02 fmd6E2St.net
>>155
関数ポインタは、関数を指すポインタという意味。
引数リストは保持していないが、関数ポインタがポイントしている関数のプロトタイプは
コンパイラなら知ってるかもしれない
157:デフォルトの名無しさん
17/08/08 23:44:08.72 nf4ZHvzc.net
>>155
何したくて何ききたいのかさっぱりだな
アドレスだけ見せられても、それが変数のアドレスなのか、関数のアドレスなのか、変数なら型は何なのか、関数なら引数あるのかないのか、あるならその型は・・・
アドレスだけじゃ解決できないよ
158:デフォルトの名無しさん
17/08/08 23:55:54.36 rlbWG25h.net
>>155
住所だけ渡されても実際に行ってみたらわかるのと一緒で
ポインタはあくまでアドレスを格納してる
民家なのか病院なのか学校なのかは重要ではない
住所・アドレスの示す先にある情報を利用するだけ
159:デフォルトの名無しさん
17/08/09 00:47:51.09 hEgnFYnk.net
int *p;が逆参照したときにintとして扱えるように
int (*p)[10];が逆参照したときに配列として扱えるように
(君の言い分だと↑も[10]を勝手に付け足しているように見えるのかもしれないが)
型というものがあって、コンパイラは型を知っているから正しくアクセスできる
同じように
void (*p)(int i);としたとき、pはintを引数に取る関数のポインタという「型」になるから
その型をもってしてコンパイラは関数を呼び出せる
そう考えれば(int i)が付くのも当たり前、それが必要だからそういう文法になっている
「アクセスするときに必要となる情報を型として与えているのだよ」
特にCの場合は「そう見なしてくれ」という意味合いが強い
キャストして型を変えれば割とどうとでもなる面白い言語
単なるメモリブロックを配列や構造体と見なしてアクセスしたり
こういうことが出来る言語はあまりないので
低レベルでは未だにC系の言語が重宝されている
160:デフォルトの名無しさん
17/08/09 00:52:32.88 hEgnFYnk.net
ちなみに
>>158は間違ってるから気にしなくてよいよ
C言語は静的型だから「実際に行かなくても先にあるものが分かる」
というか、先に何があろうが、「型」の示すものがあるものとして扱う
だから、病院の型のポインタに君の家のアドレスを入れたら
君の家に病人が殺到してバグる
キャストしなければそういう代入は出来ないようになっているがな
161:デフォルトの名無しさん
17/08/09 01:02:42.02 hEgnFYnk.net
逆に、C言語は静的型だから、「実際に行ってみても、それが何であるか分からない」
住所に行ってみても、名札も無ければ看板も無いので、それが何なのか分からない
そういった情報は全部メタ的に「型」にしかない
そして型はコンパイル時のコンパイラしか知らない
コンパイル後のコードには型情報は綺麗さっぱり消えてなくなってる
C言語はデータになんであるかを示す型情報が無い
実行時にデータから型を取得することはできない
なんで、関数ポインタの型にはそれを通して関数を呼び出せるだけの情報が必要
そういうことが出来る文法になってる
162:デフォルトの名無しさん
17/08/09 01:04:32.68 hEgnFYnk.net
>そして型はコンパイル時のコンパイラしか知らない
あとプログラマとね
163:デフォルトの名無しさん
17/08/09 01:31:24.27 6o6it4hw.net
ありがとうございます
質問が分かりづらかったようですみませんでした
intとして扱えるポインタの型や配列として扱えるポインタの型、関数として扱えるポインタの型と言うようにポインタにも幾つかの型があるんですね
ようやく皆さんの言っていることが分かりました
他にもどんな型があるのか知りたいのですが、こういったことはどこに書いてあるのでしょうか?
164:デフォルトの名無しさん
17/08/09 10:28:38.52 RdtvDY+v.net
>>160
あぁ型を除いてあくまで「ポインタ」だけに言及しただけだ
「型に家だの病院だのの情報が含まれている」と言っておけばよかったか
165:デフォルトの名無しさん
17/08/09 13:08:26.15 FEqENNu4.net
>>163
なんか勘違いしてる。
ポインタはポインタが指す先のデータ型をポインタの型と言ってるだけで、
ポインタに根本的に異なる種類があるわけじゃない。
たまに見る「ポインタはアドレスだ」っていうのはそういう意味だけど、
アドレスという言い方は初心者には分かりやすいかもしれないけど
不正確なので、そういうレスは要注意
166:デフォルトの名無しさん
17/08/09 17:47:06.00 Nvjd+alY.net
もう面倒だから void *p
167:デフォルトの名無しさん
17/08/11 11:07:36.66 Ca8C76qb.net
>>165
アドレス、でいいと思うよ、どんなときに不正確になるの?
168:デフォルトの名無しさん
17/08/11 11:37:15.24 nYt6U0do.net
>>166
昔、voidっていう人いたよね
169:デフォルトの名無しさん
17/08/11 12:03:58.06 Ca8C76qb.net
日下部さんだね、一連の馬鹿吊り上げの手法はたいしたものだ
彼にかかると面白いように釣れるんだね
170:デフォルトの名無しさん
17/08/12 11:18:07.25 gBGehi2j.net
>>167
void型のポインタに関してはアドレスでいいと思うよ
171:デフォルトの名無しさん
17/08/15 11:27:23.66 I1PHUuyRO
#include<iostream>
using namespace std;
int main() {
template <typename T>
T sum(T a, T b) {
return a+b;
}
cout <<"Sum = " << sum( 2.1, 7.9 ) << endl;
return 1;
}
上記コードをclang++でコンパイルした所、以下のエラーが出ましたが、
どこが間違っているのでしょうか?
error: expected expression
template <typename T>
^
172:デフォルトの名無しさん
17/08/22 14:42:32.63 a5iq0eNT.net
>>167
++演算子使ったときとか
ヌルポインタとか
173:デフォルトの名無しさん
17/09/09 17:22:28.03 ua/r5C7o.net
ヌルポはアドレス0を示すポインタと区別が付かない。
ポインタ演算はアドレス計算で間違いないと思うが。
174:デフォルトの名無しさん
17/09/10 01:13:46.17 kRb3fDCd.net
0を示すものに1を加えたとき、1になって欲しいのがアドレス
そうとは限らないのがポインタ
175:デフォルトの名無しさん
17/09/10 01:41:24.87 ZBmzdD/d.net
なら、そこまで言うなら
アドレスには型が無い、あっても整数型、intptr_tとか
ポインタには型があって、*や->や()を使って指し示すものにアクセスできる
という大いなる違いがある
アドレスを静的型でラップしたものにポインターという名前を付けた、程度
176:デフォルトの名無しさん
17/09/10 01:52:16.37 tW3VD+Zp.net
その程度違いがあるから、アドレス≠ポインタだね
177:デフォルトの名無しさん
17/09/10 11:43:30.44 Yx0nU1n/.net
>>173
ヌルポしたけど sage だから失敗
178:デフォルトの名無しさん
17/09/10 22:38:52.49 6lPEiBMC.net
アドレス値を入れる種類の変数(の型)≡ポインタ
179:
17/09/17 13:05:36.48 bgx1+MxI.net
アドレスとポインタは一緒だとおもうよ,ポインタに型がある,とかいうのはCコンパイラ言語仕様側の都合にすぎないし
アドレスの整数値とポインタの表現する整数値が食い違う例(ただし NULL とか far/near はわかっているから除く:-)ってそんなにないんじゃないの?
180:デフォルトの名無しさん
17/09/17 14:44:48.15 qULdwsa1.net
アドレスとポインタは違うと思うけどなあ
アドレスは数値そのもの、ポインタはその入れ物
だから「int型のアドレス」とは言わないし、「ポインタ0x12345678番」とは言わないし
181:デフォルトの名無しさん
17/09/17 15:07:54.63 KmM7k2LQ.net
>>180
これが正しい
182:デフォルトの名無しさん
17/09/17 15:32:04.84 dEX9B4aF.net
入れ物をインクリメントするのも変だよな。
183:デフォルトの名無しさん
17/09/17 15:45:07.67 iyMogwhx.net
>Cコンパイラ言語仕様側の都合にすぎないし
あほだなぁと思うのは、ここで言うポインタというのは
C言語の仕様で定められたポインタのことじゃないのか?
C言語の仕様として「ポインタ」が定められていて
それに関してどうこうって時に
C言語の仕様の都合だから~とかイミフ
C言語のポインタにC言語の仕様以外の意味なんかないだろ
184:デフォルトの名無しさん
17/09/17 15:50:42.26 53PrWSTF.net
>>183,180
これだなw
185:デフォルトの名無しさん
17/09/17 16:21:54.39 qULdwsa1.net
>>182
インクリメントしているのは入れ物の中身では?
186:デフォルトの名無しさん
17/09/17 16:52:30.92 nfmsAfUe.net
>>180の例えだと中身はアドレスってことになるが、ポインタのインクリメントは
アドレスのインクリメントとは違うだろう。
187:デフォルトの名無しさん
17/09/17 17:01:41.39 qULdwsa1.net
「アドレス0x12345678番をインクリメントする」のだから間違いでは無いと思うよ
ただ数値をいくつ増加させるかはポインタの型(つまり入れ物の型)に依存する
188:デフォルトの名無しさん
17/09/17 17:24:14.07 nfmsAfUe.net
だからそれがポインタのインクリメントだろう。
わざわざ入れ物だ中身だと意味がよくわからない例えは余計。
189:デフォルトの名無しさん
17/09/17 17:30:00.83 dEX9B4aF.net
>>187
「アドレス0x12345678番をインクリメントする」は、
a=0x12345678で、*a++ ではないか?
190:デフォルトの名無しさん
17/09/17 17:30:33.37 qULdwsa1.net
何が言いたいのか良く分からないんだが
アドレスとポインタは違うものでポインタはアドレスを入れるものってだけの話だよ
アドレスそのものに型はないがポインタには型がある
ポインタのインクリメントとは、ポインタの型に従ってアドレスをインクリメントする
191:デフォルトの名無しさん
17/09/17 17:31:34.74 53PrWSTF.net
いちゃもんレベルだなw
192:デフォルトの名無しさん
17/09/17 17:34:55.50 qULdwsa1.net
>>190は>>188宛ね
>>189
表現が悪かったね
「アドレスが指すデータをインクリメントする」じゃなくて「アドレスそのものをインクリメントする」だよ
4バイト長のデータなら「アドレス0x12345678番を0x1234567C番にインクリメント(増加)する」
193:デフォルトの名無しさん
17/09/17 17:55:30.80 KmM7k2LQ.net
>>178 >>180 >>190 が正しいだろ
ポインタとアドレスをごっちゃにしてる馬鹿は入門書からやり直せ
194:デフォルトの名無しさん
17/09/17 18:45:32.71 dEX9B4aF.net
ポインタ型変数がポインタなのか?それに入っているのがポインタなのか?
もしかしたらポインタというのは存在しないのではないか?
195:デフォルトの名無しさん
17/09/17 18:58:47.30 iyMogwhx.net
何を訳の分からないことを言ってるんだ?
Cの規格書に出てくるんだからあるに決まってるだろ
当たり前だがポインタ型変数に入っているものはポインタだ
多くの処理系で機械語レベルでは単にアドレスというだけ
同じように浮動小数点型変数に入っているものは浮動小数点だ
これも多くの処理系で機械語レベルではIEEEのホゲホゲというだけ
196:デフォルトの名無しさん
17/09/17 20:45:56.11 dEX9B4aF.net
>>195
つまり、機械語レベルではアドレスと言うものが、Cではポインタと言われているのか?
197:デフォルトの名無しさん
17/09/17 21:07:31.82 53PrWSTF.net
基本的にポインタの値は低レベルではアドレス値だけど
機械語レベルではアドレスと言うものがCではポインタと言われているとは限らない
198:デフォルトの名無しさん
17/09/17 22:10:04.90 iyMogwhx.net
多分、根本的に、型というものが理解できてないんだと思うよ
199:デフォルトの名無しさん
17/09/17 22:18:43.93 dEX9B4aF.net
>>197
ちょっと待って。そこをはっきりさせてくれよ。
200:デフォルトの名無しさん
17/09/17 22:25:24.89 iyMogwhx.net
AならBだけど、BならAとは限らないってだけ
これぐらいは高校の数学で習うだろ
もしくはアップキャストは常に成功するけど
ダウンキャストは成功するかわからない、といったところか
201:デフォルトの名無しさん
17/09/18 02:34:06.85 5sYblZKp.net
char *p のとき、
p はポインタ?それともポインタ型変数?
pに入っているのはポインタ?それともアドレス?
ポインタってどれ?
202:デフォルトの名無しさん
17/09/18 02:55:32.19 dIhl3VcQ.net
>>201
pは(char)ポインタ型変数で、入っているのは(char)ポインタ値
ポインタ値の実態はアドレスでかつ整数値のことが多いってかそれ以外の環境は見たことも聞いたこともないな
203:デフォルトの名無しさん
17/09/18 03:23:36.62 5sYblZKp.net
>>202
ありがとう。
ちょっと考えてたんだけど、やっぱりchar型ポインタとかint型ポインタってのはないんじゃないのかな。
インクリメントしたときにいくつ増えるかはポインタ変数の型で決まるだけだし。
204:デフォルトの名無しさん
17/09/18 03:35:36.95 dIhl3VcQ.net
>>203
char型ポインタ型だとなんか被ってるから省略してるだけじゃないかな
charポインタ型でもいいと思うけど。さらに言えばcharポインタでも通じると思う
205:デフォルトの名無しさん
17/09/18 10:09:10.30 Rs/BRyvp.net
>ちょっと考えてたんだけど、やっぱりchar型ポインタとかint型ポインタって
>のはないんじゃないのかな。
int i; char c;
&i //int型ポインタ
&c //char型ポインタ
206:デフォルトの名無しさん
17/09/18 16:51:15.62 XDi5i+Jp.net
>>197
>機械語レベルではアドレスと言うものがCではポインタと言われているとは限らない
具体例は?
207:デフォルトの名無しさん
17/09/18 18:57:32.72 gSdMoaKK.net
jmp addr
208:デフォルトの名無しさん
17/09/19 12:42:20.85 1YUfQXAj.net
それは関数へのポインタじゃないの?
209:デフォルトの名無しさん
17/09/19 13:21:39.96 87FEHvFq.net
jmpだけ見せられたらそれはcだとgotoかな
もちろん関数ポインタもあり得るし、ほかにも逆コンパイル先はあり得る
210:デフォルトの名無しさん
17/09/19 18:10:22.48 PcYxkZC9.net
どーでもいい話になったら伸びるねこのスレ
211:デフォルトの名無しさん
17/09/19 19:47:23.33 ruUa1Ruj.net
>>208
ifとかの分岐でもjmpは生成されるだろ
212:デフォルトの名無しさん
17/09/19 19:52:37.77 87FEHvFq.net
jneとかじゃないか?
213:デフォルトの名無しさん
17/09/20 13:01:55.83 hO1kkbas.net
関数へはcallだね。Z80だと。
214:デフォルトの名無しさん
17/09/30 01:34:37.34 /jgYbdHq.net
関数は飛んだあと戻ってこないとだめだからね
飛ぶ前のアドレスをpushして飛ぶ
そこがjmpとの違いなんだが...
まあ高級言語しか使ったことない人にはあまりそのあたりがわからないのだろう
215:デフォルトの名無しさん
17/09/30 06:58:10.31 SQk+Dlf1.net
>>214
callない変態コアもあるけどなw
216:デフォルトの名無しさん
17/09/30 10:25:39.90 BYym2Kja.net
C/C++ とあんまり関係ない話題に乗るのは気が引けるけど…
メモリへの読み書きを避けるために
戻り先アドレスをスタックに積まないCPUもあるよね。
PCの値をレジスタにコピーしてジャンプ。
リターン時にはレジスタからPCにコピー。
ARMのサブルーチン呼び出し命令が "BL" だからって変態あつかいするな。
217:デフォルトの名無しさん
17/10/01 06:44:43.98 wTXYROVe.net
>>216
>戻り先アドレスをスタックに積まないCPUもあるよね。
RISC CPUだとだいたいそれだな
リンクレジスタというのが用意されててサブルーチンコールの戻り値がリンクレジスタに格納される
スタックに戻り値を積みたい場合は手動でスタックに積む
MIPS、ARM、POWER、SPARCなどみんなこれ
218:214
17/10/01 07:54:30.40 TsPEHv68.net
214 に補足。またもC/C++と無関係ですまぬ。
投稿時には意識していなかったけど、
BL命令で「さぶ」ルーチンだから辻褄は合ってる、かも。
流石ARMさんは紳士の国イギリスの会社だなぁ。
219:デフォルトの名無しさん
17/10/01 09:14:55.87 qGSPhC6b.net
>>218
すまんどゆこと?
220:デフォルトの名無しさん
17/10/01 10:08:25.18 9UECfosW.net
うん。まったくわからん。興味ないけど
221:デフォルトの名無しさん
17/10/02 19:28:33.83 ur7JCHdr.net
おそらく、しゃぶるーちん って事でしょ
222:デフォルトの名無しさん
17/10/02 19:30:14.39 oqL7c7am.net
おおさぶっ!
223:デフォルトの名無しさん
17/10/04 12:08:31.97 QGS2LkxJ.net
デバックの為自分の昔のコードを読むと
難しくて理解するのに時間がかかったりして
己の衰えを自覚するよな
224:デフォルトの名無しさん
17/10/04 12:47:05.65 oXiXRVKi.net
数年前の自分は他人みたいなもんだしな
225:デフォルトの名無しさん
17/10/04 17:28:18.58 N0mfbhbs.net
コーディングスタイルが変わっちゃってたり、
当時は精通していたアルゴリズムを使わないでいるうちに忘れたり、
別の場所で散々書いた注釈だからと省略した場所を直すはめになったり。
226:デフォルトの名無しさん
17/10/05 15:02:15.28 RyRWuj5i.net
ソース中にコメントとか入れないの?
227:デフォルトの名無しさん
17/10/05 15:26:29.53 v1JdYXKS.net
数年前のコメントは見ても理解できないからなw
228:デフォルトの名無しさん
17/10/06 16:53:07.29 UJYLIi2n.net
それは国語からやり直した方がいいのでは…
229:デフォルトの名無しさん
17/10/06 17:36:15.61 fbkgiuQU.net
じゃ昔のコード読めなくなったら、プログラミングの勉強からやり直しだなw
230:デフォルトの名無しさん
17/10/06 17:47:23.98 5EA0jlqJ.net
当たり前だろ。
231:デフォルトの名無しさん
17/10/25 12:32:07.75 RJdooZ2I.net
C++11なしで以下のプログラムがコンパイルできて2が出力されるようにしたいです。
どうかけばよいのでしょうか。
URLリンク(wandbox.org)
232:デフォルトの名無しさん
17/10/25 13:35:04.89 juMZY67C.net
>>231
警告がでてるけどboost::phoenixで通せた
URLリンク(wandbox.org)
233:デフォルトの名無しさん
17/10/25 13:37:35.53 RJdooZ2I.net
>>232
超ありがとうございます!(5時間悩んだ)
234:デフォルトの名無しさん
17/10/25 13:42:13.44 U6sw7DMu.net
解決してるようだが
>>231
for_each(vsz.begin(), vsz.end(), boost::lambda::var(misz)[boost::lambda::_1]++);
235:デフォルトの名無しさん
17/10/25 13:53:33.16 RJdooZ2I.net
>>234
ありがとうございます!
boost::lambda::varの方はVCコンパイラでもビルドできました。
余談ですが、operator[]の代わりにstd::map<>::atを使えないか試してみたのですが
こちらは無理そうでした。
236:デフォルトの名無しさん
17/10/25 21:59:33.61 U6sw7DMu.net
> 余談ですが、operator[]の代わりにstd::map<>::atを使えないか試してみたのですが
> こちらは無理そうでした。
・そもそもmap::atがあるのはc++11以降
・しかもmap::atはキーが存在しないと例外を投げるから今回みたいな[]の代わりには使えない
・それでやるとしてもboost::lambdaではbindを使わないとできない
237:デフォルトの名無しさん
17/10/25 23:22:00.79 RJdooZ2I.net
>>236
回答ありがとうございます。
ひそかに.atが使えないか調べていて
一日中やっても駄目だったので諦めたところでした。
自分の環境はVS2012でC++11が部分的に実装されている状況だったため
.atがないことに気づきませんでした。すみません。
bindを使う方法はboost::bindやboost::lambda::bind、boost::phoenix::bind
と、一通りやってみたのですが自分にはどうやってもコンパイル通りませんでした。
238:デフォルトの名無しさん
17/10/25 23:56:46.90 U6sw7DMu.net
>>237
URLリンク(wandbox.org)
オーバーロードされてるメンバ関数のポインタを取得しなければなならないのがつまづきどころかな
239:デフォルトの名無しさん
17/10/26 00:46:41.57 CxNeOOyi.net
>>238
わざわざ調べてくださって本当にありがとうございます。
喉の魚の骨が取れた様な気分です。
キャストは思いつきませんでした。
240:デフォルトの名無しさん
17/10/27 04:44:05.29 dgw8O7sr.net
組み込み系ってC++よりもCを使うことが多いと思うが、C++を使うと問題ある?
ROM 256Kbyte、Ram 8K位の場合だと、何か注意することある?
241:デフォルトの名無しさん
17/10/27 07:05:11.65 kl+AecdR.net
C使うことなんてないわ
242:デフォルトの名無しさん
17/10/28 00:18:19.01 VLfN62TL.net
C すらためらうレベル
243:デフォルトの名無しさん
17/10/28 08:50:31.24 5mHtwzGb.net
20年以上前はためらったが今はアセンブラなんてやってられんな
昔はハードに合わせて開発したが、今は開発に合わせてハード選べばいい
244:デフォルトの名無しさん
17/10/28 12:37:02.52 siUcDApP.net
つかC言語と言っても
直接アセンブラ・ニーモニックを埋め込める
インライン機能が用意されてる処理系あるし
245:デフォルトの名無しさん
17/10/28 16:13:43.77 5T1YNIdw.net
普通C++だとRAMペースだろ。だから組み込みでRAMが8kとかでは使えないだろな。
246:デフォルトの名無しさん
17/11/20 17:48:28.20 HOO1fHXA.net
>>244
未だに半角カナ使う奴いたんだ
247:デフォルトの名無しさん
17/11/20 23:16:04.54 ste5Kj49.net
そりゃISO-2022-JPならともかく、Shift_JISやUnicodeでは正当な文字ですからね。
248:デフォルトの名無しさん
17/11/21 06:40:04.61 VCAIytbF.net
変換時の文字幅にまるで無頓着な人が増えた、という話を聞くね。
環境が全面的にプロポーショナルフォントになったことも関係あるかと。
コピーしてペーストして一部書き換え、て手順のせいで
単語中で「半角」「全角」が混在したり、それに気づかなかったり。
249:デフォルトの名無しさん
17/11/21 07:02:38.37 f5CXuOxE.net
半角カナに敏感なのって40代、50代以上だよね
未だに2chやってる奴いたんだ
250:デフォルトの名無しさん
17/11/21 07:59:10.55 CMMMtcpC.net
1月11日
みたいに一桁は全角2桁は半角ってのもあるな
251:デフォルトの名無しさん
17/11/30 13:01:31.93 D3zqdlF5.net
OpenMPで#pragma omp sectionsの役目って何なんでしょうか?
#pragma omp parallelで並列領域を
#pragma omp sectionでスレッド処理(スレッド割当て)単位を
指定することは理解できました。
しかし#pragma omp sectionsが必要となる理由がわかりません。
なぜ必要なんでしょうか?
※
#pragma omp parallel sectionsって書けるみたいですが
まぁこれは本質ではないですよね?
#include <stdio.h>
int main(void)
{
#pragma omp parallel
{
#pragma omp sections // ←コンパイラに何を指示してる?
{
#pragma omp section
printf("Hello 1\n");
#pragma omp section
printf("Hello 2\n");
#pragma omp section
{
printf("Hello 3a\n");
printf("Hello 3b\n");
}
}
}
return 0;
}
252:デフォルトの名無しさん
17/11/30 13:38:08.08 /IB/XhDr.net
>>251
URLリンク(www.google.com)
253:デフォルトの名無しさん
18/01/18 22:17:06.28 fk/Xo3MV.net
URLリンク(github.com)
の 169 行目からの記述ってどうなっているのか理解したいのですが、
どなたかヒントもらえないでしょうか?
「[SPP_IDX_SVC] = ...」 となっているのが分かりません。
254:デフォルトの名無しさん
18/01/18 22:58:14.15 7tNMQ3qD.net
>>253
C99 の「指示付きの初期化指定子」かな?
255:デフォルトの名無しさん
18/01/18 23:17:40.59 fk/Xo3MV.net
>>254
ありがとうございます。理解できました。
256:デフォルトの名無しさん
18/01/19 10:36:40.61 dM64lXT0.net
シングルトンにするのと、全部クラス変数、クラスメソッドで実装するのと
目的はあまり違わないような気がするんですけど、あえてシングルトンにする意味があれば
教えて頂けないでしょうか?
257:デフォルトの名無しさん
18/01/25 15:00:52.20 uboI0CmN.net
質問の意味がわからないが、シングルトンというのはインスタンスを一つしか持たない
ということ。クラス変数のようにインスタンスがいくつも作れると誤って2つインスタンス
を作ってしまう可能性がある。そうすると本来とは違う変数にアクセスしてしまう恐れが
ある。これをさけるんが目的。
258:デフォルトの名無しさん
18/01/25 15:45:13.06 O5EWej8a.net
>>257
レス有難うございます。
それは、インスタンス変数じゃないでしょうか?
クラス変数は同一クラスで共有される静的な変数なのでいくつも作れるものではないと理解しているのですが...
259:デフォルトの名無しさん
18/01/25 16:16:27.35 6NNXd/EM.net
微妙に違うけど例えば自分の体重管理アプリを作るとする。「自分」は一人しかいないから、体重を格納する変数だかクラスは1つあればいい
家族の体重管理アプリなら、「家族」は複数だから体重の格納も複数になる
こうしたときに自分アプリはシングルトン設計、家族アプリはシングルトンでない設計と「呼んでるだけ」。元々みんなやってたことに専門用語っぽくネーミングしただけだよw
260:デフォルトの名無しさん
18/01/25 16:36:48.08 O5EWej8a.net
>>259
それ、クラスがシングルトンじゃなくて、データが個人用(単一データ)か複数人用(配列/ディクショナリ)かって話だから、シングルトンとは違うような...
261:デフォルトの名無しさん
18/01/25 21:57:47.77 8MUKcewe.net
抽象メソッドにできるというのが一番の利点じゃないかな。
262:デフォルトの名無しさん
18/01/25 22:18:47.51 9MCrLTCo.net
組み込み環境に C++ のコードを移植しようとしているんだけど、質問ってここでしていいのかな。
RAM の容量が厳しいので、 Flash にデータを持つように改造したいと思っている。
で、これは、C++ 的には定数でデータを持つだけで実現できるらしい。幸い組み込み環境ではリードオンリーでよい。
普段 PC 環境なら計算量の多いコンストラクタを経て初期化しているあるクラスのインスタンス群を、
PC 環境上で初期化して各フィールドの値をダンプしておいて、
組み込み環境では各フィールドが const になるようにクラスを改造したうえで
何かの方法でコンストラクタをスキップしてやりたい。これでRAMも計算量も減らせたらいい。
思いついた方法は、シリアライザというかコードジェネレーターを用意してソースコード上に定数群をたくさん定義して、
MyType i { cDataA, cDataB, ... }, j { cDataO, cDataP, ... }; のような記述ができるようにする、という感じのもの。
ほかによく使われている方法はある? あるいは、アドレスのキャストか何かでインスタンスの初期化を完了できる黒魔法っぽい方法もあったりする?
263:デフォルトの名無しさん
18/01/25 22:22:11.16 9MCrLTCo.net
って隔離スレなのか。まあ過去レス見た限りでは答えてくれているようなので… よろしくお願いします。
264:片山博文MZ
18/01/25 22:42:32.30 4TKaBAL2.net
static char buf[sizeof(MyData)] = { ... };
MyData& data = reinterpret_cast<MyData&>(buf);
265:片山博文MZ
18/01/25 22:43:32.46 4TKaBAL2.net
static char buf[sizeof(MyData)] = { ... };
MyData& data = *reinterpret_cast<MyData*>(buf);
266:デフォルトの名無しさん
18/01/25 23:23:09.67 9MCrLTCo.net
ありがとう
{ ... } の部分をプログラムからうまく生成する方法はなにかあるだろうか?
267:デフォルトの名無しさん
18/01/25 23:28:29.97 9MCrLTCo.net
キャストで済んでいるのはとてもよさそうだけど、
PC 環境でのメモリ上での表現と組み込み環境でのメモリ上の表現は完全に一致するのだろうか。
アライメントというものがあるんだったような
268:片山博文MZ
18/01/25 23:29:12.87 4TKaBAL2.net
unsigned char *pb = reinterpret_cast<unsigned char *>(&data);
for (size_t i = 0; i < len; ++i)
printf("%02X, ", pb[i]);
269:片山博文MZ
18/01/25 23:32:26.13 4TKaBAL2.net
char *pch = reinterpret_cast<char*>(&data);
for (size_t i = 0; i < len; ++i)
printf("%02X, ", (*pch & 0xFF));
270:片山博文MZ
18/01/25 23:33:19.76 4TKaBAL2.net
pch[i] & 0xFF
271:デフォルトの名無しさん
18/01/25 23:46:29.85 9MCrLTCo.net
まそうですよね。再びありがとう。
アライメントについては各環境で実験して (offsetof(MyData, ...) が一致するか) いけそうなら試してみる。
エンディアンとアライメント(バイト境界)が一致してればきっと大丈夫だよね
272:デフォルトの名無しさん
18/01/25 23:59:52.47 9MCrLTCo.net
助かる、これでとんかつ定食でも食べてくれ っ [ぺいぱる]
273:デフォルトの名無しさん
18/01/27 10:10:18.54 EckHRazm.net
floatを実数Xで初期化する際にfloatではその数を正確に表現できない場合、少し大きいか小さいかでXに近い値になると思います
そういう正確には表せない場合に、どうすれば初期化される値がXを下回らない最小の値となるようにできますか?
たとえば√3(1.7320508075688...)で初期化しようと float x=1.7320508075688f; と書くと
xの値が1.732050776となり√3より小さくなってしまうので、そういうのを避けたいです
274:デフォルトの名無しさん
18/01/27 10:43:57.22 BU9rpSw9.net
精度上げたいならdouble使えば?
275:デフォルトの名無しさん
18/01/27 11:40:33.40 2gTl4aTp.net
>>273
C/C++の標準機能では無理な気がする
というか、無理関数や超越関数でそういう丸め方が出来るアルゴリズムってあるのかな?
高精度で求めてから丸めるしかないような気がするが
運が悪いとそれでも下回らない最小にはならない
276:デフォルトの名無しさん
18/01/27 11:42:00.24 2gTl4aTp.net
定数何個かなら事前に計算していれておけば良いけど
277:デフォルトの名無しさん
18/01/27 11:52:04.54 BU9rpSw9.net
そういう意味ではPython最強だな
278:デフォルトの名無しさん
18/01/27 11:53:27.06 EckHRazm.net
言葉足らずでしたが、標準やその他ライブラリの数学関数の結果として求めたいのではなく
数値リテラルとして初期化する場合に限ってもらっても結構です
閾値として使うのに、切り上げか切り下げかわかっていないと間違った結果が出て後で困ることになります
たとえば単純に閾値未満と以上のデータを別の用紙に印刷するプログラムを以下のように書いた場合
double result = calculation();
double threshold = √3
if (result < threshold) fail_list.add(result); else pass_list.add(result);`
print_to_paper(fail_list);
print_to_paper(pass_list);
計算精度に限界がある以上(閾値付近での)比較での細かい誤差は気にするなという人もいるでしょうが
それ以上に実際に紙面に載る値が要件に反する事態になってしまうと後々困ったことになるのです...
>>276
次善の策でそのことも考えますが、要件が変わった場合などに脆さが残りませんか?
279:デフォルトの名無しさん
18/01/27 12:07:53.57 BU9rpSw9.net
閾値も比較対象も同じ精度なら不都合は起きない気がするけど
不都合が起きるとすると、計算過程での誤差が許容範囲内かどうかってことじゃないの?
どっちにしても無理数はどっが切らないといけないわけだし、扱える有効桁数の範囲で計算するしかない
ちなみに、
float x=1.7320508075688f;
は、代入の時点でfloatの有効桁数を超えてるから表示した時の結果と異なるのは当たり前
doubleだと有効桁数が15~16桁程度ある。それでも不足なら、long doubleを使うとか、decimal型
を扱う外部ライブラリを使うとか
280:デフォルトの名無しさん
18/01/27 12:23:14.67 x9sgfrz+.net
(v-1ULP) <= X < v となるvを選びたいということかね?
その方法は知らんが、常に (v-1ULP) <= X < v か (v-1ULP) < X <= v のどちらかなわけだから
別に問題ないんでは?X≒vを上に組み入れるか下に組み入れるか決めりゃいいだけで。
281:デフォルトの名無しさん
18/01/27 14:20:38.41 EckHRazm.net
説明のために>>278のプログラムをfloatに戻したものを考えると
(result < 1.732050776f)という比較ではresultが1.732050776fだった場合に
1.732050776は√3未満であるのに合格リストの方に載ってしまうということです
計算上の誤差があるとかdoubleの有効桁数が多いとかでなく
プログラム内の数値の取り扱いに関係なく、実際の紙の上では間違いが起こってほしくないということです
うまく説明できてるかどうかわかりませんが、実行時どの程度誤差を許容できるかは問題ではないんです
結果を見せた時に、どうしてこの値がこっちのリストに載っているわけ? 直しておいてくれる?
と言われれば、どうせ境界値付近の値なんてどちらのリストに載っていようと計算誤差もあるしいずれにしても正確とは言えないんですよ
では通じないんです...
≒をどちらに組み込むかを決めておくというのも、結局は事前に求めておく>>276の手法と同じ手間がかかりませんか
要件の数値(実数)が変われば、切り上げか切り下げのどちらであるかも変わってしまいますから
どちらになっているかを確かめなくてはいけないですよね
282:デフォルトの名無しさん
18/01/27 14:34:58.54 BU9rpSw9.net
そもそも、 1.732050776f と言う書き方が矛盾してでしょ
末尾にfをつけてるから、floatに変換してるわけだけど、1.732050776 はfloatの有効桁数を超えた表現だからこの比較自体がおかしい
1.732050776 と比較したかったらdoubleで計算すればいいし、もっと大きな有効桁数を求めるなら、long doubleなり、decimal型を扱えるライブラリでも使えばいい
283:デフォルトの名無しさん
18/01/27 14:55:39.92 EckHRazm.net
1.732050776と比較したいのではなく√3です(√3という数も説明の便宜上です念のため)
ですからdouble型でも√3が表現できないのは変わらない以上は
floatをdoubleにしても問題の起こりやすさが減るだけで起こることに変わりないと思います
doubleを使うなら1.7320508075688...よりも多くの桁数を書くことになるというだけです(20桁以上?)...
私の場合有効桁数そのものが問題なのではなく、切り上げか切り下げを指定したいということです
あるいはどちらが行われているかがわかればそれで問題ありません(と思います)
加えるとほかの工程に渡す必要があるためdecimal等をサポートするライブラリの使用は非常に厳しいです
284:片山博文MZ
18/01/27 15:09:28.15 TUhH5TnV.net
小さかったら、FLT_MIN / 2を繰り返し足せばいいんとちゃう?
285:デフォルトの名無しさん
18/01/27 15:16:35.83 x9sgfrz+.net
>私の場合有効桁数そのものが問題なのではなく、切り上げか切り下げを指定したいということです
それならその√3を求める関数の仕様に当たるべきでは。
標準の数学関数だと、丸め方式以前に1ULPの誤差も保証されているとは限らない。
286:デフォルトの名無しさん
18/01/27 15:18:36.43 BU9rpSw9.net
>>283
√3との比較対象となる計算結果も、floatなりdoubleなりを使う計算過程で桁落ちは発生するでしょ? そっちは問題ないの?
閾値となる√3の桁落ちだけが問題?
なんにしろ、√3みたいな無理数を扱う場合は、有効桁数何桁、少数点以下何桁まで考慮するという前提がないと、それを扱う型の精度も決められないし、それがデータ設計者の役目だと思うけど
287:片山博文MZ
18/01/27 15:21:29.73 TUhH5TnV.net
ルート3に相当する数値を2乗して、3以上になればいいんだろ?
288:デフォルトの名無しさん
18/01/27 15:28:05.15 BU9rpSw9.net
>>287
√3と言うのは例として上げただけで平方根とは限らないみたいだよ
289:片山博文MZ
18/01/27 15:56:37.17 TUhH5TnV.net
逆算して、不等式を満たすかチェックすれば?
290:デフォルトの名無しさん
18/01/27 16:35:32.82 2gTl4aTp.net
>>281
丸める前の値は何?
文字列?double?数式?
291:デフォルトの名無しさん
18/01/27 16:37:26.51 2gTl4aTp.net
>>289
数学や数値計算の素人はだまってなさい
292:デフォルトの名無しさん
18/01/27 16:54:03.59 EckHRazm.net
>>290
元データは文字列で、最大で有効数字8桁くらいの10進数の小数点数です
それを単にstrtofで読みこんで、計算過程もずっとfloatです
ですけど読み込み時の誤差も含めて計算誤差は特に問題にしなくてもかまいません
それこそ計算誤差があるから仕方ないで押し通すこともできると思います
ですが、計算結果を2つのグループに分ける際に、実数の閾値に対して忠実でなければならないということです
>>286
閾値も計算の精度も32ビットのfloatで問題ないです
なので閾値となるfloat値を事前計算すれば、とりあえずは済みます
(ですが事後の変更に備えて、安全な方策がないものかと思い始めたわけです)
>>285
閾値は実行時に関数を呼び出して計算する必要はありません
単に計算機で求めた桁の多い数字を使って意図通りにfloatを初期化できれば問題は解決です
293:デフォルトの名無しさん
18/01/27 17:02:29.66 BU9rpSw9.net
>>292
32ビットfloatの有効桁数は7桁しかないよ
√3は、小数部6桁の1.732051 までしか表現できないし、
例えば整数部の最大を4桁としたら、小数部は3桁までしか使えない
大丈夫?
294:デフォルトの名無しさん
18/01/27 17:16:55.11 RR6n96sQ.net
>>291
無理数を定数値とする方法は無いから片山の意見は一理ある
295:デフォルトの名無しさん
18/01/27 17:29:56.29 RraDQJG1.net
使ってる環境のfloatのビット表現を確認して、それで誤差なく表現できる閾値以下の最大の数値を求めて、それを定数として閾値にすればいいんでないの?
296:デフォルトの名無しさん
18/01/27 17:33:27.63 2gTl4aTp.net
元の10進数の文字列に対して、
これを下回らない最小のfloatの値
これを上回らない最大のfloatの値
を求めれば良いの?
仕様をはっきりして
297:デフォルトの名無しさん
18/01/27 17:45:09.91 2gTl4aTp.net
floatの値と10進数文字列の大小比較が出来れば良い?
298:デフォルトの名無しさん
18/01/27 17:48:38.55 2gTl4aTp.net
√3やsin(1+√2)などの数式が示す値とfloatの大小比較?
299:デフォルトの名無しさん
18/01/27 18:07:06.21 2gTl4aTp.net
数式って言うと誤解を与えるのかな?
10進数表記可能な数値
数学的に定義可能な実数
それ以外
閾値はどれ?
300:デフォルトの名無しさん
18/01/27 18:28:25.65 EckHRazm.net
>>293
はい、それで問題ありません
上であげた√3の例は計算機で出してfloatには十分だと思える桁数で切っているだけです
入力データや計算誤差自体には許容的です
>>296
閾値の数は文字列から取得するわけではありません
ソースコード中のリテラル値として与えられるもので構いません
求めるものは、単純化して言うと
プログラム上のあるfloat値が、数学的な意味での実数X未満であるかそうでないかのbool値になります
>>299
10進数表記可能な数ということになります
たとえば√3も関数電卓などで求めた値で十分(20桁もあればfloatには十分すぎるだろう)という意味です
301:デフォルトの名無しさん
18/01/27 19:52:43.68 BU9rpSw9.net
>>300
floatの有効桁数は7桁だから
float x=1.7320508075688;
とするんじゃなくて、
float x = 1.732051;
とするしかないでしょ
それが嫌なら、もっと精度の高いdoubleを使うようにして
double x = 1.7320508075688;
として、これを閾値とすればいい
そして、そのことを予め顧客に確認しておけばいい
扱うデータの桁数を予め決めておくことは設計時の重要事項でしょ
何も問題は無いと思うけど、何を悩んでるのか分からない。
もし無理数を無理数のまま無制限の精度で扱いたいなら、もうそういうライブラリを使うしかない
あるのか知らんけど
302:デフォルトの名無しさん
18/01/27 20:13:29.55 EckHRazm.net
>>301
スレを後から読んだ人に混乱を広げないために念のために書いておきますが、無理数を無理数として扱う必要はありません
ついでに、計算の精度を高めたいわけでもありません
あらかじめ閾値になるfloat値を求めておけば済むというのはわかりますその通りです
早い段階で気づいていました
ですがそれだけだと変更に弱いですよね
実際に書き換えるのが三か月後の自分か赤の他人になるのかはわかりませんが
だれかの手作業で閾値のfloat値を再計算するより信頼性のある方法があれば、ということで質問を始めました
ただ5レス目しないうちから簡単には済まないだろうなとも思っていました
303:デフォルトの名無しさん
18/01/27 20:14:24.46 tkKoYj6x.net
だなー
float基準なんだからdoubleでもっときゃいい。これがdoubleでーってなってたら悩むがw
304:デフォルトの名無しさん
18/01/27 20:42:46.77 EckHRazm.net
doubleで持つ考えもわかります
ただfloatの丸め方がわかれば(あるいは制御できれば)問題は解決(>>303が悩むdoubleが必要な時にも拡張できる方法)だと思うのですが...
その方法が簡単でないということが分かったことは収穫...?でした
305:デフォルトの名無しさん
18/01/27 20:56:05.82 tkKoYj6x.net
floatの丸め方が分かったら、それを求めるために(floatが32ビット型だとしたら最低でも)33ビットで計算しないといけなくなるわけでしょ?
つまりは33ビット型を新たに作ることになるわけで・・・だったら最初からある64ビット型を使たほうがってw
306:デフォルトの名無しさん
18/01/27 21:11:10.44 EckHRazm.net
実行時の精度ではなく、コンパイラがソースコード中の数値文字列をどう機械語(float型)に翻訳するかということではないですか?
ソースコード上では20桁もある数値文字列を実際にコンパイラが適切な32ビット型に変換しているので
33ビット型とかいう変な方を導入するまでもないと思うのですが
実行時に実数がどうまとめられたかを知りたいわけじゃないんです
初期化式の右辺に来る数値リテラルをコンパイラ内部で何ビットで処理しようが関係ありませんよね?
実行時にfloatやdouble値の実体を持つ閾値が、切り下げられたか切り上げられたかを判断するのであれば
33ビットの浮動小数点数型が必要になるでしょうけども...
307:デフォルトの名無しさん
18/01/27 21:11:56.87 BU9rpSw9.net
>>304
floatの丸め方が知りたかったの?
round、floor, ceil とかあるじゃん
例えば、double型の小数部第6位で切り捨ててfloat型へ代入したければ、ありがちなやり方としては
double d = 1.7320508075688;
float f = floor(d * 100000.0) / 100000.0;
んな感じで
308:デフォルトの名無しさん
18/01/27 22:03:45.49 EckHRazm.net
実行時の変数の丸め方ではありませんよ
丸めという言葉はよくなかったかもしれませんすみませんでした
今はfloatの初期化式を書いた時にコンパイラがどう振舞うかということの意味です
それと前に10進数表記可能な数と書いたのは、単にソースコード上で
そう書き表すことのできる(√とかsinとかその他を使わない)数という意味で
10進数の数のある桁で四捨五入するという意味ではありませんでした
丸めという言葉もULPに対するものとして言ってるつもりでした
>>280で出てるのでこちらから出しませんでしたが言葉足らずでした重ねてすみまんせん
元々は1.7777777fupとか1.7777777fdownとか(桁数や表記法はともかく)
お手軽に意図通りの値に初期化できないものかと考えて質問しました
そうすれば、実数から浮動小数点数への翻訳方法(コンパイラによる切り上げ切り下げ)にかかわらず、
ソースコード上に記述されている通りの、数学的な大小関係を損なわないプログラムが書けると考えたからでした
次にいつここへ来るかわからないので今日の私の質問はこれで終わりにします
返答してくれた人たちは本当にありがとうございました
309:デフォルトの名無しさん
18/01/28 01:49:55.74 x3ZlVnQ6.net
2進数の小数リテラルの記述が出来るようになるんじゃなかった?
なんで今まで出来なかったのかが不思議だけど
それで満足なのか?
小数のリテラルの、コンパイル時の文字列から値への変換は
普通はその文字列が表す値に一番近い値になる
丸め方を自分で決めたければ、文字列から数値に変換するconstexpr関数を作れば良い
310:デフォルトの名無しさん
18/01/28 10:42:15.33 YQxX9lfa.net
2進で書いたってなんの解決にもならんよwww
リテラルのみだとしても結局はdouble分の計算が必要でしょ。計算するのがコンパイル前でも構わなくなるってだけ
311:デフォルトの名無しさん
18/01/28 11:03:46.96 Y4YkWHjI.net
二進できっちり仮数部23bitで書けばいいだろう
それなら1ULP未満切り捨てになる
312:デフォルトの名無しさん
18/01/28 11:14:12.99 YQxX9lfa.net
やりたいことは、その切り捨てがあるなら切り上げたいってことでしょ
だから切り捨てがあるかないかを事前に計算する必要ある
313:デフォルトの名無しさん
18/01/28 11:31:33.17 Y4YkWHjI.net
>やりたいことは、その切り捨てがあるなら切り上げたいってことでしょ
どこをどう読んだらそうなる
>>283は切り上げか切り捨てかどちらか特定できればいいって書いてるだろ
314:デフォルトの名無しさん
18/01/28 11:51:46.98 YQxX9lfa.net
> floatを実数Xで初期化する際にfloatではその数を正確に表現できない場合、少し大きいか小さいかでXに近い値になると思います
> そういう正確には表せない場合に、どうすれば初期化される値がXを下回らない最小の値となるようにできますか?
これを読んだらそうなる。特定したらこれが解決するでしょ。その解決のために計算が必要になる
315:デフォルトの名無しさん
18/01/28 12:11:57.99 Y4YkWHjI.net
そこしか読まないからそうなる
その後のレスでどちらでもよいと補足しているだろう
316:デフォルトの名無しさん
18/01/28 12:20:06.50 Y4YkWHjI.net
というか、
>2進で書いたってなんの解決にもならんよwww
これが否定されたのがそんなに我慢ならなかったのか
317:デフォルトの名無しさん
18/01/28 13:17:58.45 YQxX9lfa.net
> double分の計算が必要
むしろこっち否定しろよw
318:デフォルトの名無しさん
18/02/01 14:07:29.89 BjxdiDzB.net
二進リテラルでええやろ
それかstd::nextafterで切り上げるか切り下げるか
319:デフォルトの名無しさん
18/02/01 20:59:41.19 uG0JSReu.net
二進リテラルはいいが、nextafterはちょい違うな。
320:デフォルトの名無しさん
18/02/02 10:30:51.76 ahF+s6Dw.net
2進小数を10進小数に変換出来るツールの提供と
リテラル記述箇所へのコメント
現実的な解はこの辺かと
321:デフォルトの名無しさん
18/02/02 12:14:54.40 NAEfRvIa.net
そういう設計にするとバグ出まくり。しかも発見が非常に困難
普通に仮数部足す関数作ってそれかましておけばいいでしょ
322:デフォルトの名無しさん
18/02/02 13:00:05.92 ahF+s6Dw.net
足す?
何を?
どうやって?
323:デフォルトの名無しさん
18/02/02 13:15:59.60 NAEfRvIa.net
力技でビット演算してもいいし、仮数部1ビットだけ建てたの用意して普通に加算してもいいでしょ
324:デフォルトの名無しさん
18/02/09 16:44:31.74 9b+Wa+Ns.net
hoge(int *) という関数があり、hoge(&a) とすれば a に値を返す仕組みとします。
ここで、char a をキャストして hoge((int *)&a) として実行した場合、意図した結果が返されない
ケースがあるのはいいとして、他に問題はありますか?
例えば、hoge()自身は渡されたものが int のポインターなんだから char 以上のメモリー範囲を
超えて書き込むからメモリーが破壊されるといったことが起こりますか?
325:片山博文MZ
18/02/09 17:01:41.47 owaGciqs.net
>>324
最適化を無効にして
char ab = 0x7F;
char a;
char aa = 0x7F;
hoge((int*)&a);
printf("%d, %d, %d\n", ab, a, aa);
で試してみて。
326:デフォルトの名無しさん
18/02/09 17:32:12.48 9b+Wa+Ns.net
>>325
既に稼働してるシステムで上記の箇所を見つけはしたものの、何食わぬ顔をして動いていたので
疑問に感じていましたが、新規プロジェクトで試したら一発でしたね。
スタックオーバーフローでした。
どうもありがとうございました。
327:デフォルトの名無しさん
18/02/09 20:59:14.12 9QnGJOcV.net
>>324
条件によっちゃよくやる
例えば
char a,b,c,d;
こんなのでaのアドレスに対してint読み出しかけて、abcdくっつけたint16値を取り出すとか
その逆にint16値をaにキャストしてabcd個別にアクセスとか
ただ連続したメモリ空間に入らないことがあるから、
その辺はstructでまとめたり、pragma packやら何やらで指定しとくとか、プラットフォームとコンパイラに合わせる
328:デフォルトの名無しさん
18/02/10 09:55:27.64 sEVENX79.net
>>327
横からでごめんやけど
int nとchar a,b,c,d,x[12]をunionってのはやら無い方がよさげ?
329:デフォルトの名無しさん
18/02/10 10:44:47.90 A/uZfZpr.net
unionで書いたほうがスマートなこともあるな。その逆なこともある
動作自体は何使っても同じだから、ソースの見やすさやclass設計考えながら選択したらいい
330:デフォルトの名無しさん
18/02/16 01:33:43.00 Ja2iVc8/.net
構造体の、一部のみゼロ埋めする方法を知りたいです
CコンパイラはMingw-win32のgcc 6.3.0を使ってます
struct aaa_tag{
uint32_t a;
uint32_t b;
uint32_t c;
:
uint32_t z;
}
という構造体に、fread(&aaa, sizeof(aaa), 1, fp)でファイルから値を読み込んでいるのですが
実は構造体としてファイルから読み込むべきサイズが条件により変える必要があります
例えば以下のようにです
・bが1の場合は有効なのはaとbのみ。c以降の値はゼロで書き戻す
・bが5の場合は有効なのはa~wまで。x以降の値はゼロに書き戻す
まずbを読んで、それから必要なサイズを読み出す…も考えたのですがそうではなく、
構造体の途中以降をゼロクリアしようと思っているのですが、これがうまくいきません
if (b == 1)memset(&aaa + sizeof(uint32_t) * 2, 0x00, sizeof(aaa) - sizeof(uint32_t));
等と試行錯誤しているのですが、SIGSEGVが出てしまいます
解決法を教えていただけますか
331:片山博文MZ
18/02/16 06:04:46.72 tdYV0Px7.net
上から順番に読み込むか、fseekで読み込み位置まで移動してから読み込む。
位置はoffsetofとかFIELD_OFFSETという名前のマクロを使う。そのようなマクロがない場合は自作する。
読み込むときは、位置とバイトサイズによく注意すること。また、NULLや無効な場所に読み込んではいけない。
332:デフォルトの名無しさん
18/02/16 06:11:24.04 W1XJdyx1.net
☆ 日本の、改憲を行いましょう。現在、衆議員と参議院の
両院で、改憲議員が3分の2を超えております。
『憲法改正国民投票法』、でググってみてください。国会の発議は
すでに可能です。平和は勝ち取るものです。お願い致します。☆☆
333:デフォルトの名無しさん
18/02/16 06:26:26.41 6scYlSnj.net
>>330
セグメンテーションフォールトを起こす直接の原因は、
memset() の第1引数 &aaa + sizeof(uint32_t) * 2 の部分だろうね。
printf("%p\n", &aaa);
printf("%p\n", &aaa.c);
printf("%p\n", &aaa + sizeof(uint32_t) * 2);
上の3行の出力を比較検討すると理屈が分かると思うけど説明は長くなる。
というか、俺にはポインタ加算について短く平易に説明する能力がない。
#include <stddef.h> // offsetof()マクロの定義
if (b == 1)memset(&aaa.c, 0x00, sizeof(aaa) - offsetof(struct aaa_tag, c);
で動くと思うけど、
ダミーの構造体に読み込んでから、bの値を見て有効な部分だけ
(あらかじめ0クリアしておいた)返却用の構造体にコピー、とする方が素直かも。
334:デフォルトの名無しさん
18/02/16 12:40:06.06 6scYlSnj.net
カッコの対応が合ってないね。
× if (b == 1)memset(&aaa.c, 0x00, sizeof(aaa) - offsetof(struct aaa_tag, c);
○ if (b == 1)memset(&aaa.c, 0x00, sizeof(aaa) - offsetof(struct aaa_tag, c));
335:デフォルトの名無しさん
18/02/16 20:12:13.91 hi0D4ZsY.net
>>330
構造体のアラインメントでぐぐれ
336:デフォルトの名無しさん
18/02/16 20:28:30.02 Ja2iVc8/.net
328です
皆様情報ありがとうございました
構造体先頭から末尾までのmemsetとは事情が違うということが分かりました
offsetof()やダミーの構造体など、方針を見直します
ありがとうございました
337:デフォルトの名無しさん
18/02/16 21:00:38.75 hi0D4ZsY.net
だからアラインメントでぐぐれって・・・
それむこうにすればできるから
338:デフォルトの名無しさん
18/02/16 21:26:52.07 5NiD1AgL.net
328のセグフォはアドレスとポインタの違いが分からない時にやらかすミス
339:デフォルトの名無しさん
18/02/16 22:05:59.54 qDhjnryl.net
アライメント無視して詰め込むとミスってバスエラーになるからやらないな
340:デフォルトの名無しさん
18/02/16 22:59:31.13 IhCFworu.net
>>337
>>330のケースではアラインメントを無効化してもダメだろうよ
341:デフォルトの名無しさん
18/02/16 23:35:42.63 wAiK151t.net
>>338が正解だろう。アライメントは関係ない。
342:デフォルトの名無しさん
18/02/16 23:47:57.54 Ja2iVc8/.net
>>337
アライメントについては、OS、アプリ共に32ビットであり、
メンバも32ビットに揃える(パディングはさせない)ように
考慮されてはいるので、無効にしてみましたが変化はなさそうです
__attribute__ ((packed))付与有無でsizeof(aaa)としてみましたが、
どちらも4バイト×メンバ数となり、やぱりパディングは
されていないのかなと
>>338
構造体は、パディングに関わらず先頭以外の場所へmemsetやmemcpyで
触ってはならないのだろう、という思いに至り、方針を見直そうと思ったのですが
実際、書くとしたらどう書くことになるのでしょう
例えば、a~zまで並べられているメンバ中、cからyまでゼロで埋める…みたいなので…