C言語なら俺に聞け 144
■ このスレッドは過去ログ倉庫に格納されています
>>737
キャリーフラグと言ってレジスタの範囲を超える加減算があると1になるビットがステータスレジスタにある
32ビットCPUにだってあるぞ >>741
C で多桁長計算を記述するときは、キャリーフラグという便利なものが使えないので、いちいちマスクしたり、と苦労しますね
http://mevius.2ch.net/test/read.cgi/tech/1434079972/28
C で書かないほうが楽で記述量も少ないかもしれない
>>718 は初学者には無理かもしれません アセンブラだと当たり前のようにキャリーフラグを見るけど
高級言語だとキャリーフラグを活用してるのは皆無じゃないかと
思えてくるのが悲しい I/Oがメモリにマッピングされてるんだから見れると思ってる
ぼくはそういうプログラミングがしたい Reno版のカーネルのソース読んだとき、
VAXのHDDのドライバが分かりやすくてビビった。
メモリマップドI/Oだた。 ここの人達ってOpaqueポインタとか使ってます? とりあえず本買ってきて読んでいます。3月末ぐらいにはなんとか結果を出したい・・・ とりあえずプログラム初心者だが将来有望な頭脳をもった奴を
2人ほど用意した・・・。 >>742
うーん。最上位ビット使えばできるのでは?
まあしかしアセンブラ使った方が効率はいいだろうな。
CPU違ったら動かんけど。 >>748
実ソースではvoidポインタしか見たことない 3進数用にBCD3を定義する
1桁を2進数2bitで表現して
最下位桁の次に2bitのエンドコード11を付与する
例えば
0=00 11
1=01 11
2=10 11
3=01 00 11
4=01 01 11
5=01 10 11
6=10 00 11
7=10 01 11
8=10 10 11
9=01 00 00 11
...
3^1024=01 00 00 ...(00 が1020個(左右に書いたもの含めると1024個))... 00 00 11 >>754 議論の本質から逸れた混ぜ返しになるけど、
BCD が 二進化十進数 binary coded decimal の略なら、
3進数の場合は binary coded tricimal で BCT ではないかしら。
3進数が tricimal なのか、ちょいと自信がないけど、
とりあえずネット検索でヒットする言葉みたい。 >>756
訂正ありがとう。確かに ternary が辞書に載ってる言葉みたいね。
triple あたりからの類推では到達できない綴りだったわ。
これからは注意して取り締まることにする。 従来のbooleanの変数が1個だけあっても、2進数とは呼ばんだろ。 2進数なら無駄なく表せるけど
struct {
bool b1:1;
bool b2:1;
bool b3:1;
bool b4:1;
bool b5:1;
bool b6:1;
bool b7:1;
bool b8:1;
}
3進数だと3バイトずつセットにしないと無駄なく表せないよね
3進数使うメリットあんの? 自然対数の底2.71828…により近い3進数の方が効率が良いっておばあちゃんが言ってた。
2進数なのは単に電気で表しやすいからだって。 元の質問が3の累乗を求める問題だから3進数の方が単純化できるというだけのこと このあたりのソース揃ってるソフトでC言語の勉強してるわ。
スカパーの録画環境も構築できるし。
https://www65.atwiki.jp/psky/ const char ○○とchar ○○について。
○○はフォルダ名。
後者ではエラー、前者ではエラーにならない場合何が考えられますか?
CとC++だと記述が違うとかあります? 恐らく何らかの標準関数の引数にでもした時にエラーが発生したんだろうけど、具体的なことが分からないので何とも言えない
constについてはCとC++では微妙に扱いが違う >>766
そりゃ2値で3進数を表現しようとしてるから当たり前
1本の線が3値になるようなハードなら3進数の方がやり易い エラー発生箇所の最小のコードとエラー内容を張らないと憶測だらけに >>776
それはソフト屋さんの思考やね
ハード的に0ピッタリなんてできなくて結局ある範囲を見る必要があるから1V, 2V, 3Vでも-1V, 0V, 1Vでもたいしてハードは変わらない curl.exeをsystemコールするのだけど
その標準出力をバフに入れたり、バフの値を標準入力に入れたりするのってどうすればできるのだろう? >>779
オプションをつけて標準入力をcurl.exeで〜とかってのはコマンドライン上で実現できてるけど
それをコードで実現する方法が知りたいです const 無しのポインタ変数にリテラル文字列を与えると
C++だと (リテラル文字列の)指し先を書き換える気あるのかボケェ と警告やエラーになるですよ
Cは過去のコードの互換性の為に黙ってることが多い
(けどオプションで警告したりエラーにしたりするんだっけか?) "!"!"!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
{ >>779-780
Rubyではパイプラインで、サブプロセスを実行し、結果を受け取れる。
例えば下は、メモ帳の実行ファイルの場所を探す
resText = ""
IO.popen("where notepad") { |io| resText = io.read }
puts resText
出力結果
C:\Windows\System32\notepad.exe
C:\Windows\notepad.exe >>779-780
Rubyではパイプラインで、サブプロセスを実行し、結果を受け取れる。
これで、サイトのHTML が取れる
resText = ""
IO.popen("curl サイトのURL") { |io| resText = io.read }
puts "終了ステータス : #{$?}", resText >>779
system()ではなくpopen()使うと楽だ。 色々ありがとう
>>785
Linuxだからそいつは無理なんだ...
>>787
>>788
すまん
Cは決定で、さらに言うとexecvで実行も決定なんだ
実行部のソースコードの変更はしたくないので... curl.exe を Linux で?
こりゃ触っちゃダメな人だな Linux なら、curl はコマンドである。
環境変数PATH も通っている
which curl で、
/usr/bin/curl
>>787
これは、Windows10 のWSL 上の、Ubuntu 16.04 で、Ruby で実行したもの >>790
すまねぇ
正確に言うとcurlだった
実行ファイルってのを言いたかったんだけど紛らわしかったわ....
>>791
コマンドラインで実行をコード上からして
その結果をメモリに書き込みたいって感じ
int main()
{
char* buff[1024]
execv(curl..........)
}
子プロセス作成とかは書いてないけどこのexecvの結果をbuffにいれたい >>779 と >>789 は同じ投稿者なのかな?
「curl.exeをsystemコールする」という文の意味は、
実際には curl.exe でなく /usr/bin/curl かどこかの Linux のコマンド、
systemコールと言っても system() 関数でなく execv() 関数で呼ぶ、
という条件でいいの? >>793
同じです
メチャクチャ困惑させてすみません
そうです #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;
} 自分で fork, exec するなら pipe() 作って dup() で繋げ。
やり方はUNIXやLinuxのシステムコールに関する入門書みたいなのがあれば必ず書いてあると思うのでそういうのを見るか、またはググれば世界中で解説やサンプルプログラムが見つかると思う。
かなり基本的な事だ。 急造のデッチ上げだけど、こんな感じかな。
要点は、名前なしパイプを作って標準入出力と差し替える。
外部コマンドの標準出力はパイプを通って出ていく、
呼び出した側は標準入力を読むとパイプから入ってくる。
32行制限に収めるために行が詰めたら見にくいね。 などと書いている最中に真上にサンプルプログラム出現w curlだったら、オプションで全部ファイルに書き出せるじゃないか 親プロセス側は標準入力をパイプに差し替える必要ないね。
パイプのディスクリプタから素直に読みゃいいんだわ。
// 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]); // 使用済みパイプの入力を閉じる >>801
本物らしいな
しかも解説ドキュメント付
やっぱオープンソースよりプロプライエタリのほうが忖度が充実してるね 流出どころかAppleがそもそも堂々と公開してるじゃないか >>808
OSのソースコードはないじゃん(´・ω・`) まあ、ライセンスが必要な部分は非公開なんだけどね。 処理が進んでくにつれてエラー処理のif文の中身が増えていくのをどうにかしたいんだがいい方法ない? >>815
エラー時に行う定型的な処理の塊を関数化するのではいかんの? >>815
普段起こりえないエラーは全部gotoでケツに例外処理を書く >>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)。しかしこの方法はループでもないのにループを書くという何か不自然なものになる。 >>818
C言語の場合は同じような事をする場合はgotoの方が可読性高いと思うけどなあ。とにかく間すっ飛ばして使ったリソース開放して即リターンしたいわけだし。 >>816
それで対応できるものもあるんですけどね・・・
>>817
>>819
gotoは絶対使っちゃいけないみたいな感覚があって考えていませんでした
どうしようもないときに使ってみます goto hell;はdo-whileで置き換え可能。
do {
...
break; // goto hell;
...
} while (0);
hell:; >>823
ああ。do while で 0 で抜けるようにするのでもできるか。
まあしかし goto 使わないならそんな風にするしかないよな。 単純に置き換え可能じゃないから do while(0) は定着しなかった
※個人の感想です do while(0) も使うけど、その中でループを書く場合は面倒だからgoto使うかなあ
必ずどっちかだけってことは無いですね return は1箇所でまとめる派 (関数出口は1箇所)
とっと return してしまう派 (関数出口は散らばる) cでgoto使わないのは唐揚げにレモンかけないようなもんやで break 1 とか
break 2 とかで
抜ける {} の段数指定できない仕様が糞 >>823
gotoというキーワードに対する言葉狩りでしかない
うちの若いのがそんな変態コード書いたらしばく do{}while(0)は普通に使うやろ
特にマクロで
どこが変態やねん! 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; O'ReillyのLinuxデバイスドライバ本では
初期化の失敗時、一部分だけ確保できたリソース群を
確保時とは逆順に行儀良く解放するのにgotoを使う方法を勧めてるね。
そういう具合にgotoが出てくる場面が明確ならば
必ずしもgotoが可読性を落とす、とは言えないじゃろ。 >>829
なんかの理由でネストを増やしたら全部書き換えになる糞仕様だろ
ループにラベルつけてラベルを指定してbreakできるようにしてほしい >>831
使わねーよノーマルさんなら
変態の自覚がない真性変態め goto を使わないようにというのは
昔、ダイクストラ大先生が「gotoは有害だ!」
とのたまわれたので、それ以後gotoを使わない
構造化プログラミングというのが流行ってFortranなども
Fortran 77で一部構造化されたりしてきたという経緯が
あります。
たしかに、昔のBASICプログラムはやたらgoto が多くて
まさにスパゲッティプログラムで論理を追うのに苦労しました。
最近のBasis(たとえばFree Basic)などは構造化されていて
使いやすく感じます。
Cもgotoを使わなくて書けるのですから、やむおえない
(gotoを使わなければ、どうしようもない)場合場合以外は
使わないにこしたことはないと思います。 ダウト
昔のBASICはGOTO文のせいで読みづらいんじゃない
最大のネックは変数が全てグローバルであること
次いでFOR文のNEXTの自由度が高すぎることだ
メインフレーム脳でPCを語るジジイどもが
行番号を批判していたが的外れもいいとこ >>833
gotoの使い道なんてそのパターン以外ないな。 ■ このスレッドは過去ログ倉庫に格納されています