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/20(月) 00:19:11.88ID:houfzDz0
>>24
配列っぽい表記に惑わされて、sizeofして長さを求めようとしたというバグを何度か見ました。
2018/08/20(月) 00:26:25.44ID:ftO9aq8g
 
f(int data[100]) なんて渡し方だと、どう?
2018/08/20(月) 01:02:08.56ID:houfzDz0
そんな文法はない。
宣言としては有効かな。でも意味はないだろうね。ただのポインタ。
2018/08/20(月) 01:20:33.12ID:ftO9aq8g
>>33
じゃあ、これをポインタ表記に置き換えて見てください、お願い
2018/08/20(月) 03:08:45.92ID:k5zLgYIW
>>24
なるほど、じゃあ君は
void swap_int(int lhs[], int rhs[]);
と書いてもらえれば判断つきやすいんだな
36デフォルトの名無しさん
垢版 |
2018/08/20(月) 04:14:23.20ID:GHO1XUgy
なんというか、Cならではの問題かな。
Javaもちょっと似てるか。
2018/08/20(月) 06:23:59.34ID:W9GZumqR
下のようなコードを書くとコンパイルエラーになるでしょ。
int ary[100];
int val;
val = ary++;
このaryは配列だから、ary自体の値を変化させる操作は出来ない。
それの類推で関数の仮引数はポインタで受けるんじゃないかな。
関数の中でポインタ風に使う変数はポインタの形で宣言。

関数内で値を変化させず [] によるインデクスだけでアクセスするなら
仮引数を配列の形で宣言するのも分かりやすい書き方かも。

後は歴史的な事情。
配列風に書くとインデクス計算に掛け算を使われて遅かった名残り。


>>30 俺はmainの引数は main(int argc, char *argv[]) だな。
保守的だけど、こんな場面で独自色出すことないしね。
2018/08/20(月) 07:23:53.30ID:iMQAgpc+
>>24
あんたの感覚は正しいと思う
同じだと言ってる奴もいるけど
foo(int a[]){
a = … /* エラー */
とか微妙に違う
ただそこまで気にする人があまりいないだけ
2018/08/20(月) 07:29:22.22ID:OvqDIJZn
関数の引数では配列の要素数は無視されるだけ
変数としての配列とポインタは別物だけど、関数の引数では全く同じもの
2018/08/20(月) 08:10:21.73ID:iwav6OWh
理由は既出だけど、C言語では配列とポインタは明確に違うよ。
相互変換可能なだけ。
2018/08/20(月) 09:01:16.78ID:KJZ73X54
ぶっちゃけ、相互変換可能ならその二つは同じじゃねえか?
数学的に
2018/08/20(月) 09:09:43.44ID:zNROsdOB
同じ点もあるし違う点もある
同じ点を強調したいときに「同じ」
違う点を強調したいときに「違う」
と言うだけ

具体的に語らないと何の意味もない
2018/08/20(月) 09:30:29.85ID:W9GZumqR
>>38
そのコード片、エラーになるかな?
仮引数のa(intへのポインタ)に
関数内で値を代入することは許されるはずだけど。
2018/08/20(月) 10:24:22.53ID:B6E8iGMG
代入ではエラーにならんと思うよ。
lvalueとして使えると思う。配列っぽく書けるがあくまでポインタ。
2018/08/20(月) 10:37:33.39ID:iMQAgpc+
>>43-44
すまん、お前らの言う通りだ
なんか勘違いしていたみたい
2018/08/20(月) 11:31:29.94ID:mV0yla1z
>>20
パクリで儲かる成功例
2018/08/20(月) 11:46:22.27ID:B6E8iGMG
引数の配列がホンモノだとすると、非NULLが保証されてないとあかん。
というか構造体渡しと同様の配列渡しが必要だな。まあ使わんか。
2018/08/20(月) 13:08:43.61ID:k5zLgYIW
>>37
その例は
void func(int ary[100])
{
int val;
val = ary++;
}
との違いを示そうとしているのだとしたら
int *val; じゃないとおかしいだろ

>>37
[]で書くべきと主張するんなら
char argv[][]にしなきゃねえ
もちエラーだけどw
49デフォルトの名無しさん
垢版 |
2018/08/20(月) 13:28:58.98ID:HLNtX2wQ
>>47
ま、必要なら構造体の中に入れて渡すと。
2018/08/20(月) 16:12:09.36ID:K5YeoIjy
配列をパラメータにするのは
サイズが決まってる時にそれを明示したい場合くらいだな

ポインタの方が汎用性が高いから
2018/08/20(月) 16:14:24.46ID:K5YeoIjy
構造体みたいに
値渡しやコピーもあると(たまには)便利
2018/08/21(火) 07:18:10.26ID:gERn4ySS
>>50
void func(int ary[100]); これと
void func(int *ary); これが
意味が違うと思っているのか?
2018/08/21(火) 07:20:36.44ID:hlK4Wy69
設計意図を示すコメント的な意味ならあると思う
中身は同じだけど
2018/08/21(火) 07:38:47.67ID:Xgm2Pp2D
初心者に対して誤解を与えるだけじゃね?
必ずそのサイズで呼ばれると保証されるわけでもないし。
2018/08/21(火) 08:20:07.94ID:FuTngql1
>>52
意味は違うね

要素が100個以外の時に前者を使ってるコードを見たら気持ち悪いだろ?
そういうこと

コンパイラによってはary[1000]にアクセスすれば警告が出る
2018/08/21(火) 08:40:04.69ID:ZsMFgi2m
ほんとに警告出るのか?
サイズ指定に意味がないというのが規格だし、コメント程度の役割しか持たせたらあかんという気が
2018/08/21(火) 08:48:21.68ID:Y1HyydAv
gcc8でもclang6でも警告でなかったょ…
2018/08/21(火) 09:13:57.61ID:GIXT+l9b
お高い静的解析ツールだと警告出るかもね。
やってないから知らんけど。

そういう環境で開発できるならコメント以上の意味はあるかも。
仮定で申し訳ない。
2018/08/21(火) 09:28:29.44ID:gERn4ySS
>>55
おまえの主観は聞いてない
プログラムの実行結果が違ってくる例を示せ
2018/08/21(火) 09:30:24.31ID:Y6yN+LUK
>>59
屁理屈乙
2018/08/21(火) 09:31:42.61ID:hk/Hf9fq
>>48
多次元配列なら
void func(int ary{}[100])
{
}
とか
void func(int (*ary){}[100])
{
}
2018/08/21(火) 09:35:21.28ID:hk/Hf9fq
>>61
間違えた

void func(int ary[][100])
{
}
とか
void func(int (*ary)[100])
{
}
2018/08/21(火) 10:40:22.58ID:gERn4ySS
>>60
もう一度言う、おまえの主観は聞いてない
正論か屁理屈かはおまえの主観だ
客観的事実を示せ、理屈はそれからだ
2018/08/21(火) 10:57:00.63ID:vnB4usre
>>63
だれも機械の解釈の違いには言及してない定期
2018/08/21(火) 10:59:30.05ID:gERn4ySS
>>62
void func(int ary[][100]); これはできるのに
int func(void)[][100] これはできない
{
int ary[][100]; これもできない
ary = 0;
return ary;
}
extern int ary[][100]; と
extern int (*ary)[100]; は意味が違う
結局、[]で書くべきなんて主張は
通用しないところが多すぎる戯れ言だ
2018/08/21(火) 11:01:09.20ID:gERn4ySS
>>64
プログラム言語は機械に解釈させるためのものだ
自明なことを誰も言ってないなんてことこそ屁理屈そのものだろうが
2018/08/21(火) 11:01:29.60ID:+F/9g7TB
>>66
糖衣構文
2018/08/21(火) 11:02:23.89ID:gERn4ySS
>>67
全然関係ねえぜ
暑さで気が触れたか?
2018/08/21(火) 11:05:05.84ID:eIEuxTun
>>68
機械の解釈が同じでも人間には違う意味に見えるのはあるよな?
2018/08/21(火) 11:55:44.43ID:gERn4ySS
>>69
void func(int ary[100]); これのどこが
void func(int *ary); これの構文糖衣なんだ?
書いた奴の頭を疑わせる以外にどんな意味があるんだよ
2018/08/21(火) 11:56:39.26ID:gERn4ySS
サイズが100でなければならない関数なら
void func(int (*ary)[100]); こう書いて
int ary[100];
func(&ary); こう渡せよボンクラ
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したいのかとは思うが
■ このスレッドは過去ログ倉庫に格納されています
5ちゃんねるの広告が気に入らない場合は、こちらをクリックしてください。

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