トップページ⇒tech
1001コメント297KB

C言語なら、俺に聞け! <7>

■ このスレッドは過去ログ倉庫に格納されています
0001sageジョブスNGNG
おれは21才、9年間プログラムを一生懸命作ってきた。
あちこちの言語に手を出したが結局極めたのはC言語だけだった。
大体のことなら分かるからオレに聞け。

だが、いちいちFAQに載った質問に応えるほど暇じゃない。
課題丸投げなら別スレにいけ。

・comp.lang.c Frequently Asked Questions
http://www.eskimo.com/~scs/C-faq/top.html

・C FAQ 日本語訳
http://www.catnet.ne.jp/kouno/c_faq/c_faq.html

・前スレ C言語なら、オレに聞け! <6>
http://piza2.2ch.net/test/read.cgi/tech/999617524/
0002デフォルトの名無しさんNGNG
ポインタってなんですか?
0003武夫。NGNG
こんにちは
0004デフォルトの名無しさんNGNG
>>2
アドレス
0005前すれ 973NGNG
>> 前すれ 974 さんへ
すみません, 話のふりがまずかったですね.

> if (sscanf(str, " hogehoge = %d ", &n) == 1) {
はもちろんその通りです.

で, scanf() っていろいろ癖がありますよね.
例えば書式文字列中に空白があったときは, 入力フィールドはどういう風に
扱われるとか, 書式文字列中では \n は必要なのかとか, %s 使ったら
(あたりまえなのかもしれないけど)入力フィールドの文字列全部取られたとか ...

そういうのをより実践的な例を使って説明してる本とか Web とかって
ほとんどないですよね ? で, そういう話をここでできてばいいなあと
思って話をふってみました(失敗した感じだけど).

おそらく本職のプログラマさんはこんなのが必要なときは
scanf() なんか使わないで, もっとがりがりトークンの切り出しのプログラムとか
lex/yacc とか使うんだろうとは思うんですけどね(ちなみに私は本職のプ
ログラマではありません).
0006超初心者NGNG
連立微分方程式を数値積分して解くときに、
最大原理を用いて、4次のルンゲクッタ法で計算したいのですが、
ポインタを使わないで計算するプログラムソースとかありませんか?
または最大原理を説くプログラムソースなどがある場所を教えて下さい。
0007デフォルトの名無しさんNGNG
シューティング法のプログラムがわかりません。
どこかにないですか?
0008デフォルトの名無しさんNGNG
シューティング法ってなに?
ねぇ、なに?
教えてよ、お願い
0009デフォルトの名無しさんNGNG
>8
C言語で書かれた、シューティングゲームのソースです。
0010デフォルトの名無しさんNGNG
>>6
ポインタを使うと何か不都合がありますか?
0011超初心者 NGNG
>>10
ポインタを使った事がないので、プログラムが理解できないです・・・鬱
2次の配列を使ってやるのが良いと言われたのですが・・・
何処かにないですか?初心者ですみません。
0012デフォルトの名無しさんNGNG
最大原理を用いる4次のルンゲクッタ法を私に教えてくれれば、
私がプログラムを書いてあげよう。
0013デフォルトの名無しさんNGNG
>>12
そのくらい自分で調べろよ。
0014974NGNG
>>5
K&Rに書いてあるだろ。
他の本はしらん。
0015デフォルトの名無しさんNGNG
タコな質問ですいません。
VBでChr(9)のようにAscii文字を指定するような関数って
Cにもありますか?
0016ぷろぐらまぁNGNG
>>15
出力先によっても違うが、printfかsprintfかfprintfあたりを使うと良い。
ex) printf("%c", 65); /* ASCIIコードで65が出る */
0017デフォルトの名無しさんNGNG
>>15
char ch = 9;
変数に直接アスキーコードを代入すればいい。
001815NGNG
>>16
ありがとうございます。
できれば標準入出力ではなく、VBのように
const chr* Chr( int );
のような感じで関数として使いたいのです。
こういうのってやっぱ自分で作らないといけないんですかね。
001915NGNG
>× const chr*
>○ const char*
ですね。
0020デフォルトの名無しさんNGNG
>>18
Cでの文字列の取扱に関して理解してる? 文字と文字列は別だよ?
0021!=17NGNG
>>15
何がしたいのか分からん。
'\t'や'\x9'や'\011'の文字定数や(char)9も結局9だし、
それを文字として印字したいならprintf("%c", 9)やputchar(9)。
VBの頭でCを考えてないか?
002215NGNG
>>17
そっか、別にわざわざ関数化することないんですよね。
なんか難しく考え過ぎてました。
0023デフォルトの名無しさんNGNG
String型ってやっぱ欲しいよね。
というわけでむかし自作したんだけど
需要あるのかな?
0024デフォルトの名無しさんNGNG
>23
PascalやVBで使われてるStringと互換性を持たせれば、あるいは。

ってかもうあるような気もするけど、知らない。
0025デフォルトの名無しさんNGNG
>>23
オラ、イラネ
0026デフォルトの名無しさんNGNG
高速かつ低資源な検索ルーチンを教えて。
ハッシュだとある程度の数なら十分に動作するんだが・・・
数が大量になるとスピードがでない。
なんか良いロジックある?

それともここは
「printf」で数値を出力したい場合のフォーマットは何?って
レベルのことを聞くところかな?
0027デフォルトの名無しさんNGNG
>>26
ハッシュってのがまさしくそれ。
たぶん実装がヘボいと思われ。
0028デフォルトの名無しさんNGNG
>>27
激しく同意。

>>26
>「printf」で数値を出力したい場合のフォーマットは何?って
>レベルのことを聞くところかな?

というのだったら、

>数が大量になるとスピードがでない。

などとあいまいなことを書かずに、

>逐次検索アルゴリズムでは,検索データが見つかるまでの条件判定文�@の
>実行回数は最小1回,最大[(3)]回である。検索データXの出現確率がS1〜Snの間で
>一様分布するとき,条件判定文�@の平均実行回数 はおよそ[(4)]回である。
>したがって,この検索アルゴリズムの計算量のオーダは[(5)]であるといえる。
> 一方,2分検索アルゴリズムでは,配列Sのデータは[(6)]必要があり,
>その計算量のオーダは[(7)]である。

ぐらいの考察をかましちゃってもいいんだよ。
みんな分かるから。
002926NGNG
>>27
あら、それを言われると辛い(^^;)
じゃ、高速なハッシュってどうやって組むの?
私のルーチン、いたって標準的な使い方だと思う。
100万のオーダなら平気だけど、2000万近くになると…

へぼいって言ってくれるくらいだから、さぞや素晴らしいロジックを
持ってるんだろうね。教えてください。
0030デフォルトの名無しさんNGNG
>>29
>じゃ、高速なハッシュってどうやって組むの?

だから、オーダーでものを言え。
どう低速なのか説明できないのか?
0031デフォルトの名無しさんNGNG
>>26
オープンアドレス法?
チェイン法?
(って話からするとチェインか?)
ハッシュテーブルのサイズは?

2000万近くあるなら BST のほうがいいかもよ。
もしくはチェインの下に BST を吊すとか。
003226NGNG
>>28、30
27へのレスを書いてる際には28のレスは無かったのよね。
別に変に煽ろうとかって意味じゃないから(^^;)

>>31
チェイン法使ってます(たぶん(^^;))
BSTって言葉の意味がわかりませんので解説してもらえませんか?
申し訳ないです。
ハッシュのサイズは現在色々試してるんですが、資源量との兼ね
合いもあるので、そんなに大きくは取れない状態です。今のとこ
ろ1万位かな?まだ妥協点を探している最中なんで(^^;)
0033デフォルトの名無しさんNGNG
>>32
BST はバイナリサーチツリー、2分探索木ってやつ。

ハッシュテーブルのサイズが1万ってことは
それにリスト垂らしてて 2000万 とかなら
一つのテーブルに 2000 もの長さのリストがあって
それを線形探索してるのか? 平均1000ぐらいの比較?

BST なら 2000万 の要素でも 24,5回の比較で探索できますよね。
チェインに1000個の要素の BST なら 10回ぐらい。

BST の実装法は探せばいっぱいでてくるはず。
003433NGNG
日本語変だ…。鬱氏
003526NGNG
>>33
ありがと。確かに自分のコード、しょぼかったです。
0036デフォルトの名無しさんNGNG
あぁ、オーダーっつーのは、計算量のことね。
データの量じゃないぞ。
0037デフォルトの名無しさんNGNG
>>33
べつに、木をぶら下げなくても、
じどうでハッシュのサイズを拡張するようにすればいい。
Optimize・・・ とか言う本に詳細載ってたけど、
具体的な書籍名は忘れた
0038デフォルトの名無しさんNGNG
>>37
チェイン法において、リストの代わりに木を使うって話だよ。
ハッシュテーブルに全てを入れようとするのは大変なだけだと思う。
サイズ変えるコストも馬鹿にならないだろうし。
0039デフォルトの名無しさんNGNG
>>38
詳細は覚えてないんだけど、再ハッシュする必要がある要素は、
極わずかっていう手法だったはず。
0040デフォルトの名無しさんNGNG
char *name[]={"ノビタ","シズカ","スネオ"};
char name[][6]={"ノビタ","シズカ","スネオ"};
上と下の初期化の仕方って、どっちがいいの?
0041デフォルトの名無しさんNGNG
>>40
上と下ではまるで意味が違います。
0042デフォルトの名無しさんNGNG
>>40
良い悪いじゃなくて、処理内容が違うんで目的によります。
char *str = "abc";
char str[4] = "abc";
この違い分かってます?
004342NGNG
あらかぶっちゃった。スマソ。
0044デフォルトの名無しさんNGNG
>>42
すみませんが詳しく教えてください。
0045デフォルトの名無しさんNGNG
>>42
自分で勉強しろよ。
0046デフォルトの名無しさんNGNG
>>44
この程度は基本。2chで訊くようなものじゃない。
K&Rを死ぬほど読め。
0047デフォルトの名無しさんNGNG
> K&Rを死ぬほど読め。

最近このスレで流行ってる?
0048デフォルトの名無しさんNGNG
>>47
このスレッドでは最近かもしれないが、世間ではここ十年以上は流行ってると思われ。
0049デフォルトの名無しさんNGNG
>>6
服部雄一:C言語とPADによる数値計算(培風館)

>本書ではポインタ変数を一切使わずにプログラムを記述する。
0050デフォルトの名無しさんNGNG
>>49
それって、著者がポインタを理解してない上にサンプルがトンチキで有名な本では…
005147NGNG
>>48
あ、K&R でなくセリフがね…
0052デフォルトの名無しさんNGNG
>>50
そうなの?…じゃあこれ
Numerical Recipies in C[日本語版](技術評論社)
0053デフォルトの名無しさんNGNG
あげようよ。
そこから始めようよ。
0054デフォルトの名無しさんNGNG
K&Rってそんなにいいのか?
アンサーブックで十分だろ。
0055デフォルトの名無しさんNGNG
K&R?
初心者にはお勧めできない。
0056デフォルトの名無しさんNGNG
すみません、既出かもしれないけど、ここで質問させて下さい。
ポインタで悩んでます。

普通の変数だったら
int a;
a = 10;
を一行で初期化を表現するには
int a = 10;
と書けばよいわけですよね?

ところがポインタだと、
int x = 10;
int *p = &s;
という具合に、右辺に書く内容が *p についてではなくて p になってしまうのですか?
メモリの中身(*p)でなくて、番地(p)を書くのですか?
もしそうだとしても、感覚的に理解できないのです。
005756NGNG
すみません、下から4行目は
int *p = &x;
でした。スマソ。
0058デフォルトの名無しさんNGNG
int a;
int *p = &a; // *はポインタであることを示すだけ

int *p;
p = &a;
int b = *p; // *はポインタが指す内容

という違いがある。
変数宣言時の'*'とその他の場所の'*'は違うよ。
0059デフォルトの名無しさんNGNG
ちなみに後者は「ポインタ演算子」と呼ばれるもので、+や-などと同じカテゴリ。
&もそうだね。

前者をなんと呼ぶのかは知らん。
0060デフォルトの名無しさんNGNG
そんなことを56は言ってんじゃないと思うが。
何かを指すものがポインタだから、としか言いようがない。
006156NGNG
レスありがとうございました。

>変数宣言時の'*'とその他の場所の'*'は違うよ。
心の中でもやもやしてたものが晴れました。
ありがとうございます。
ポインタの宣言するときだけは
int* p=&a;
のイメージで捉えたらいいのですね?
0062デフォルトの名無しさんNGNG
漏れはコンパイルの度にmakeって打つことによって、
人生通算で何回負けたかワカラン
0063デフォルトの名無しさんNGNG
>>60
そんなことを56は言ってんじゃないと思うが。
つーか、あんた何で56の言いたいことがわかるのさ!
0064デフォルトの名無しさんNGNG
>>61
>int* p=&a;
>のイメージで捉えたらいいのですね?

イメージとしてはそうかもね。C++ではそういう風に書くのが推奨されてるし。

でも、
int *p, *q;
と書くつもりで、
int* p, q;
ってイメージして
int *p, q;
ってやっちゃ駄目よ。
006560NGNG
>>63
56を読んでそう思ったからだ。
少なくとも型指定時の*と間接参照の*を混乱しているようには
読めなかった。まぁ56が疑問を解決したのならいいけど。。
0066デフォルトの名無しさんNGNG
bcc32でコンパイル、実行すると特に問題なく動作プログラムがあって、
それをVCでコンパイルならできるのですが、実行すると

runtime error R6002
- floating point not loaded

というメッセージがでてエラーになります。
このメッセージの意味は何なんでしょうか?
0067ビル・ジョブスNGNG
>>みんな
宣言時はポインタ修飾詞。

>>56
intは整数を入れる変数だよね。
で、ポインタはアドレスを入れる変数だよ。
(もう分かってる?)
0068ビル・ジョブスNGNG
>>66
DOS窓だね。
浮動小数点演算がソフトウェアエミュレーションになってる?
VCの設定は確認済み?
006966NGNG
>>68
はい、DOS窓です。
浮動小数点を使っているのは一箇所だけ実行時間を計っているところだけ
なんですが、printfで表示するときに直接計算せず、いったんdouble型の
変数に代入してから実行するといけました。
そのソフトウェアエミュレーションというのを設定するというのは
どこをいじればいいんでしょう?ヘルプで「ソフトウェアエミュレーション」
といれても、でてこなかったので...。
0070デフォルトの名無しさんNGNG
hitck[ix][iy]=off;
ixとiyの関係を教えて下さい。
0071デフォルトの名無しさんNGNG
>69 一箇所だけなら 整数で計算させたらいいじゃんと思うのだが?
  単に少数点表示がメンドクサって事だけでしょ?

c=a/b
((a-c*b)*100)/b
0072デフォルトの名無しさんNGNG
flushかそんな感じのあったと思ったけど忘れた。教えて。
printfで事情があって改行しなかったら出力されなかったので、flushしたい。
0073デフォルトの名無しさんNGNG
fflush()
0074デフォルトの名無しさんNGNG
>>71 div()というのも蟻

#include <stdlib.h>
div_t d = div(a, b);
printf("%3d.%.2%%\n", d.quot, d.rem);
0075デフォルトの名無しさんNGNG
fflush(stdout)
007674NGNG
これは適切じゃないな、スマソ。
0077デフォルトの名無しさんNGNG
fパラメータって無いのか
0078デフォルトの名無しさんNGNG
fflush()って、どういう時に使うのですか?
バッファを書き出す、と言われてもピンと来ない……。
0079デフォルトの名無しさんNGNG
#innkuru-do <esuthidhiaio-dotto.etti>
boido meinn (zoido)
{
innto a,b,c
huro-to x,y

purinntoehu("itteyosi")
あぎゃあああああああああああ
}
008080NGNG
そもそもストリームって何のことですか?
0081デフォルトの名無しさんNGNG
>>80
川の流れのようなもの
0082デフォルトの名無しさんNGNG
C言語でマルチスレッドプログラミングってできるもんなんでしょうか?
0083デフォルトの名無しさんNGNG
>82
 OSによってはAPIを呼び出せば非同期型スレッドは簡単

 SETJMP LONGJMPで 同期型のスレッドは作れる
 もちろんアセンブラでスタック切替をしても同じ。
0084デフォルトの名無しさんNGNG
タコな質問ですが、たとえば、

あいうえお<A>かきく<B>けこ→あいうえお@かきく\けこ

のようにある記号で挟まれた文字列をその内容によって
変換するようなプログラムってどう書けばいいでしょうか?
0085デフォルトの名無しさんNGNG
>>84
???
いまカッコ内かどうかのフラグを持たせて、
フラグがたってる間だけ変換処理を実行する。
じゃ、ないの?
0086デフォルトの名無しさんNGNG
>>82
pthreadライブラリを探せ
0087デフォルトの名無しさんNGNG
>>84
それって正規表現使うのがいいんじゃない?
Cに正規表現ライブラリってあるかなぁ?
008856NGNG
>>56-57で質問させて頂いた者です。
みなさんレスありがとうございました。
しかし一度は納得したものの、再び分からなくなってしまいました。
というのも、

void main(void)
{
char* p="A";
printf ("%d\n",*p);
}

を実行したら、65 が表示されたからです。
『あれ? この場合は65番地の中に入ってるデータが表示されるんじゃなかったのか!?』
とパニックになってます。

どなたかお助けを!!
0089デフォルトの名無しさんNGNG
>>88
p と *p は全然別のもの。
ちなみに 'A' == 65 である。

void main(void) {
char *p;
p=65;
printf ("%d\n",*p);
}

とするか

void main(void) {
char *p = 65;
printf ("%d\n",*p);
}
とすればお望みの動作になる。
0090デフォルトの名無しさんNGNG
>>88=56
文字列を " " で囲むと,それは文字列へのポインタになります
しかも文字列の末尾にはちゃんと nil 文字('\0')が付加されます
p にはその文字列へのポインタが代入されます
*p を参照すれば,そこにはポインタに指し示された部分にあるデータを得ることができます
つまり p にはよく分かんないアドレスが,*p には 'A' が入ってるってこと

65 番地のデータを表示させたいならば
char* p = 'A';
もしくは
char* p = 65;

# きっと正確な説明じゃないと思うけど,こんな理解でも大丈夫なはずです
0091デフォルトの名無しさんNGNG
ここでは65=0x41 という文字コードが印刷されたという事です >>88

C言語の文字列はバイト列をそのまま扱うような形になります
他の言語で文字型、文字列と順序型が明確に区別されていたのに馴れていると
訳が判らなくなると思います。

*p は いつでも (int)ord(*p) という変換がされているとでも考えて下さい
009256NGNG
>>90
>文字列を " " で囲むと,それは文字列へのポインタになります

そ、そうだったんですか・・・・(納得)
'A'はどういう意味になるのですか?

>>91
すみません、僕の頭ではちょっと難しくて・・・・(^^;)
C以外さわったことないんで。。
0093デフォルトの名無しさんNGNG
>>92
char型という8ビットの"整数"です。
char型はASCIIひと文字分の文字コードを扱うのに使ったりします。
C言語の文字列はchar型の単なる配列です。
0094デフォルトの名無しさんNGNG
文字コードを意識したくない。
どうすればいいかな?
0095デフォルトの名無しさんNGNG
>>94 他の言語を使え Windowsなら C++とかDelphiとか
0096デフォルトの名無しさんNGNG
ある掲示板で char, short, long は使うな、
int8_t, int16_t, int32_t を使えと言われたんですが、
char, short, long では何かまずいんでしょうか?
教えてください。
0097デフォルトの名無しさんNGNG
>>96
なにもまずくないけど?
0098デフォルトの名無しさんNGNG
>>96
目的も書かずに、「char, short, longは使うな、
int8_t, int16_t, int32_t を使え」っていうのでは何とも言えない。
「何のために」っていうのがまずあるはず。
教えて下さいの前に、質問の仕方を改めること。
場合によっては、Cは使うな、Perlの方がずっとその目的には向いてる、
ということもある。
0099デフォルトの名無しさんNGNG
>>95
C++やDelphiだと文字コードを意識しなくていいって?
Delはプラットホームが限られるからってことか?
0100デフォルトの名無しさんNGNG
MS-DOS/V 6.2 で10ms間隔で割り込みを発生させ、カウンタを作りたいんです。

ネットでいろいろ検索しましたが、うまく行きません。
知っておられたら、教えてください。

環境:MS-DOS/V 6.2
コンパイラ:VC++ 1.51 (MS-C 8.03)
で行っています。

よろしくお願いします。
0101デフォルトの名無しさんNGNG
100のつづき
テスト中のソースは以下の通りです。

struct SREGS sregs;
union REGS inregs, outregs;

long timl;
short tims;

interrupt timint(void)
{
_disable();
timl++;
tims++;
printf(" %04x\n",tims);
_enable();
int86x(0x1c, &inregs, &outregs, &sregs);
}

void timer_set()
{
void far *ptr;

ptr = timint;
inregs.h.ah = 0x02;
inregs.x.cx = 1; // 1で10[ms]
inregs.x.bx = FP_OFF(ptr);
sregs.es = FP_SEG(ptr);
int86x(0x1c, &inregs, &outregs, &sregs);
}

void main(void)
{
// void interrupt (*vect)();

timl = 0l;
tims = 0;
// vect = _dos_getvect(7);
timer_set();
while(1){
printf("xxx=%04x,yyy=%08ld\n",tims,timl) ;
}
// _dos_setvect(7, vect);
}

tims、timl 共に0のままです。
■ このスレッドは過去ログ倉庫に格納されています