X



C言語なら俺に聞け 144
■ このスレッドは過去ログ倉庫に格納されています
0001デフォルトの名無しさん (ワッチョイ 838a-3nWA)
垢版 |
2017/12/23(土) 19:33:43.89ID:dghfoRy20
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/


http://mevius.5ch.net/test/read.cgi/tech/1509107288/
VIPQ2_EXTDAT: checked:vvvvv:1000:512:----: EXT was configured
0782デフォルトの名無しさん (ワッチョイ 97b3-C7gl)
垢版 |
2018/02/07(水) 19:49:53.17ID:I0UlpN+80
const 無しのポインタ変数にリテラル文字列を与えると

C++だと (リテラル文字列の)指し先を書き換える気あるのかボケェ と警告やエラーになるですよ

Cは過去のコードの互換性の為に黙ってることが多い
(けどオプションで警告したりエラーにしたりするんだっけか?)
0784デフォルトの名無しさん (ワッチョイ 57b3-wbgk)
垢版 |
2018/02/07(水) 22:29:07.83ID:MTpdY7NJ0
"!"!"!MOHYO!"!"!"2"

1.[[[HUn≒MUL=POSI≠MAHO+Set*HUGE=SAGE=LOGE=NOISIA=0≒1]]]

2-[[[[[[[E=RAT%2^10%SPELAn!%]&!TOWA&!PEG#!NOLNOL8!#!HYAGO!2#]1*2=1]U]S]0]O]!#PAL!

3--->PAGODOL7&!@17,2222734.15&[[[%%RENRAK6,9,99"^10"]#$11.2%}]KAIJ]{

41.2SSS = RALQI2.β{{{RA4,0,238^97,1,$.S.L.E.I.L."Q5352.15Q"JOL"5*3>>>41.3q}}}>1.2<0
.3φTALHOSI"0">>>105.10<1.235<1.2>51≠52===55.632>V="E=0.835"of"1.32","632",0.683,1.end

{
0786デフォルトの名無しさん (ワッチョイ 2e80-2I1n)
垢版 |
2018/02/08(木) 02:47:50.39ID:31uXy/SD0
>>779-780
Rubyではパイプラインで、サブプロセスを実行し、結果を受け取れる。
例えば下は、メモ帳の実行ファイルの場所を探す

resText = ""
IO.popen("where notepad") { |io| resText = io.read }
puts resText

出力結果
C:\Windows\System32\notepad.exe
C:\Windows\notepad.exe
0787786 (ワッチョイ 2e80-2I1n)
垢版 |
2018/02/08(木) 03:57:59.54ID:31uXy/SD0
>>779-780
Rubyではパイプラインで、サブプロセスを実行し、結果を受け取れる。
これで、サイトのHTML が取れる

resText = ""

IO.popen("curl サイトのURL") { |io| resText = io.read }

puts "終了ステータス : #{$?}", resText
0788デフォルトの名無しさん (ワッチョイ 319f-R9JW)
垢版 |
2018/02/08(木) 04:04:45.98ID:FQ2Hecmn0
>>779
system()ではなくpopen()使うと楽だ。
0792デフォルトの名無しさん (スップ Sdc2-Rwrx)
垢版 |
2018/02/08(木) 08:12:52.25ID:JMUgsKdMd
>>790
すまねぇ
正確に言うとcurlだった
実行ファイルってのを言いたかったんだけど紛らわしかったわ....

>>791
コマンドラインで実行をコード上からして
その結果をメモリに書き込みたいって感じ

int main()

char* buff[1024]
execv(curl..........)


子プロセス作成とかは書いてないけどこのexecvの結果をbuffにいれたい
0793デフォルトの名無しさん (ワッチョイ 4193-jcwv)
垢版 |
2018/02/08(木) 08:29:27.70ID:Mx6kxOEl0
>>779>>789 は同じ投稿者なのかな?

「curl.exeをsystemコールする」という文の意味は、
実際には curl.exe でなく /usr/bin/curl かどこかの Linux のコマンド、
systemコールと言っても system() 関数でなく execv() 関数で呼ぶ、
という条件でいいの?
0795デフォルトの名無しさん (ワッチョイ 4193-jcwv)
垢版 |
2018/02/08(木) 09:24:02.21ID:Mx6kxOEl0
#include <unistd.h>
#include <stdio.h>

int main() {
  int pp[2];
  pid_t pid;
  pipe(pp);   // パイプを生成 (エラーチェック略)
  pid = fork(); // プロセスを複製 (エラーチェック略)
  if (pid > 0) {
    // 親プロセス: 子プロセスから情報を受け取る
    close(0);   // 標準入力のディスクリプタを閉じる
    dup(pp[0]);  // パイプの入力を標準入力に複製
    close(pp[0]); // パイプの入力を閉じる
    close(pp[1]); // パイプの出力側は使わない
    char buf[1024];
    int nbytes = read(0, buf, sizeof(buf)); // 子プロセスからのデータ受け取り
    printf("[%*s]\n", nbytes, buf); // 受け取ったデータの確認
  } else {
    // 子プロセス: 外部コマンドを呼び出し、標準出力経由で親プロセスに送る
    char *cmds[] = { "/usr/bin/echo", "hello, darling", NULL }; // ダミーの外部コマンド
    close(1);   // 標準出力のディスクリプタを閉じる
    dup(pp[1]);  // パイプの出力を標準出力に複製
    close(pp[1]); // パイプの出力を閉じる
    close(pp[0]); // パイプの入力側は使わない
    // 外部コマンドの呼び出し (エラーチェック略)
    execv(*cmds, cmds);
  }
  return 0;
}
0796デフォルトの名無しさん (アウアウカー Sa69-OLJ2)
垢版 |
2018/02/08(木) 09:25:00.98ID:Bk9SeRO9a
自分で fork, exec するなら pipe() 作って dup() で繋げ。
やり方はUNIXやLinuxのシステムコールに関する入門書みたいなのがあれば必ず書いてあると思うのでそういうのを見るか、またはググれば世界中で解説やサンプルプログラムが見つかると思う。
かなり基本的な事だ。
0797795 (ワッチョイ 4193-jcwv)
垢版 |
2018/02/08(木) 09:25:52.35ID:Mx6kxOEl0
急造のデッチ上げだけど、こんな感じかな。

要点は、名前なしパイプを作って標準入出力と差し替える。
外部コマンドの標準出力はパイプを通って出ていく、
呼び出した側は標準入力を読むとパイプから入ってくる。

32行制限に収めるために行が詰めたら見にくいね。
0798デフォルトの名無しさん (アウアウカー Sa69-OLJ2)
垢版 |
2018/02/08(木) 09:26:09.44ID:Bk9SeRO9a
などと書いている最中に真上にサンプルプログラム出現w
0800デフォルトの名無しさん (ワッチョイ 4193-jcwv)
垢版 |
2018/02/08(木) 12:29:54.84ID:Mx6kxOEl0
親プロセス側は標準入力をパイプに差し替える必要ないね。
パイプのディスクリプタから素直に読みゃいいんだわ。

// close(0);   // (不要)標準入力のディスクリプタを閉じる
// dup(pp[0]);  // (不要)パイプの入力を標準入力に複製
// close(pp[0]); // パイプの入力側はまだ閉じちゃダメ!
  close(pp[1]); // パイプの出力側は使わない

// int nbytes = read(0, buf, sizeof(buf)); // (変更)
  int nbytes = read(pp[0], buf, sizeof(buf)); // 子プロセスからのデータ受け取り
  close(pp[0]); // 使用済みパイプの入力を閉じる
0804愛恥人
垢版 |
2018/02/08(木) 22:40:11.36
消えてる(>_<)
0807恥人
垢版 |
2018/02/08(木) 23:03:59.16
どういう意味?(´・ω・`)
0809恥人
垢版 |
2018/02/08(木) 23:17:16.32
>>808
OSのソースコードはないじゃん(´・ω・`)
0811恥人
垢版 |
2018/02/08(木) 23:57:44.62
>>810
気づかなかった(´・ω・`)
0819デフォルトの名無しさん (ワッチョイ 319f-R9JW)
垢版 |
2018/02/09(金) 22:53:36.09ID:nN2BoaGY0
>>815
あー。ファイル1を開く、エラーならリターン、ファイル2を開く、エラーならファイル1をクローズしてリターン、ファイル3を開く、エラーならファイル1、ファイル2をクローズしてリターン、
・・・って具合にリターン直前にクローズするファイルがどんどん増えていくみたいなやつだよね?

そういうのは俺はもう goto 使って関数の終わりの方に飛ばしてそこで必要なクローズやらfree()やらをまとめてやるようにしたよ。関係する変数は関数のブロックの先頭の宣言で全部 NULL や -1 で初期化して goto の飛び先で NULL や -1 でなければクローズやfree()をする。
(但し関数の途中で自分でクローズやfree()をした場合はその直後にNULLや-1を代入するように書く必要がある)。C言語は try catch みたいな例外処理は作れないから仕方がないね。

goto 使わずにやるとしたら for (;;) か while (1) のブロック内に書いてエラーが出たら break すればできる(もちろんループの終わりは break)。しかしこの方法はループでもないのにループを書くという何か不自然なものになる。
0820デフォルトの名無しさん (ワッチョイ 319f-R9JW)
垢版 |
2018/02/09(金) 22:55:50.14ID:nN2BoaGY0
>>817
うう。かぶった。リロード忘れてた。
0821デフォルトの名無しさん (ワッチョイ 319f-R9JW)
垢版 |
2018/02/09(金) 23:00:38.39ID:nN2BoaGY0
>>818
C言語の場合は同じような事をする場合はgotoの方が可読性高いと思うけどなあ。とにかく間すっ飛ばして使ったリソース開放して即リターンしたいわけだし。
0824デフォルトの名無しさん (ワッチョイ 319f-R9JW)
垢版 |
2018/02/10(土) 00:06:47.82ID:l9ZzjyKP0
>>823
ああ。do while で 0 で抜けるようにするのでもできるか。
まあしかし goto 使わないならそんな風にするしかないよな。
0829デフォルトの名無しさん (アウアウエー Sa4a-3MxQ)
垢版 |
2018/02/10(土) 05:56:43.86ID:1vRRPdaia
break 1 とか
break 2 とかで
抜ける {} の段数指定できない仕様が糞
0831デフォルトの名無しさん (アウアウエー Sa4a-3MxQ)
垢版 |
2018/02/10(土) 06:14:37.72ID:1vRRPdaia
do{}while(0)は普通に使うやろ
特にマクロで
どこが変態やねん!
0832デフォルトの名無しさん
垢版 |
2018/02/10(土) 08:04:34.03
int ret = 1;
int fdA = -1;
int fdB = -1;
int fdC = -1;

if (ret) {
 fdA = open(A);
 if (fdA < 0) {
  printf(“ファイルAオープンエラー¥n”);
  ret = 0;
 }
}

if (ret) {
 fdB = open(A);
 if (fdB < 0) {
  printf(“ファイルBオープンエラー¥n”);
  ret = 0;
 }
}

if (ret) {
 fdC = open(A);
 if (fdC < 0) {
  printf(“ファイルCオープンエラー¥n”);
  ret = 0;
 }
}

if (ret) {
 いろいろ処理
}

if (fdA >= 0) close(fdA);
if (fdB >= 0) close(fdB);
if (fdC >= 0) close(fdC);

return ret;
0833デフォルトの名無しさん (ワッチョイ 4193-jcwv)
垢版 |
2018/02/10(土) 08:04:56.81ID:aodeHLjm0
O'ReillyのLinuxデバイスドライバ本では
初期化の失敗時、一部分だけ確保できたリソース群を
確保時とは逆順に行儀良く解放するのにgotoを使う方法を勧めてるね。

そういう具合にgotoが出てくる場面が明確ならば
必ずしもgotoが可読性を落とす、とは言えないじゃろ。
0836デフォルトの名無しさん (ワッチョイ e1a1-nHV3)
垢版 |
2018/02/10(土) 08:54:55.97ID:DmmJmf560
goto を使わないようにというのは
昔、ダイクストラ大先生が「gotoは有害だ!」
とのたまわれたので、それ以後gotoを使わない
構造化プログラミングというのが流行ってFortranなども
Fortran 77で一部構造化されたりしてきたという経緯が
あります。

たしかに、昔のBASICプログラムはやたらgoto が多くて
まさにスパゲッティプログラムで論理を追うのに苦労しました。

最近のBasis(たとえばFree Basic)などは構造化されていて
使いやすく感じます。

Cもgotoを使わなくて書けるのですから、やむおえない
(gotoを使わなければ、どうしようもない)場合場合以外は
使わないにこしたことはないと思います。
0837デフォルトの名無しさん (ワッチョイ 6ed7-jA6l)
垢版 |
2018/02/10(土) 09:02:56.46ID:cpx12OHt0
ダウト
昔のBASICはGOTO文のせいで読みづらいんじゃない
最大のネックは変数が全てグローバルであること
次いでFOR文のNEXTの自由度が高すぎることだ
メインフレーム脳でPCを語るジジイどもが
行番号を批判していたが的外れもいいとこ
0843デフォルトの名無しさん (ワッチョイ 99b3-7Au1)
垢版 |
2018/02/10(土) 11:35:32.34ID:4W9TXsf60
>>818
初心者…gotoを使いまくる
中級者…gotoを一切使わない
上級者…適材適所を覚える
0844デフォルトの名無しさん (ワイモマー MMa5-O4V4)
垢版 |
2018/02/10(土) 12:01:34.42ID:s8Yuzl0xM
>>818
内部的には全部goto(継続とか)だって事を理解すれば、適切な使い方が出来るようになる。
0845デフォルトの名無しさん (アークセー Sxf1-c21i)
垢版 |
2018/02/10(土) 12:09:51.29ID:BZD8vxg8x
ドラクエもテトリスもファイナルファンタジーも全部
C言語で作っているのですか?ふと疑問に思いました。
0847デフォルトの名無しさん (ワッチョイ 419f-VKlD)
垢版 |
2018/02/10(土) 14:08:50.97ID:wR2OqAa50
>>846
> C言語なら理由があるgoto文は普通に使われるぞ
さすがにこれは言い過ぎだろう。
ただしgoto不要論も50年前の理論であり、盲信するのも間違いだというだけだ。

問題は、goto を無くしたいだけの理由で余分なフラグやループ(もどき)を導入する是非だ。
ソースが余計に見にくくなるのは事実だからね。
最近の風潮なら、linter等によって「間違ったgotoの使い方」を検出できるようになれば、
gotoは完全にありになるだろう。
問題はこれが難しい(と言うよりやる気がない)ことで、
Cのノリなら「お前が間違えなければいいだけ、何故特化文法が必要になる?」になってしまう。
ラベル付きbreakとか、導入しても俺はいいと思うけどね。

例外については、今のところ他言語でも上手い解を見つけられていない。
goto文を使った場合はあくまで自関数内のtry-catchになってしまうが、正直、これで十分だ。
OOPでの継承先からのcatchとかを許可すると、便利な反面、密結合になってしまい、
noexceptとか言いだしているし、完全にあっちは暗礁に乗り上げつつある。
Cだと最初からnoexceptしかない。OOPが色々屋上屋を架しているのも事実だね。
0850デフォルトの名無しさん (オッペケ Srf1-5OAx)
垢版 |
2018/02/10(土) 14:35:35.79ID:hk3lMPpyr
>>836
「gotoは有害!」と言われるそのgotoは昔のBASICみたいな、別のサブルーチンの中に無節操にジャンプできる機能のことだったんじゃないかと思われる。
関数の外に飛べないgotoなら、関数の行数が少なければさして問題じゃない。
0852デフォルトの名無しさん
垢版 |
2018/02/10(土) 15:41:31.33
こんな時代だからこそあえてmain関数にすべてを詰め込むプログラミングスタイルを確立していきたい
0853デフォルトの名無しさん (ワッチョイ 319f-R9JW)
垢版 |
2018/02/10(土) 15:42:18.37ID:l9ZzjyKP0
あー。別サブルーチンにgotoあったねえ。

6502アセンブラで書かれた Apple ][ のモニタプログラムにもそういうの結構あって当時すげえとか思ったが、無理矢理2KBのROMに押し込むための苦肉の策だったんだよな。
当時はメモリが高価で少ないのが当たり前だったから何でもかんでもトリッキーな方法使って小さくしてた。
0854デフォルトの名無しさん (ワッチョイ 0676-3MxQ)
垢版 |
2018/02/10(土) 15:45:49.28ID:jClKPuF30
long_jump
0855デフォルトの名無しさん (ワッチョイ 319f-R9JW)
垢版 |
2018/02/10(土) 15:47:06.49ID:l9ZzjyKP0
>>851
試してみ。お前のコンパイラは何か違うかも知れない。
ただし出来た場合、それをC言語と読んで良いのかどうか悩ましいところだ。
それと、一体どのようなコードを作っているのかが気になる所だな。

>>852
変なことに挑戦するなよw
Cだとそれできちゃうんだからw
0858850 (オッペケ Srf1-5OAx)
垢版 |
2018/02/10(土) 19:34:42.47ID:hk3lMPpyr
>>851
ああ、>>850 で書いたのはもちろんC言語のgotoじゃない。
そもそもgotoはよくないという主張が叫ばれたのが1960年代、C言語ができたのは1972年らしいんだから。
0859デフォルトの名無しさん (ワッチョイ 6e24-yPCn)
垢版 |
2018/02/10(土) 21:42:11.48ID:YQ6eMVvy0
ガチの初心者で申し訳ないんやが...。
unsigned char型変数には8ビットしか入らんはずやのに
0〜255の数値が入るのはなんでなんや?
8ビットを二進数変換すると11111111でこれを10進数に変換すると255になるのは分かるんやが
なぜ255の半角が入るのかがわからんのや。

#質問するとこ、ここで合ってるよな?
0861デフォルトの名無しさん
垢版 |
2018/02/10(土) 21:48:30.15
>>859
うん、”255”の半角を入れるなら終端文字まで含めると4バイト必要だね
‘2’(0x32) ‘5’(0x35) ‘5’(0x35) ‘¥0’(0x00)
0863デフォルトの名無しさん (ワッチョイ 99b3-7Au1)
垢版 |
2018/02/10(土) 22:17:10.51ID:4W9TXsf60
>>861
小人さんがASCIIコードに変換してる
0864デフォルトの名無しさん (ワッチョイ 6e24-yPCn)
垢版 |
2018/02/10(土) 22:18:39.30ID:YQ6eMVvy0
すまん、いま投稿しようと思ったら、クソ規制に弾かれたわ
だから詳細が書けない。
0865デフォルトの名無しさん
垢版 |
2018/02/10(土) 22:19:04.81
たぶんこんな感じ

2進数で格納すると8文字(11111111)
16進数で格納すると2文字(FF)
10進数で格納すると3文字(255)分の領域が必要なはず

なのになんで10進数の数値255を
1文字分の領域(unsigned char型変数)に格納できるの???
0866デフォルトの名無しさん (ワッチョイ 6e24-yPCn)
垢版 |
2018/02/10(土) 22:23:07.55ID:YQ6eMVvy0
>>865
だいたいこんな感じ。
0868デフォルトの名無しさん (ワッチョイ 6e24-yPCn)
垢版 |
2018/02/10(土) 22:26:25.15ID:YQ6eMVvy0
簡単に書くわ

signed char var = 255;

↑これが何故格納できるのかわからない。
0869デフォルトの名無しさん (ワッチョイ 99b3-7Au1)
垢版 |
2018/02/10(土) 22:31:38.43ID:4W9TXsf60
>>868
さっきまでunsigned言うてたのに…
0871デフォルトの名無しさん
垢版 |
2018/02/10(土) 22:44:47.34
>>868
signed charでは-1を意味しているけど
中身は同じ8bit(2進数で表すと11111111)だから格納はできる
0872デフォルトの名無しさん (ワッチョイ 6e24-yPCn)
垢版 |
2018/02/10(土) 23:11:03.86ID:YQ6eMVvy0
>>869
ごめん、「un」を書き忘れてた。
0873デフォルトの名無しさん (ワッチョイ 3181-Ejv6)
垢版 |
2018/02/10(土) 23:18:49.98ID:mAbz3z0v0
何が分からないのか、それがよく分からない
1ビットなら、0,1
2ビットなら、0,1,2,3
3ビットなら、0,1,2,3,4,5,6,7




8ビットなら、0,1,2,3,4,5,6,7.....253,254,255

指折るなりしてちょっと考えてみよう
0875デフォルトの名無しさん (ワッチョイ e1a1-nHV3)
垢版 |
2018/02/11(日) 00:27:54.48ID:aNzM17qZ0
>856

Edgar Dijkstra: Go To Statement Condidered Harmful

Communications of the ACM 11, 3(March 1968) 147-148

というように、ダイクストラ大先生が権威ある
Communications of the ACM
にお書きになっていますが。

この論文は検索すれ読めますよ。
0876デフォルトの名無しさん (ワッチョイ 319f-jA6l)
垢版 |
2018/02/11(日) 00:43:28.76ID:B0DbdRYG0
>>868
数値としての255だからだよ。コンパイラが"255"の文字の並びを見て数値の255として扱って8bitのvarを初期化するコードを作ってくれるの。
0877恥人!id:ignore (ワッチョイ e175-80pK)
垢版 |
2018/02/11(日) 00:43:51.30ID:/hLQhQLG0
コンディダードってなんだよ
0878デフォルトの名無しさん (ワッチョイ 319f-jA6l)
垢版 |
2018/02/11(日) 00:45:40.11ID:B0DbdRYG0
知らない
0879デフォルトの名無しさん (ワッチョイ 4193-jcwv)
垢版 |
2018/02/11(日) 07:01:25.77ID:o7b316W00
>>877 そんなのネットですぐ分かるだろ、と「コンディダード」を検索したら
5ちゃんねるの「C言語なら俺に聞け 144」て掲示板の投稿877番がトップに出た。

最新のネット用語で言うところの「モルゲッソヨ」みたいな感じね。
0880デフォルトの名無しさん (ワッチョイ 42b3-/0XS)
垢版 |
2018/02/11(日) 08:37:08.13ID:S5L6PYJ00
>>875
だからその
> Go To Statement Condidered Harmful
って言うタイトルはダイクストラじゃなくてニクラウス・ヴィルト(Pascal作った人)が付けたって話な
ちなみに本人がつけたタイトルは A Case Against the Goto Statement
そもそも論文の中身を読めばgoto有害一辺倒でないこともわかる
読んでない知ったかさんがタイトルだけで騒ぎすぎ w
■ このスレッドは過去ログ倉庫に格納されています

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