X



C言語なら俺に聞け 150

■ このスレッドは過去ログ倉庫に格納されています
0001デフォルトの名無しさん (アウアウクー MM57-IE4z)
垢版 |
2019/02/06(水) 13:39:03.21ID:c4bnQMl3M

次スレを作る時は上記1行をコピーして2行に増やして必ず1行目に入るようにしてください。

C言語の話題のみ取り扱います C++の話題はC++スレへ
質問には最低限の情報(ソース/コンパイラ/OS)を付ける
数行で収まらないソースは以下を適当に使ってURLを晒す
https://paiza.io/
https://ideone.com/
http://codepad.org/

C11
http://www.open-std.org/jtc1/sc22/WG14/www/docs/n1570.pdf

C99
http://www.open-std.org/jtc1/sc22/WG14/www/docs/n1256.pdf
http://kikakurui.com/x3/X3010-2003-01.html

C FAQ 日本語訳
http://www.kouno.jp/home/c_faq/

JPCERT C コーディングスタンダード
https://www.jpcert.or.jp/sc-rules/

※前スレ
C言語なら俺に聞け 149
https://mevius.5ch.net/test/read.cgi/tech/1540731704/
VIPQ2_EXTDAT: checked:vvvvv:1000:512:----: EXT was configured
0452デフォルトの名無しさん (ワッチョイ b75f-tQZn)
垢版 |
2019/03/02(土) 16:14:23.72ID:ixsZHls30
>>447
割り算はコンピュータにとって簡単なことではない。人間だってそうだろ。
0455はちみつ餃子 ◆8X2XSCHEME (ワッチョイ bf3e-3oSp)
垢版 |
2019/03/02(土) 17:04:52.74ID:tMatklv80
C では比較演算子が返すのも、 if の判定にも真偽値型は現れない。
真偽値型は後付けで、言語の中核の意味論には関与しない。
真偽値型は整数型の一種だから何か演算しようとすると整数拡張で int になってから計算するしな。

_Bool で表現してもほとんどの場合にコメントと同程度にしか意味ない。
コメントと同程度に「意図」を表せるならそれはそれで有用ではあるけど、
型システムが間違いを防止する役に立つ場面はあんまりない。

(余談だが C++ では (組込みの) 比較演算子は真偽値型を返すし、
if の条件節は真偽値型にキャストして判定するので C とは解釈が違う)
0463デフォルトの名無しさん (ワッチョイ ff63-3oSp)
垢版 |
2019/03/02(土) 18:07:30.88ID:U++dipsO0
「ばあさん、いただきものは型を意識した応答だろう」
「いいえ、お爺さん型を意識した応答でしたよ」
「そうかい、わしゃまた型を意識した応答だと思ったよ」
0466はちみつ餃子 ◆8X2XSCHEME (ワッチョイ bf3e-3oSp)
垢版 |
2019/03/02(土) 18:46:41.44ID:tMatklv80
>>464
双方が int に拡張されて足し算されて 2 になったのが
再び bool にキャストすると 1 になる。

演算子の両方の型が int より小さい場合には
両方が int に拡張されてから計算されるというのが
C の基本的なルール。
(全ての演算子がそうというわけではない。)
0467383 (ワッチョイ ff2c-Im2K)
垢版 |
2019/03/02(土) 19:01:27.14ID:Gk4CLPf80
>>455
MISRA-C は、C89/90に、bool という概念をバックポートした。
それを「実質的なブール型」と呼んで、単純な整数型と区別している

ブールを表現する場合は、整数型を使っていても、
それはブール型ですよってアピールする事で、
技術者間での意思疎通を図り、安全性を高める
0472383 (ワッチョイ ff2c-Im2K)
垢版 |
2019/03/02(土) 19:43:06.08ID:Gk4CLPf80
整数型には加算はあるけど、
ブール型として扱うなら、加算は存在しない

AND, OR, NOT だけしかない

だから技術者間での、こういう共通意識が大切なわけ。
これは「実質的なブール型」として扱っているから、整数型の演算はできません!

ブール型が無かった時代の、
技術者間での意思疎通を図り、安全性を高める、苦肉の策
0474 ◆QZaw55cn4c (ワッチョイ bfe9-IBRN)
垢版 |
2019/03/02(土) 19:56:01.42ID:Ud+LwFnR0
>>467
>それはブール型ですよってアピールする事で、技術者間での意思疎通を図り
そういうのは、わりきってハンガリアンを使う方がいいのでは?
bool を使うことで文法的縛りが導入されないことには意味がない気がします
0477はちみつ餃子 ◆8X2XSCHEME (ワッチョイ bf3e-3oSp)
垢版 |
2019/03/02(土) 20:47:30.41ID:tMatklv80
>>467 >>472
コーディング規約・ガイドラインを設けるのは結構だが、
それを守っている組織・プロジェクトの中では意思統一しやすいという話であって、
技術者一般にまで適用できるほど強い権威は MISRA-C には無いよ。

仮に (あくまで仮に!) MISRA-C がとても良い習慣だとしても、
言語仕様としての理屈を理解しておくことは大前提だ。
元の質問者である >>376 みたいなのに MISRA-C を勧めても何のたしにもなりゃしないだろ。

規約としての理屈よりも言語としての理屈をまず説明してわかってもらわんと。
0480デフォルトの名無しさん (ワッチョイ 9f01-dMaL)
垢版 |
2019/03/03(日) 06:55:31.52ID:EUJr/Yte0
>>479
> 最後に評価されるタイミングで一致してりゃなんでもいいんだけどね
とか言うなら内部処理ガーとか言うなよ
って話だろ

> +って相当するのはxorだかorだかわからんという問題もあるね
orはわかるがxorになることなんてあるのか?
0482デフォルトの名無しさん (ワッチョイ d77b-vPGa)
垢版 |
2019/03/03(日) 08:25:42.12ID:HIAqsaOR0
ブール値は 0/1 しかとらないから1ビットの整数値、と解釈して
true + true == 1 + 1 == (2進数で)10 → 下位1ビットを採用して結果は 0
よってブール値での加算はビットでの排他的論理和と同等、
という考え方もあるんだわ。

「無符号整数のオーバーフローの方式を1ビット幅まで狭める方向に推し進める」
とでも言おうか。
0483デフォルトの名無しさん (ワッチョイ 9fda-W5e4)
垢版 |
2019/03/03(日) 08:41:37.16ID:ojZ/TgF60
基本的なハーフアダー演算器の考え方だね
キャリーを出力してビットを反転させる
多ビット加算の基本構成
いくら高級アセンブラとしてのC言語であってもキャリーを抽象化した演算を実装するのは結構面倒だけど
多バイト加算はそれなりに手間が掛かる
0485デフォルトの名無しさん (ワッチョイ 9f01-dMaL)
垢版 |
2019/03/03(日) 10:00:14.37ID:EUJr/Yte0
>>482
> よってブール値での加算はビットでの排他的論理和と同等、
> という考え方もあるんだわ。
そんなの聞いたことないw
お前のオレオレ理論じゃないと言うならその考え方を示してる例を出してくれ
0486482 (ワッチョイ d77b-vPGa)
垢版 |
2019/03/03(日) 10:41:34.05ID:HIAqsaOR0
>>485 分かりやすく説明できる自信はないけど、一応答えてみる。
と言っても、新しい情報は出ないので期待されちゃ困る。

>>482 は、そう考える考え方(代数系)が可能、という意味で、
そのように内部処理してるプログラミング言語の処理系が存在する、
という主張とは違うって点をまず断っておく。

その「ブール値の加算を排他的論理和と同等に扱う」体系が
内部的に矛盾を生じないこと、実用的な面で利用価値があり、
現実にも使われているってことは、>>483 がコメントしてくれた
前半部分で、十分に例示されてると思う。
て言うか、俺が下手にクドクド書いてもあのレベルは無理。
0487デフォルトの名無しさん (スププ Sdbf-5O6o)
垢版 |
2019/03/03(日) 10:46:47.10ID:3MaRmCtMd
少なくともC言語である限りは規格に反するんじゃ?
_Bool型は0に等しければ0、その他は1って明記されてる(C11の6.3.1.2)から2進数で10は0に等しくないように思うが
0489デフォルトの名無しさん (ワッチョイ d77b-vPGa)
垢版 |
2019/03/03(日) 11:25:33.68ID:HIAqsaOR0
Cの、ビット幅の狭い整数値は int に変換してから計算するってルールにより
true + true → (int)1 + (int)1 == (int)2 → true
という流れで true + true == true であることは納得してるんだ。
型が _Bool でも適用されるよね。勘違いなら訂正求む。


(今回の話とは直接関係ないけど、まるっきり無関係でもない余談)
ただ、これが例えば unsigned int の値を真偽値として扱う場合だと、
unsigned int a = UINT_MAX; // 真偽値としては真
unsigned int b = 1; // 真偽値としては真
a + b == UINT_MAX + 1 == (オーバーフローして)0 → 真偽値では偽!
という事態も起こりうるのでご注意。
0490デフォルトの名無しさん (アウアウカー Sa6b-WzxR)
垢版 |
2019/03/03(日) 11:31:58.04ID:f6/fijs9a
加算てのは常に状態を変える操作なので、論理演算としてはXORの方が似てるんですよ。
もちろん単に似てるという話で、加算は禁止するくらいが正しいといえば正しい。trueとfalseを1と0に割り当てたせいで足し算できそうな気になってしまったのがよくない。
1ビット整数だと考えてもいいが、元々そんなもんないからsizeofも1以上にするしかないという。
構造体に入れたらビットフィールドと同じメモリのレイアウトになるんだろうか。実装としては。
0491デフォルトの名無しさん (ワッチョイ 9fda-W5e4)
垢版 |
2019/03/03(日) 11:46:05.73ID:ojZ/TgF60
C言語の_Bool型(boolはただの別名)のtrueを1以外に割り当てるとC++との互換に問題が生じる
C++のbool型のtrueの内部表現は1
bool(論理型)をcharやintなど(整数型)にcastすると1が返される
C++では論理型同士での四則演算は不可能なので問題は生じないが論理型の存在しないC言語ではどうしようもない
trueを1に割り当てて妥協するしか無いと思う
0493 ◆QZaw55cn4c (ワッチョイ bfe9-IBRN)
垢版 |
2019/03/03(日) 21:09:45.45ID:OccEVyH10
>>444
>「実測しろ」って原則を無批判に(条件反射的に)振りかざしてるんじゃないの?

いいところを突きますね、そうそうその調子、いい感じですよ
百人一首の上の句と下の句をつなげる、みたいな思考力を使わない、言葉のオートマタを批判するのはすばらしい着目です、感心しました
0496デフォルトの名無しさん (ワッチョイ 9fda-W5e4)
垢版 |
2019/03/04(月) 07:32:41.06ID:yZdj1rJq0
昔8bitマイコンの組込みシステム開発で、被除数が24bit長、除数が固定値(値は3)の除算処理が必要となったとき、
C言語の除算処理では実行時間が要求仕様を満足しなかったのでインラインアセンブラで書き下ろしたことがある
処理系そのものは16bit長までしか対応してなかったので、32bit長の汎用演算ライブラリ関数が付属してたのはいいけど
そのライブラリが遅くて使い物にならなかった
0497デフォルトの名無しさん (アウアウウー Sa9b-mjQG)
垢版 |
2019/03/04(月) 09:27:34.36ID:uCsPZ+haa
昔bool型ってのを初めてみたときは、誰が使うんだよ気持ちわりーって思ったな。charで8個もフラグ取れるし、
flg & 04とかで好きな位置のビット取れるし、なんでわざわざtrue,falseと思ったもんだ。
0501デフォルトの名無しさん (ワッチョイ bf02-wVf3)
垢版 |
2019/03/04(月) 16:53:38.87ID:TpCWsYE80
>>497
思い切り最適化されて最終的なコードがそうなれば誰も文句言わないんだろうけどな。
0502はちみつ餃子 ◆8X2XSCHEME (ワッチョイ bf3e-3oSp)
垢版 |
2019/03/04(月) 17:08:34.72ID:Cw9L4ZBc0
bool は真偽値を格納するのに充分であればいいんだから普通は 1 バイトだろっていうのも昔の話で、
今の主要な処理系はだいたい int と同じ幅だったりしてあんまりリソースの節約にもならんかったりするし。
0503デフォルトの名無しさん (ワッチョイ d77b-vPGa)
垢版 |
2019/03/04(月) 17:13:39.42ID:7Cz1/mIW0
ブール値の変数を1ビットで表現して1バイトに8個押し込めば
容量の節約にはなるだろうけど、速度的には損な気がするな。
(これも「実測しなけりゃ何も分からない人」向けの釣り餌かも)

ブール値をバイトなりワードで記憶すれば、CPUによっては
レジスタにロードした時点でゼロフラグに反映されて
ゼロとの比較やマスク演算が不要という利点を得られる場合もある。
0504デフォルトの名無しさん (ワッチョイ bf02-wVf3)
垢版 |
2019/03/04(月) 17:16:40.19ID:TpCWsYE80
>>503
CPUしだいだろうね。レジスタに入れないで0かどうかだけ調べる命令があったらそれの方が速いかも知れんし。
0505デフォルトの名無しさん (ワッチョイ 9f2f-W5e4)
垢版 |
2019/03/04(月) 17:18:44.97ID:kNFhD2SD0
                  / ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄
                  |CPUしだいだろうね。レジスタに入れないで0かどうかだけ調べる命令があったらそれの方が速いかも知れんし
                  \___________  _______
                                    V
   / ̄ ̄ ̄ ̄ ̄ ミ                      / ̄ ̄ ̄ \
  /   ,――――-ミ                   /         |
 /  /  /   \ |                    ∨∨∨∨∨\ |
 |  /   ,(・) (・) |                    |▲  ▲  ||
  (6       つ  |                    |(・) (・)  6)
  |      ___  |                    | |    ||
  |      /__/ /                    |  ¨     /
/|         /\                    \/\  /\
                                  / ̄ ̄ ̄    \
     ∧
  / ̄   ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄
  | なわけねーだろ!!
  \__________________
0506はちみつ餃子 ◆8X2XSCHEME (ワッチョイ bf3e-3oSp)
垢版 |
2019/03/04(月) 17:21:36.33ID:Cw9L4ZBc0
真偽値の超巨大な配列が必要な場合ならともかく、
今の時代なら 1MB が 8MB になったくらいならたいした差ではないしな。
ただ、キャッシュにのるかどうかで劇的な差になったりもするから、
そこらへんは状況によるというか、それこそ実測しなきゃわからん。
0511デフォルトの名無しさん (ワッチョイ bf02-wVf3)
垢版 |
2019/03/04(月) 18:38:48.94ID:TpCWsYE80
>>505
あれ?そう?そう断言できる根拠あるの?
0512デフォルトの名無しさん (ワッチョイ 9f2f-W5e4)
垢版 |
2019/03/04(月) 18:51:09.16ID:kNFhD2SD0
>>511
レジスタに入れないでって無理
メモリREADサイクルでどのみちラッチするんだから
名前のある公開レジスタか、名前のない非公開レジスタかという違いにしかならない

どうしても疑うんならHDLでCPU書いてみろ
0514503 (ワッチョイ d77b-vPGa)
垢版 |
2019/03/04(月) 19:06:20.72ID:7Cz1/mIW0
自分にツッコミ。
「ブール値の変数を1ビット幅にしてメモリ1バイトに8個押し込む」方式は
Cの規格とは相性悪いね。
&でポインタ取ったときにバイト番地で表現できないとか、
sizeofで1より小さな小数を返すのか、とか。
「ある変数が1バイトより小さな領域しか占めない」って性質が原因だ。

>>509
その点は気がつかなかった。1回の判定しか考えてなかったわ。
1バイトを1回だけ読んでマスク値をシフトしながら判定と、
1バイトずつ8回読むのとで比較しないといけないね。
一度にもっと多く、4バイト単位とかで処理できるかも知れないし。
0515デフォルトの名無しさん (ワッチョイ d701-WeXs)
垢版 |
2019/03/04(月) 19:30:00.46ID:FaqzbzR10
ソフトから見て1命令でも、メモリに対して1バスサイクルでビット操作は不可能だからねぇ。
メモリビット操作命令は裏でマイクロコードが暗躍して結局ロードストアアーキと同じ動きしてる。
lockが必要ない利点はあるけども。
0517デフォルトの名無しさん (ワッチョイ bf02-wVf3)
垢版 |
2019/03/05(火) 00:00:07.09ID:VLRAu/TX0
>>512
知らんよ。そういうCPUがあればそうだねってだけの話だし、お前もその自分の体験や知識から言ってるだけで全世界の全CPU調べた上で言ってるわけじゃないだろ?予想外の変なCPUはあるかも知れんから断定はできんだろう。
0518デフォルトの名無しさん (ワッチョイ bf02-wVf3)
垢版 |
2019/03/05(火) 00:07:19.93ID:VLRAu/TX0
>>514
一応C言語では構造体にビットフィールドがあってビット単位で扱う事が出来るようになっているな。まああれは数値変数として扱うだけでboolではないわけだけど。効率が良いかどうかはどう最適化されるかに掛ってるかな。
0520KAC (ブーイモ MM3b-KKw9)
垢版 |
2019/03/05(火) 00:55:28.63ID:zhV7s4kGM
>>515
メモリバスがネックになるようなシステムなら、
バス幅のビット分情報が詰まってるほうが、
メモリのアクセス回数減らせるから利点もあるだろう。

なんにしろ、一長一短は有るんだから
正しく理解して正しく使うことが重要かと。
0521デフォルトの名無しさん (ワッチョイ d77b-vPGa)
垢版 |
2019/03/05(火) 05:52:07.47ID:Q+OO1XNi0
>>518 1ビット幅のブール変数をビットフィールドと同じ扱い、
つまり「アドレスを求めることもsizeofを適用することもできない」
というルールにする手はあるか。

と言っても、アドレスを取れないとなると、ポインタ経由での操作、
配列に入れてインデクスで順番に走査することもできないわけで
非常に使い勝手の悪いものになってしまうね。
0522デフォルトの名無しさん (ワッチョイ 9fda-W5e4)
垢版 |
2019/03/05(火) 06:03:05.43ID:C3u1nlxm0
ビットフィールド構造体はあくまで構造体であるのでアドレスを返すことは出来る
というか自分ならビットフィールドだけでは使い勝手が悪いので構造体をcharなどと一緒に共用体に纏める
構造体を配列で操作するときなどは同一アドレスのchar変数でビットフィールドを纏めたパッケージとして取り扱う方が使い勝手がいい
0523デフォルトの名無しさん (ワッチョイ bf8c-Q9lp)
垢版 |
2019/03/05(火) 06:15:17.45ID:BSZ7CWqR0
maxima
(%i1) load("bitwise")$
(%i2) bit_not(i);
(%o2) bit_not(i)
(%i3) bit_not(bit_not(i));
(%o3) i
(%i4) bit_not(3);
(%o4) - 4
(%i5) bit_not(100);
(%o5) - 101
(%i6) bit_not(-101);
(%o6) 100
0524デフォルトの名無しさん (ワッチョイ 9fda-W5e4)
垢版 |
2019/03/05(火) 06:34:30.57ID:C3u1nlxm0
typedef struct {
unsigned8 b7 :1; /* bit7 */
unsigned8 b6 :1; /* bit6 */
unsigned8 b5 :1; /* bit5 */
unsigned8 b4 :1; /* bit4 */
unsigned8 b3 :1; /* bit3 */
unsigned8 b2 :1; /* bit2 */
unsigned8 b1 :1; /* bit1 */
unsigned8 b0 :1; /* bit0 */
} BYTE_FIELD;
0526デフォルトの名無しさん (アウアウウー Sa9b-mjQG)
垢版 |
2019/03/05(火) 09:35:09.67ID:XZEd/J30a
>>521
謎だな。
ブールの配列ならint bool やら char boolやらした時点で確保されるメモリをそのまま使って、and or xorあたりでビット操作してshiftで走査したらいいじゃん、ってのが爺の言い分。
どのビットを何に使ってるかってのはコメントに書いておいたり仕様書に書いといたりカンペ回したり。

メモリ確保もロードも最小単位があるんだから、単独1ビットのブール変数ってのは無理だろ。
あ、組込み用のマイコンは知らないけど。
0527デフォルトの名無しさん (アウアウウー Sa9b-RuLt)
垢版 |
2019/03/05(火) 12:23:27.77ID:TQUHbSsoa
>>525
君がマウントを取りたいだけのサルということが良くわかった。
ま、頑張れ。
0529デフォルトの名無しさん (アウアウウー Sa9b-RuLt)
垢版 |
2019/03/05(火) 12:58:00.63ID:TQUHbSsoa
>>528
マウントご苦労様です。
0531デフォルトの名無しさん (アウアウウー Sa9b-RuLt)
垢版 |
2019/03/05(火) 14:27:58.97ID:TQUHbSsoa
>>530
いつもマウントありがとうございます。
0534デフォルトの名無しさん (ワッチョイ b702-IBRN)
垢版 |
2019/03/05(火) 18:58:34.77ID:6hPuHs1J0
intが64ビットの環境で32ビットの変数を扱いたいので、
とりあえず(私の環境で) typedef long INT32;とか定義してるんですが、
longを使うのが普通でしょうか?
環境によって違うらしいとは知っているのですが、
typedefに出来るだけ無難な型を使っときたいという意図です。
0536デフォルトの名無しさん (アークセー Sx0b-WeXs)
垢版 |
2019/03/05(火) 19:08:28.28ID:JrR+GNVhx
レジスタに入れずに直接メモリ上のビット操作はないよ。
そりゃやろうと思えばメモリセルの制御単位を1ビットにしてデータバスを1ビット、アドレスバスのアドレス単位も1ビットにでもすれば1バスサイクルでのビットアクセスができるだろうけど、あまりにも非効率なのでやらないだろう。
そんな汎用CPUはどこにもないと断言しても良いレベル。
0541デフォルトの名無しさん (ワッチョイ d77b-vPGa)
垢版 |
2019/03/05(火) 19:25:55.02ID:Q+OO1XNi0
>>538 コンパイラ付属のヘッダファイルも存在しないのかな。
その場合は、コンパイラの取説でも見て、32bitになる整数を選んで
typedef すれば良いかと。

どのみち移植する際には、その辺も含めて丸ごと再検討ってことになるだろうし。
0545デフォルトの名無しさん (アウアウクー MM0b-tQZn)
垢版 |
2019/03/05(火) 20:17:27.37ID:EdVc4MwEM
int型が64ビットの環境で、longという型が32ビットなのは引っかけだな。

あとで見た他人に恨まれるぞ。
0546デフォルトの名無しさん (アウアウウー Sa9b-RuLt)
垢版 |
2019/03/05(火) 20:37:31.74ID:TQUHbSsoa
>>537
話の流れとしてそこはビット単位の話ではなくなっている。
■ このスレッドは過去ログ倉庫に格納されています

ニューススポーツなんでも実況