C言語なら俺に聞け 152

■ このスレッドは過去ログ倉庫に格納されています
1デフォルトの名無しさん (アウアウウー Sa4f-7DQ/)
垢版 |
2019/06/17(月) 18:27:10.41ID:3L1/L9kLa
!extend:checked:vvvvv:1000:512
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/
-
VIPQ2_EXTDAT: checked:vvvvv:1000:512:----: EXT was configured
※前スレ
C言語なら俺に聞け 151
https://mevius.5ch.net/test/read.cgi/tech/1554171817/
VIPQ2_EXTDAT: checked:vvvvv:1000:512:----: EXT was configured
2019/07/19(金) 01:28:45.01ID:QK1dwfXD0
ネタで言ってるのか本気で言ってるのか判断が付かない
2019/07/19(金) 01:46:29.51ID:ZOnA3nWq0
ポインタ難しいって言われてるけどそんなに難しいか?
メモリイメージできれば理解できると思うけどな
2019/07/19(金) 02:19:29.42ID:1jezjf9K0
俺はポインタは難しいことがわかってたから、一度にすべて理解しようとしなかった
数年使って徐々に理解した
それが正解だった
2019/07/19(金) 02:49:16.94ID:ApXEphk20
初期化してないポインタにアクセスするとどうなっちゃうの
とか危険そうなのは試してないからわからないが
ハードウェアのイメージがあれば難しさはあまりない
(命名規則で Xxx_p と書いておけば
2019/07/19(金) 06:09:16.79ID:8762T9lH0
> (命名規則で Xxx_p と書いておけば

システムハンガリアンは大大大大大嫌い
2019/07/19(金) 07:17:09.85ID:gH0zRzIgM
>>585
ada, APLも知らない情弱知ったかは黙っとけ

>>589
まあ作者は同じだから後継って感じだし
2019/07/19(金) 09:10:50.31ID:EJb/7aTM0
>>599
そういう人もいるのか
おれはアセンブラもやってたので秒で理解した
604デフォルトの名無しさん (アウアウウー Sad3-9T1T)
垢版 |
2019/07/19(金) 09:29:24.25ID:uab/wKdga
>>580
マイコン用の小さいコードも作れるから。
昔のマイコンやPCはメモリが物凄く少ないのでその辺は重要。
少なくとも毎回でかいランタイムライブラリがくっついてしまうようではダメだ。

それと元々 UNIX の記述用に使ってた言語なので Linux 等の互換OSでも使われていて、そういうのが徐々に広まっていったので、それを通してCが流行った面もあると思う。
605デフォルトの名無しさん (アウアウウー Sad3-9T1T)
垢版 |
2019/07/19(金) 09:39:17.61ID:uab/wKdga
>>603
アセンブラできるとポインタについては理解が楽だよね。
アセンブラの方では普通に使う考え方だし。(というかないとプログラム作れないぐらい重要)。
2019/07/19(金) 11:29:42.41ID:1jezjf9K0
>>603
はじめてのプログラミング言語がCだったからな
けっこう苦労したよ、先輩
2019/07/19(金) 11:43:44.67ID:nbu0jJrl0
プログラムはZ80からなので、当たり前のようにアセンブラから学習した
CPUの仕組みを学ぶのにちょうど良かった気がする
2019/07/19(金) 12:47:23.54ID:8762T9lH0
Z80だとパイプラインとかあんまり憶えないよな
でRISCブームのとき苦労させられたと
2019/07/19(金) 13:03:51.18ID:hLCIQJ7mx
まぁZ80全盛期にパイプラインしてたCPUなんて限られてたしな。
そういう汎用コンピータはほぼ高級言語使われてたし。
2019/07/19(金) 13:07:02.40ID:8762T9lH0
6502とか
2019/07/19(金) 13:28:17.26ID:EJb/7aTM0
>>606
C++とかじゃ未だにオーバーライドとオーバーロードを間違えるので
レベル的にはおまえとドッコイだよ、後輩
2019/07/19(金) 14:13:06.92ID:ZOnA3nWq0
ムカデ長老を見習え
2019/07/20(土) 21:04:06.20ID:lWqONft90
泣いてる顔文字→( ; ; )がforの無限ループにしか見えないのですが、職業病でしょうか?
2019/07/20(土) 21:31:18.65ID:TRa6Slo50
8086のアセンブラはセグメントで挫折する・・・と言われてたけど
Z80やってたらすんなり理解できたな。
2019/07/21(日) 01:27:26.84ID:3tY7pLz50
>>613
煽りとかで()とか書かれてると関数に見えるときある
例: 職業病()とか言われましても
2019/07/21(日) 04:14:55.91ID:Nmc6oncn0
>>615
草、見えたことないわw
617デフォルトの名無しさん (ワッチョイ 3fad-lraP)
垢版 |
2019/07/21(日) 06:51:52.49ID:F3an1Rtm0
>>613
はい。

>>614
セグメントすごくわかりやすいと思うけどな。まともに説明出来る人と巡り会えなかったのだろうか。
2019/07/21(日) 08:20:20.57ID:/atv33Bt0
>>608
わかりやすいけど面倒だよね
2019/07/21(日) 15:59:50.66ID:FmQzr+LX0
>>613
forで無限ループつかうの?
おれはwhileかなw
2019/07/21(日) 16:10:09.79ID:g8U8cyIO0
forの方が短くてすむじゃないか
2019/07/21(日) 16:20:48.28ID:PhbbaTTy0
>>614
Z80にセグメントの概念なんてあったけっけ?
メモリバンク切り替えは機種によってはあったけど、あれはZ80の機能ではないし。
2019/07/21(日) 16:27:59.21ID:m/GaQUZU0
空白のcontinue節みたいなのに入る必要がないから
ちょっとwhileのほうが早いイメージ
2019/07/21(日) 16:43:59.35ID:g8U8cyIO0
>>622
インタープリターじゃないんだからさ
2019/07/21(日) 16:52:32.65ID:/atv33Bt0
>>619-620
俺はfor(;;)だな
while(TRUE)は警告表示されることが多かったから
2019/07/21(日) 18:08:15.14ID:Q0wcPMRB0
for (;;) とwhile (1) がどっちがぱっと見分かりやすいか戦争勃発しますか?
あとfor派は;;周りにスペースを入れるか入れないかでさらに細かく派閥が分かれていると聞きました!
2019/07/21(日) 18:19:58.86ID:FmQzr+LX0
>>625
まさに永久ループ戦争!
2019/07/21(日) 18:30:02.78ID:+S54SSox0
字下げのいらないgotoも参戦
2019/07/21(日) 18:32:50.79ID:Q0wcPMRB0
あ、do {} while(1);派も出てくるとおもうので皆さん頑張ってください応援してます
2019/07/21(日) 18:38:59.23ID:g8U8cyIO0
do while(0)は便利
2019/07/21(日) 18:39:57.32ID:vddupZNY0
>>629
それは #define で使うときだけでしょう?
2019/07/21(日) 18:44:37.26ID:g8U8cyIO0
いや、エラー判定とかでもよく使うだろ?
2019/07/21(日) 18:48:06.96ID:I0JRxlnTx
for (;;) は forever と読むとか
2019/07/21(日) 18:50:32.60ID:/atv33Bt0
バッドノウハウに近いが
do {
if(...) break;

if(…) break;

} while(0);
みたいなのは昔書いてたわ
2019/07/21(日) 18:52:10.72ID:Q0wcPMRB0
do {} while (0); の意味と目的【do while false イディオムの利点】 | MaryCore
ttps://marycore.jp/coding/do-while-false-idiom/
2019/07/21(日) 18:58:23.23ID:FmQzr+LX0
flag=true;
while(flag)
{
flag=(....);
}
2019/07/21(日) 19:09:32.73ID:/atv33Bt0
>>634
do {
if (that(value)) break;
if (value == -1) break;
if (value == 0) break;
puts("有効な値です");
} while (0);
みたいなのは
do {
if (
that(value)
|| value == -1
|| value == 0
) break;
puts("有効な値です");
} while (0);
って書けばいいだけ
do {
if (that(value)) break;
value = f(…);
if (value == -1) break;
value = g(…);
if (value == 0) break;
puts("有効な値です");
} while (0);
みたいに間に処理をはさまる場合が難しい
2019/07/21(日) 19:18:11.94ID:Q0wcPMRB0
このスレって直接ここに複数行のソース書き始める人多いよね
2019/07/21(日) 19:37:52.68ID:m/GaQUZU0
>>633
小さなスコープを作るため?
2019/07/21(日) 19:39:13.75ID:g8U8cyIO0
breakが使えるスコープね
2019/07/21(日) 20:14:20.69ID:/SITzbMm0
#define fe for( ; ; )
が最強
2019/07/21(日) 20:35:26.43ID:+S54SSox0
>633
おかしな事してるのが一目で、continue が外に漏れるこれ オススメ
switch(0)default:{
2019/07/21(日) 20:45:42.22ID:R+Rb+3j1d
gotoが便利すぎて禁止されがちなのが悪い。ちゃんと使えばコードが見やすくなることこの上なしなのに。
2019/07/21(日) 21:09:22.26ID:/atv33Bt0
>>642
そう言うこと
なので最近は素直にgotoで書くことが多い
一部の言語の様にブロックに名前付けて
break 名前;
でそのブロックを抜けられるようにしてくれれば良いのにと常々思う
2019/07/21(日) 21:21:29.94ID:m/GaQUZU0
ないものねだりではありますが
perlのようにブロックやループの頭にラベルをつけて、
redo next last があったらもっと良い
do {...} while(0); も {} と簡潔
2019/07/21(日) 21:42:59.10ID:ZJZWYLqf0
>>642
便利すぎってどういうことだよ
教条主義的goto禁止論の域を出とらんだろうが
2019/07/21(日) 21:46:07.68ID:AbjqA2h30
>>621
インデックスのことかも
2019/07/21(日) 22:36:03.44ID:c+HlyquL0
>グローバル領域に予め必要な変数や配列確保しておけば

>ネタで言ってるのか本気で言ってるのか判断が付かない

実際に仕様なんかがしっかりしているタイプで
メモリー確保が動的に大きく変化しないものなら
実際にそういう風に作っているのを聞いた事は有る

配列式だと動的に確保したり開放したりが無く
リークしたり無効になったりしない分かなり安全
実行開始時に使用する領域が完全に確保されているから
2019/07/21(日) 23:24:53.03ID:R+Rb+3j1d
>>645
すまん、そんなに深い意味はない。
2019/07/22(月) 00:04:19.79ID:PN8KKKdJa
静的な所にプール作るのはメモリ制限ある組込では割とあったと思いますよ
650デフォルトの名無しさん (アウアウウー Sad3-9T1T)
垢版 |
2019/07/22(月) 15:35:08.24ID:vmYUDJ0Ja
>>643
最近の言語ではそういうのあるね。
とはいってもJavaには既にあったのでかなり前からあるな。
Java以前はあるかどうか俺は知らん。
651デフォルトの名無しさん (アウアウウー Sad3-9T1T)
垢版 |
2019/07/22(月) 15:37:04.86ID:vmYUDJ0Ja
あ、Perlもループにラベル付けてlastで抜けるなんてのあるな。
2019/07/22(月) 16:18:33.80ID:QnLUYAOH0
break ラベル で、多重ループから一気に抜けられると便利なんだがな
2019/07/22(月) 16:35:14.27ID:rxI3cfFL0
gotoが便利すぎというより
単純な break returnで間にあわないときには
それしか制御がないのでは
2019/07/22(月) 17:24:33.59ID:7pc0Xm6O0
二重ループから抜けるにはgotoが一番
gotoを廃止した言語制作者は天罰を受けるべき
2019/07/22(月) 17:30:50.79ID:rxI3cfFL0
goto はそれで使われている保障がないから、
保守性のためにも
ループなどに名前付けて、それを抜けると明記したい
2019/07/22(月) 17:54:19.31ID:e8FkVPqsa
まず多重ループを避けろと
657デフォルトの名無しさん (ワッチョイ 3fab-5Xl5)
垢版 |
2019/07/22(月) 18:05:34.66ID:LktYqlpm0
gccで X Window System (x11) でウインドウつくって画像合成するのって

どうすればできますか? なにかサンプルプログラムなど無いでしょうか?
2019/07/22(月) 18:22:30.58ID:QnLUYAOH0
>>656
二次元配列を総なめする場合に
ループを 1変数でやるのかな?
2019/07/22(月) 18:36:31.65ID:zh10SCAHd
>>657
古本を漁ればやり方が書いてあるかも。
XScreenSaverのソースみれば参考になるかも。
2019/07/22(月) 18:39:10.09ID:zh10SCAHd
いにしえのシステムなら、関数名をmanコマンドで引けば、X Windowの関数のマニュアルが見られるはず。
661デフォルトの名無しさん (ワッチョイ 3fab-5Xl5)
垢版 |
2019/07/22(月) 18:42:21.76ID:LktYqlpm0
>>659
linuxOSだとSDL(Simple DirectMedia Layer)で書いたほうが情報が多く 
描画書き換え速度もはやい気がします

SDLに移行したほうがやはり無難でしょうか?
2019/07/22(月) 18:50:51.45ID:QnLUYAOH0
質問者自身で決定すれば良いと思うが
2019/07/22(月) 18:54:21.58ID:zh10SCAHd
>>661
X11は将来、Waylandにバトンを渡すらしい。新しい端末ではX11が採用されない状況が考えられる。クロスプラットフォームの方が安心かな?
2019/07/22(月) 18:56:55.15ID:zh10SCAHd
暗号化されてないX11をネットワークで見たら丸裸だからあんまり使いたくないよね。
665デフォルトの名無しさん (ワッチョイ 3fab-5Xl5)
垢版 |
2019/07/22(月) 19:02:32.68ID:LktYqlpm0
ネットワーク環境はsshしか使ったこと無いのですが
SDL_net などは関数に暗号化などがふくまれているのですか?
2019/07/22(月) 19:08:12.59ID:zh10SCAHd
>>665
ソーシャルゲームを作るなら、暗号化は必須。暗号化方式を決めて、それに合った暗号化専用のライブラリーを使う形になる。
667デフォルトの名無しさん (ワッチョイ 3fab-5Xl5)
垢版 |
2019/07/22(月) 19:10:57.83ID:LktYqlpm0
>>666
C言語の暗号化ライブラリで使いやすいのおせーてください
2019/07/22(月) 19:22:24.63ID:zh10SCAHd
ソーシャルゲームは専門ではないが、暗号化なら
https://ja.m.wikipedia.org/wiki/%E6%9A%97%E5%8F%B7%E3%83%A9%E3%82%A4%E3%83%96%E3%83%A9%E3%83%AA%E3%81%AE%E6%AF%94%E8%BC%83
2019/07/22(月) 19:25:19.41ID:MRg17CtQa
いろいろあるんですけど、ライセンス的にopensslでいいやみたいな感じになりましたね
waylandは5年後くらいにはなんとかなるんかな。どういうレイヤでサービス提供したいのかよくわからん所がある。
2019/07/22(月) 21:33:35.10ID:tAjmkx+m0
同じくopensslでいいんじゃないかと思いますな
671デフォルトの名無しさん (ワッチョイ 4f25-WSqd)
垢版 |
2019/07/23(火) 03:25:09.81ID:/ZO3BTO70
gchar **command = (gchar *[]){"./Hello.exe","World",NULL};

を gcc6 で compile すると以下の2種類の warning が出ます。

warning: ISO c++11 does not allow conversion from string literal to 'gchar *' (aka 'char *') [-Wwritable-strings]

warning: pointer is initialized by a temporary array, which will be destroyed at the end of the full-expression [-Waddress-of-array-temporary]

どう書くのが正解なのでしょうか? 教えてください。最後の NULL がなければ、

gchar **command = (gchar **)((char [][20]){"./Hello.exe","World"});

で良いと思うのですが、最後の NULL も必要です。よろしくお願いします。
2019/07/23(火) 04:01:15.67ID:XJs/DfWFa
要素の文字列をそれぞれキャストしてみるとか?
でも別に文字列の実体を用意した方が無難では。
673デフォルトの名無しさん (ワッチョイ ff2f-Im00)
垢版 |
2019/07/23(火) 05:54:57.80ID:XS6t8zxL0
char * const command[3] = {"./Hello.exe","World"};
2019/07/23(火) 09:58:47.20ID:J+ZHGa1Mr
初心者で勉強中なんですが、
switch文は
if文みたく
switch(a >0)のように()の中に関係演算子を使った式はかけないんでしょうか?
エラーがでるので無理なのかなと思ったんですが
2019/07/23(火) 10:46:29.88ID:DdnFitx+M
エラーじゃなくて警告では?
動かない理由はないと思うのでgccで試してみたけど、ちゃんと動いたよ。
ただ、結果は1か0の2値しかないのでif文使ったほうが良いと思うよ
2019/07/23(火) 10:51:17.50ID:unlUKZmGx
本当は
 switch (a) {
 case a > 0:
...
的なことをしたかったのではないかとエスパーしてみる。
2019/07/23(火) 11:36:41.71ID:LSxEgoA20
>>674
これなんか意味あるの?
具体的に何がしたいか知りたいなあ
2019/07/23(火) 11:42:11.95ID:CU39ntZ20
>>676
switch(true) って裏技 あれマジで気色悪いよね
2019/07/23(火) 11:44:08.90ID:SF2VCGvmM
case に何を書けばいいんだ?false は 0 でいいだろうけど、true は?
680671 (ワッチョイ 4f25-WSqd)
垢版 |
2019/07/23(火) 11:49:30.09ID:/ZO3BTO70
>>673
>char * const command[3] = {"./Hello.exe","World"};

ありがとうございます。これでも1つめの warning "does not allow conv..." は出ました。皆さんの所では出ませんか?

それと、 command はどうしても char ** 型である必要があります。
仮想端末で何かを実行させる関数 vte_terminal_spawn_async() に与えるためです。
https://developer.gnome.org/vte/unstable/VteTerminal.html#vte-terminal-spawn-async

引き続きアドバイスをお願いします。
2019/07/23(火) 11:53:01.06ID:4sm3RNn+0
>>674
書くことはできる
関係式は int 型の 0 または 1 という結果を生じるので
switch (a > 0) は a の値により
switch (0) もしくは
switch (1) と等価になる

おまえさんが言いたいのは switch で範囲チェックができるのか
ということだろうがそれはできない
a と case に指定した定数の == 比較しかできないのが switch だ

不等号や != が使いたければ if 文か3項演算子ということになる
682671 (ワッチョイ 4f25-WSqd)
垢版 |
2019/07/23(火) 12:04:01.45ID:/ZO3BTO70
>>672
ありがとうございます。具体的にはどうしたら良いでしょうか?

char list[2][20] = {"./Hello.exe","World"};  
gchar **command = (gchar **){ (char *)list[0], (char *)list[1], NULL};

だと、↓のエラーになります。
error: function-style cast to a builtin type can only take one argument

正しいやり方をお願いします。

うーむ。どうしたものか。 gchar ** 型をどうやって作るのかさっぱり分からない。。。
ダブルポインタがよく分かってない。もう warning は放っておくしかないのかな?
2019/07/23(火) 12:10:49.21ID:XJs/DfWFa
その前に、671の警告でC++11って出てるのはなぜなのか。
複合リテラルってあれキャストではないよな。知らんけど。
684671 (ワッチョイ 4f25-WSqd)
垢版 |
2019/07/23(火) 12:21:12.41ID:/ZO3BTO70
>>672

gchar list1[][20] = {"../Exe/H2O.exe","World"};
gchar *list2[] = {(gchar *)list1[0], (gchar *)list1[1], NULL};
gchar **command = (gchar **)list2;

いろいろ試したところ、↑だと warning でなくなりました。意図されたのはコレでしょうか?コレで良いでしょうか?
2019/07/23(火) 12:21:15.34ID:d2s+lfJ+0
>>682
https://ideone.com/a1eBqF
これなら警告出ないけど、やりたいことと合ってるかどうかは知らん
2019/07/23(火) 12:22:08.73ID:7yf4dx7Q0
>>680
文字列リテラルは書き換え不可なので当然の警告。
char const* const command[] なら警告は出ないだろうけど、渡した先で書き換えしない保証がないならアウト。
渡した先で書き換えしない保証がないなら、リテラルでの初期化は無理だと思う。
687671 (ワッチョイ 4f25-WSqd)
垢版 |
2019/07/23(火) 12:24:46.80ID:/ZO3BTO70
>>683
なんかおかしいですよね。

でも Makefile に書いていいて実際に compile に使っているのは間違いなく gcc6 です。
warning が g++6 と共通なのですかね?
2019/07/23(火) 12:30:44.31ID:d2s+lfJ+0
https://ideone.com/Cek4Tz
そもそもgcharってなんなの?
charのエイリアスかなんか?
2019/07/23(火) 12:33:40.67ID:d2s+lfJ+0
> warning: ISO c++11 does not allow conversion from string literal to 'gchar *' (aka 'char *') [-Wwritable-strings]
charのエイリアスか
なら最初に書いとけよ
2019/07/23(火) 12:38:30.05ID:XJs/DfWFa
>>684
そういう話です。
691671 (ワッチョイ 4f25-WSqd)
垢版 |
2019/07/23(火) 13:18:08.85ID:/ZO3BTO70
>>688
ありがとうございます。スマートですね。参考にします。
gchar は char の別名です。すみません。
692671 (ワッチョイ 4f25-WSqd)
垢版 |
2019/07/23(火) 13:24:51.89ID:/ZO3BTO70
>>683
Makefile には gcc6 と書いてあるのですが、出力をみると c++ でコンパイルしていました。。。
今気づきました。 -std=c++11 もつけてある。
Cのソースを c++ でコンパイルするとマズいですか?今のところ何も問題はないです。
2019/07/23(火) 14:56:41.16ID:XJs/DfWFa
>>692
C++に複合リテラルないんじゃないかな。なくても困らんか。

あとさっきの配列の要素にstrdup突っ込むとconstにしなくていいかもな。
もしくはmemcpy(malloc(100),"hoge",5)とか。
標準に沿った書き方かどうかは知らん。
694671 (アウアウカー Sac3-WSqd)
垢版 |
2019/07/23(火) 17:13:31.67ID:TCk4qRZWa
>>693
ありがとうございます。なるほど、複合リテラルですね。調べてみます。

自分、C で書いていて compile も C でやっているつもりだったんですが、コンパイラが c++ だった。。。
これは c++ 用の Makefile を流用した為です。
最初 c++ でアプリを作ろうとして、Makefile を用意して、ソースを書き始めたのですが、途中で仮想端末オブジェクトが c++ ではうまく使えない事が判明して、
ソースを C に書き変えたのです。Makefile はフラグ等あるので流用してしまった...

これ以上は困らないですかね。困った時にはコンパイラが c++ な為を疑ってみます。

strdup と memcpy も試してみます
これをヒントに検索していて g_strsplit なる関数もある事を発見しました。
695デフォルトの名無しさん (アウアウウー Sad3-9T1T)
垢版 |
2019/07/23(火) 18:36:28.60ID:5chEKyGia
C++ には引数に void だけって関数がないらしいぞ。
その他細かい違いがあるかも知れないので要注意だ。
2019/07/23(火) 18:58:12.02ID:Ffr5F2PG0
どちらかというと()の解釈が違う
c++だと()は(void)と同じ
cは()が(void)と同じになる文脈とそうでない文脈がある
697デフォルトの名無しさん (アウアウウー Sad3-9T1T)
垢版 |
2019/07/23(火) 19:36:26.79ID:5chEKyGia
こうしてまた(void)論争が始まり3スレぐらい消費されるのであった。
■ このスレッドは過去ログ倉庫に格納されています
5ちゃんねるの広告が気に入らない場合は、こちらをクリックしてください。

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