トップページ⇒tech
909コメント312KB

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

■ このスレッドは過去ログ倉庫に格納されています
0001C言語ハッカー Kusakabe YouichiNGNG
おれは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言語なら、オレに聞け! <8>
http://pc.2ch.net/test/read.cgi/tech/1005811510/l50
0083デフォルトの名無しさんNGNG
sizeof(unsigned long) < sizeof(void *)
な処理系、あるいは両者のcastがうまくいかない処理系って
どんなのがありますか?規格では保証していないようですが。
0084デフォルトの名無しさんNGNG
>>82
そのやりかた、あってる?
あと、FAQの何章に書いてありました?
見つからなかった(^^;
0085デフォルトの名無しさんNGNG
>>82
いいんじゃないの?
それならcharでもintでもいけるし。たぶん。

最上位ビットを残して云々 って一瞬考えたけど
処理系にすげー依存しそうだしやめた。
0086デフォルトの名無しさんNGNG
>>85
マイナスのとき、処理がうまくいかないよ。
0087Kusakabe YouichiNGNG
余談ですが、

In article >>81, 81 デフォルトの名無しさん
wrote:
>  for( i = 0; i < M; i++ ) {

こういうふうに「for」と「(」をはくっつける、
「(」と「)」の内側に空白を明けるっていうのは、
どこの影響だろう :)

括弧のフォントをデザインした人がかわいそうだ :)
0088デフォルトの名無しさんNGNG
>>82 シフトせず、2で割る。 i /= (2 << n);
でも、そういうのはアセンブラで書いたほうが確実。
処理系依存部分は、処理系依存言語に任せる。これ最強。
0089Kusakabe YouichiNGNG
In article >>82, 82 デフォルトの名無しさん
wrote:

> 符号付き整数を符号維持したまま右シフトするもっとも単純な方法って?

「>>>」 :-P

> FAQには符号付き整数の右シフトは処理系依存と書いてあります。
> #define RSHIFT(i,n) ((i>0?1:(-1))*(signed)(((unsigned)i)>>n))
> こんな馬鹿みたいなのしか思いつかないのですが。

unsignedにcastするか、負の場合だけ場合分けしてmaskを使うかでしょうね。
009082NGNG
>>84
すみません。処理系依存とは書いてないですね。
ですが Q20.15(書籍版ですが)に「負の数を右シフトすることは割算と
等しくない」とあります。

また、K&R第2版の253ページに「右シフトを負の数にした場合、結果は処
理系依存」という旨の文章があります。

>>84,86
思いきりまちがえてますね。失礼しました。

(ちょっとオリジナルFAQ&JIS本見る時間が無いので夜まで失礼します)
0091デフォルトの名無しさんNGNG
なるほど、カニチャーハンには
右シフトしたときに処理系によって
0が入るのと符号がはいるのと両方ある
って書いてあるね

手元のだとP60だから、まあその辺
0092デフォルトの名無しさんNGNG
>>89
>>> って古いコンパイラでもつかえる?
0093デフォルトの名無しさんNGNG
>>81
60点。確率が均等でない。
ためしにN=2でtable[0]が2になる確率を考えてみろ。

19,4c19,7
<   int r = rand() % M;
<   int tmp = table[i];
<   table[i] = table[r];
<   table[r] = tmp;
---
>   int r = rand() % (M - i);
>   if (r) {
>    int tmp = table[i];
>    r += i;
>    table[i] = table[r];
>    table[r] = tmp;
>   }
0094Kusakabe YouichiNGNG
In article >>91, 91 デフォルトの名無しさん
wrote:
> なるほど、カニチャーハンには
> 右シフトしたときに処理系によって
> 0が入るのと符号がはいるのと両方あるって書いてあるね

私なら、「そこだけJavaやる」:) も。
なんでCには「>>>」がないんだろうね。
0095Kusakabe YouichiNGNG
In article >>92, 92 デフォルトの名無しさん
wrote:

> >>89
> >>> って古いコンパイラでもつかえる?

いや、新しいのでも無理では?
0096デフォルトの名無しさんNGNG
>>94
> 私なら、「そこだけJavaやる」:) も。

もうね、アホかと。馬鹿かと。
0097Kusakabe YouichiNGNG
In article >>96, 96 デフォルトの名無しさん
wrote:

> >>94
> > 私なら、「そこだけJavaやる」:) も。
>
> もうね、アホかと。馬鹿かと。

そんなにうれしいですか? :)
0098デフォルトの名無しさんNGNG
インラインアセンブラはあっても、インラインジャヴァはありません
0099Kusakabe YouichiNGNG
In article >>98, 98 デフォルトの名無しさん
wrote:

> インラインアセンブラはあっても、インラインジャヴァはありません

あってもだれもつかわなそう:)
0100てきとうNGNG
#define RSHIFT(i,n) (((i<0?1:0)*(~((unsigned)~0)>>n))|(i>>n))
0101てきとうNGNG
(i<0?1:0) は 真偽値が 真:1 偽:0 でない処理系を考慮

かっこがおおいのはかんべんしてちょー ぷりぷり
0102デフォルトの名無しさんNGNG
>>94
> なんでCには「>>>」がないんだろうね。

Cは実行効率至上主義だから。
CPUの都合を考えて実行効率の良い方法でやっちゃって良いよって方針だから。
符号拡張しなけりゃならんとか決めたら、
そーゆー命令のないCPU上で実行効率が落ちるから、そーゆーのを嫌って。
0103MarezoNGNG
#define RSHIFT(i,n) (signed)((unsigned)i&0x8000|((unsigned)i&0x7fff)>>n)
0104デフォルトの名無しさんNGNG
>>103
それnが2以上だと
0105味噌醤油醸造株式会社NGNG
>>103
うちのPCだと、変な結果になります(T-T)
0106デフォルトの名無しさんNGNG
>>105
うん。間違ってるもん。
0107初心者NGNG
C言語で画面の制御はどんな関数を使用するんですか?
画面上のラインとカラムを指定して、値の入力・出力ができるんでしょうか?
又、表形式で罫線をひいたりすることはできるんですか?

C言語入門の本は読んだのですが、上記の部分は載っていませんでした。
公開されているサンプルPGも調べてみたのですが、
(調査不足ならすいません)見つけることができませんでした。
教えてください。
0108デフォルトの名無しさんNGNG
>>107
ncursesのようなライブラリが用意されてれば
それを使うがいいし、もしなければ
機種依存上等!てな感じで
コントロールコードやエスケープシーケンスを駆使して
描画すればいいじゃん、って感じ
0109初心者NGNG
グラフィック関数を使用するのですか?
0110デフォルトの名無しさんNGNG
>>109
絵を描きたいならそう言えよ。
0111初心者NGNG
絵ではなくて、表なんですけど。
すいません。

本には一行単位で入出力が行なわれているんですが、
画面単位で特定の項目の内容を受け取りたい場合や
画面単位で項目名や注意書きを表示する方法が
無かったんです。
で、調べていくうちグラフィック関数の名前だけを知り
それで、表作成ができるのかなと思ってたんです。
0112Kusakabe YouichiNGNG
In article >>102, 102 デフォルトの名無しさ
ん wrote:
> > なんでCには「>>>」がないんだろうね。
>
> Cは実行効率至上主義だから。
> CPUの都合を考えて実行効率の良い方法でやっちゃって良いよって方針だから。
> 符号拡張しなけりゃならんとか決めたら、
> そーゆー命令のないCPU上で実行効率が落ちるから、そーゆーのを嫌って。

でも、その割には1の補数とか、1命令でできないハードウェアもたまに
存在するのに、演算子はありますね。
0113デフォルトの名無しさんNGNG
>>112
たとえばどのハード?
そういうハードに出会ったこと無いので教えてほしい
0114デフォルトの名無しさん NGNG
RSHIFTって、ROTATEじゃなくて、あくまで符号付のままのSHIFTだろ。
>>82 のまんまでいいと思うけど。
0115Kusakabe YouichiNGNG
In article >>107, 107 初心者 <[email protected]
yndns.org> wrote:

> C言語で画面の制御はどんな関数を使用するんですか?

環境依存でしょう。
0116デフォルトの名無しさんNGNG
-8を符号付で右シフトする例
11111000 -8
(unsigned)
00001000 8
>>1
00000100 4
符号復活
11111100 -4

あー>>82のままでいいのか。納得
0117あぼーんNGNG
あぼーん
0118Kusakabe YouichiNGNG
In article >>113, 113 デフォルトの名無しさ
ん wrote:

> >>112
> たとえばどのハード?
> そういうハードに出会ったこと無いので教えてほしい

正確には「ない」のではないかもしれないが、
メルコムとか、その上のCの処理系が履くコードをみてみると、
わざわざ数命令で実現しているので、「ない」のだと思ったが。
(そのマシン純正のfortranもそうだったのでたぶん本当にハード的にないんだと思
う)

まあ、「ないようなハードがいけない」といわれればそれまでだが、
だったら「>>>」も入れてくれてもいいのになーと思ったわけです。
0119デフォルトの名無しさんNGNG
>>116
>あー>>82のままでいいのか。納得

printf("%d\n", RSHIFT(-8,1));
うちで実行すると結果はこうなります。
-2147483644

これで、いいんでしょうか?
(俺が勘違いしてるかのかな?)
0120デフォルトの名無しさんNGNG
>>118 (´Д`)
おいおい確認もしないで発言してたのかよ
0121デフォルトの名無しさんNGNG
>>119
>>100のはどうよ?
0122デフォルトの名無しさんNGNG
>>119
0x80000004 だな
なんかヘンテコリン
0123デフォルトの名無しさんNGNG
#define RSHIFT(i,n) (i>=0?i>>n:(signed)~(((unsigned)~i)>>n))
0124デフォルトの名無しさんNGNG
>>121
printf("%d\n", RSHIFT(-8,1));
で結果は
-4
だった。
0125デフォルトの名無しさんNGNG
>>124
じゃあ>>100のが正解か
もうちっと短くならんかね?
0126デフォルトの名無しさんNGNG
>>123
それじゃあ、iが負のとき正になっちゃうんじゃないか?
0127デフォルトの名無しさんNGNG
Cを習得するのにどれくらいかかった?
C++は?
VBは?
誰か教えて!
0128123NGNG
>>126
10010010
↓反転
01101101
↓シフト
00110110
↓反転
11001001
0129初心者NGNG
>>115

環境依存って、例えばエクセルやアクセスで画面展開して、
必要項目をテキストファイルでCで受け取る。
というような事ですか?
0130デフォルトの名無しさんNGNG
>>127
Cは二ヶ月。
C++は半年。
VBは一日。
0131about:RSHIFTNGNG
最上位ビットが1かどうかを値が負かどうかで判定するのは
内部表現が2の補数であるという仮定に基づいていると
思いますが、この仮定って規格で保証されてましたっけ?
保証されていない場合、最上位ビットの判定は
n&~((~((unsigned)0))>>1)
でいいでしょうか?

この問題って、いかなる内部表現であれ、
2の補数表現の数を2で割ったようなビット操作を
エミュレートせよ、ってことなのかな。。
0132デフォルトの名無しさんNGNG
こんな感じの変数を宣言した場合、関数に渡すときって
どんな感じでやればいいのでしょうか?

char *buf[4][8];

今は下みたいにしていて、コンパイルは通るけど
sub関数でmemcpyをして、その値を出そうとするとcoreを吐いてしまうのですが

void sub( char *[][] );
main(){
char *buf[4][8];
sub( buf );
}

sub( char buf[][8] ){
}
0133デフォルトの名無しさんNGNG
>>131
おおっと。たしかにそんな規定は無いかもしれないけど
内部表現が2の補数じゃないアーキテクチャって
どんな表現なのかな?
つーかビット演算って
0134デフォルトの名無しさんNGNG
>>132
main(){
char *buf[4][8];
sub( buf );
}

sub( char *buf[][8] ){
}

でいいんでないの?
0135デフォルトの名無しさん NGNG
実際には見たことないけど,内部に符号ビットがあって、
数値表現は全て正数表現っていうアーキテクチャが一部の
大型計算機にある(あった?)というのを聞いたことがある。
正か負は符号ビットで判断するんだって。
0136Kusakabe YouichiNGNG
In article >>127, 127 デフォルトの名無しさ
ん wrote:

> Cを習得するのにどれくらいかかった?
3日
> C++は?
3週間
> VBは?
3version:)
0137Kusakabe YouichiNGNG
In article >>132, 132 デフォルトの名無しさん wrote:

> こんな感じの変数を宣言した場合、関数に渡すときって
> どんな感じでやればいいのでしょうか?
>
> char *buf[4][8];

> 今は下みたいにしていて、コンパイルは通るけど
> sub関数でmemcpyをして、その値を出そうとするとcoreを吐いてしまうのですが
>
> void sub(char *[][]);
> sub(char buf[][8])

っていうか、よくコンパイル通りますねえ
0138デフォルトの名無しさんNGNG
>>127
>Cを習得するのにどれくらいかかった?

一年くらいかかた。
COBOLをやってたから、最初は、ローカル変数とか引数ってのが
ビンとこなくて、変数は全部、ソースの先頭のところにグローバル
で使ってた。しかも仕事で。はっはっは!
0139デフォルトの名無しさん NGNG
>>132
>sub関数でmemcpyをして
なにやりたいのか,よくわからんのだけれど,
*buf[][]に、memcpyするってこと?
0140デフォルトの名無しさんNGNG
>>136-137
それはageなくちゃいけないような内容なのか?
0141デフォルトの名無しさんNGNG
ところで、右にシフトしたら数が小さくなる規定はあるんだろうか?
0142デフォルトの名無しさんNGNG
>>141
処理系依存じゃないか?
0143デフォルトの名無しさんNGNG
>>141-142
2進数表現を素直にマッピングできないような
アーキテクチャのマシンわざわざ作る奴いないだろ。
数字を左から書く文化圏でコンピュータが発明されていたなら
あったかもしれないけど。

数値にグレイコードとか使う変態マシンも理論上ありえるけど
アキュムレータが大変なことになりそう。
0144デフォルトの名無しさんNGNG
Cの手っ取り早い環境はlcpadとlsicのみでいいですよね?
で、cpadのコンパイラパス入力すれば歓声〜〜、ですか?
0145C初心者NGNG
K&Rを初めて購入したのですが、この本を使う上での注意点とかありますか?
0146デフォルトの名無しさんNGNG
>>145
破って尻を拭かないように。
0147デフォルトの名無しさんNGNG
>>141
右にシフトしたら数が小さくなる、んじゃなくて、
シフトして数が小さくなる方向が右、なんじゃない?
0148デフォルトの名無しさんNGNG
実際の環境で試しながら読む。
0149C初心者NGNG
>>148
ありがとうございます。
他の本でK&Rをケチョンケチョンにこき下ろしてる記述(K&RはC言語を分かりづらくしている諸悪の根源とか)
があったりするのですが、実際どうなのでしょうか・・・・。
0150デフォルトの名無しさんNGNG
>>149
Cが分からないと言う奴はそもそもK&Rを読まない。
0151C初心者NGNG
>>150
オレもそう思うんですけどね。。。
K&Rをこき下ろしてる本とは、これです。↓
http://www2.gihyo.co.jp/books/bookinfo.asp?ID=971
0152デフォルトの名無しさんNGNG
そう言う本は「処理系決め撃ち」で勝手な規格を作ってるんじゃないの?
だからintは4バイトだの、void mainだのって平気で書いちゃう
K&Rには未定義な動作は未定義と書いてるだけだから、そこは別途調べる必要が有ります
0153C初心者NGNG
>>152
いや、この本はその辺はちゃんとしてます。
void main についてもわざわざ欄を設けて説明してありました。
0154デフォルトの名無しさんNGNG
でも、実際問題、あのポインタ表記はどうにかならんものかと思う。
0155C初心者NGNG
>>154
と、言いますと?
0156デフォルトの名無しさんNGNG
>>151
ああ、あれか。K&Rの第五章を焼き直した本ね。

参考文献にK&Rが入っていないCの本は見たことない。
参考文献すら書いてない本は買うに値しない。

ちがう?
0157C初心者NGNG
>>156
そんな、オレを責められても困りますよ。
0158デフォルトの名無しさんNGNG
K&R、本屋で立ち読みした。
3分で吐き気がした。
コンピューターとは話せるが、まともな人間と普通のコミュニケーションが取れないヲタが文章を書くと、ああなるという、良い見本だった。
教育学の教科書にサンプルとして採用しようと思った。
もちろん、ダメな解説例として。

人にわかりやすく物事を教えるには、それなりに「教えるスキル」が必要だ。
カニチャーハンは、その辺がまったくわかっていない。
K&Rは、最後の一冊として読むべきだ。最初に読んではいけないし、勉強の途中で読んでもいけない。
ほとんど全部他の本を読み尽くして、C++に逝く直前に読むと良い。
0159C初心者NGNG
>カニチャーハン
ワロタ!
0160C初心者NGNG
うーん、K&R買わなければ良かったかなあ・・・(鬱
0161デフォルトの名無しさんNGNG
>>160
> うーん、K&R買わなければ良かったかなあ・・・(鬱
買っといて損はない。
K&Rが理解できればCの文法は理解したと思って良い。

あと、K&Rは規格書やマニュアルに近い書き方なので、
慣れていない人が読むと>>158のような感想を持つでしょう。
0162デフォルトの名無しさんNGNG
>>158
K&R はあくまで「Cの入門書」であって「プログラミングの入門書」でも教科書でも
ないからね。

基本的なプログラミング技術が身についていない人間が読むのは、ちょっと辛い。
身近に質問できる先輩とかいれば、どうにかなるけど。
0163C初心者NGNG
>>161
なるほど・・・。
「解説書」ではなくて「規格書」「Cの定義文」みたいに接すれば有用だということですね?
0164仕様書無しさんNGNG
>>158
プログラマー辞めてよし!
0165デフォルトの名無しさんNGNG
つか、日本語版訳が悪いから止めとけってばよ(藁
0166C初心者NGNG
>>165
その話はよく聞きますね。
0167デフォルトの名無しさんNGNG
じゃー漏れがもっとわかりやすく翻訳しなおしてやろうか?
あれって許可いるのか?
0168C初心者NGNG
もちろん原著者の許可が要るでしょう。
0169デフォルトの名無しさんNGNG
ヲイヲイCの文法理解すんのに大袈裟じゃないか?
0170デフォルトの名無しさんNGNG
引用には許可は不要です。翻訳してもOK.
0171デフォルトの名無しさんNGNG
>>170
いや、引用でなくて、丸ごと一冊訳そうとたくらんどるんだけど。
0172デフォルトの名無しさんNGNG
>>171
どっかスレ作って、そこでガンガン訳しちゃうってのはどう?
添削も出来るし。

まーこの際著作権は無視だな、ムシ
0173デフォルトの名無しさんNGNG
親切な人がホームページにまとめてアップしてくれそうだし
なんならオレがその役をかってでてもいい
0174デフォルトの名無しさんNGNG
煽ってるが、捕まるかもw
0175デフォルトの名無しさんNGNG
しかし、あんなクソ訳を放置しておくというのも日本全体の利益にならんな。
役所が金出してくれればいいんだが。
0176デフォルトの名無しさんNGNG
>>151
こきおろしている、というより「時代遅れな記述がある」と言っているんじゃ・・・
俺にはそう読めましたが。
(まあ、たしかにどうでもいいあげあしとりもありますが)
0177MarezoNGNG
>>103
勘違いしていた(^^;
#define RSHIFT(i,n) i<0 ? (signed)!(!(unsigned)i >> n) : i >> n;

確か「!」はnotだったはず。
0178デフォルトの名無しさんNGNG
>>177
つーか負の表現に2の補数を使ってるところなら
>>100で完了してるんだけど、どうよ?
0179デフォルトの名無しさんNGNG
関数をstatic宣言するのとしないのの違いを教えてください。

static void hoge();
void hoge();

returnした時に挙動が変わるようなのですが・・・・
よろしくお願いします。
0180デフォルトの名無しさんNGNG
>179
外部から参照できる(static なし)かできないかの違い(static)
0181デフォルトの名無しさんNGNG
>>179
static にすると同一の翻訳単位 (厳密に言うと #include とかあるからアレなんだが、
基本的には同じ *.c に書いてある範囲)からしか呼び出せない。static にしないと、
外部からでも呼び出せる。

> returnした時に挙動が変わるようなのですが・・・・
それは static 変数と勘違いしてないか?
018282NGNG
どうも右シフトの元質問者です
なんだかお題の書き方が曖昧だったみたいですんません
割算をしたいという趣旨ではなくて、最上位ビット以外をシフトしたい
ということでした。てことでいろいろヒントをいただいた結果こんなん
になりました。

#define MASK ((~(unsigned)0)>>1)
#define RSHIFT(i,n) (signed)((i<0?(~MASK):0)|(((unsigned)i&MASK)>>n))

簡単にならんかな・・・
■ このスレッドは過去ログ倉庫に格納されています