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

C言語なら、オレに聞け! 47

■ このスレッドは過去ログ倉庫に格納されています
0001デフォルトの名無しさんNGNG
まず問題を冷静に吟味してCの話か否かをはっきりさせてから質問しろ。
むしろ質問する前にWEBで検索するのが常識だ。

GUIなどの標準Cではできない事の質問は使用している開発環境のスレへ行け。
ソース丸投げ、宿題、書籍 は専門の別スレがあるのでそこへ行け。

コンパイラを探しているなら >>2 を見よ。

上記を逸した場合の結果は激しく未定義とする。ウヒ

C FAQ 日本語訳
http://www.catnet.ne.jp/kouno/c_faq/c_faq.html
Cプログラマ必読 ・プログラミング言語C(通称 K&R)
http://www.amazon.co.jp/exec/obidos/ASIN/4320026926/

前スレ
http://pc3.2ch.net/test/read.cgi/tech/1039328710/
0153デフォルトの名無しさんNGNG
>>145
ポインターのポインターを使用するしか・・・
0154デフォルトの名無しさんNGNG
>>146
なるほど。言ってる意味はわかったが、
果たしてその解釈で合ってるかな。

E1>>E2 は、E1 を E2 ビット分右にシフトし、それを結果とする。
E1 が符号無し整数型をもつ場合、又は E1 が符号付き整数で非負の値をもつ場合、
結果の値は、E1 を 2 の E2 乗で割った商の整数部分とする。
E1 が符号付き整数型で負の値をもつ場合、結果の値は、処理系定義とする。

ビット並びで見た場合、空きビット以外の部分は保証されていると思うが。
0155154NGNG
>>154 は
JIS X3010 (ISO/IEC9899:1990) からの引用ね。
0156デフォルトの名無しさんNGNG
>>152
みんな仲良くしようよ
0157デフォルトの名無しさんNGNG
>>145
>>10000個分が全部まとまった
>>状態でしかそのデータを読み込めないんです。

この辺が何を言いたいのか理解できないんだが。
malloc()、realloc()で確保した領域は構造体の配列と同じようにアクセスできるけど、それじゃだめか?


>>153
なぜ?
0158デフォルトの名無しさんNGNG
何にしろ、個数が分からん限りmallocで確保するのは絶対に不可能。
ループで回してる中で1個づつ追加していきたいならreallocでできるでそ?
100個でも10000000個でもreallocしていけば。

しかしreallocの時間的コストってどんなもんだろうな。
10000000回もreallocするのなんか抵抗あるが。
0159名無し@沢村NGNG
>>152
刀あげるから…!!
0160デフォルトの名無しさんNGNG
>>159
>>152
0161デフォルトの名無しさんNGNG
>>154 たしかにそうだ。私が間違えていた。すまん。
bit ならびは新しく入る部分以外は保存される。

わたしが漠然と思っていたことがやっと分かった。
マスク (&0xff) せずに、
buffer2[0] = buffer >> 24;
とした場合ははダメで、
buffer2[0] = (buffer >> 24) & 0xff; /* CHAR_BITS==8 の場合 */
ならOK ってことだ。
つまり、&0xff なら、左のビットが捨てられるだけだが、
前者のようにマスクせず int を BYTE に代入したら、
(BYTE が 8 bit の符号無し整数だとして)
256を法としてbufferと合同な最小の整数が buffer2[0]に入るから、
負数の内部表現によって結果が異ってしまう。

このスレではみんな &0xff としてるので、問題ないわけだ。
私がわるかった。重ねがさね済まん。
0162124NGNG
>>127
うるせーここんとこ仕事ヒマなんだよ
放っとけ
0163デフォルトの名無しさんNGNG
#include <limits.h>
&(unsiged(1<<CHAR_BIT)-1)
多分これで処理系に関係なく1バイトのみの値を取る事が出来る
と言っても、こんなガイキチみちたコードなんて書かずに
素直に、処理系依存のコードにした方が、かなりまし
0164デフォルトの名無しさんNGNG
>>163
そんなガイキチみちたコードなんて書かずに
素直に、UCHAR_MAXと書いたほうがまし
0165さっぱりNGNG
すいません。C言語の初心者です。
課題で出されたCがわからなくてこまってます。
課題は2つの行列AとBを加算するプログラム(matadd.c 未完成)をディスクに保存する。

入力用データファイル matadd.dat をディスクに保存する。

ソースプログラムをコンパイルし,実行する。
実行時に次のように入力のリダイレクトを行い,データファイルからデータを読み込ませる。

matadd < matadd.dat


表示された結果とソースプログラム内容を観察し,どのような手順で2次元配列を入力・出力しているか,理解する。

次に,C=A+B を計算し,Cの各要素を行列らしく出力する部分を追加して完成させる。
上と同様に実行して動作確認ができたら,ソースプログラムを提出する。
0166163NGNG
書くの忘れてた…
これ、>>89-100辺りに出てたマスクの話
(マスクが必要か必要無いかの話は別問題として)
0167デフォルトの名無しさんNGNG
>>165
>>1よめ厨房。

>ソース丸投げ、宿題、書籍 は専門の別スレがあるのでそこへ行け。
0168デフォルトの名無しさんNGNG
>>164
UCHAR_MAXって(unsigned)0-1になる事が規格で保証されてたっけ?
0169デフォルトの名無しさんNGNG
>>103
struct data {
 int xxx;
 char yyy[256];
};
char dummy=0;
struct data *info;
info=(struct data *)malloc(sizeof(struct data )*kazu);
…
dummy = (info+index)->yyy[xxx];//info[index]->yyy[xxx]; と同じアクセス方法。indexはkazuを超えない事。
…
free(info);

ダイレクトにアクセスできますぜ。
ただ、確保された領域の外には手を出さない事。(事故でも)
ソースは、131から流用を改変。thx.
0170デフォルトの名無しさんNGNG
>>169 ここCのスレなんだから、せめてこれ位に…
typedef struct {
 int xxx;
 char yyy[256];
} data;
0171デフォルトの名無しさんNGNG
>>103
構造体のメンバを表す時の.や->の意味とポインタの概念を理解出来れば
>>169の(info+index)->yyy[xxx]をinfo[index].yyy[xxx]と
置き換えられるようになる事が理解出来るので、頑張っ勉強して下さい
0172171NGNG
「頑張って」のが「て」が抜けた…
0173デフォルトの名無しさんNGNG
>>168
不安なら(unsigned)0-1って書けば?
>>163よりはマシだと思われ
0174デフォルトの名無しさんNGNG
>>168
保証もなにも、普通違う値だろ。

~(~0u<<CHAR_BITS)
0175デフォルトの名無しさんNGNG
>>173
(unsigned char)0-1の書き間違えだと思うが
それが8ビットの場合255になってくれる処理系を俺は見た事がない
0176175NGNG
誰も書かないようなので自分で突っ込みを入れると
(unsigned char)(-1)
なら動くが、たまに動かない物もあるので注意
0177175NGNG
さらに書くと、>>176で動く場合
ただ単にキャストすればマスクの必要はない
0178デフォルトの名無しさんNGNG
このスレ的に処理系の規格準拠は前提にしていいの?
0179デフォルトの名無しさんNGNG
処理系の規格準拠って何ぞや?
0180デフォルトの名無しさんNGNG
コンパイラが ANSI なり ISO なりの規格に準拠してるかって事だろ。
C 言語の前に日本語は大丈夫か?
0181デフォルトの名無しさんNGNG
> (info+index)->yyy[xxx];

イヤな書き方するな。
0182デフォルトの名無しさんNGNG
>>145
> 10000個データがあったとしても、1個ずつ読み込んで処理できるんなら
> その時にカウントしていけばいいんですけど、10000個分が全部まとまった
> 状態でしかそのデータを読み込めないんです。
> だから、最初からその分の領域を確保しなければならないので困ってます。
C++のVectorの実装を参考にしてみろ。
まず、適当な大きさでmallocし、追加するたびに上限値を超えていないかのチェックを行う。
上限値を超えていた場合、上限値を増やしてreallocする。
こんな感じの実装の仕方だったはず。
0183デフォルトの名無しさんNGNG
> C++のVectorの実装を参考にしてみろ。

この一行がものすごく余計な気がする
0184デフォルトの名無しさんNGNG
>>175
整数演算がオーバーフローした場合の結果は未定義だが
符号なし整数はオーバーフローしない
よって(unsigned char)0から1を減じた結果が
UCHAR_MAXとなることを処理系は保証すべき

符号付き整数-1を,より少ないビット数の符号なし整数unsigned charに変換する場合
変換後の値は,UCHAR_MAX+1で割った非負の剰りであると規定されているから
UCHAR_MAX==255の処理系では(unsigned char)-1==255となるべき

>>181
イヤじゃない書き方って
info[index].yyy[xxx]
のことか?
漏れ的にはポインタに[]はあんまり使いたくない
仮引数*hogeをhoge[]と書くのも気持ち悪い
0185デフォルトの名無しさんNGNG
> 符号なし整数はオーバーフローしない

そんな事が決まっていたっけ?

> UCHAR_MAX==255の処理系では(unsigned char)-1==255となるべき

unsigned char に変換する前の -1 の全ビットが立っている保証はあったっけ?

> info[index].yyy[xxx]
> のことか?

そう。

> 漏れ的にはポインタに[]はあんまり使いたくない

ならこう書け。
(info + index)->yyy + xxx

> 仮引数*hogeをhoge[]と書くのも気持ち悪い

int main(int argc, char **argv)
と書く人ですか?
まあいいけど。
0186デフォルトの名無しさんNGNG
> (info + index)->yyy + xxx

こうね。
*((info + index)->yyy + xxx)
0187デフォルトの名無しさんNGNG
>>185
> そんな事が決まっていたっけ?
少なくともJIS X 3010-1993では決まっていますが何か?
JIS X 3010-1993(ISO/IEC 9899:1990)
6.1.2.5 型 4段落目の中程から引用
  符号無しオペランドを含む計算は、決してオーバフローしない。
  すなわち、格納する符号無し整数型で表現できない結果が、その符号無し整数で
  表現しうる最大値より1だけ大きい数を法とする剰余とする。
0188デフォルトの名無しさんNGNG
>>185
> > 符号なし整数はオーバーフローしない
> そんな事が決まっていたっけ?
オーバーフローしたときの動作が決まってたはず。

> > UCHAR_MAX==255の処理系では(unsigned char)-1==255となるべき
> unsigned char に変換する前の -1 の全ビットが立っている保証はあったっけ?
ない。
0189デフォルトの名無しさんNGNG
>>187
ありがとう。
C99 では 6.2.5 Types の項 9 だね。
でも、訊いただけだから、何かと訊き返されても困るけど。
0190デフォルトの名無しさんNGNG
> > UCHAR_MAX==255の処理系では(unsigned char)-1==255となるべき
> unsigned char に変換する前の -1 の全ビットが立っている保証はあったっけ?

訊き方がまずかったかも。
符号付整数の負数を符号無し整数にキャストした時、どの負数がどの正数値に対応
すべきという規定はあったっけ?
0191デフォルトの名無しさんNGNG
>>185

-1のビットパターンには関係がない
-1を256で割った非負の剰りが255なだけ
0192184NGNG
ん,(unsigned char)0から1を減ずることはできないな
(unsigned char)0-1と書いても格上げが入るから
((int)(unsigned char)0)-((int)1)になるだけだ
0193デフォルトの名無しさんNGNG
なるほど
0194デフォルトの名無しさんNGNG
>>192
inf i = 0;
i--;
と言いたいわけか?
0195194NGNG
寝言言ってる。
unsigned char c = 0;
c--;
0196デフォルトの名無しさんNGNG
んー、あれ、ちょっと待てよ。
(unsigned char)0-(unsigned char)1
は、ずっと unsigned char のままで演算されないか?
0197デフォルトの名無しさんNGNG
C の事はここでは訊いてはいけないって本当ですか?
0198デフォルトの名無しさんNGNG
>>196
(unsigned char)((unsigned char)0-(unsigned char)1)
なら、そう実装しても構わない。
0199デフォルトの名無しさんNGNG
>>196
unsigned char c;
printf("%u\n", sizeof(c));
printf("%u\n", sizeof(c - c));
0200デフォルトの名無しさんNGNG
>>169
そもそも103はそのkazuってのがその時点で不明だから悩んでるんじゃないか?
話がループしてるぞ。
0201デフォルトの名無しさんNGNG
ディレクトリに対して読み込みモードでfopenすると成功するんですけど、
それから読み込みを行うのは安全ですか?
0202デフォルトの名無しさんNGNG
>>200
それについてはrealloc()が5回くらい出てるんだが、読んでないのか?
0203デフォルトの名無しさんNGNG
>>201
読めることは読めるだろうけど、得られたデータには何の保証もない。
0204デフォルトの名無しさんNGNG
>>203
安全ならそれでいいんです。
じゃあ大丈夫だってことですか?
0205デフォルトの名無しさんNGNG
>>204
何を安全とするか、何を大丈夫とするか、によって答えは変わる。
0206デフォルトの名無しさんNGNG
>>205
プログラムが異常終了したりしないかとか。
0207デフォルトの名無しさんNGNG
>>201
普通opendirじゃないの。ディレクトリもファイルの一種。
0208デフォルトの名無しさんNGNG
>>206
システムや処理系次第だろうな。
真っ当なシステムなら、openできた以上以上終了ってことは多分ないと思うが、
もちろん保証の限りではない。

POSIXなシステムでは、ディレクトリに対するfopen()は書き込みじゃなけりゃ
成功するように見える。
ttp://www.opengroup.org/onlinepubs/007908799/xsh/fopen.html
[EISDIR]
  The named file is a directory and mode requires write access.

ちなみにLinuxでは即EOFになった。
0209デフォルトの名無しさんNGNG
MAC だとフォルダ開けてしまい、読もうとした瞬間あぼーんされたりすると聞いた事あるが。
0210184NGNG
>>186
ワラタ
*((*(info + index)).yyy + xxx)

[]や->も使えば可読性が上がる場面では漏れも使ってるけどよ
たとえば冒頭の例のように*をちゃんと追うのは大事な基本だと思うから
ポインタで間接参照しているところはありのまま書いておきたいって
気持ちがあるわけよ

char s[2];
s[1] = '\0'; なんかだと
*(&s[0] + 1) = '\0'; がありのままだが
配列の実体に直接アクセスしているところはそう見せたい
extern char s[];
s[1] = '\0';
のような場面が脳裏をよぎるんだ

*argv[]も漏れの周りがそうしてるから合わせてるさ
あんまり使いたくないってのは
必ずしも本音と建て前が一致しないことがあるってことで
絶対使わないって意味じゃない
0211デフォルトの名無しさんNGNG
210 の言いたい事もわからないでもないけど、結局シンタックスシュガーを許容
できない頑固者としか思えないよ。
シンタックスシュガーが何の為にあるのか考えた方がいい。
もちろん、自分しか読まないようなソースであれば、その限りじゃないけど。
0212184NGNG
シンタックスシュガーは逆効果に気をつけて使うべきだろ
マクロをあんまり使いたくないのと同じだよ
0213デフォルトの名無しさんNGNG
(゚Д゚)ハァ?
0214184NGNG
[]や->は1重間接の*を隠すだけだろ
2重間接になってる所では却って邪魔になることがあると言いたい
0215デフォルトの名無しさんNGNG
何が邪魔になるのかよくわからないから例を挙げてはくれないか?
0216デフォルトの名無しさんNGNG
(*p)[n] = &(*q)->r;
*(*p + n) = &(**q).r;
まあ気分の問題ちゃそれまでなんだけどよ

>もちろん、自分しか読まないようなソースであれば、その限りじゃないけど。
こんなこと言われるのは心外だったりする
0217216=184NGNG
失礼,名乗るのを忘れた
0218デフォルトの名無しさんNGNG
主観満載な事を“使うべき”なんて言われてもねぇ
0219デフォルトの名無しさんNGNG
>>216
後者の方がよっぽどワケワカランに見えるけど?
0220デフォルトの名無しさんNGNG
>>202
ハァ? 頭悪すぎ。
169の内容と何も関係ないだろ。
0221デフォルトの名無しさんNGNG
>>218
可読性を主観以外の何だと言う気だ?
よもや自分だけ違うなんて言い出すまいな
それから漏れは「べき」と言ったか?
0222デフォルトの名無しさんNGNG
>>221
あんたが 「べき」 と言ったかどうかは知らないが、212 にはそう書いてある。
0223デフォルトの名無しさんNGNG
>>222
ああ,そいつは悪かった
確かに漏れが言った
逆効果なんかありえないと言う訳にもいかんが

>>219
漏れが組んでいる相手がそう言ったら当然考えるさ
人に読ませることを考えてないような言われ方が心外だと言っている
0224223=184NGNG
いかん,また名乗るのを忘れた
0225デフォルトの名無しさんNGNG
ポインタ(dat = *pointer)と配列(dat = dim[0])ってどっちがアクセス高速ですか?
0226デフォルトの名無しさんNGNG
>>225
実測しる
それしかない
0227デフォルトの名無しさんNGNG
まあ、お前ら落ち着けよ。
とりあえず、他人が読んで分かりやすいのが良いに決まってるんだが
その他人が読みやすいってのが、個人個人で違うから主観だって話でそ?
チームで開発してれば、その大多数が読みやすい形で書くのがベストであって
つまり、一番使ってるやつが多い形に合わせるのが自然だな。
自分のスタイルと変えて書くほうは大変だが。
0228デフォルトの名無しさんNGNG
>>225
ちなみに、VC6 は最適化レベルに関わらず、どちらも同じコードを吐く。
0229184NGNG
>>227
そうだな
人に例を要求しておいて自分は何も出さないまま煽るだけの
抽象論を相手に漏れも大人げなさすぎたよ
0230デフォルトの名無しさんNGNG
(*p)[n] = &(*q)->r;
*(*p + n) = &(**q).r;

この例を取って主観で言うけど、漏れは 1 つの塊に * が 2 つ以上あるのは
読みにくいと思う。
184 の主論は 「隠れた処理があるのはわかりづらい」 という事だと思うんだけど、
漏れは 「わかりきった処理は隠蔽された方が読みやすい」 と思う。
i < 0? -i: i と書くより abs(i) と書いた方が読みやすいのと同じ話じゃないかな。
0231184NGNG
**くらいでピーピー泣くなって
0232230NGNG
229 が、否定側も例を出してくれという話に読めたから書いたんだけど、
その反応がそれかい。
別に、読めないとは言ってないよ。
0233デフォルトの名無しさんNGNG
(*p)[n] で書けば済む話なのにわざわざ *(*p + n) とする理由が 231 なのかと
0234184NGNG
>>230で使っているのは漏れが出した例だ
わかりきった処理というが**を使っている場面では
*と**を使い分けるから下手な隠し方はない方がマシだと思う
0235184NGNG
>>233
逆だよ**に抵抗があるような足手まといに迎合して
わざわざ(*p)[n]と書きたくないと言っている
0236デフォルトの名無しさんNGNG
俺的には *(*p + n) つー表記の方が“態々”な感じだなぁ。
まぁ好きにしろや。
0237デフォルトの名無しさんNGNG
>>235
230 の最後の行もあんたが出した例か?

というか、184 が何故 [] や -> を 「わかりにくい」 としているの理由が分から
ないけど。
特に [] は、ポインタに対して配列的なアクセスをするという事を明示する。
*(p + n) も慣用句として覚えればそれほど見にくいわけではないけど、慣用句より
言語レベルの演算子である p[n] の方がずっと見やすいはずだという考えは間違いか?
0238デフォルトの名無しさんNGNG
> *と**を使い分けるから下手な隠し方はない方がマシだと思う

そんな事が必要な設計は間違っていると思う。
0239184NGNG
>>236
結局,主観って所でしか反論できなかったな

「C使いは**くらい使えろ」
これも主観で逃げとけや
0240236NGNG
>>239
反論してるように読めたか?
まぁ好きにしろや。
0241デフォルトの名無しさんNGNG
おまえらC#でもやっとけ
0242184NGNG
>>237よ,それは>>214で既出だ
だからabsが浮いたまでのこと

>>238よ,それは>231で既出だ(藁
0243184NGNG
>>236
すまん>>230と間違えたらしい,悪かった
0244デフォルトの名無しさんNGNG
>>242
> >>237よ,それは>>214で既出だ
[] や -> を使うとき、1重間接の * が隠れている事を意識する必要は無い。

> >>238よ,それは>231で既出だ(藁
238 が言いたい事が分かってないだろ。
と**を使い分ける、なんて事はすべきではない。
0245244NGNG
訂正。

> と**を使い分ける、なんて事はすべきではない。
*と**を使い分ける、なんて事はすべきではない。
0246デフォルトの名無しさんNGNG
もちつけ
     /\⌒ヽペタン
   /  /⌒)ノ ペタン
  ∧_∧ \ (( ∧_∧
 (; ´Д`))' ))(・∀・ ;)
 /  ⌒ノ ( ⌒ヽ⊂⌒ヽ
.(O   ノ ) ̄ ̄ ̄()__   )
 )_)_) (;;;;;;;;;;;;;;;;;;;)(_(
0247デフォルトの名無しさんNGNG
  ___   ガスッ
 |___ミ      ギビシッ
   .||  ヾ ミ 、      グシャッ
   ∩_∧/ヾヽ
   | ,| ゚∀゚). .|  |;,      ゲシッ
  / ⌒二⊃=|  |∵.
 .O   ノ %`ー‐'⊂⌒ヽ  ゴショッ
   ) ) ) )~ ̄ ̄()__   )
  ヽ,lヽ) (;;;;;;;;;;;;;;;;;)(_(
0248184NGNG
>>244
だからよ,配列とポインタは違うんだちゅーのに
なんでそんなに同じと思いたがるかよ
char(*p)[Q];とchar **p;が同じだと思いこむアフォを量産し
char s[1];にextern char *s;で参照に逝くアフォを量産する
ある意味必要悪を何でそんなに必死に擁護せにゃならんのだ
初心者時代から*をなるべく[]と書こうとしていたツケが
*は読みにくいって後遺症になって回ってきてるだけだろ
0249デフォルトの名無しさんNGNG
>>248
そんな事言われても、配列に対して *(p + n) というアクセスもできるんですが・・・。
0250184NGNG
疲れた
そろそろ落ちたいので
反論したい者は手短に頼む
0251デフォルトの名無しさんNGNG
>>184 の可読性の基準は自分が読みやすいかどうかなんですか?
0252デフォルトの名無しさんNGNG
> char(*p)[Q];とchar **p;が同じだと思いこむアフォを量産し
> char s[1];にextern char *s;で参照に逝くアフォを量産する

関係無い話を持ってくるなよ。
メモリ領域がどう確保されているかと、*(p + n) と p[n] のどちらが見やすいかは
全く別の話。
■ このスレッドは過去ログ倉庫に格納されています