C言語なら俺に聞け 147

■ このスレッドは過去ログ倉庫に格納されています
1デフォルトの名無しさん
垢版 |
2018/08/16(木) 23:36:02.22ID:fOCSKLtw
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言語なら俺に聞け 146
https://mevius.5ch.net/test/read.cgi/tech/1525031257/
2018/08/21(火) 12:10:27.14ID:QteKsmYB
まあ多次元配列を引数にするのは良くないと思うわ
2018/08/21(火) 12:28:57.33ID:GIXT+l9b
>>71
どうした?
コードレビューで上司にボコボコにされた腹いせか?
こんなとこでイキっても虚しいだけやで。
2018/08/21(火) 12:29:15.96ID:GIXT+l9b
>>71
どうした?
コードレビューで上司にボコボコにされた腹いせか?
こんなとこでイキっても虚しいだけやで。
2018/08/21(火) 12:47:09.71ID:EQ4qcC3V
>>72
なぜ?
2018/08/21(火) 12:53:55.98ID:gERn4ySS
>>73
ここがム板ってことを忘れたか?
技術的な話で来い
77デフォルトの名無しさん
垢版 |
2018/08/21(火) 12:54:14.69ID:m1oFA/yA
多次元配列の型は typedef で型名作っておけば楽なのでは?
2018/08/21(火) 12:56:41.15ID:Fhw28p93
>>68
>>76
この書き込みのどこが技術的な話なんだw
単にイキってるだけじゃん。
2018/08/21(火) 13:04:39.72ID:gERn4ySS
>>78
構文糖衣の話をしたんだが
構文糖衣と書いてないと読めないオツムなのか?
アホw バカwww
2018/08/21(火) 13:05:57.10ID:gERn4ySS
さて、買い物に行くぜ
妻子の夕飯を作らにゃならん
2018/08/21(火) 13:09:48.25ID:O6Fgkzwj
>>75
そりゃわかりにくいからだよ。
引数にするとCの多次元配列の嘘くささがよく表れるわ。
せめて構造体で包むとかして名前を付けた方がいいね。
2018/08/21(火) 13:09:58.77ID:EQ4qcC3V
>>71
無駄なコスト
2018/08/21(火) 13:10:23.54ID:RiLuNws8
>>70
それを糖衣構文というかどうかどうでもいいけど
だれも機械の解釈の違いには言及してない定期

>>50>>52
明示とは機械に対してではなく人間に対してのことを言ってるからこの返信は意味がずれてる
84デフォルトの名無しさん
垢版 |
2018/08/21(火) 14:09:26.92ID:Xve8S0h8
超初心者です。
シミュレーターで動かしながら独学で学んでいるのですが、
scanfが動かない(スルーされる)ので困っています。scanfが動くシミュレーターってあります?
2018/08/21(火) 14:13:40.03ID:Xve8S0h8
今はpaiza.ioを使っています
2018/08/21(火) 14:16:15.27ID:Hz7fBosn
下の入力欄が空白じゃないの?
2018/08/21(火) 14:27:50.04ID:Xve8S0h8
解決しました。ありがとうございました。
2018/08/21(火) 20:15:22.43ID:FwleoeVd
for文でこんなのを発見したのです。
for(;;)
ご覧のとおりセミコロンがカッコ内に2つあるだけ。
これはどういうfor文でしょうか。
ググり方も分からないです。
2018/08/21(火) 20:17:35.28ID:bAEvazF4
無限ループ
2018/08/21(火) 20:22:25.64ID:i/CPlprw
昔からその書き方の無限ループを好む人は多い
俺が知ってる範囲だとカーニハンもその書き方を好んでいた
9188
垢版 |
2018/08/21(火) 20:22:27.49ID:FwleoeVd
>>89
(*´Д`)ありがとうございました。
2018/08/21(火) 20:27:12.52ID:mIqstMqN
無限ループって言っても
大概は何かの条件で脱出するわけだから
while (条件) が一番わかりやすいと思う
あ、好みだろうから、反論は不要です
2018/08/21(火) 20:34:59.42ID:8p839GFL
>>92
俺も無限ループはwhile(TRUE)派だな。
静的解析で怒られるから使うなって人もいるけど。
これも個人の好みなので反論不要です。
2018/08/21(火) 20:45:15.49ID:FwleoeVd
無限ループには
for(;;)
while(1)
while(true)
などがあるようですが、驚いたことにfor(;;)がC言語の伝統的スタイルなんだそうで。
2018/08/21(火) 20:50:55.87ID:mIqstMqN
goto 笑
2018/08/21(火) 21:07:06.74ID:FuTngql1
do {
} while (true);

だな
97デフォルトの名無しさん
垢版 |
2018/08/21(火) 21:12:46.13ID:xHZnBR+z
true って新しいCだと使えるの?
2018/08/21(火) 21:15:49.80ID:Bspmt0aQ
_Bool
2018/08/21(火) 21:18:05.52ID:mIqstMqN
while (1==1)
なんて
2018/08/21(火) 21:21:39.51ID:WLqP+HZB
for(;;)は無条件であることを的確に表現してる
条件が書いてないのはこれだけ
101デフォルトの名無しさん
垢版 |
2018/08/21(火) 21:30:40.05ID:xHZnBR+z
そういややったことないけど while () はできないのかな?
できたらできたでなんか怖いがw
2018/08/21(火) 21:35:16.36ID:8p839GFL
>>100
冷静に考えると、何でfor(;;)の真ん中の条件式のとこ空欄でも正しい構文になるんだろうね。
for以外に条件式省略できる構文ってないよね?
103デフォルトの名無しさん
垢版 |
2018/08/21(火) 21:39:06.78ID:xHZnBR+z
if () ができたらなんか嫌だな
2018/08/21(火) 22:56:19.30ID:7hn0MDmO
>>102
確かに…
2018/08/21(火) 23:14:00.83ID:H0lJZ+G5
左右の式が省略できるから、ついでに真ん中の式も省略可能にしたんだろう。
2018/08/21(火) 23:18:17.02ID:mIqstMqN
二つのセミコロンも省略して良いことにしようw
2018/08/22(水) 01:03:40.03ID:Vm7yolE7
ループの話でふと思い出したんだけど、この書き方キモいと思う?

LOCK();
while (条件) {
  UNLOCK();
  LOCK();
}
UNLOCK();
2018/08/22(水) 01:07:46.55ID:srSdeWyK
きもいけどきもいだけだから必要ならそうする
Cだしね
2018/08/22(水) 01:11:58.05ID:+gfjb8L8
condwaitみたいなの、たまに書くと混乱するわ
2018/08/22(水) 01:18:33.81ID:J6lVaoNe
LOCKして、何かして、UNLOCKして解放する
わけではないんだ?
111デフォルトの名無しさん
垢版 |
2018/08/22(水) 02:53:55.25ID:wb9Zg9xS
for (\(^o^)/)
2018/08/22(水) 06:53:07.59ID:Vm7yolE7
>>108
while (条件) で統一したいと思いつつ、この手の場合LOCK, UNLOCKのインデントがズレててキモいなといつも気になってしまう
まあどーでも良すぎていつも放置するが

>>110
アトミックな条件チェックの話
2018/08/22(水) 07:33:35.95ID:RPMrdt6N
>>112
手動でインライン展開する必要がなければ、普通は、

while (check_func()) {
}

bool check_func(){
LOCK();
bool retval = XXX; // check something here
UNLOCK();
return retval;
}

とする。
C++なら inline を付ければインライン展開時(元のコード)と似たようなオブジェクトコードが出ることになっている。
2018/08/22(水) 09:35:21.99ID:ULC6Ul0L
>>107
do {
LOCK();
UNLOCK();
} while (条件);
115114
垢版 |
2018/08/22(水) 09:36:42.99ID:ULC6Ul0L
ごめん、ちがた
2018/08/22(水) 09:52:30.97ID:2YTphjWh
>>107
条件を判断するためだけにLOCK/UNLOCKを行うコードだとしたら最悪のコードだ

do {
LOCK
判断
UNLOCK
if (!判断結果)break;
} while (1);

素直にこうしなさい
2018/08/22(水) 11:11:08.70ID:yAP1ongv
条件判断が目的じゃないと思うぞ
2018/08/22(水) 11:35:04.81ID:yJL450CM
どこが素直なんだ
締め切りが迫ってバグが取れず
なりふり構ってらんなくなったやつが書く
イカレたコードでしかない
2018/08/22(水) 11:58:31.90ID:DbwOmzYq
>>116
これは酷いw
2018/08/22(水) 12:04:07.83ID:MGgq/0yt
イカれたコードを紹介するぜ
2018/08/22(水) 12:27:28.23ID:2YTphjWh
ん?
一番素直だろうが
条件判断の為だけにLOCKしてるという前提で

判断を関数に分ける?
分けるかどうかはこんなちっぽけな理由で判断するべきじゃないよ
判断の度に関数にしてたら意味不明な関数で溢れるぞ

もちろん意味が明瞭で他にも同じ判断を使う可能性があるのであれば
関数やマクロでパッキングすべきだが
2018/08/22(水) 12:36:44.83ID:yJL450CM
LOCK
判断
UNLOCK
というアトミックなシーケンスを関数にする理由はちっぽけじゃない
LOCK/UNLOCKが必要な具体的な場面を想定しての発言には見えない
2018/08/22(水) 12:50:05.96ID:2YTphjWh
どういう場面かなんて>>107では判断不能だし
分けるべきか分けないべきかも>>107では判断不能

判断出来ないのに
「わざわざ関数構成を変えるべき」
なんて主張をすべきじゃない
2018/08/22(水) 13:02:48.20ID:Xk7aTjF/
>>123
いやー、わからんのはあなたに実務もしくは勉強の経験がないからよ
2018/08/22(水) 13:14:18.16ID:yJL450CM
昨日のvoid func(int ary[100]);にしても
ary[1000]を警告する処理系の具体的な例が挙がってないしな
2018/08/22(水) 13:39:37.67ID:2YTphjWh
>>124
わからんねえ
エスパーじゃないんだから

経験が少なくて
分けないべき場面が思い浮かばないんだろうねえ
2018/08/22(水) 14:01:43.77ID:yJL450CM
間違いない、昨日のバカだ
NGIDっと
2018/08/22(水) 14:12:07.92ID:JOaq3c53
>>127
そういうあなたは昨日のイキってた方の人?
2018/08/22(水) 14:15:28.00ID:J6lVaoNe
パッと見て何をしているか分からないソースって
後の人が取っても苦労するし、気の毒
2018/08/22(水) 14:19:13.21ID:J6lVaoNe
多分書いた人の意図は 
while文内の判定時に
LOCKしたいのかとは思うが
131デフォルトの名無しさん
垢版 |
2018/08/22(水) 14:26:31.81ID:TfhbroeT
while ( ^∀^)
2018/08/22(水) 15:10:17.96ID:44OVOulF
check_func()というアドホックっぽい関数名が誤解のもとかな
get条件atomically()にすれば意図が明白
2018/08/22(水) 15:19:38.80ID:yJL450CM
atomicallyって文言いるかねえ
いちいち全部につけて回るより
LOCK/UNLOCKしてることは
忘れたフリができるほうがいいと思うが
2018/08/22(水) 16:17:52.89ID:BT6ndhEb
英語圏の人には for (;;) をまとめて熟語的に "forever" と読めて
座りがいいのかも知れん。
カーニハンとパイクの『プログラミング作法』に
それに近いようなことが書いてあった。
2018/08/22(水) 16:25:37.12ID:6OOlmfSC
>>133
条件取得の関数がすでにあってそれがアトミックでないケースも想定
2018/08/22(水) 16:31:28.34ID:UfcjGeQr
>>134
なるほどforeverか
そういう風にも読めるな
2018/08/22(水) 16:44:34.35ID:AU3mefLA
>>134
そう言われると確かに座りが良いかもしれんが、(;;)をeverと読むのか。。。
今の時代では顔文字の失敗作にしか見えんなw
2018/08/22(水) 16:54:07.40ID:yJL450CM
>>134
#define ever (;;)
とかやんの?

だったら
#define forever for (;;)
のほうがマシだと思う

>>135
空想論なら付き合ってらんねえぜ
139134
垢版 |
2018/08/22(水) 17:01:35.42ID:BT6ndhEb
「その部分のループ、終了条件が色々なんでとりあえず for (;;) で回して」
みたいな口答でのやりとりで for (;;) を forever と読めば手っ取り早いでしょ。
while (1) で…よりも言いやすいんじゃないかと。

これは空想論だけどね。
2018/08/22(水) 17:28:26.65ID:yJL450CM
無限ループで済むことを
forの第2式を空欄で
なんて回りくどい言い方しねえよ
2018/08/22(水) 17:52:35.43ID:l5cdWJfA
>>140
別に回りくどくないし
良く見るコードだよ

いろんな人のコードを見たりしないの?
みんないろんなポリシーでいろんなコードを書くから

いろんな書き方を知っていた方が良いよ
2018/08/22(水) 17:59:10.07ID:l5cdWJfA
while (条件)
でしかループが組めないのはちょっとさみしい

無理やりこの形にするために
>>107みたいな意味不明なコードになる
2018/08/22(水) 18:07:38.93ID:yJL450CM
>>141
口頭でのやり取りつってんだろ
流れを読めよ
2018/08/22(水) 18:22:36.66ID:PnEe4J3b
マウント取りたくて必死なアスペだから仕方ない
2018/08/22(水) 18:30:03.99ID:l5cdWJfA
口頭で
forの第2式を空欄で
なんて発想は出て来なかった
146デフォルトの名無しさん
垢版 |
2018/08/22(水) 20:52:31.01ID:ROURn6Ut
for ( ;∀;)
2018/08/22(水) 21:21:35.96ID:yJL450CM
> while (条件)でしかループが組めないのはちょっとさみしい

ここは同意
while(1) であろうが for(;;) であろうが同じこと
どっちかが好みで他方で書かれたからって可読性が落ちたとか騒ぐ
救いようのないドアホには付き合ってらんね
それだけだ
2018/08/22(水) 21:23:43.06ID:82KbBjx+
>>116を認めないお前も同じようなものかと
2018/08/22(水) 21:26:52.07ID:MwkxeX8r
whileで無限ループする場合、0じゃなければ1以外を
使ってもいいわけだがどうする?
電話番号とか使えばオシャレかもしれないよ
2018/08/22(水) 21:27:18.15ID:JglTnHlJ
とりあえず、おかしなのに絡まれた >>134 に同情を禁じ得ない。
2018/08/22(水) 21:28:19.40ID:yJL450CM
別にiocccのコードが読めろとか言ってない
int *aryがint ary[100]じゃなきゃ読めないとかぬかしたり
while(1)がfor(;;)じゃなきゃ読めないとかぬかす
想像を絶するアホには付き合ってらんねつってるだけ
lock/doit/unlockを関数化する必要性がわからないアホも含まれる
2018/08/22(水) 21:33:30.14ID:Jjipv9/i
>>151
「じゃなきゃ読めない」ってどこかに書いてたっけ?
そんな気はしてたが、やっぱり日本語不自由な人だったらしい。
2018/08/22(水) 21:42:00.39ID:yJL450CM
じゃあ喚くのやめろ
うるせえんだよ
2018/08/22(水) 21:43:08.30ID:Jjipv9/i
>>153
やっぱり日本語不自由な人なんだw
2018/08/22(水) 21:51:19.93ID:Vzjpb7lE
何がじゃあなのかわからない
思考がbool値しかないのか
2018/08/22(水) 21:51:23.19ID:wgajpaTM
アトミックな操作の意味がわかってたらああはならんのですよ
2018/08/22(水) 21:52:48.42ID:Vzjpb7lE
世の糞コードのほとんどはコミュニケーションの失敗により発生する
2018/08/22(水) 21:54:35.09ID:Jjipv9/i
C言語以前に日本語もちゃんと理解できない人と議論が噛み合うわけない。
相手しただけ損したわ、アホらしい。
2018/08/22(水) 22:02:56.29ID:yJL450CM
勝手に損してろ
誰にも賠償請求できない
泣き寝入りだな
アホw バカwww
2018/08/22(水) 22:05:01.83ID:Jjipv9/i
はいはい、ちゃんとにほんごをべんきょうしてりかいできるようになってから、かきこんでくださいね。
2018/08/22(水) 22:13:51.56ID:RPMrdt6N
まあ概ね ID:yJL450CM が言っていることは正しい。

>>107のコードは、かなり特殊で、普通はあり得ない。
キモイかと問われれば、キモイと答えるのが正しい。
(必要ならやればいいが)

>>116
それはdo-whileの標準的使い方とは異なるので、混乱を招く。

>>132
check_func()は、107を書き直した場所がすぐに分かる名前にしただけ。
実際、問題なく伝わってるだろ。
本番コードでこの名前はあり得ない。名前が被るから。


ただ、正直、こんなどうでもいいところで拘るのは止めた方がいい。上達しなくなる。
どれでもいいから自分が好きなのを選び、グダグダ言わずにどんどん書いた方がいい。
なお、Goにはwhileが無い。廃止されて、forだけになっている。

ちなみに、俺は
固定長ループ(単純ループ): for … for (int i=0;i<num;i++) 程度の簡単な場合は常にこれ
可変長ループ(複雑なループ): while
無限ループ: while (1)
do-while: 使わない
にしているが、正直、ここら辺は好みだし、自分がどう決めるかだけ。(上記は標準的だとも思っているが)
それよりは、自分の中で統一するほうが重要だ。
(少なくとも自分が書いたコードを読むときに混乱しなくなる)

業務なら、グダグダ言わずコーディングルールに従えばいい。
場所によってはwhileとforのどちらかが禁止とかもある。(どっちかは忘れた)
理由はバグって無限ループにしてしまったときにコード上から判定しづらいとかだったはず。
162107
垢版 |
2018/08/22(水) 22:19:27.48ID:Vm7yolE7
非常にくだらない質問にレス付けてくれてサンクス
なんか荒れる原因つくってスマンかった

やっぱりあの書き方きめえよなあ・・・
2018/08/22(水) 22:57:41.03ID:RPMrdt6N
>>112
> LOCK, UNLOCKのインデントがズレててキモい
これは諦めろ。
酷い話、インデントがぴったり合ってないと駄目な奴はプログラマに向いてない。
どうやってもずれるからだ。
googleのコーディングルールにも昔は
・インデントを揃える努力は、キリがないしやるだけ無駄だから諦めろ
と書いてあったはず。(今見る限りないが)


ちなみにキモイ理由は、インデントではなくて、完全に入れ子になっていないからだ。
最近はこの「入れ子」の厳密さも増していて、XML(HTML等)では入れ子しか文法的に認めないだろ。
例えば、

<while>
</while>

ならありだが、

<lock>
<while>
</lock>
</while>

は駄目で、

<while>
<lock>
</lock>
</while>

にしなければならない。
2018/08/23(木) 00:15:44.74ID:wxGNRrqx
>>161
do while の標準的な使い方?
無限ループも標準的な使い方ですよ

do whileはforやwhileに比べてパフォーマンスが良いことがあるので
使える時には積極的に使う人もいます

do whileを一切使わない人もいますが
165デフォルトの名無しさん
垢版 |
2018/08/23(木) 00:29:51.18ID:qYtPM3Ou
>>107
対称性保たれてるし、よくあるコードだぞ。
俺はキモイと思わん。
2018/08/23(木) 00:38:41.07ID:wxGNRrqx
ロックしたい対象がわかりづらい
同じ用途のロック/アンロックが2箇所ずつある
2018/08/23(木) 00:40:13.64ID:wxGNRrqx
C++の場合だと
無駄にロック期間が長くなる可能性がある
2018/08/23(木) 00:53:05.68ID:/qY100we
>>167
なんで?
2018/08/23(木) 00:59:32.58ID:HinwMmX/
頭が良い人ならすぐに意図がくみ取れるけど
メンテする人が必ずしも頭が良いとは限らない
コメント書いてもバグではまって始めて読まれたりするからね
ワザと作られた落とし穴なんて受けとられる危険もありそう

バカでも分かるような書き方をする方が安全かなと思う
2018/08/23(木) 01:59:34.18ID:y9Wx8uZn
>>164
>>116のコードは、while (1) で開始しても同じだし、(=do-whileを使う意味がない)
そもそも>>113に比べてメリットもないだろ。
そこで do-while 使う奴なんて皆無だと思うぞ。

まあそれでもやりたければやればいい。
個人開発ではメチャやって、その失敗を業務に生かした方がいい。

ただ、上達したければ、ある程度普通のコーディングルールで組んだ方がいい。(世間に合わせる)
自分と相手のルールが一致してたら、相手のコードも読みやすく、
結果、同じ時間、同じ努力でも読める量に違いが出てくるから。

あと、初心者はよく
・色々文法を知ってて、様々な書き方が出来る奴が偉い
と勘違いしがちのようだが、これは明確な間違いだ。(これは他言語では本当に酷い)
こんな糞どうでもいいところを様々な書き方をしているような奴は雑魚だ。
上手い奴は、そいつが決めたやり方に従って、一定の書き方で書く。
だから、後で読み直すときも楽だってこと。
自分の手書き文字なら相当汚くても読めるだろ。それに近い。

基本的には意味のない手動インライン展開は止めた方がいい。
それは無駄に関数を大きくする。
関数呼び出しのコストが気になるなら、C++なら inline が用意されてる。
そもそもロックなんて糞遅いから、そこでCPU命令数個ケチる意味もないはずだが。

可読性を上げる為に最初にやるべきなのは、関数を分割して小さくすることだ。
呼び出しコストは考えず、分割しまくった方がいい。
結果、抽象度が上がり、読みやすくなる。(全体を読まなくても済むようになる)
2018/08/23(木) 03:30:32.78ID:w8vcpguW
あくまで、プログラマが初心者の場合の話だけど。

いろいろなソースを見てきたけど。
仕事としてやるなら、初心者は、なるべく関数化してほしくないかな。
練習としてなら、いいけどね。

関数化する等して、抽象化した方が見やすいソースになるかというと、
間違いじゃないけど、正しくもない。

有能なプログラマーが書いたソースは素晴らしいし、可読性も申し分ない、うん。
でも、クソなコードは、関数化しちゃいけないものが、関数化されているなどが原因で、
追跡が難くなるんだな。
オブジェクト指向を謳う言語のソースなんか、C以上にプログラマーの手腕によって、
可読性の差が生じてしまう。関数だけでなく、クラスの設計が腐ってて、どうしもないとかね。
そうゆうソースの追跡は辛いわ。

Cの場合、ぐちょくちょなソースの場合、関数化されていない方が、
コードのメンテ等で、強引に追跡する際は苦労が少ない、そんな感じ。
■ このスレッドは過去ログ倉庫に格納されています
5ちゃんねるの広告が気に入らない場合は、こちらをクリックしてください。

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