C言語なら俺に聞け 143
■ このスレッドは過去ログ倉庫に格納されています
>>333
記憶するのに必要なメモリの量は読み込んだバイト数でいいけど
「1文字に要するバイト数が可変」なので
「文字数」をカウントするとなるとそうせざるを得ないね 暇つぶしで気になったんだけどC言語でもOSは作れるだよな、でも制御とかでコンピューターをちゃんと理解してないとやっぱ作れない? FreeDOS、Linux、ReactOSなどのオープンソースなOSは、ソースが見られるから参考にするといい。
例えば、OSで並列処理をしたい場合は実際のCPUの知識が必要になるし、OSをCD-ROMからインストールしたい場合は、CD-ROMのファイルシステムの知識が必要になる。
OSを便利にしたいなら、それなりの知識が必要になるのさ。 モダンなOSは巨大化・複雑化しているから、一人ですべてを把握するのは難しい。
必要な機能を分割統治して、ライブラリなどによってブラックボックスとして実装するのが一般的。 >>336
OS自作入門とかいうそのものズバリな本があるよ
勉強目的なら割りとオススメ モダンでなくても、C単体ではシステムコールとCPUステータスに
関わる部分が書けないので、100%は不可能。
asm文とか使うなら別だけど。 なお、OSで商売したいなら、著作権のトラブルをクリアしないといけない。
マイクロソフトやグーグルのようにOSを売るのは至難の技だ。 パソコン向けじゃなければ、日本企業でもOSを開発しているところはある。
どんなOSを開発したい? あとメモリ上に読み込んだバイナリデータをwchar_tの文字列に変換することは可能でしょうか? ただC言語の本にアセンブリ言語またC言語でもOS作成可能ってあったから気になっただけ
他の言語もコンパイルして機械語にするからC言語も間接的な言語しかないのかなって疑問に思っただけ 嘘ついてるかもだけど、wchar_tのたぐいって、使うとはまる奴じゃなかった?
文字列はcharオンリーな今日この頃。
cpu限定すれば、変換はいけるんじゃない? ワイド文字だと場合によってはエンディアンを気にする必要があるのと
結局>>334は避けられないあたりを忘れなければハマることはないかと OSのコードを書くのってC言語のインラインアセンブリが使われてるんじゃないの? インラインなんかほとんど使わない
アセンブラが必要なところはガチのアセンブラを使う
量にして全体の数%ってとこ >>339
あれかなり良いけどフロッピー使うし作るOSもかなり独特だからモダンな感じでもう一冊くらい書いて欲しい >>330
UTF-8 とは何か?
そして wchar_t 型とはなにか?
まずはこの2つについて徹底的に調べると君の頭は少し良くなると思う。 >>336
OS作れるどころかOSを書くために作られたような言語がCだよ。UNIXな。 mallocとかcallocでNULLが帰ってくる原因が分からない
メモリも十分あいてるしfree忘れもないのに おれの昔使ってたシステムでは、free忘れじゃなくて、mallocしたアドレスを2度freeしたり、もしくはmallocとは全然関係無いアドレスをfreeすると、
その後のmallocでおかしな動作をすることがあった >>362
おそらく、そういう系だろうな
どこかで未定義の動作をやらかしてる ゲイツOSかどうかには関係ねえぞ
malloc/freeが空き領域をどのように管理しているかの実装の問題だ 解決した
不定のポインタに対して代入
変なとこ書き換えたせいでmalloccallocに失敗したみたい また別の問題が・・・
メモリ上にある時は問題ないのにwprintfで表示するときに文字化けする >>374
visualstudioのメモリの中覗く奴
>>375
main関数でやってる >>378
chcp 65001をsystem関数で実行してる system関数で出来る子プロセスは、別プロセスだから、現在の画面出力には影響しないと思う。 解決した
関数の中で宣言したwchar_t の配列buff[20]のポインタを返してそれを表示してたんだけどそれがまずかったみたい
スコープから抜けた瞬間に解放されちゃうみたい
無知だったわ申し訳ない buffの中身をmallocで確保した所にコピーしたのを返すことにしました >>382
GC言語使ってた奴がよくやるパターンだ。ドンマイ。
>>383
それだと後でいちいちfreeするのが面倒だろ。
普通は呼び出し元で buff[20] 確保してポインタを渡し、子関数内でそこに書き込む。
なおどうしても値返しで組みたければ、structならreturnで値返しできるからくるめばいい。(はず) 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;
} 意味は同じだし最適化されるからどうでもいいことではあるが、
そこの &str[0] は単に str と書くだけでいいんじゃないの?
見やすさの点からも受け取る部分が char *str ならそのまんま
str って書いておいた方が分かり易いと思うんだけど。 初心者はこれだけ守ってれば良いかと
処理対象のメモリは呼び出し元で確保、alloc-freeで処理をはさむ
処理の戻り値は基本intでエラーコードを返す
ローカル変数は16k未満、可変長配列は使わない
>>387
そんなことはない > 処理の戻り値は基本intでエラーコードを返す
malloc先生やprintf先生を見習ったら違反だな
> ローカル変数は16k未満、可変長配列は使わない
何だそのマジックナンバーは?? malloc に限らんけど、ポインタを返す関数は
失敗の場合にNULLを返すってのはまぁ基本だね。
線形リストの探索、見つからなければNULL、みたいに。
printf の返り値はintだから一応は >>388 の方針通りじゃろ。
成功なら非負の値、失敗したら -(エラーコード) が返る、
と決めておけば何かと使いやすいわね。 >>390
ちょw
printfの仕様を知らんのか エラーはnullとか-1とかの正常時には戻らない値
エラーコードは errno 見ろよ
って言うのが以前のお約束だった気がするけど printf("%d",printf("1*2*3=")); printf() の man page 見てもエラーの時は負の値を返すとしか書いてなくて errno に何か入るとは書いてない。
まあ、実際には中で putchar() と同等な事をするだろうからその中で使われる write() で何か書かれるとは
思うがその辺は保証されていないので使えない。(書き込み時のエラーではないかも知れないしな)。
GNU の asprintf() もエラー時は -1 を返すのみで errno については何も書いてない。
それと snprintf() のような結果を書き込むバッファの大きさを指定できるやつはバッファを使い切った場合の
エラーの返し方が違う。 条件が
文字列の長さ
文字列比較
でソートしたくて2回forで回してます
流石にこれでは件数が増えたときにとてつもなく遅くなるので1回のforだけでやる方法を教えてください >>396
普通にソートすれば、長い方が後に来るんじゃね? 条件を変えて2回まわしたら1回目のソートは(ほぼ)意味がないんじゃない?
(順位を保つソート法なら 多少意味が出てくる: qsort はその保障はない)
qsort の srot_cmp の記述で
比較すべき それぞれの要素 c1 と c2 を多重に比較すればいい
・「文字列長さ」で比較し 違うなら大小関係を返す→
↓
・(上の比較が等しいので)「文字列」比較し 違うなら大小関係を返す→
↓
:
↓
・(上の比較が等しいので)等しいと返す
これならソートは1回だけ https://i.imgur.com/rkQ9ns8.jpg
この2.の(2)の総ステップ数って
f=1で1回、for文内でn回で、T(n)=n+1
であってる?
なんか授業でやったときは3n+4だったか4n+3だったかそんな数字だったと思うんだが求め方がよく分からん >>399
f=f*i の部分は四則演算1回と代入1回だから2ステップなのでは? 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 とか。よくわからんけど >>401
いまどきオプティマイザあるからどっちも同じアセンブルコードになる悪寒 i++ を1ステップ勘定するか 2ステップ勘定するかは悩ましいけど
分解して 四則演算の1 + 代入の1 計2ステップ の見積もりするのが妥当なんかな
題中にインクリメント演算についてのステップ数は明示されてないし i++みたいにハード的にありえない(メモリは加算機能を持たない)ことは
マイクロコードで実現しているわけで、1ステップなわけがない 単体のi++は無駄だから++iにしろってばっちゃが言ってた じっちゃんはそんな差は最適化で消え失せるって言ってたよ ++は対象がレジスタに乗ってるときに1命令だろ
とくにアドレスレジスタの場合に *p++ をポストインクリメントレジスタ間接アクセス命令にそのまま置き換えられるから、
オプティマイズがまだ発達してなかったころに重宝したはず そのバヤイは0.5命令だね
* と ++ を同時並列でやるわけで >>411 実際のマシンとは関係のない、問題のための問題だから
問題を作った人の答えが正解というルールは仕方ないとして…。
i++ が1ステップなのか2ステップなのか、という疑問が出るスレッドで、
f = f*i はまとめて1ステップです、という解説が現れるのは予想外だったわ。
f*i が四則演算で1ステップ、fへの代入でもう1ステップ、と思うよね。 単純に行数で示す場合もあるし
いろいろだよ
重要なのは計算オーダーと実測値
ステップ数は計算オーダーを見積もる為の道具で
定数倍はわりとどうでも良い
計算量をもっと正確な値を知りたい時は
加減算○回、乗算○回、除算○回
など、より具体的な値とする 末尾に/が入っていたとき全て削除したいのだけどどうすれば簡単に実装できるだろうか
データはcharの配列に入っている
ex
aaa.txt
aaa.txt/→aaa.txt
aaa.txt/////→aaa.txt あとsystem関数の戻り値の判定に悩んでます
https://linuxjm.osdn.jp/html/LDP_man-pages/man3/system.3.html
上記参考にしたら四つのケースに別れていて
下二つはwexitなどのマクロで取得可能
上二つの内ひとつはnullチェックで弾くこと可能
残りは子プロセス作成失敗の-1で網羅できてると考えているのだけど間違ってるのかな?
やりたいことは
system関数のコマンドライン実行したアプリのステータスコードを取得したい。そのためにマクロ使ってる
ただ子プロセスの取得云々の前にsystemの結果判定必要なんでは?と指摘を受けて修正してるのだけどsystemの返す値がさっぱりわからなくて困ってます >>419
ごめん略してたけどもフォルダもあるんだ
/xxxx/yyyy/aaa.txt
みたいな
その関数だとこのパターンは処理できない?できる? 俺様専用脳内マシンは1ステップ命令に変換するんだから1ステップなんだ!!
アホらし。 >>420
末尾の/を取り除きたいのか、頭のファイルパスを取り除きたいのか、よく分からないけど、/を区切り文字として文字列を分割さえしてしまえばどうにでも出来る gcc -lライブラリ名 hoge.c
stdio.hと同じフォルダに自分が使いたいヘッダーファイルが存在してるのに
いちいち-lライブラリ名ってしないと参照できないんです
どうしてstdio.hは-lstdioって書かなくても使えるのに自分がインストールしたヘッダーファイルはいちいち-lで指定しないと使えないんでしょうか?
すか? >>417
if(配列[strlen(配列)-1]=='/') 同=0;
をループで回せ。 null-endと仮定するなら普通にこれで良い
int i;
for (i = strlen(配列) - 1; i >= 0; i--)
if (配列[i] != '/') break;
配列[i+1] = '\0'; >>423
スクリプトかバッチを作ればいい
たとえばmycc.batというファイル名で
gcc -lライブラリ名 %*
と書き込んでおいて
mycc hoge.c
とやる >>423
標準ライブラリオブジェクトはスタートアップファイル(crt0)に組み込まれていて自動的にリンクされる
標準以外のライブラリオブジェクトは明示的にリンクしないと使えない >>415
> f*i が四則演算で1ステップ、fへの代入でもう1ステップ、と思うよね。
f と i がレジスタなら大抵のプロセッサで1ステップだと思う まあ、先の問題については、ステップの厳密な定義が読み取れないし。
回答者の説明に矛盾がなければ○でいいと思うわ。
それでも誤答とされてしまったら、出題者がウンコだと思って忘れるレベル。 ■ このスレッドは過去ログ倉庫に格納されています