C言語の質問スレッド<42>
■ このスレッドは過去ログ倉庫に格納されています
0001デフォルトの名無しさん
NGNG問題をちゃんと切り分けて、Cの話かそうでないか洗ってから質問してくれ。
というより、聞く前に一応 Web で検索しろ。
コンパイラを探してるなら >>2 を見ろ。
過去ログ(DAT落ちあり)なら>>3-100あたりにあるかも。
GUIとか、C標準でできない事の質問は使ってる開発環境のスレに逝ってくれ。
ソース丸投げ、宿題、書籍 は専門の別スレがあるからそこへ逝ってくれ。
未定義・処理系依存ネタはご遠慮ください。
誰かが(故意にではなく)それらの書き込みをしても、いちいち突っ込まないでください。
規格オタクはこのスレッドには必要ありません。論争したかったら独自にスレッドを立ててそこでやってください。
C FAQ 日本語訳
http://www.catnet.ne.jp/kouno/c_faq/c_faq.html
comp.lang.c FAQ(英語の原文)
http://www.eskimo.com/~scs/C-faq/top.html
Cプログラマ必読 ・プログラミング言語C(通称 K&R)
http://www.amazon.co.jp/exec/obidos/ASIN/4320026926/
推薦図書/必読書のためのスレッド PART6
http://pc3.2ch.net/test/read.cgi/tech/1033207156/
前スレ <41>
http://pc3.2ch.net/test/read.cgi/tech/1036876790/
0756デフォルトの名無しさん
NGNG0757デフォルトの名無しさん
NGNG答え: >>750-754
理由: >>750-754 が現に存在するから。
0758デフォルトの名無しさん
NGNG普通はそんな糞質問に答える義務等、無い。
cより前にk語を覚えよう。
0759デフォルトの名無しさん
NGNGs4[400] は、exit() の呼び出し元のアドレスを格納したスタックの直前の領域に確保される。
ANSI では int a4[400]; を宣言した時に a4[400] にアクセスできる事を保証しているので、
実際には sizeof(int) * 401 バイトの領域が確保される。
つまり、a4[401] は呼び出し元のアドレスが格納されているので、これを書き換えてやると関数から
戻る先が換えられる。
なお、int s4[N]; の時に s4[N + 1] にアクセスすればいいので、N == 400 である必要は特に無い。
あと、引数は呼び出し元のアドレスより後のスタックに格納されるので、いくつあるかは関係無い。
が、これがうまくいくのは余程限定された状況でだな。
「i386 上」 だけでは成り立たない。
コンパイラが、変数を必ずスタックに、詰めて確保する事。
sizeof(int) == sizeof(void (*)()) が成り立つ事。
操作した戻り先のアドレスに、必ず安全なコードが書かれる事。
コードが最適化されない事。
デバッグモードでコンパイルされない事。
これだけの条件が揃う事はあまりない。
よって >>750 はクソ。
0760デフォルトの名無しさん
NGNG0761デフォルトの名無しさん
NGNGだから、それすら確定していない。
> 操作した戻り先のアドレスに、必ず安全なコードが書かれる事。
特定のコンパイラが吐いたコードのリスティングを取るか逆汗して
調べたんだろ。
ちなみに VC6 では、call _exit、pop ebx、pop esi、pop edi が
スキップされる。
push に対する pop がスキップされるのは、malloc() に対する free() が
スキップされるのに等しい。
0762761
NGNGはっきり言って何が起こるか分からない。
0763デフォルトの名無しさん
NGNGで終わりにしたいな(w
0764761
NGNGVC6 では、無条件の exit() があると、それより後ろを全部カットする。
だから printf() は結局実行されない。
0765デフォルトの名無しさん
NGNGまあgccもgetsを使うと危険だと警告してくれたりするけど。
0766デフォルトの名無しさん
NGNG0767デフォルトの名無しさん
NGNG多いと思うよ。
VC なんか ZeroMemory() をインライン展開したりするし。
0768デフォルトの名無しさん
NGNGtest()の実引数のクリアはどこ行ったのよ?
add esp,16
0769デフォルトの名無しさん
NGNG最適化 Off の状態で。
ただし、main() と test() を別々にコンパイルするなら別。
0770768
NGNG0772デフォルトの名無しさん
NGNG0773デフォルトの名無しさん
NGNGこっちも唐揚げ
0774768
NGNGつーか、test()がstaticでない限り、外からも呼ばれる可能性が
あるので、test()とのパラメータ受け渡しは省略できるはず
ないと思うんだが。俺が変なのかな?
push 3
push 2
push 1
push 0
call _test
add esp, 16
push 1
call _exit
add esp, 4
0775769
NGNGスマソ、もれの勘違いだったようだ。
(問題を簡単にするために仮引数無しのバージョンのソース書いてた)
で、
>>759
> 引数は呼び出し元のアドレスより後のスタックに格納される
外からいくら引き渡されても、結局スタックの一番先頭にあるのは戻り先のアドレス。
test() はそれを使って return するだけ。
スタックに大量に積んだ引数の始末は、その後に呼び出し側がつける。
よくわからないなら、(あなたはアセンブリコードが読めるようなので) 実際に
そうしてみて確認してみればいい。
引数が全く指定されなくても大量に指定されても、動作に影響の無いコードに
なってるはずだ。
0776デフォルトの名無しさん
NGNGみたいにやって返値を無効(?)にしてるのかどうか
わかりませんが
これが呼び出し側に与える影響というのは
どういうものなのでしょうか?
返値を何かになんらかの変数に代入してる
ようなことは見受けられませんので理由がわかりません
0777デフォルトの名無しさん
NGNG付けても付けなくてもコンパイラは同じコードを吐く。
戻り値は一般に、CPU 内部の特定の作業領域に保存される。
(x80 なら EAX レジスタ)
その後のプログラムによって、いずれその CPU 内部の特定の作業領域は
別のデータで上書きされて消える。
それだけだ。
その戻り値が変数に代入されていたり式に使用されていれば、上書きされる前に
どこかのメモリ領域か、CPU 内部の他の作業領域にコピーする。
0778デフォルトの名無しさん
NGNGbsdのpingとか観てたらそんなコードがありましたんで
そっか
0779デフォルトの名無しさん
NGNGlintなどのツールに文句を言われないために付けることはある。
0780デフォルトの名無しさん
NGNGコンパイラの警告を黙らせるためのおまじないだと思う。
0781デフォルトの名無しさん
NGNGあるのか?
0782デフォルトの名無しさん
NGNGswitch (c) ...
とした時、caseがちょうど0〜255だけあるのに
レンジチェックするコードが出てしまいます。
レンジチェックせずにいきなりテーブルジャンプするように
する方法はないでしょうか?
あるいは「このコンパイラならOK」という情報でも
けっこうです。
今使っているコンパイラはVC6です。
0783デフォルトの名無しさん
NGNGテーブルジャンプするのにswitchを使うのが間違い
func tbl[] = { func_a, func_b, fund_c, ...};
tbl[c]();
でいいんじゃないか?
0784774
NGNGあれ?もしかして後半も俺向けの返事?
だったら、
> 引数が全く指定されなくても大量に指定されても、動作に影響の無いコードに
> なってるはずだ。
これは間違い。
関数から戻った直後に引数をクリアするコードが
入っているかどうかによって、
s4[401] += 16; した時の戻り先も変わってくる。
(戻り先アドレスは変わらないが、後続の命令の配置がずれる)
さらに言えば、引数の有無だけでなく、
引数のサイズが256バイト以上か未満かでも
add esp,バイト数
という命令のコードサイズは違ってくるはず。
つまり、もろに動作に影響する。
0785デフォルトの名無しさん
NGNGsuitch で評価されるのは int 値じゃなかった?
unsigned char で評価されるのは期待できなかったと思うけど。
0786775
NGNGすまん、漏れの解釈が間違ってた。
「あの場合に限って」 と言うなら、あなたの言う通り。
test() に s4[401] += 16; のような危険なコードが入ってなければ、
漏れの言った通り。
0787デフォルトの名無しさん
NGNG0788デフォルトの名無しさん
NGNG0789デフォルトの名無しさん
NGNGVC6で試してみたけど、やっぱりチェックコードが入ってるね。
andeax, 255; 000000ffH
チェックコードの直前にこういうコードが入ってるんだから、
チェックする必要ないんだけど、ここまでは考えてないんだろうね。
0790デフォルトの名無しさん
NGNG0791デフォルトの名無しさん
NGNG0792デフォルトの名無しさん
NGNG0793デフォルトの名無しさん
NGNGmain()
{
int n;
printf("SEISUU=");scanf("%d",&n);
printf("%d\n",n);
}
上記のようなプログラムを実行した場合に
絶対値の大きな整数を入力すると入力した通りの数字が表示されないんですが
何が理由なんでしょうか?あと、表示される数字には規則性はあるんでしょうか?
0794デフォルトの名無しさん
NGNG0795デフォルトの名無しさん
NGNG#include <limits.h> をやった上で、INT_MIN と INT_MAX を %d で printf()。
それが int 型で扱える数値の範囲です。
もっと大きな方が必要な場合は、double を使ってください。
limits.h と float.h を調べると、いろいろな型の限界がわかります。
ただし、ここの数値を換えても限界値が変わるわけではないので変えないで下さい。
>>794
( ´,_ゝ`)フーン
0796デフォルトの名無しさん
NGNGintの範囲外の数値を入力したんじゃネーノ
0797793
NGNG親切にどうもありがとうございます
助かりました
0798JPS ◆M0LaMzf5rY
NGNGあれのWhileループでEOFみたいに
while(c=getche() != 0x1a)
ってやってんだけど、どういう意味?
16進数だよね?
0799デフォルトの名無しさん
NGNG0800デフォルトの名無しさん
NGNG0801デフォルトの名無しさん
NGNGWindows環境でのみ動作するヘッダだYO!
0802デフォルトの名無しさん
NGNGむしろDOS環境
0803デフォルトの名無しさん
NGNG実行してみそのままだから
何かキーが押されたらそのキー出力して0x1a(^z)だったら終了
0804デフォルトの名無しさん
NGNGsage のだけクリックしとけば、それ以外が何かしら違うものと色で区別つくから
覗いてみたりするけど。
0805デフォルトの名無しさん
NGNGwhile((c=getche()) != 0x1a) {
printf("%x\n", c);
}
こういうコードでも動かしてみて、片っ端から
キーを押せば、どれか分かるんじゃない?
0806デフォルトの名無しさん
NGNGボケにマジレスされたからって、いちいち文句言わなくていいよ。
0808デフォルトの名無しさん
NGNGint list_insert(Node *list,int in_number,int value)
{
Node *pos_node=list,*new_node;
if(in_number < 0)
in_number = 0; // 限界値チェック
new_node=malloc(sizeof(Node));
if(new_node == NULL)
return 1;
// 目的位置の一個前まで移動
while(in_number > 1 && pos_node->next != NULL)
{
pos_node = pos_node->next;
in_number--;
}
// 挿入ノードに 元目的位置のポインタ
// および 挿入する値 を代入し
new_node->next = pos_node->next;
new_node->value = value;
// 目的位置の一個前に挿入ノードを連結
pos_node->next = new_node;
return 0;
}
0809808
NGNGlistをこぴってるから、直接リストをいじるのとかわらないんでないの?
0810デフォルトの名無しさん
NGNG必要ないです。
かわらないです。
いじょ。
0812デフォルトの名無しさん
NGNG引数を直接いじると何か気持ち悪い、っていう程度の
理由だと思うよ。
0813デフォルトの名無しさん
NGNG気持ちはわかるね。たぶん808のソースはどっかのコピペだろうから
分かりやすくしてんだろう。
でもオレも後で見たときの可読性を考えれば、いい事だと思う。
0814デフォルトの名無しさん
NGNGあなたの文章には鬱病の人特有の言い回しが見れます。
病院に行ったほうがいいと思います。
鬱は必ず直ります。
0815デフォルトの名無しさん
NGNGうつ病特有の言い回し?
0817デフォルトの名無しさん
NGNG0818デフォルトの名無しさん
NGNGいるよ。はあはあ
0819デフォルトの名無しさん
NGNGお前らコンパイラとエディタなんですか?
0820デフォルトの名無しさん
NGNG0821デフォルトの名無しさん
NGNGそんなあせんなよ。
0822デフォルトの名無しさん
NGNG0823デフォルトの名無しさん
NGNG{
int num;
list *next;
}
みたいな線型リストだとして
list == NULLっていうのはどういうことですか?
listの要素全部が0,NULL,'\0'ってこと?
0824デフォルトの名無しさん
NGNG線型リストのさいしょの構造体には値は入れないんですか?
0825デフォルトの名無しさん
NGNGそれは実装した人次第だが、一般的にはリストが空。
0826デフォルトの名無しさん
NGNG最初はポインタの方がすっきりするが、プログラムを組むとわかるが
空の構造体の方が扱いやすい。
0827デフォルトの名無しさん
NGNGそれをおセンチっていいます。
0828デフォルトの名無しさん
NGNGなつかしいでつね
0829デフォルトの名無しさん
NGNG質問と回答が殺伐としていてよいね
>>827-828
消えろ。
0830デフォルトの名無しさん
NGNGサンクス
0831デフォルトの名無しさん
NGNGどうやって調べたらよいのでしょうか? なにかリストみたいなのはありますか?
printfは再入可能でないらしいのですが、僕には理由がわからず。
とにかく、リストがあればとりあえずは楽かなと。
0832デフォルトの名無しさん
NGNGC++ってなかなかいいセンスしてると思うのは俺だけか。
0833デフォルトの名無しさん
NGNG0834デフォルトの名無しさん
NGNGマルチスレッドで使って安全という意味だよね?
C言語の規格自体ではそこまで決まってない。
かといって処理系ごとにまったくバラバラかというとそうでもない。
Unix系のOSなら、Single Unix Specificationという規格でけっこう細かく
決まっている。
http://www.opengroup.org/onlinepubs/007908799/xsh/threads.html
のThread-safetyセクションにリストされている関数はthread-safeで*ない*。
他は全てthread-safe。(printfもthread-safe。)
SUS準拠OS以外なら、処理系のマニュアルを見るしかない。
0835デフォルトの名無しさん
NGNG今度から初心者の質問すれと
上級者の議論すれにわけたいね
0836デフォルトの名無しさん
NGNGわけたら余計に人減るじゃん。
0837デフォルトの名無しさん
NGNGマルチスレッドもありますが、割り込みでprintfを使おうとしてました。
自分なりに調べましたが、
printfはスレッドセーフですが、Async-Cancel-Safe 関数ではないそうです。
いやぁ、よくわかりませんなぁ。素人は割り込むなと言うことですか?w
0838デフォルトの名無しさん
NGNGシグナルハンドラの中で使いたいのなら、async-cancel safeじゃなくて
async-signal safeなものを探すべきでしょう。
Solarisだとマニュアルに一覧があるけど(90個くらい)。
0839デフォルトの名無しさん
NGNGSolarisのAsync-Signal-Safe functions一覧
http://docs.sun.com/db/doc/816-0220/6m6nkoroc?a=view
0840デフォルトの名無しさん
NGNGprintfをシグナルハンドラから呼びたいなら、
Async-Signal-Safeでないライブラリ関数を実行中はシグナルをブロックするように
すれば良いんじゃない?
あるいは、シグナルハンドラでは何か情報を変数に書くだけにして、
メインのスレッドでその情報をプリントする。
0841デフォルトの名無しさん
NGNGchar buf[BUF_SIZE] = "";
と書くとbufの先頭1バイトだけでなくBUF_SIZE全部が終端文字で初期化されます。
これは標準なのでしょうか?
0842デフォルトの名無しさん
NGNG「終端文字で」ではなく、「残りは、staticな変数と同じように」
初期化されます。それが規格どおりの振る舞いです。
0843デフォルトの名無しさん
NGNGすばやいご回答ありがとうございました。
0844デフォルトの名無しさん
NGNGvoid signal_handler (int s)
{
i = 1;
printf ("%d\n", s);
}
↑ここでprintfを呼ぶのと
int main ()
{
signal (SIGINT, signal_handler);
while (!i)
printf ("%d\n", i);
return 0;
}
↑ここで割り込みを入れるのと、どちらがいけないということですか?
0845デフォルトの名無しさん
NGNG(断っておきますが、これはC言語の範囲を超えた話題です。)
mainからprintfを呼び出して実行中にシグナルを受け取ったとします。
そのとき、printfが何かの資源をロックしていたとします。
signal_handlerの中からprintfを呼ぶと、デッドロックが起きる可能性が
あります。
汎用の解決策は >>840 の通りです。処理系によっては、シングルスレッドの
プログラムだとprintfが資源をロックしたりしない(したがってデッドロック
が起きない)かも知れません。
0846デフォルトの名無しさん
NGNG説明して頂いてどういうことか分かりました。
この例では両方で呼び出してはまずいということですね。
割り込みをするプログラムでは、
printfを使ってはいけないのかと思ってしまっていました。
ありがとうございました。
0847デフォルトの名無しさん
NGNGその前に糞スレの削除依頼出してこいや
話はそれからだ
0848デフォルトの名無しさん
NGNGリンクにポインタを使ってたばかりに、reallocしたら大変な事になって
しまいますた。
問題なのは当たり前だけど、reallocを使う可能性がある時は整数インデックス値
振らんといかんの?ってのは常識!?
0849デフォルトの名無しさん
NGNGまともな日本語で書いてみてくれないか。
0850デフォルトの名無しさん
NGNGと配列を初期化したとき、配列の要素数を簡単に知る方法はありますか?
0851デフォルトの名無しさん
NGNGひょっとして、リンクにつながった要素をreallocしようとしてるとか?
(1)大きさが変わる可能性のあるものは、リストにつながってる構造体とは
別にして、リストの構造体からポインタで指す。
(2)双方向リストにして、reallocする前にいったんリストからはずし、
reallocの後で挿入しなおす。
のどちらかで解決。
0852デフォルトの名無しさん
NGNGレコードの増減・並び替えが行われるデータ構造があるんだが、最初にこれを読み込む時
にはレコード総数が分かっているのでmalloc(データ構造*レコード数)という感じでメモリ確保
していたんだ。
で、データの追加・削除・並び替えが発生するんで、リスト構造にし、リンクにはレコード
参照ポインタを使っていたの。
しかし、ここで問題があって、データの追加・削除時にはreallocを使って全データのメモリ
を再確保していたんだよね。
これすると、メモリアドレス変わっちまうんで、リンク情報が役に立たなくなって困ったわけ。
1レコード読むたびにmallocして、追加・削除するたびにもmalloc,freeしていれば
よかったんだけど、レコード数が多いから速度的に難があると思って、全データを
一気にmalloc,reallocしてたの。
漏れ、
非常識なんだろな。
0853デフォルトの名無しさん
NGNGですた。
>851 ありがと。
0854デフォルトの名無しさん
NGNG追加時にreallocする必要はないだろ。(1個ずつmallocすればよい。)
削除時にreallocは無理だろ。(途中だけ削除したりしないのか?)
いずれにせよreallocはやめるべし。
最初にまとめてmallocするのはそのままでもよい。
freeする替わりに、自分で作ったフリーリストにつないで置けばよい。
追加のときはフリーリストから空き構造体を取り出す。フリーリストが
空ならmallocする。
0855デフォルトの名無しさん
NGNGsizeof(a)/sizeof(i)
■ このスレッドは過去ログ倉庫に格納されています