C言語なら俺に聞け 143

■ このスレッドは過去ログ倉庫に格納されています
1デフォルトの名無しさん (ワッチョイ b375-rVGZ)
垢版 |
2017/10/27(金) 21:28:08.20ID:pAogLeJi0
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言語なら俺に聞け 142
http://mevius.2ch.net/test/read.cgi/tech/1502364083/
VIPQ2_EXTDAT: checked:vvvvv:1000:512:----: EXT was configured
2017/11/16(木) 17:45:35.36ID:1Qzf60whd
FreeDOS、Linux、ReactOSなどのオープンソースなOSは、ソースが見られるから参考にするといい。
例えば、OSで並列処理をしたい場合は実際のCPUの知識が必要になるし、OSをCD-ROMからインストールしたい場合は、CD-ROMのファイルシステムの知識が必要になる。
OSを便利にしたいなら、それなりの知識が必要になるのさ。
2017/11/16(木) 17:50:48.01ID:1Qzf60whd
モダンなOSは巨大化・複雑化しているから、一人ですべてを把握するのは難しい。
必要な機能を分割統治して、ライブラリなどによってブラックボックスとして実装するのが一般的。
2017/11/16(木) 18:09:46.26ID:j+aaxsF+0
>>336
OS自作入門とかいうそのものズバリな本があるよ
勉強目的なら割りとオススメ
2017/11/16(木) 18:10:16.42ID:NJ9DPXHtM
モダンでなくても、C単体ではシステムコールとCPUステータスに
関わる部分が書けないので、100%は不可能。
asm文とか使うなら別だけど。
2017/11/16(木) 18:10:19.85ID:++5Qg6gN0
なお、OSで商売したいなら、著作権のトラブルをクリアしないといけない。
マイクロソフトやグーグルのようにOSを売るのは至難の技だ。
2017/11/16(木) 18:29:05.66ID:1Qzf60whd
パソコン向けじゃなければ、日本企業でもOSを開発しているところはある。
どんなOSを開発したい?
2017/11/16(木) 18:42:10.01ID:lNSovIGo0
OS劇場っぽいやつ
2017/11/16(木) 20:19:28.30ID:FIH9Q68l0
あとメモリ上に読み込んだバイナリデータをwchar_tの文字列に変換することは可能でしょうか?
345デフォルトの名無しさん (ワッチョイ 86e7-0Cia)
垢版 |
2017/11/16(木) 20:33:55.78ID:NqJtZOMo0
ただC言語の本にアセンブリ言語またC言語でもOS作成可能ってあったから気になっただけ
他の言語もコンパイルして機械語にするからC言語も間接的な言語しかないのかなって疑問に思っただけ
2017/11/16(木) 21:44:00.25ID:lLXMegrc0
>>317
2017/11/16(木) 22:16:50.50ID:SDKqgqGy0
嘘ついてるかもだけど、wchar_tのたぐいって、使うとはまる奴じゃなかった?
文字列はcharオンリーな今日この頃。

cpu限定すれば、変換はいけるんじゃない?
2017/11/16(木) 22:50:06.96ID:j+aaxsF+0
ワイド文字だと場合によってはエンディアンを気にする必要があるのと
結局>>334は避けられないあたりを忘れなければハマることはないかと
2017/11/16(木) 23:02:19.01ID:53UzEJx90
OSのコードを書くのってC言語のインラインアセンブリが使われてるんじゃないの?
350デフォルトの名無しさん (ワッチョイ 8203-Eq1o)
垢版 |
2017/11/17(金) 03:13:34.00ID:HNipYc2I0
インラインなんかほとんど使わない
アセンブラが必要なところはガチのアセンブラを使う
量にして全体の数%ってとこ
2017/11/17(金) 08:21:02.54ID:5vMCLRTs0
フリーのOS作るため勉強するよ
2017/11/17(金) 08:39:11.50ID:Noghda3Sa
>>339
あれかなり良いけどフロッピー使うし作るOSもかなり独特だからモダンな感じでもう一冊くらい書いて欲しい
353デフォルトの名無しさん (ワッチョイ 919f-8CrJ)
垢版 |
2017/11/17(金) 23:24:01.69ID:mCQOvNmw0
>>330
UTF-8 とは何か?
そして wchar_t 型とはなにか?

まずはこの2つについて徹底的に調べると君の頭は少し良くなると思う。
354デフォルトの名無しさん (ワッチョイ 919f-8CrJ)
垢版 |
2017/11/17(金) 23:32:51.13ID:mCQOvNmw0
>>336
OS作れるどころかOSを書くために作られたような言語がCだよ。UNIXな。
355デフォルトの名無しさん (ワッチョイ 919f-8CrJ)
垢版 |
2017/11/17(金) 23:36:03.75ID:mCQOvNmw0
>>342
超漢字はPCで・・・
2017/11/18(土) 01:14:51.20ID:rocDtfxqa
mallocとかcallocでNULLが帰ってくる原因が分からない

メモリも十分あいてるしfree忘れもないのに
2017/11/18(土) 01:20:58.17ID:j81pJ1Fd0
要求している大きさが 0 とか?
2017/11/18(土) 01:23:12.16ID:SBD2pOIJa
>>357
流石に0ってことはないと思うわ
2017/11/18(土) 01:40:38.42ID:bkH0AyDYa
どこかでバッファオーバーランしてるのかなあ
2017/11/18(土) 01:54:02.41ID:ravPC5RbM
0 allocでもnullは返さないはず
2017/11/18(土) 02:00:44.06ID:xg8+Glw40
perrorくらいしてから書け
2017/11/18(土) 03:52:04.95ID:V3PmucT60
おれの昔使ってたシステムでは、free忘れじゃなくて、mallocしたアドレスを2度freeしたり、もしくはmallocとは全然関係無いアドレスをfreeすると、
その後のmallocでおかしな動作をすることがあった
363デフォルトの名無しさん (ワッチョイ 919f-8CrJ)
垢版 |
2017/11/18(土) 06:02:16.21ID:4FIhP4xR0
>>358
本当か?
364デフォルトの名無しさん (ワッチョイ 25d6-Eq1o)
垢版 |
2017/11/18(土) 06:22:35.45ID:mIICZMYh0
>>362
おそらく、そういう系だろうな
どこかで未定義の動作をやらかしてる
2017/11/18(土) 07:00:43.85ID:ScUjvH+z0
>>361
それ関係ないやろ
2017/11/18(土) 09:37:24.12ID:N5k0nP0W0
>>362
windowsなんだけど可能性あるの
367デフォルトの名無しさん (ワッチョイ 25d6-Eq1o)
垢版 |
2017/11/18(土) 09:47:18.69ID:mIICZMYh0
ゲイツOSかどうかには関係ねえぞ
malloc/freeが空き領域をどのように管理しているかの実装の問題だ
2017/11/18(土) 11:15:25.02ID:QN3bDN6ad
Winなら2重freeで死ぬんじゃね
2017/11/18(土) 11:27:25.57ID:rocDtfxqa
2重freeだとその時点でエラーはかないの
2017/11/18(土) 11:56:53.68ID:ScUjvH+z0
>>368-369
>>367
2017/11/18(土) 12:20:10.83ID:N5k0nP0W0
解決した
不定のポインタに対して代入

変なとこ書き換えたせいでmalloccallocに失敗したみたい
2017/11/18(土) 16:45:23.67ID:LYf4SJAt0
よかったな鼻から鼻毛が出る程度で
2017/11/18(土) 20:07:48.43ID:N5k0nP0W0
また別の問題が・・・
メモリ上にある時は問題ないのにwprintfで表示するときに文字化けする
374デフォルトの名無しさん (ワッチョイ 919f-8CrJ)
垢版 |
2017/11/18(土) 20:09:57.58ID:4FIhP4xR0
>>373
「問題ない」とは?何で確認した?
2017/11/18(土) 20:10:41.39ID:QiNK1qRtd
setlocaleした?
2017/11/18(土) 20:37:46.90ID:N5k0nP0W0
>>374
visualstudioのメモリの中覗く奴
>>375
main関数でやってる
2017/11/18(土) 20:39:12.15ID:QiNK1qRtd
ideoneに貼ってよ。
2017/11/18(土) 20:49:06.97ID:ravPC5RbM
コンソールのロケールは?
2017/11/18(土) 20:54:11.61ID:N5k0nP0W0
>>378
chcp 65001をsystem関数で実行してる
380デフォルトの名無しさん (ワッチョイ e92b-0hG5)
垢版 |
2017/11/18(土) 21:10:22.92ID:V3PmucT60
setlocaleの引数は?
2017/11/18(土) 21:47:57.26ID:QiNK1qRtd
system関数で出来る子プロセスは、別プロセスだから、現在の画面出力には影響しないと思う。
2017/11/18(土) 21:48:38.17ID:N5k0nP0W0
解決した
関数の中で宣言したwchar_t の配列buff[20]のポインタを返してそれを表示してたんだけどそれがまずかったみたい

スコープから抜けた瞬間に解放されちゃうみたい

無知だったわ申し訳ない
2017/11/18(土) 21:49:45.49ID:N5k0nP0W0
buffの中身をmallocで確保した所にコピーしたのを返すことにしました
2017/11/18(土) 23:02:18.25ID:euoYf0NO0
>>382
GC言語使ってた奴がよくやるパターンだ。ドンマイ。

>>383
それだと後でいちいちfreeするのが面倒だろ。
普通は呼び出し元で buff[20] 確保してポインタを渡し、子関数内でそこに書き込む。
なおどうしても値返しで組みたければ、structならreturnで値返しできるからくるめばいい。(はず)
385デフォルトの名無しさん (ワッチョイ 419f-Eq+G)
垢版 |
2017/11/19(日) 03:54:32.58ID:+NeHX1+n0
char* hoge(){
   char buff[20];
   strcpy(&buff[0], "何らかの処理");
   return &buff[0];
}

int main(int argc, char* argv[]){
   char* str = hoge();
   printf("%s\n", str);
   return 0;
}

多分、こうなってたんじゃないか?
配列は、自分で管理すべきだよねー。

void hoge(char* const str){
   strcpy(&str[0], "何らかの処理");
   return 0;
}

int main(int argc, char* argv[]){
/*  char str[20]; */
   char* ptr = nul;
/*  ptr = &str[0]; */
   ptr = (char*)malloc(sizeof(char) * 20);
   hoge(ptr);
   printf("%s\n", str);
   return 0;
}
386デフォルトの名無しさん (ワッチョイ 919f-8CrJ)
垢版 |
2017/11/19(日) 04:46:36.12ID:uKY6C0dJ0
意味は同じだし最適化されるからどうでもいいことではあるが、
そこの &str[0] は単に str と書くだけでいいんじゃないの?
見やすさの点からも受け取る部分が char *str ならそのまんま
str って書いておいた方が分かり易いと思うんだけど。
2017/11/19(日) 05:47:08.77ID:UDBnG5b80
c言語でこういう処理はやめておけ?
2017/11/19(日) 09:57:18.82ID:v7NTUoVSM
初心者はこれだけ守ってれば良いかと

処理対象のメモリは呼び出し元で確保、alloc-freeで処理をはさむ
処理の戻り値は基本intでエラーコードを返す
ローカル変数は16k未満、可変長配列は使わない

>>387
そんなことはない
389デフォルトの名無しさん (ワッチョイ 82a4-Eq1o)
垢版 |
2017/11/19(日) 10:16:36.97ID:Rb2sIcHm0
> 処理の戻り値は基本intでエラーコードを返す

malloc先生やprintf先生を見習ったら違反だな


> ローカル変数は16k未満、可変長配列は使わない

何だそのマジックナンバーは??
2017/11/19(日) 10:34:41.84ID:YNZopTj60
malloc に限らんけど、ポインタを返す関数は
失敗の場合にNULLを返すってのはまぁ基本だね。
線形リストの探索、見つからなければNULL、みたいに。

printf の返り値はintだから一応は >>388 の方針通りじゃろ。
成功なら非負の値、失敗したら -(エラーコード) が返る、
と決めておけば何かと使いやすいわね。
391デフォルトの名無しさん (ワッチョイ 82a4-Eq1o)
垢版 |
2017/11/19(日) 10:42:05.59ID:Rb2sIcHm0
>>390
ちょw
printfの仕様を知らんのか
2017/11/19(日) 10:59:03.36ID:KR+9hAut0
mmapはNULL返さねーけどな
2017/11/19(日) 11:41:24.76ID:lBNHVI9l0
エラーはnullとか-1とかの正常時には戻らない値
エラーコードは errno 見ろよ
って言うのが以前のお約束だった気がするけど
2017/11/19(日) 12:18:44.42ID:qf87F9y70
printf("%d",printf("1*2*3="));
395デフォルトの名無しさん (ワッチョイ 919f-8CrJ)
垢版 |
2017/11/19(日) 13:05:21.82ID:uKY6C0dJ0
printf() の man page 見てもエラーの時は負の値を返すとしか書いてなくて errno に何か入るとは書いてない。
まあ、実際には中で putchar() と同等な事をするだろうからその中で使われる write() で何か書かれるとは
思うがその辺は保証されていないので使えない。(書き込み時のエラーではないかも知れないしな)。
GNU の asprintf() もエラー時は -1 を返すのみで errno については何も書いてない。

それと snprintf() のような結果を書き込むバッファの大きさを指定できるやつはバッファを使い切った場合の
エラーの返し方が違う。
2017/11/19(日) 16:13:09.94ID:ViWWOCHYa
条件が
文字列の長さ
文字列比較
でソートしたくて2回forで回してます

流石にこれでは件数が増えたときにとてつもなく遅くなるので1回のforだけでやる方法を教えてください
397デフォルトの名無しさん (ワイモマー MM05-harS)
垢版 |
2017/11/19(日) 16:19:33.08ID:lEYmgXHFM
>>396
普通にソートすれば、長い方が後に来るんじゃね?
2017/11/19(日) 16:32:59.11ID:NI05LLAC0
条件を変えて2回まわしたら1回目のソートは(ほぼ)意味がないんじゃない?
(順位を保つソート法なら 多少意味が出てくる: qsort はその保障はない)

qsort の srot_cmp の記述で
比較すべき それぞれの要素 c1 と c2 を多重に比較すればいい

・「文字列長さ」で比較し 違うなら大小関係を返す→
 ↓
・(上の比較が等しいので)「文字列」比較し 違うなら大小関係を返す→
 ↓
 :
 ↓
・(上の比較が等しいので)等しいと返す

これならソートは1回だけ
2017/11/19(日) 18:57:37.27ID:LiOPGVVq0
https://i.imgur.com/rkQ9ns8.jpg

この2.の(2)の総ステップ数って
f=1で1回、for文内でn回で、T(n)=n+1
であってる?
なんか授業でやったときは3n+4だったか4n+3だったかそんな数字だったと思うんだが求め方がよく分からん
400デフォルトの名無しさん (ワッチョイ 919f-RuWE)
垢版 |
2017/11/19(日) 19:18:57.18ID:uKY6C0dJ0
>>399
f=f*i の部分は四則演算1回と代入1回だから2ステップなのでは?
2017/11/19(日) 19:34:22.94ID:H23Xb2RQ0
f=1 代入1回
for(i=1;i<=n;i++) -> for(i=1;i<=n;i=i+1) 代入1回; 条件判断n+1回; 四則演算n回、代入n 回
f=f*i; 四則演算n回、代入n回

なので合計 5n+3 ステップかな、i++ を1ステップとする処理系なら 4n+3 とか。よくわからんけど
2017/11/20(月) 14:16:42.45ID:QGisDeezp
>>401
いまどきオプティマイザあるからどっちも同じアセンブルコードになる悪寒
2017/11/20(月) 14:28:22.74ID:8OH1W8zR0
i++ を1ステップ勘定するか 2ステップ勘定するかは悩ましいけど
分解して 四則演算の1 + 代入の1 計2ステップ の見積もりするのが妥当なんかな
題中にインクリメント演算についてのステップ数は明示されてないし
404デフォルトの名無しさん (ワッチョイ ae6e-Eq1o)
垢版 |
2017/11/20(月) 17:25:41.15ID:ZHV8ZCmh0
i++みたいにハード的にありえない(メモリは加算機能を持たない)ことは
マイクロコードで実現しているわけで、1ステップなわけがない
2017/11/20(月) 17:45:57.87ID:8KCSU74o0
狙いは記述の簡潔化
2017/11/20(月) 17:54:00.78ID:jMZlCBbia
単体のi++は無駄だから++iにしろってばっちゃが言ってた
2017/11/20(月) 18:09:22.43ID:uYx1UAMqH
じっちゃんはそんな差は最適化で消え失せるって言ってたよ
2017/11/20(月) 19:51:59.87ID:glF63Wia0
i += 1;に統一しろや
2017/11/20(月) 20:13:15.58ID:WOKp52/B0
つまりC++死ねと言う事で
2017/11/20(月) 20:44:27.03ID:Y8ntE/6M0
暗号の話で面白いネタありませんか?
2017/11/20(月) 23:46:50.09ID:iMFZcv9G0
https://i.imgur.com/DnscbT9.jpg
>>399だけど、これが一応正解らしい
412デフォルトの名無しさん (ワッチョイ ae6e-Eq1o)
垢版 |
2017/11/20(月) 23:56:46.22ID:ZHV8ZCmh0
おまえ自身は何も言わないわけか
413デフォルトの名無しさん (ワッチョイ e92b-0hG5)
垢版 |
2017/11/21(火) 00:13:10.99ID:j0/qDr3U0
++は対象がレジスタに乗ってるときに1命令だろ
とくにアドレスレジスタの場合に *p++ をポストインクリメントレジスタ間接アクセス命令にそのまま置き換えられるから、
オプティマイズがまだ発達してなかったころに重宝したはず
414デフォルトの名無しさん (ワッチョイ ae6e-Eq1o)
垢版 |
2017/11/21(火) 06:23:40.67ID:uBkGRn7P0
そのバヤイは0.5命令だね
* と ++ を同時並列でやるわけで
2017/11/21(火) 06:30:17.80ID:VCAIytbF0
>>411 実際のマシンとは関係のない、問題のための問題だから
問題を作った人の答えが正解というルールは仕方ないとして…。

i++ が1ステップなのか2ステップなのか、という疑問が出るスレッドで、
f = f*i はまとめて1ステップです、という解説が現れるのは予想外だったわ。
f*i が四則演算で1ステップ、fへの代入でもう1ステップ、と思うよね。
2017/11/21(火) 07:23:37.68ID:V9LM9CF/0
単純に行数で示す場合もあるし
いろいろだよ

重要なのは計算オーダーと実測値
ステップ数は計算オーダーを見積もる為の道具で
定数倍はわりとどうでも良い

計算量をもっと正確な値を知りたい時は
加減算○回、乗算○回、除算○回
など、より具体的な値とする
2017/11/21(火) 09:57:32.04ID:6BA+Ife8d
末尾に/が入っていたとき全て削除したいのだけどどうすれば簡単に実装できるだろうか
データはcharの配列に入っている

ex
aaa.txt
aaa.txt/→aaa.txt
aaa.txt/////→aaa.txt
2017/11/21(火) 10:04:28.94ID:6BA+Ife8d
あとsystem関数の戻り値の判定に悩んでます
https://linuxjm.osdn.jp/html/LDP_man-pages/man3/system.3.html

上記参考にしたら四つのケースに別れていて
下二つはwexitなどのマクロで取得可能
上二つの内ひとつはnullチェックで弾くこと可能
残りは子プロセス作成失敗の-1で網羅できてると考えているのだけど間違ってるのかな?

やりたいことは
system関数のコマンドライン実行したアプリのステータスコードを取得したい。そのためにマクロ使ってる

ただ子プロセスの取得云々の前にsystemの結果判定必要なんでは?と指摘を受けて修正してるのだけどsystemの返す値がさっぱりわからなくて困ってます
2017/11/21(火) 10:38:25.75ID:IvGEWozr0
>>417
自分ならstrtok関数を使う
2017/11/21(火) 10:49:16.27ID:6BA+Ife8d
>>419
ごめん略してたけどもフォルダもあるんだ
/xxxx/yyyy/aaa.txt
みたいな
その関数だとこのパターンは処理できない?できる?
2017/11/21(火) 10:54:29.00ID:rkhjnhkRp
俺様専用脳内マシンは1ステップ命令に変換するんだから1ステップなんだ!!

アホらし。
2017/11/21(火) 10:58:18.95ID:0pj8KC/M0
>>420
末尾の/を取り除きたいのか、頭のファイルパスを取り除きたいのか、よく分からないけど、/を区切り文字として文字列を分割さえしてしまえばどうにでも出来る
423デフォルトの名無しさん (エーイモ SEed-Aqvu)
垢版 |
2017/11/21(火) 11:41:02.99ID:qTGygbeTE
gcc -lライブラリ名 hoge.c

stdio.hと同じフォルダに自分が使いたいヘッダーファイルが存在してるのに
いちいち-lライブラリ名ってしないと参照できないんです
どうしてstdio.hは-lstdioって書かなくても使えるのに自分がインストールしたヘッダーファイルはいちいち-lで指定しないと使えないんでしょうか?
すか?
2017/11/21(火) 12:27:08.32ID:ylDmWfHBd
>>417
if(配列[strlen(配列)-1]=='/') 同=0;

をループで回せ。
2017/11/21(火) 13:06:11.86ID:b7HcaLG8d
>>424
うわっ
最悪のアルゴリズム
2017/11/21(火) 13:13:57.97ID:b7HcaLG8d
null-endと仮定するなら普通にこれで良い

int i;
for (i = strlen(配列) - 1; i >= 0; i--)
if (配列[i] != '/') break;
配列[i+1] = '\0';
2017/11/21(火) 13:34:45.06ID:IvGEWozr0
http://codepad.org/0hrLI4aL
428デフォルトの名無しさん (ワッチョイ ae6e-Eq1o)
垢版 |
2017/11/21(火) 14:23:21.10ID:uBkGRn7P0
>>417
regex.hを使ってはどうかな?
https://sourceforge.net/projects/gnuwin32/files/regex/2.7/
429デフォルトの名無しさん (ワッチョイ ae6e-Eq1o)
垢版 |
2017/11/21(火) 14:47:42.58ID:uBkGRn7P0
>>423
スクリプトかバッチを作ればいい
たとえばmycc.batというファイル名で
gcc -lライブラリ名 %*
と書き込んでおいて
mycc hoge.c
とやる
2017/11/21(火) 19:27:53.90ID:5ScqS7z90
>>423
標準ライブラリオブジェクトはスタートアップファイル(crt0)に組み込まれていて自動的にリンクされる
標準以外のライブラリオブジェクトは明示的にリンクしないと使えない
2017/11/21(火) 20:38:46.08ID:IlBdcuWwM
>>415
> f*i が四則演算で1ステップ、fへの代入でもう1ステップ、と思うよね。
f と i がレジスタなら大抵のプロセッサで1ステップだと思う
2017/11/21(火) 21:45:59.93ID:EZGPgPj40
まあ、先の問題については、ステップの厳密な定義が読み取れないし。
回答者の説明に矛盾がなければ○でいいと思うわ。
それでも誤答とされてしまったら、出題者がウンコだと思って忘れるレベル。
2017/11/21(火) 22:17:44.53ID:6BA+Ife8d
>>428
やはり正規表現か
2017/11/21(火) 22:26:46.51ID:6oQfsQ1l0
スクリプトとかならまだしも
Cで末尾の/削るためだけに正規表現とか持ち出すのは馬鹿だと思う
2017/11/21(火) 22:38:13.64ID:IS6cxUc80
replace("/$","");//うろおぼえ
なんでよ簡潔にかけて最高じゃないか
正規表現は心の友
すぐ忘れるけど
2017/11/21(火) 22:48:24.18ID:n0bc2/yX0
>>435
末尾に連続する'/'が有ったら、消さないと
■ このスレッドは過去ログ倉庫に格納されています
5ちゃんねるの広告が気に入らない場合は、こちらをクリックしてください。

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