1 :
デフォルトの名無しさん:
2 :
デフォルトの名無しさん:2012/10/17(水) 18:13:04.11
< `∀´> ニダー
/* NOTREACHED */
/* FALLTHROUGH */
lint厨か
え?lint 使える環境まだあるの?kwsk
BSD系
8 :
デフォルトの名無しさん:2012/10/18(木) 17:48:24.07
小学校の先生とプログラマってどっちがデスクワーク多い?
9 :
sage:2012/10/18(木) 17:53:55.34
みなさま、お知恵をお貸しください。
私は、関数電卓を作っている者です。
文字列を構文解析し、現れたワードごとに演算を行うという簡単なプログラムです。
私は、ある問題に直面しました。
sin(n*M_PI)が0にならないのです。(nは整数です)
DBL_EPSILONを使った切り捨ては試しました。
しかしながら、nが大きくなると再び誤差が表示されてしまいます。
例 sin(1000000*M_PI)=誤差
この誤差はgoogle電卓でも現れました。
驚いたことに、市販の関数鵜電卓では、いっさいこの誤差が現れません。
C言語で、市販の関数電卓のように誤差をなくすにはどうしたらよいでしょうか?
詳しい方ご教授お願いします。
|
|
|
|
/V\ ,J
/◎;;;,;,,,,ヽ
_ ム::::(;;゚Д゚)::| ジー
ヽツ.(ノ::::::::::.:::::.:..|)
ヾソ:::::::::::::::::.:ノ
` ー U'"U'
nが整数かどうかを
まず判定すりゃいいじゃん
12 :
デフォルトの名無しさん:2012/10/18(木) 18:30:11.58
SINの中にM_PIが入ってたら2M_PIでmodするようにすれば?
10年ぶりにunixCの開発に関わって、修正差分見ていたら
memcpy(wk, '\0', sizeof(wk));
なんて見つけたんだけど、なぜかコアは吐かないし同じ使い方してる本番アプリが他にもある
コンパイル調べたらなんか「NULL文字ポインタ」だとかで、
実験したら最大8192バイトまでヌルの配列が取れるようでカルチャーショックを受けました
でも書くならNULLだろ、'\0'は文字だろとか思ったけれど、俺はもう古い人間だってことでしょうか?
memcpy(wk, " ", sizeof(wk)); のほうはさすがに理解してないようですが
その市販関数電卓で sin(0.1)-sin(1000000*PI+0.1) を計算させてみてほしい
え?いいの?
18 :
sage:2012/10/18(木) 19:23:01.56
>>11さん
>>12さん
返信ありがとうございます。double型でmodが使えるんですね。初めて知りました。
if(fmod(SINの中身,M_PI)<DBL_EPSILON && fmod(SINの中身,M_PI)>-DBL_EPSILON){
return 0;
}else{
return sin(SINの中身);
}
てなかんじですかね?
>>14さん
返事ありがとうございます
3.3727E-9です
>>18 > 3.3727E-9です
つまり、整数*pi の時だけ特別扱いしてるってことだな
20 :
デフォルトの名無しさん:2012/10/18(木) 19:27:56.61
>>16 memcpyの第2引数が何であるべきか調べてから書け
21 :
sage:2012/10/18(木) 19:30:47.41
>>19さん
そのようです。
はずかしながら、私は整数の判別法が思いつきません。
キーを監視するしかないのでしょうか?
>>16 >>13が言いたいのはmemcpy( void *dest, const void *src, size_t count )の引数srcはポインタなのに'\0'=0=NULLポインタを渡して大丈夫なのかという事だと思うの。
memset( void *dest, int c, size_t count )の引数cならintだからナル文字だけど、memcpyの場合はぬるぽと解釈されているはずだからね。
よく見ずにレスしちゃったんだね。猛省だね。
>>20 memset() と思い込んでいた。
>>16 古いだけでまったくわかっていない人間だったのは俺だった。猛省する。
トークンが実数か整数かなんて文字列的にわかりそうなもんだけど
許してやるよ
>>24 変数だったらどうすんの?
sin(sin(pi/2)*2*pi)だったら?
>>13 まず、このコードでcoreを吐くかどうかは、OS, アーキテクチャによるが、
一般にはcoreを吐きうる不正なプログラム。
次に、'\0' は整数の 0 とまったく区別はなく、
ポインタやポインタ引数に代入されたら NULL と同じになる。
>>26 字句解析した時点で定数の型は分かるじゃん。
計算して求まる値は整数同士なら結果も整数とか決めておけばいいし、
変数は値を設定する時にどの型かわかるじゃん。
整数同士を足したら結果も整数、とか
ごめんやっぱ嘘でw
というか、指定した1文字(この場合'\0')で領域を初期化することに対して、
memsetではなくmemcpyを使用するメリットが分からない。
紛らわしいだけでしょ、絶対にレビューでつつかれるわ。
>>13の検証によると8192バイトの制限まであるらしいし。
処理速度でも違うのかね?
携帯から稚拙な文で失礼しました、一般には不正な文と見て良いようで安心しました。
このサイトでは問題なく動くのだから受け入れます。ポインタに'\0'を使うのは違和感ありますが、慣れます
たまたま0番地から8Kゼロなページがマップされてる環境なのでは
>>32 > 慣れます
慣れずに、こんな糞コード書くな、正解はこうじゃ、って修正してやる気概が必要
Oracle関係のらしく ccに-v /(忘れた)/
[email protected] 付けたら落ちない、付けないとコアです
makeの詳細は理解していないのでこれ以上は解らない、参照でポインタを0から回したら8192で落ちます
>>23みたいにmemsetとmemcpyをとりちがえて、たまたま動いて、そのままってケースかな
37 :
sage:2012/10/18(木) 21:39:03.29
みなさま
様々な回答ありがとうございます。
整数の判断について調べていたところ
floor()==ceil()の条件式を使うと良いことがわかりました。
if (floor(x/PI)==ceil(x/PI)) {
return 0;
}else{
return sin(x);
}
コードはこのようになります。
これで希望の動作ができるようになりました。
調べていて、「処理理系によってはうまく働かないことがある」
という記述を見つけたので、少し不安ではありますが
これで様子をみてみます。
マヌケな古いプログラムを救済するために0番地から8Kメモリが割り当てられてるだけだろ。
そんなのになれたら阿寒。
>>37 > 調べていて、「処理理系によってはうまく働かないことがある」
だろうな
C言語初心者にオススメの書籍を教えてください
typedef int (*iarr)[]; // (1)
typedef int (*iarr10)[10]; // (2)
int a[10];
iarr aa1 = &a; // error
iarr10 aa2 = &a; // ok
うーん?
(1)の型は何処で出てくるんだ?
43 :
40:2012/10/19(金) 07:52:13.75
>>43 それは古すぎるからやめとけ
つかそもそも本を買うなんてバカな真似はやめておきなさい
図書館で読んで自分に合ってそうなものを持ち帰って読む
重要なところは自分で書き写す
図書館に無ければ注文する
プログラムの勉強は自習するだけならこれで十分
たかが文字情報に金を払う必要は無い
あらゆる情報はすべての人にとって平等で無料かつ自由に扱えるもので有るべきだ
そんな労力使うくらいなら買った方が安上がりだなwww
時間の価値は人によって違うからな
本を買った方がいい人と、そうでない人がいる
お前らはわかってない
時間が大切だからこそ写しなんだよ
いつでもさっと検索してWebより密度の高い情報にアクセスできるという利益はなかなか代えが効くものではない
「あーあれなんだっけな調べよう…でも資料は家だ明日にまわすか」なんてことをしてるからお前らはゴミなんだ
それでもまだこの期に及んで書き写す手間が嫌だというなら機械にやらせれば良い
われわれはIT技術者なのだから物事を自分でやる必要は無い
たった一度の投資で図書館のすべての本が自分のものになるのだからやらない理由は無いぞ
>>50 時代にそぐわないと言ったんだが、君の理解力大丈夫か?
時代にそぐうお前に合ってたすばらしい本挙げてけよ
「窓から捨ててください」
「焼く捨ててください」
C言語初心者にK&Rはない
それしかない時代もあったんだから問題ない。
問題ないね
CってK&Rじゃ対応できないほど新しいこと増えた?
読み物として面白いのは
「C言語を256倍使う本」
今では不要となった技術がてんこ盛りだが
侍魂にも通じるフォントいじりがなされていて
読んでいてマのなんたるかを直接に面白おかしく知ることができる
東海道中膝栗毛なみの本だな
Cの初心者ならK&RとエキスパートCプログラミングあたりでいいだろう
コンピュータ自体の初心者なら、ハードルが少し高いかもしれないが
ans = 'C'<<8;
>>63 エキスパートCプログラミングは天才達の昔話が読み物としても面白いし、実用小ネタも多くていいよね。
変数や関数の宣言を読み解くフローは目から鱗だったわ。
66 :
デフォルトの名無しさん:2012/10/20(土) 12:21:50.63
目から鱗だったね
桜庭ななみ
>>65 >変数や関数の宣言を読み解くフロー
K&R2 にのっているネタでは?
うん、載ってるよ
結論:K&R2 でほぼ十分
反例:K&R2の線形リストは糞実装
自分で嫁馬鹿野郎
>>71 そいつはこの板に粘着している技術力0のクズで、そいつのレスには1oの
信ぴょう性もないからかまってはいけない。
talloc使ってたやつか?
桜庭ななみ
77 :
デフォルトの名無しさん:2012/10/20(土) 20:45:40.93
桜バナナ実
>>71 線形リストもしらずに「K&R2の線形リストは糞実装」といってるクズだってわかっただろ。
相手にするだけ時間の無駄。
>>9 バイナリツリーに言及している時点で線形リストは既知と判断するのが普通なのですけれども
K&R2 のその部分が初心者向けで終わっているとのはまぎれもない事実
読んだことないの?
うん、ないよ
で、その「クソな実装の線形リスト」はK&Rのどこに載ってるんだ?
カンカンカンカンカン、終了〜
84 :
デフォルトの名無しさん:2012/10/20(土) 23:49:41.92
そこの処理には絶対行かないのに
そこ(whileとかforやブロックの中身)変更すると実行結果が変わる時ってありますか?
printfチェックで
絶対そこの部分には行かないのに
変更すると実行結果が変わってしまいます。
それはメモリ破壊してます
検査してみて
絶対行かないとかホザいてるアホは
さっさとその臭いソースを出せよ
お前のタコなソースなんて
オレ様がみりゃー
一発だよ
>>84 >>86 と同意見です。この手のバグとりは結構難解で、printf() デバッグではどうしようもなく、デバッガ出動に踏み切らざるを得ないと思います。
もしよろしければソースをみせていただけると何かヒントを提案できるかもしれません。
>>82 K&R2 6.5、手元の和訳ではp171とか。
おっとよくみると線形リストじゃなかったね。記憶が混同していました。
ともあれ、ここで終わっているのは非常に惜しい
またQZの敗北かw
負け惜しみが笑えるww惜しいのはお前だよwwww
線形リストを知らずに「K&R2の線形リストは糞実装」といってたクズ。
かまわない方がいいって証明できただろ。
>>71
秘密だよ
>>88 手元の原書だと
6.5 Self-referential Structures (P.139)
(ツリーを使って単語の出現数を出力するプログラム)
だけど合ってる?
何がクソなのか分からない
>>92 void addtree(struct tnode **p, char *w) {
if (p == NULL) {
...
} else if ( ... ) { ... } else if (cond < 0)
addtree(&((*p)->left), w);
else
addtree(&((*p)->right), w);
}
あるいは
struct tnode *root;
addtree(&root,word);
まで踏み込みたかった。
root = addtree(root, word)
は実にムダにみえないか?
見える見えないじゃねーんだよ
whyを書けよアホ
自分の能力が低いから「みる」とかアバウトでアホでクズな単語使ってんだろ
そういうやつはお願いだからこのスレに書き込むなよテイノウ
>>93 >>94 まあまあ、せっかくだから比較してみよう、ちょっと書いてみるわ
ビット演算が8進数wwwww
クズは他人のものにケチつけるより、自分のコードからムダを省くよう努力しろよw
98 :
92:2012/10/21(日) 14:48:16.83
>>98 そうそう。
慣れてくると、メンバ変数のポインタを渡すほうがわかりやすかったりする。
>分からんでもないけど、K&Rのコードのシンプルさ(分かりやすさ)の方が
>入門書には合ってると思う。
入門書としては確かにそうだと思う。誰しも最初はこれからスタートする。
K&R は入門書だが、無理やりK&R を批評したかっただけかもしれませんね。
http://toro.2ch.net/test/read.cgi/tech/1313183984/403 に比較を書いてみました、基本書かないと理解できない体質です。
>>94 why そのものが書いてあるのにわからない?
みえる、という単語に反応し過ぎてみえなくなったのね
>>97 今後とも精進して参ります
>>100 コテつけろよ。
returnするほうが明らかにわかりやすい。
バイナリーツリーを必死こいて実装するようなやつが慣れとかw
ふっふっ
へっへっ
>>100 テメーがヘボなのを言語(Java)の所為にしないように。ゴミクズにレクチャーするのは無駄だからしないが。
ああ、バカにレクチャーするのは完璧なる無駄だから、出来ねーな。
ああ、バカにレクチャーするのは完璧なる無駄だから、出来ねーな。
思ったんだけど関数から関数を呼び出せたりするというC言語の機能が
プログラムを分かりにくい状況にしているんじゃないですかね?
メモリ上では関数から関数を呼び出した時呼び出し側のデータがスタックに保持されて
帰ってきた時データをそのまま使えるけど構造は非常に複雑ですよね。
関数から関数を呼び出せなかったら困るのでは
それはC言語に固有の機能ではない。
それでプログラムがわかりにくい状況になってると感じるなら、
プログラミングという思考作業に対して、キミの知能が足りないだけ。
プログラムの構造が理解できなくなる
お前がゴミだから仕方ない
ならメイン関数のみで1万行を超えるプログラムを書いてみろよ
たやすいことさ
goto main01_005_08;
main01_005_08_ret:
goto main01_005_09;
main01_005_09_ret1:
関数が
とか仰っている御仁は
関数型プログラミングとかは
ましてやラムダなんとかやらは
絶対に理解できそうもないな
C言語の関数とそのての関数は違うべさ
ローカル変数をスタックに置いてるから複雑になってるという主張かな。
デバッガ作る人にとっては複雑かもなあ。
アセンブリレベルで動作追うときにフレームポインタの間接参照見るのは面倒。
でも、この程度であって関数が基本リエントラントである恩恵の方がはるかに大きい。
entry
int main(){
int a00000000001;
int a00000000002;
int axxxxxxxxxxx;
return(0)
}
いまどき関数の無い言語ってバッチファイルぐらいでしょ
なんで関数の無い方がいいと思ったのやら
>>124 2段落目から推測すると「関数から関数を呼び出す」は再帰呼び出しを
意味していると思われる。
>>120が書かれた後で理解できてないお前も大して変わらない低レベル。
再帰できなかったらスタックをよういせにゃならんのでしょ、そっちのほうが複雑じゃん
末尾再帰
末尾再帰じゃないものを末尾再帰に変形するのもまた複雑
あたえられたコード読むのと
やりたいことを考えた時に思い浮かんだやり方
思考が違うからなー
>>124 バッチファイルもcall :label出来るし。黙ってた方が良かったね。
ふっふっ
へっへっ
133 :
デフォルトの名無しさん:2012/10/23(火) 20:24:39.78
お互い呼び合うとか構造理解できないでしょ。
int happy()
{
yes();happy();
}
int yes()
{
happy();
}
こうなったらスパゲティ以外の何者でもないでしょ...
図を書こうと思っても同じ関数のブロック何回も出てきて訳がわからなくなる
そりゃ階乗計算の再帰みたいに単純なのだといいけど....
134 :
デフォルトの名無しさん:2012/10/23(火) 20:32:52.36
詩ね
そんなんあるか?
コールバック関数
min-max法とか再帰で書くとこうなるよね
>>133 それはキミの知能がゾウリムシくらいしかないという証明。
139 :
デフォルトの名無しさん:2012/10/23(火) 20:50:52.23
>>136 コールバックってjavaじゃなかったっけ?
オイ
マジモンの無能がいるぞww
141 :
デフォルトの名無しさん:2012/10/23(火) 21:01:56.88
お互い呼び出すとか異次元スパゲティだわな
構文解析なんかは 式、項、因子の3つを相互再帰するが。。。
入門じゃ重い部類かもしれぬ
再帰下降パーサとか習ったことない土方か。土方はphpでも使って炉。
ふっほっ
>>128 できないのもあるしね二方向以上の再帰とかね
>>142 因子を処理中括弧の中は式に丸投げは再帰を使わないで書けとか罰ゲームとしか
そりゃ一番難しいところがプログラミングの初期に全部掘り起こされて
言語としてはドンドンあほになって行ってるじゃん
へっほっ
ここってP2Pチャットのプログラムに関する質問も受け付けてる?
一応1カ月でスパルタされたポインタも怪しいにわかなんだが
とりあえず投げてみるのも一興
エィ
153 :
デフォルトの名無しさん:2012/10/24(水) 10:57:51.15
やー
一ヶ月でポインタも怪しいって、教える方がよっぽど馬鹿じゃなきゃ見込みないから諦めるべきだな。
さらばポインタ厨
Cの経験1か月でポインタはスパルタ受けたという意味だろう。
ポインタ理解するのに1か月もかかる池沼が世の中に存在するはずがない。
長くとも30分で理解出来ないとこの業界にいるのはキツイね
キツイね
30分では無理だ
何年経験してても、ポインタ関連のデバッグは、たいへん
恐れず侮らず
ふぅ
デバッグは大変、ならわかるが
みなさま教えてください
double型の数値の小数点以下の桁数を求めるにはどうしたらよいでしょう
>>162 2進数でよければ仮数部を指数部でシフトして
もっとも右にある1を探す感じで出来る
>>166 10進数もそれと同じ桁数になるんじゃね?
0.1(2) → 0.5(10)
0.01(2) → 0.25(10)
0.001(2) → 0.125(10)
0.0001(2) → 0.0625(10)
>>167 そもそも精度の関係で例えば0.7のときに巧くいかない。
え、doubleから(おそらく10進数での)小数点下桁数を求めよってお題でしょ
0.7とかdoubleで表現できない数値を扱う必要あんの?
0.7の近似値の桁数になるだけ。問題なく求められる。
171 :
150:2012/10/24(水) 20:34:59.41
P2P式の複数人用のチャットアプリなんだが、P2Pの概念がよくわからん
OSはUNIX
TCP通信マルチスレッドでC/S型の複数人チャットのソースは組めた
ここからP2P型に改造する予定だが、サーバのソースにクライアント部分の接続〜送信を加えたらP2P?
同じプログラムで通信するのがP2Pって思ってるんだけど、違う?
172 :
150:2012/10/24(水) 20:39:59.41
同じプログラムじゃねえ、ダイレクトに相手IPアドレスでアクセスしてるし、これでP2Pなのかなって
>>171 > サーバのソースにクライアント部分の接続〜送信を加え
ここ意味わからん
ただ、
> 同じプログラムで通信するのがP2Pって思ってる
そんな定義はない。
(多数の)ピア同士が何か特定のホスト(サーバ)を
経由せずに通信できればP2Pだろ。
問題は、相手をIPアドレスやホスト名で指定せずに
済ませる方法がないと実用にならないし、
NAT越えも必要になる。
174 :
150:2012/10/24(水) 21:00:50.90
>>173 >同じプログラム〜
ここは忘れてください、とち狂ってました
>サーバの〜
親スレでconnect〜send
子スレでソケットをbind→listen→acceptの無限ループ
孫スレでrecv→printfで接続元が切断するまでループ
これで説明になってるんだろうか
175 :
150:2012/10/24(水) 21:57:49.55
なんか支離滅裂になってるorz
多分自己解決しました
connectする時にNAT越えして相手のIPアドレス指定出来ればいいのかな…
さあ
C言語の質問はいつ出てくるんだ?
明日
明後日
明後後日
――そして一年が過ぎた
WindowsプログラムでPC(レジスタ)を直接書き換えることってできるんでしょうか?
あと、以下のように自由にアクセスってできるんでしょうか?
a = ((char*)0)[10];
((char*)0)[31] = 0xFF;
それはC言語の範囲ではないので適したスレで聞いてください
プリンタへの出力でわからないことがあるので教えて下さい
イベントが発生したら、指定したwordファイルを自動で印刷するようにしたいのですが
int StartDoc(
HDC hdc, // デバイスコンテキストのハンドル
CONST DOCINFO *lpdi // ファイル名を指定する
);
この場合lpdiにどのような値を入れたらいいですか?
>>184 MSDNを自分で読めよ。それでもわからなかったら教えてやる。
読んだけどわかりませんでした!!
すみません
charの例えば56と、fdをくっつけて、2バイトの変数に56fdとして代入したいんですが、どうやるのが最善でしょうか?
2バイトの変数を用意して、1バイトめを代入して、8ビットシフトし、2バイト目と0xFFのビット積をとって加えると出来るんですがまだるっこしい感じがします
>>191 uint8_t bar = 0x56;
uint8_t baz = 0xfd;
uint16_t foo = bar << 8 | baz;
ってこと? 何が不満なんだ?
不満点を上げるとすればまだるっこしいのあたり。
>>192 うーんまぁ、そんなもんですかね
foo = unite(bar, baz);
みたいな感じでサクッと結合出来ないかなーと思ったんですが
#define unite(x, y) ((uint8_t)(x) << 8 | (uint8_t)(y))
ふっほっ
共用体でやったことある
>>198 共用体だとビッグエンディアン、リトルエンディアンを気にする必要があるね。
200
きのこは素人には判別不可能
203 :
デフォルトの名無しさん:2012/10/25(木) 22:14:14.74
お、お、おれのワライタケを判別してもらおうか
(笑)
www
プゲラ
いつからエノキダケがワライダケという名前になったんだよ
ここだけの話、野生のきのこはまだ放射能があぶないらしい
一応、基準以上は出荷停止してるんじゃないのか?
このスレも基準以下のは出荷停止の書き込み禁止にしてほしいな
放射能よりも害悪だ
キノコはやばいよ
出荷基準は実質無意味だよ
自分で興味もって調べないと死ぬよ
「野生のきのこ」だよ、出荷されてるかどうかはしらね
さすがに関東〜東北で野生のきのこ食う奴なんていないだろ
70歳以上くらいならただちに影響ないだろうけど
露地栽培だって同じようなもん、それを出荷しようと企むテロリストがいるから困る。
C言語と関係ない話はやめろ
ほっほっ
茸の話してるところすみませんがC言語の方でお願いします。
2〜1000の中から素数を出力するプログラム
http://codepad.org/7ab7zj65 のi%jの計算回数を出来る限り減らせという課題ですが、色々やってこうなりました。
http://codepad.org/4ubNQTvg 計算回数自体は減りましたが、9とか15とか合成数も出力されるようになってしまいました。
プログラムを変えてみた時の変化や高専編入者からのアドバイスが入っていますが、パラメータで制御するならどのようにすればよいでしょうか?
計算回数は経験者を見ている感じでは1500〜2200辺りになりそうですが、計算回数を減らす方法も何かいいものはありますか?
自分でMOD実装すれば組み込みの剰余は0回で済むよ
これが正解ね
if(j > (int)sqrt(i))
この方式で剰余をさらに減らそうというなら、
候補の i = 3 5 7 9 11 13 15 ...
のうち、3回に1回は調べなくてもいいよね、とか。
で、それを押しすすめると、エラトステネスになって、
自分で実装しなくても剰余が不要になる。
>>216 素数の整数倍にチェック付けて
チェックされてないヤツだけ余り調べる
225 :
デフォルトの名無しさん:2012/10/26(金) 07:03:14.25
合成数は必ず平方根以下に約数があるってのはすぐわかることだと思うんだが
律儀に元の数字まで相手してる奴よくいるみたいだな
小さい方から調べていって2 3 5 7 11 13 17 19 ....と見つかっていくわけだが
jはそれまでに見つけた素数だけを入れれば無駄はなくせる
偶数は最初から無視するとして
3 5 7は決め打ちでいいな
9-23 (8個)なら3 -> 8
25-47 (12個)なら3 5 -> 24
49-119 (36個)なら3 5 7 -> 108
121-167 (24個)なら3 5 7 11 -> 96
169-287 (60個)なら3 5 7 11 13 -> 300
289-359 (36個)なら3 5 7 11 13 17 -> 216
361-527 (84個)なら3 5 7 11 13 17 19 -> 588
529-839 (156個)なら3 5 7 11 13 17 19 23 -> 1248
841-959 (60個)なら3 5 7 11 13 17 19 23 29 -> 540
961-1367 (1000までで20個)なら3 5 7 11 13 17 19 23 29 31 -> 200
でそれぞれ割り切れるものがあるかどうかを調べればいい
↑で9以上で3328になるな
前j-1回分のうちに割り切れたjを除外すれば多分どーんと減る
たとえば99の処理が3で終わるので101, 103では3を除外
日々の雑務を自動化する為に
中小規模のアプリをさっと作るのに最適な言語を探してるんだが何がイイかな
欲しい条件は
・GUIの扱いが楽
・文字列の扱いが楽
・XMLパーサーなど便利なライブラリが充実してる事
・書きやすく読みやすく保守がしやすい事
・Win Linux Macの最新か一世代前のOSで安定する事
なんやけどどうでっしゃろ?
228 :
216:2012/10/26(金) 08:33:16.91
>>217-225 皆さんレスありがとうございます。
修正が少なくて%の演算回数が一番少ないのは
>>218ですね。
エラトステネスなどはアルゴリズムに入るのか?ということで学科内では避けられています。
>>221>>225 素数の整数倍ですか、見た感じ一番効率よさそうですね。組んでみます。
>エラトステネスなどはアルゴリズムに入るのか?ということで学科内では避けられています。
アルゴリズムじゃなきゃなんなんだよw
その方法がアルゴリズムかどうか、
そこから議論してるのか?
ヤヴァイ集団だぞそれ
おまいらはアルゴリズムとそうでないものの区別がつかないような集団で、
そしてあなたはその一員か?
アルゴリズムの定義ってなんだよ
素数とかそういう段階じゃネーゾソレ
ましてやプログラミングの早さを競う段階でもない
もっと根本的なことから勉強し直さないといけないような集団だろ
マジでヤバイものの一端を見た
教育や学生の頭脳が劣化してる、
そして何よりも、アルゴリズムか否かを多数決で決めてるフシがある
それが一番危険だ、
自分のアタマで判定してない
好意的に解釈すれば、この課題で認められた範疇かどうかってことじゃね?
しかしそんなもん、出題者に聞けば一発なのに。
人類の知能低下は物理的な必然なんだよ
核実験時代の汚染が人々の遺伝子と脳を破壊し白痴が大量生産された
放射能汚染度の高い韓国の国民性をみればその恐ろしさが分かるだろう
Fukushimaによってばら撒かれた超汚染によって世界は韓国と同じレベルに収束する事もはやが約束されているのだ
アルゴリズム学ばないCマも多数活躍しています。
>>226 C のスレで質問するのもどうかと思うが
C 経験者にもおすすめなのは python
>>226 C言語スレで他の言語を探してどうするよw
236 :
デフォルトの名無しさん:2012/10/26(金) 11:03:39.51
C言語と関係ない話はやめろ
>>230 論点が不明なのにそのように言い切ってしまうお前の知能の方が10000倍ヤバい。
>>237 どんな論点で話し合った結果だったんだ?
>>238 さあ? 傍観者のオレにはわからないが、「こういう理由で(オレらの定義の)アルゴリズム
じゃない」という説明がなされた途端に
>>230の頭の悪さがはっきりとする。
ぼくが2ちゃんでまなんだこと
・馬鹿はどこにでも居る
・馬鹿は伝染る
・ある馬鹿が居なくなっても必ず別の馬鹿がどこかから現れる
伝染るというか最初から最後まで一人じゃない?
・他人から見ると自分も馬鹿
卒業したら戦闘機に乗りたいと言う奴にまずバイク免許取れと言うような感じ
244 :
デフォルトの名無しさん:2012/10/26(金) 19:31:17.31
卒業したらメジャーに行きたいと言う奴にまず日本のプロ野球に入れと言うような感じ
桜庭ななみ
246 :
デフォルトの名無しさん:2012/10/26(金) 19:54:47.19
先週のプレイボ〜イのななみちゃんはエロくて良かった
247 :
デフォルトの名無しさん:2012/10/26(金) 19:58:39.37
エロいの最高!
買いそびれた
もう売ってなかった
だれか持ってない?
女優板で聞いてみたら?
for ( i = 0; i < 9; i++ )
fprintf(fp, "%2.2s\n", "123456789" + i*2 );
こんな感じで全角数字を順に1文字ずつ表示するプログラムがあったのですが理屈がよくわかりません。
%2.2sの意味と、文字列同士の加算のように後ろに数字がくっつく結果にならない理由辺りを中心に解説お願い致します。
いやらしいやり方だな
"123456" + i
の半角でまず試せ
次は
"123456"[5]
とかで一文字ずつ出力しろ
そのシステムで全角数字は2バイトで表現されている。
"123456789"
は先頭から0バイト目が1, 2バイト目が2... と配置されている。
"123456789" + i*2
はiの値に応じて文字列"123456789"の先頭から
0バイト, 2バイト... のアドレスになる。
%2.2s は指定されたアドレスから2文字(2バイト)出力する。
いえいえ
こういうのを書いて試すようになると色々解って楽しくなるからオススメ。 10年以上やってても色々実験する
char wk[11] = "1234567890";
fflush(stdout);fprintf(stdout, "s =[%s]\n",wk);
fflush(stdout);fprintf(stdout, "As =[%5s][%15s]\n",wk);
fflush(stdout);fprintf(stdout, "-As =[%-5s][%-15s]\n",wk);
fflush(stdout);fprintf(stdout, ".As =[%.5s][%.15s]\n",wk);
fflush(stdout);fprintf(stdout, "A.Bs =[%5.7s][%15.17s]\n",wk);
fflush(stdout);fprintf(stdout, "B.As =[%7.5s][%17.15s]\n",wk);
256 :
デフォルトの名無しさん:2012/10/27(土) 10:01:36.54
10年もやっててそんなミスするのかよ
動作だけで判断すると後で後悔する
仕様を読んだうえで想定通り動くかの確認にすべき
動作させることで仕様の理解が深まることがある。
動作させられるなら、先に動作させてから仕様を確認したほうが効率的な場合が多い。
仕様書の文章が理解しやすい文章で書いているとは限らない。
printfのフォーマットの仕様くらい、読んで理解できない池沼は向いていない。
バグも含めて仕様です。(キリッ
仕様ですね
うん(キリッ
>>255 このコードを保存しとけばいいのに。
毎回こんなことやるのかw
どこかでみたぞ
えっ
>>258 その通り
俺も若かりし頃に、言語仕様では「正常ならTRUE」を信じてコーディングして
しばらくハマったことがある
ここら辺で学ぶんだよな、実装ではどうなってるか確認する必要があると
あと、条件式は合致するケースの少ないものを書いた方がいいとも
※true : 0以外、false : 0
例えば、仕様書に
「
>>258 その通り」
のみ書いてあったとする。
だが実際の動作は
「俺も若かりし頃に、言語仕様では「正常ならTRUE」を信じてコーディングして
しばらくハマったことがある
ここら辺で学ぶんだよな、実装ではどうなってるか確認する必要があると
あと、条件式は合致するケースの少ないものを書いた方がいいとも」
で、仕様書とは真逆だったりする。
文章なんてそんなもの。
>>269 引用するならまともな引用でたのむよ
俺のと君のが混ざっとる
通常、引用は引用符でくくられている。
言語仕様じゃなくて、誰かの作った関数の仕様に誤記があっただけじゃないの?
つまり、関数設計者は誤記するが、言語設計者は誤記しないと。
いや、誤記というよりも、何を書いているのか曖昧な仕様書なら動作確認したほうが内容の理解が早いって話
ok by japanese.
>>272 ちゃう、例えばVC++6ではTRUEを1って#defineできってたから、if文で
if(hogehoge(...) == TRUE)
などと書くと、hogehoge関数の戻り値が2,3辺りが返ってきてもelseに
なるんだわ
これ、実際の標準ライブラリで起きた話ね
>>277 それは TRUE なんか使うからだ
あるいは if(exp == 1) なんかやるからだ
仕様以前に文化を理解していないという問題かと
isalpha()とかみっちり使ったことがあれば回避できる問題、ライブラリの問題じゃない、C はそこまで親切じゃない
int *pって書くとint型のポインタって奴になるですよね
データ本体(インスタンス)を指し示す変数自体は、どの型も同じ何で間違っていませんか?
*pにHoge型のポインタをセットした時、Hoge型ではなくint型で参照しに行くとおもいます。
つまり、int *pって書いた時の「int」はインスタンスを参照しに行く時に、どのデータ型で参照するかをコンパイラに教えているためだけに書いてある
けれども、実際には型がHogeなので落ちる
間違えてないでしょうか
別に落ちないけど。
ポインタの型による違いは、pに対して加減算を行なった時の値が違うだけ。
p+1がp+sizeof(int)になるかp+sizeof(Hoge)になるかの違い。
>>280 java の経験があるのかな?
だいたいあってる、
けれども落ちるとはかぎらない、だまって int のつもりでさっさと動いてしまうことも
>どのデータ型で参照するかをコンパイラに教えているためだけに書いてある
あってる
>実際には型がHogeなので落ちる
コンパイラが警告やエラーはだしてくれるだろうけど、動作時に落ちるかどうかは時と場合による
大抵は無理やり読み込んだ意図しない値で進んでしまいそうな気がする
>>281-283 回答頂きありがとうございます
落ちるか落ちないかは時と場合によるんですね
.net系の職業PGですorz
C<--->.netの連携がさっぱりわからなくて、Cを勉強しようかなと
参考書の質問ってここで大丈夫ですか?
はい。C言語なら。
287 :
285:2012/10/28(日) 23:52:50.27
どうも。それなら
学科の授業では教科書にK&R2 日本語訳が指定されてるんですが、各所レビューなど見ても分かる通り、仕様書としては良くても入門書としてはどうかなと思っています。
授業ではそれも踏まえて「くどく説明します」と言ってるのに、実際はどこかで詰まると置いてかれる授業です。
そんな訳で何か別に入門書が欲しいと思うんですが、皆さんはどの本から入りましたか?
因みに、友人が他学科の教科書になってる柴田望洋先生の本を貰ってて、いいと言ってました。
あと、授業で配られたこのプリントの出典が分かる人は教えてください。
http://www.imgur.com/ysf9V.jpg
>>278 >>269 俺は
>>268と
>>277なんだが、始めに「若かりし頃」と書いてるように相当昔の話だよ、書いた件は
あとライブラリが悪いとも書いてない、どちらかというと実装と言語仕様の違いについて、こんな
ことあったよという話
>>288 要するに、TRUEという名前の定数があることを知ってたから
「真を返す」を書いてあった文章をTRUE値を返すと勘違いしたってだけだろ
TRUEを返すと書いてあって2とか3が返ったのならともかく、「真を返す」等の
記述だったなら勘違いしたお前が悪い
BOOLは後付けで決まった仕様だからね
えっ
>>288 いいたいことはわかる。
しかし、真偽と非零/零が対応することはいにしえのN-BASICからのやりかたであるし文化の問題であることは否めない。
まあ、今はうまくやっているんだろう?
>>293 ん?C言語ってN-BASICより新しい言語だっけ?
C言語に慣習はよく聞くけど文化なんて聞いたことがない。
>>288 どの言語仕様に「正常ならTRUE」と書いてあったんだ。そんなのがあるなら有害図書として殲滅しておけ。次世代につなぐな。
(アルツハイマーの症状が悪化しただけで、存在しないんだろうけど。)
N-BASICは、
0:真
-1:偽
だったと思う。
一方、Cは、
非0:真
0:偽
なのに、main() の戻り値は
0:成功
非0:失敗
を期待してるっぽいのが訳判らんくて混乱したな。
エラーコード
0:成功 非0:エラー、その値によりどういうエラーかの詳細も
真偽値
非0:真 0:偽
>>296 そんなに必死でウソを書く、お前の原動力はいったい何なのだ?
>>296 >N-BASICは、
> 0:真
> -1:偽
>だったと思う。
ぎゃくだ。0:が偽、非0 が真だ。
10 print 1==1
を実行すると
-1
の結果を得る
>>299 BASIC の一致比較は == でなくて = だと思うの
char* str = "1234567890";
この str の文字数を求めたいのですがうまくいきません。
【試した方法その1】
int length = strlen(str);
【試した方法その2】
int length;
for( length = 0; str[length] != '\0'; ++length ){
}
【結果】
いずれの方法でも length には 1 が代入されてしまいます。
>>302 原因はlengthを使う場所にありました…
素早い回答をありがとうございました。おかげさまですぐに解決しました
DOSのファンクションコールの戻り値は基本
負数:エラー
0以上の正数:正常処理
だっけ?
305 :
デフォルトの名無しさん:2012/10/29(月) 19:01:13.61
Javaの参考書とCの参考書のページ数比べたら圧倒的にJavaの方が
多いし1冊じゃ足りないよね
int i;
int *ip;
i = 5;
ip = &i;
printf("%p, %d\n",&i, i);
printf("%p, %d\n",ip, *ip);
とやったら、ポインタ変数ipのアドレス番地も変数iのアドレス番地も同じになりました。
ポインタ変数ipは具体的にどこかにアドレスがふられて変数として領域が確保される
のではないのですか?
>>306 ipのアドレスは&ipでしょ。
ipが指すアドレスは&iだけど。
「アドレスがふられて変数として領域が確保される 」
なんとなく違和感が ...
違和感を感じる
感じるね
感じないけど
いえいえ
ポインタの大小比較は、
p > q
でできるのですか?
>の記号で正当に定義されていますか?
それともlongとかintとかにみなされて比較されるのですか(それはまずいとおもう)
ただの32ビットのデータ
それはマズイな
ポインタは64bit
少なくとも、同じ配列内を指すポインタの大小比較はちゃんと出来るはず。
出来るはずだね
同じ配列内でポインタの大小比較は、禁止されていないわけですね
まあね
>>314 どういう比較をして欲しいのかがわからん。
ポインタはアドレスなんだから32ビットの数値として比較されて当然。
大きくなると負数判定されるかもとか気にしてるの?
Cの規格としては、32ビットとかぎらないでしょ
hugeポインタを検索したら、16ビットの時代の話がでてくる
でてくるの?
325 :
デフォルトの名無しさん:2012/10/29(月) 22:39:41.88
hageポインタ
>>325 使えないとのうわさがちらほら、far を自分で管理するのが吉
>>320 末端+1までが合法だったっけ?
int foo[10];
int *p = foo + 9; /* 実体のある最後尾
int *q = foo + 10;
328 :
デフォルトの名無しさん:2012/10/29(月) 23:04:07.33
foo < foo + 11 まで保証
d
少なくとも 0〜確保数+1 までは大小関係の維持が保障されてるのか
宣言したサイズのアドレス外の値を参照するなら問題だけど、ポインタの比較なら確保数とか関係ないでしょ。
p < p + nは、nが幾らだろうと(正の整数でね)保障されるんでないの?数値演算の結果でしかないんだから。
#include <stdio.h>
int main(){
int a[10];
int *p;
for(int i=0; i<15; i++){
if(!(i>= 3 && i<=8)){ // 途中は表示省略
p=a+i;
printf("p=a+%d : p = %p, p-a = %d, (int)p-(int)a = %d, a < p = %d\n", i, p, p-a, (int)p-(int)a, a < p);
}
}
return 0;
}
---実行結果---
p=a+0 : p = 0012FF4C, p-a = 0, (int)p-(int)a = 0, a < p = 0
p=a+1 : p = 0012FF50, p-a = 1, (int)p-(int)a = 4, a < p = 1
p=a+2 : p = 0012FF54, p-a = 2, (int)p-(int)a = 8, a < p = 1
p=a+9 : p = 0012FF70, p-a = 9, (int)p-(int)a = 36, a < p = 1
p=a+10 : p = 0012FF74, p-a = 10, (int)p-(int)a = 40, a < p = 1
p=a+11 : p = 0012FF78, p-a = 11, (int)p-(int)a = 44, a < p = 1
p=a+12 : p = 0012FF7C, p-a = 12, (int)p-(int)a = 48, a < p = 1
p=a+13 : p = 0012FF80, p-a = 13, (int)p-(int)a = 52, a < p = 1
p=a+14 : p = 0012FF84, p-a = 14, (int)p-(int)a = 56, a < p = 1
当然の結果になる。"大小関係"っていう認識が違ってるのだろうか?
確保数+1 まではオーバーフローしない位置に配置してポインタとする ってことでしょ
変態的なアーキテクチャでも一定の範囲では大小比較を保証するよ、みたいな意味かと思った。
変態的なのが実際にあるのかは知らないけど。
4kページングとかで struct a{char a[4096-(管理情報領域)];};をmallocしたときにfault出さないようコンパイラ側に2ページ確保する責任がある
てことでしょ
アクセスは保証する必要がないから、確保しなくてもいいんじゃないの?
335 :
デフォルトの名無しさん:2012/10/30(火) 10:23:06.39
struct Hage {
int size;
char hoge[0]; (または char hoge[1];)
};
struct Hage *hage = (struct Hage *)malloc(sizeof(struct Hage) + size);
hage->size = size;
で hage->hoge[n] (0 <= n < 1) じゃなくて (0 <= n < size)
ってアクセスすることがあるから >327-329 はおかしい
>>335 mallocで思いっきり確保してるじゃん。
おまいらがいつもよくやってる
他人の心に土足で踏み込むっていう意味じゃないかな
合意がないのに女子中学生にチンコ入れるお前のことだろ
入れる気満々で先っぽだけって言ってるようなもんだからな。
343 :
デフォルトの名無しさん:2012/10/30(火) 20:26:55.00
AVL木の回転の操作方法が全然分からん
Cやっぱ難しいな............
そりゃお前の頭が悪いだけだ
Cは全く関係ない
346 :
デフォルトの名無しさん:2012/10/30(火) 20:50:14.91
>>344 生まれつき頭悪いのは自分でも承知です
A[10]を例にして教えてくれませんか?
A[0]=1..........A[9]=10
どこがAVL木?
>>339 だから undefined behavior なんだって
鼻から悪魔
Cで悪魔召喚プログラムの書き方を教えてください
350 :
桃白白:2012/10/30(火) 22:25:55.61
>>346 こんばんは桃白白です。
教えてやろうか? 教えてあげるよ? 聞きたいでしょ? 桃白白ひまだから教えてあげてもいいよ?
どうする? 教えてほしいでしょ? じゃあ教えちゃう。A[10]の意味がわからないのでそれは無視するけど。
AVL木の回転操作には一重回転と二重回転がある。
これが右方向への一重回転
http://uploda.cc/img/img508fcfd7ebf3e.png 回転後にトップノードとなるノード、この場合はBを変数にコピーして
Aの左にBの右の子を付けてやっちゃうわけ。そしてBの右の子にAをつけちゃえば回転完了。
これが右方向への二重回転
http://uploda.cc/img/img508fd26919772.png まず子のノード(B)で一重回転を行って、そのあと親のノード(A)で一重回転を行う。
子のノードで回転後にトップノードとなるのはEなのでEを変数にコピーして
一重回転の要領で付け替える。Eは親のノードで一重回転したときにもトップノードとなる
ノードだったりしちゃうわけ。もういちどこんどは親のノードのところで一重回転の要領で
ノードを付け替えちゃったら回転完了。
プログラムはこんな感じ。
http://ideone.com/yAWgFX 一重回転のコードが4行、二重回転のコードが6行、簡単っしょ。
351 :
デフォルトの名無しさん:2012/10/30(火) 22:33:53.64
>>350 ありがとう
要素の入れ替わりが激しくて
どこで回転してるのか分からない
何が回転なのかわからない.................................
ちなみに配列は単に木を保存してるだけです。
352 :
桃白白:2012/10/30(火) 22:55:21.30
>>351 わからないわけないだろ、B、Dが右上に上がってA、Cが右下に下がってるだろ。
完全に回転してるだろ、これこそが回転だろ、まごうことなき回転だろ、これが回転なんだよ。
353 :
デフォルトの名無しさん:2012/10/30(火) 23:00:06.50
魔界の転送屋と悪魔召喚の契約をした後、魔界銀行のある口座に代金を振り込む。すると転送サービスを通じて人間界に悪魔が転送される。
354 :
デフォルトの名無しさん:2012/10/30(火) 23:02:07.40
>>352 3が1から離れてるのとかアクロバティックすぎてよく分からん
割と本気で困ってる
355 :
桃白白:2012/10/30(火) 23:20:48.39
>>354 わからないわけないだろ、なにがアクロバティックだ、あまりふざけたことぬかしてっと桃白白は
ドドンパを行使することも視野に入れる覚悟だ。AVL木は平衡二分探索木。
平衡二分探索木は左右の平衡を保つ二分探索木。二分探索木は、左の子が親の子より
小さくて右の子が親の子より大きい二分木。二分木は2つの子を持つ木。
回転したとき2が一番上に位置するだろ、3は2より大きいから2の右側にいなければいけない。
1は2より小さいから2の左側にいなければいけない。二分探索木の条件を崩さずに平衡を保つために
ノードを付け替える、それがAVL木における回転操作。
356 :
デフォルトの名無しさん:2012/10/30(火) 23:23:30.43
>>355 ありがとう図付いてるし考えてみる
ただ計算量まで求めるとなるとお手上げ
ちなみに俺が持ってる回転のイメージは
1 2 3 4 5 → 5 1 2 3 4 → 4 5 1 2 3
こんな感じ
複雑な回転の仕方はイメージできないんだ
だれかすまんが、なんで木が1次元配列になってんのか説明してくれ
>>356 それただ単に、
一次元の配列をrotateしただけ…
359 :
桃白白:2012/10/30(火) 23:35:28.43
>>357 大丈夫だ問題ない、桃白白にもそれはわからない。
360 :
デフォルトの名無しさん:2012/10/30(火) 23:49:21.95
>>357 A[0]
A[1]A[2]
A[3]A[4]A[5]A[6]
...................
こんなイメージですかね?
Heapなんかも1次元配列だけど実質木構造だしな
マジで言ってんのかよ……
いまの計算機、木構造をそのまま入れれんのか?
実質もクソもなんも
最終的なデータの形態なんてメモリにならんだビットのコマ切れじゃん
それが意味あるように見えてる、見せてるだけだろ……
木作る時は
配列複数作ったほうがいいのか?
>>361 ヒープは木の構造は配列サイズで確定されて、
操作が内容のスワップだけだから配列で表現できるってだけだろ。
AVLで同じことやろうとしたら、空き要素が大量にいるだけじゃなくて、
回転したとたんに要素の大移動しなきゃならん。
ならねーよカス
366 :
287:2012/10/31(水) 00:25:55.53
>>289 返事遅くなりましたが、ありがとうございます
明解C言語はすぐにでも試し読みできそうなので、見てみたいと思います
>>364 もちろん一次元配列で平衡木は非現実的だよ
ヒープソートがどういう動きをしてるのか分からない人がいるのでちょっと触れてみた
>>362 うん、だからわざわざ連続領域の配列に持たせる意味がないんだよね
int x;
while(1){
x=getchar();
if(x==EOF) break;
printf("%d",x);
putchar(x);}
char型の理解を深めようと色々試していたところ
これの%dを%sにして出来たファイルを実行したらセキュリティーソフトからウィルス警告来たのですが
無視しても大丈夫ですか?
ウイルス作成罪キター
ってのは冗談だが、"%s" に文字(char)とか整数(int)を与えちゃいかんよ。
いまどきのコンパイラなら警告オプションちゃんとつければ、
だめよって警告してくれるはず。
セキュリティソフトってハッシュで確認するだけのもんだと思ってたわ
入門用のコード書いてコンパイルしたらAvast!に隔離されちゃうことがあるな
下のコードを MinGW gcc 4.6.2 で -O2 オプションでコンパイルすると
ld がマルウェア作ったとかいってブロックされるwww
#include <stdio.h>
int main(void)
{
int a, b;
scanf("%d", &a);
scanf("%d", &b);
printf("%d %d\n", a, b);
return 0;
}
scanfは糞
一律に糞扱いして思考停止するんじゃなくて、
使える条件が整えば便利に使えると思うよ
条件確認して慎重にコーディングしなきゃダメな時点でクソだろ
それで得られるメリットがめんどくささを凌駕するならまだしもそんなこともないしな
sscanf()はけっこう使う
まぁ、sscanf()も入力が想定できるケース以外では出番が減るけどね。
バッファ突破の話とは別で
scanf は解釈に失敗した場合に巻き戻せないのが難点
sscanf ならバッファを書き換えない限りいけるので まだ融通が利く
実務では結局他のパーサー使うんでスキャンエフの出番はないです
scanf は糞。論外。
sscanf は入力行のチェックをしてから通す。常識。
383 :
デフォルトの名無しさん:2012/11/01(木) 12:54:04.04
ところで標準のファイルストリームで扱えるサイズを超える巨大ファイルをOSのAPIなしに扱うにはどうすればいいんすか?
シーケンシャルアクセスだけですべて解決する問題なら気にしなくていいのだけどランダムアクセスしたい時に困ります
longが32bitのシステムでfseek(3)じゃ足りないってこと?
POSIXにはoff_tで使えるfseeko(3)があるけど。
fseek64 とか
Cの仕様が時代についていけなくなりつつあるね。
拡張関数とかでお茶にごしてるけど。
C の仕様というよりは処理系の実装上の問題では?
>>384 は long を必要分だけ拡張すれば済む話。
sizeof(int)=4 はいいとして
sizeof(long)=4 とした処理系が跋扈し、というかそれ以外の処理系とライブラリが主流にならなかった点に問題がある。
C の規格自体にはそのあたりに縛りはないから「時代にとらわれる」ということは基本ない
>>384 外部設計を見直し、ランダムアクセス不要にする
390 :
デフォルトの名無しさん:2012/11/02(金) 10:16:18.61
標準関数はおまけに過ぎない
拡張こそ肝心で、これを妨げないことが標準の使命だ
普通にfseekoじゃないのか
うん
少なくとも何バイトのファイルを扱えるみたいなルール決まってないの?
整数みたいに少なくとも幾つまでは安心して使える的な
C言語としては、それを決めてはいけない側だ
なら一キロのファイルも開けない環境があってもいいわけか
標準準拠だと何もできないなこの言語って
なんでそうなる
実装の自由度が広いって事だ
言語ができた当時の環境やコンパクトな実装がC言語と名乗れなくなるだろ
言語けなしたって自分は偉くならないよ
Qzとかいうクズに言ってやれ。
Qが言語をけなしたことがあるとでも?
うん、そうだよ
単に事実を述べただけでは?
402 :
デフォルトの名無しさん:2012/11/03(土) 03:29:32.30
こんばんは。
初めての質問です。
C言語で簡単な自己複製プログラムを作るにはどうすればいいでしょうか。
クワインのような自身のソースコードを出力するプログラムではなく、複製後実行までするプログラムです。
アセンブラやC言語の知識が必要だと思いここに書き込みました。
よろしくお願いします。
>>402 宿題スレで回答できるくらいのレベルになればいいんじゃね?w
if ( ...... ){
} else if ( ..... ){
.... ;
} else {
... ;
}
for ( i=0; i<N; i++ );
printf ( "....\n" );
np = (HOGE *)malloc( sizeof(HOGE) );
などなど、皆さんは空白入れたり、入れなかったりどうしていますか?
好きにしています。
else と if の間の空白は取ると意味が変わるから入ってるときは入れたままにしなきゃだめ
408 :
桃白白:2012/11/03(土) 11:27:38.83
桃白白はこうだな、とにかく条件式の場所をそろえるべきだと思うの。
if (0) {
} else if (a == a) {
hogehoge;
} else if (a == b) {
fugafuga;
} else if (a == c) {
taopaipai;
}
>>405 K&Rスタイル
if (), while (), switch () と制御文のキーワードの後は空白を入れる
func() 関数の後には空白を入れない
関数の引数に関しては func(a, b, c) 引数の区切りの, の後ろにのみ空白をいれる
カンマ演算子以外は演算子の前後に空白があるようにする。カンマ演算子の場合は後ろに空白があるようにする
そんなところかなあ
おおこれは斬新
識別子が長くなってしまった場合はどこで改行してる?
int x = looooooooooooooooooooooooooooooooooooooooong_type.functiooooooooooooooooooooooooooooooooooooooon
(a1, a3);
int x = looooooooooooooooooooooooooooooooooooooooong_type
.functiooooooooooooooooooooooooooooooooooooooon(a1, a3);
int x = looooooooooooooooooooooooooooooooooooooooong_type.
functiooooooooooooooooooooooooooooooooooooooon(a1, a3);
どれか選べといわれたら演算子の後で改行かな
jf 内の条件式が || && の連結で長くなる時にどこで改行するかスタイル
末尾に || && 若しくは 行頭で || &&
414 :
デフォルトの名無しさん:2012/11/03(土) 13:54:35.64
続きであることが一目瞭然になるため
行頭で || &&
415 :
デフォルトの名無しさん:2012/11/03(土) 14:24:51.28
C学習中のものですが、質問です
コンパイラはVC++2010を使っています
#include <stdio.h>
#define MAX 30
#define COUNTBY 3
int main(void)
{
int i;
for(i=1; i<MAX; ++i)
if(i%COUNTBY==0)
printf("%d ",i);
return 0;
}
というソースなのですが、これではif文内が実行されません(実行されることを期待していた)
for(i=1; i<MAX; ++i)
if(i%COUNTBY==0){
printf("%d ",i);
}
若しくは、
for(i=1; i<MAX; ++i){
if(i%COUNTBY==0)
printf("%d ",i);
}
とすると実行されます。この理由がわかりません。元の文も一応大きく見て一つの文であると思うのですが
何故なのか分かり兼ねます。よろしければ、解説していただきたいのですが。
初歩的な質問で申し訳ありません
>>415 3 6 9 12 15 18 21 24 27
でしょ。問題ない。
ただ、for文もif文も{ }でくくっておいた方がいいのでは?
どうしてもというスタイルにこだわりがなければ。
>>415 単純にMSVCがCコンパイラとしてクズだってことじゃね
VC 2010でコピペして実行したが
>>417の結果が出たぞ
420 :
415:2012/11/03(土) 14:57:45.60
>>416 >>417 >>418 >>419 質問に答えて頂いて、ありがとうございます
私は、普段ビルド後はデバッグで結果を確認しているのですが、
実行に問題無いということでしたので、試しにデバッグでは無くそのまま実行してみたところ
確かに問題なく、実行されました。つまり、VC++のデバッグ等がうまくいかない理由なのかもしれません
デバッグ時は、return 0;の位置にブレイクポイントをおいてデバッグしています。
やはり、こういった問題や、読みやすさを考えるなら、
>>417さんの言うとおり、
for文、if文も{}で括ることが推奨されるのでしょうか
何にしても、普通に実行すれば問題は無かったのに、わざわざ皆さんの貴重な時間を割いてしまって申し訳ありません
感謝しております
じゃあ、ただのtypoだな
例えば、for の行末や、if の行末にセミコロンがあったとかな。
初心者にはありがちかも。
423 :
415:2012/11/03(土) 15:13:43.25
>>421 >>422 確認してみましたが、タイプミスでは無いかと思います。
全く同じソースコードでも、通常実行時は問題がありませんが
デバッグ時は出力されません
>>420 単純にフラッシュされてないだけじゃね?
ブレポと標準出力は相性悪い気がする。
>>423 vc2010のバグだね。
ループの終わりが↓になるけど、
>>415の1番目でreturnにブレークポイント設定すると
(1)に設定される、2,3番めは(2)に設定される。
call dword ptr [__imp__printf (12E82D4h)]
add esp,8
cmp esi,esp
call @ILT+300(__RTC_CheckEsp) (12E1131h)
jmp main+27h (12E13D7h) <<< (1)
xor eax,eax <<< (2)
バカっぽい略語(ブレポ)使う奴の回答は信頼性が低いという現象がまた観測されてしまった。
2chで信頼性とか
バカっぽい略語つかう奴とクソなコテハンの回答は読み飛ばす。
これでかなり捗る。
>>429 もしかして、hoge 嫌い?
chromeをチョロメとか言われたら気分を害すタイプか?
>>429 略語の方は関係ないと思うけどコテハンを読み飛ばすのは効果的ですね
432 :
415:2012/11/03(土) 18:03:47.54
>>426 バグでしたか
回避策としては、{}を付けるか、ブレークポイントろ使わないということになりそうですね
ご助力ください。
以下のような関数内でfloat型の変数の中身を文字列として使用したいのですが
PICのプログラム領域不足のためsprintfを使用することが出来ません。
何か代用になる関数等は無いでしょうか?
cMsgの中に1023を100%とした100分率の値を格納したいのです。
もしスレチでしたら誘導していただけるとありがたいです。
unsigned int giDuty;
void dispDuty(void){
float fDuty = 0;
unsigned char cMsg[16];
memset(cMsg, 0x00, sizeof(cMsg));
fDuty = giDuty / 1023 * 100;
sprintf(cMsg, "Heater:%3.1f %%\n", fDuty); ←これが大きすぎてコンパイルできない。
sb1602_cmd(0xC0); // カーソルを先頭に移動
sb1602_str(cMsg); // LCD表示
}
開発言語:C
コンパイラ:HITEC C
マイコン:PIC12F683
10倍にしてintに入れて1ケタづつ表示してはどう?
>fDuty = giDuty / 1023 * 100;
それ以前にfDutyに整数しか入ってなくね?1023.0とか1023fとかにしないと
案としては434だろうね
int Duty = giDuty*1000/1023;
sb1602_int(Duty/10);
sb1602_str(".");
sb1602_int(Duty%10);
みたいなイメージか
うん、いいよ
>>433 そういうプラットフォームでprintf系の関数を使ったり、掛け算や割り算、ましてや浮動小数点を使うなんてバカなの?
コンパイルは出来るだろ
って釣り?
そんなこまかい事を
釣りだな
ターゲットをPICに設定していたら、xxxx.objができませんみたくなるんじゃね?
え、違う?
うん、違うよ
>>438 そういうプラットフォームとか言うが、PIC も色々あるぞ。
printf( ) 系のライブラリとか浮動小数点あたりはまだ同意するけど、
掛け算、割り算まで使うなとか言う 8bit 時代から進化できない爺は
早くリタイアしてくれないかなぁ。
445 :
433:2012/11/04(日) 02:29:35.21
>>434 >>435 遅くなりましたが今確認とれました。
無事動作しました。
ありがとうございました。
マイコン使うなんて初めてで標準関数がこんなに重いものだとは思いませんでした。
使えなくなって初めて有り難味がわかるものですね。
>>439 >>442 リンク中かもしれません。
確かpicc.exeプログラム領域が足りないって怒られてました。
もうログ流れちゃったので具体的な文は出せないですが。
446 :
433:2012/11/04(日) 03:01:14.02
>>438 >>444 試しに別な関数の乗算をシフト演算でやってみましたがプログラム領域は変わりませんでした。
コンパイラが最適化してくれてるんですかね。
乗算のままの方が読みやすいのでそのままにしておきます。
>>407 意味が変わるっていうか、コンパイルエラー吐くだろ?
いまは違うんか?
やってみればすぐ判ることを
elseif(x == 0)
;
エラーにならない例。
コンパイルでは警告どまりで、そのあとリンクエラーじゃね?
452 :
デフォルトの名無しさん:2012/11/04(日) 15:25:42.71
構造体とポインタについてお伺いします。
構造体で個体情報を保持し、リストで管理するようなプログラムです。
(実際はもっとごちゃごちゃしてますが大体ということで)
1.main内で構造体変数のポインタを宣言し、
2.それを関数に渡します(参照渡し)
3.関数内でポインタに、構造体変数の実体を保持したポインタを代入します。
これだけのプログラムですが、うまくいきません。
関数内では、割り当て元のPも割り当てた後のP(引数で受けたもの)も
きちんとアドレス参照で確認できます。
けれど、mainに戻って、渡したポインタから数値を確認すると、きちんと代入されていません。
もう少し具体的に書くと
1.main()内 → struct STRUCT *p; 構造体へのポインタ宣言
2.void func(struct STRUCT *p)関数へ引き渡し(func(p);)
3.関数内での代入 p=ptmp;
4.一応関数内での確認 printf("kakuninn %d %g \n", p->value1, p->value2);
5.mainにもどって同じように確認すると、めちゃくちゃ。
コンパイラはgccです。
ポインタへのポインタとか、そのあたりの認識ミスだと思うのですが、
自分なりに考えても、これであってると思うので手詰まりです。
お願いします。
453 :
452:2012/11/04(日) 15:38:58.12
やっぱりポインタへのポインタなのかな
その方向で一度書き直してみます。
もし間違ってたらアドバイスを……
454 :
デフォルトの名無しさん:2012/11/04(日) 15:45:25.10
どうみてもポインタのポインタです
>>452 一番簡単なのは、
>3.関数内での代入 p=ptmp;
のところで、
*p = *ptmp
とすれば多分オケ
それじゃ *p をたぐった時に死ぬんじゃないの?
457 :
デフォルトの名無しさん:2012/11/04(日) 16:11:29.35
これはひどい
>>456 すまぬ、領域の確保までしたいのか
よく見てなかったわ
すると、ダブルポインタしかないね
>>452 ソースがあればはっきりするが、関数から戻った時に、ptempの内容が破壊されてるんでは?
460 :
デフォルトの名無しさん:2012/11/04(日) 16:37:42.58
>>452です
プログラムが大きいので部分的にしか導入できてませんが、
void func(struct STRUCT **p)に変更し、
関数への引渡しはfunc(&p)、
関数内での処理はp=&ptmp
となるでしょうか。
これで一応回りそうなのですが。
>>460 ローカル変数のアドレスを外に返したらあかん。
あと、*p = &ptmp
463 :
デフォルトの名無しさん:2012/11/04(日) 16:57:10.56
>>462 関数内のpは、目的ポインタのアドレス確保のためのポインタですので、
p=&ptmpでいいのではないでしょうか
>>461 実体部のアドレスに書き直しました
464 :
452:2012/11/04(日) 17:02:29.74
あれ
*p=ptmpではエラーが出ず
p=&ptmpではエラーが出る
あ、ptmp は元々ポインタなのか。
それなら
>>462 は大嘘で *p = ptmp かな。
466 :
デフォルトの名無しさん:2012/11/04(日) 17:07:32.54
なんかいろいろ整理できてないですね
とりあえず*p=ptmpで通りました
まあ、本能の赴くままに書けばいいよ...
468 :
デフォルトの名無しさん:2012/11/04(日) 17:09:42.93
整理できてないのは自分の説明です。
ありがとうございました
>>452 こうか?
#include <stdio.h>
struct STRUCT {
int value1;
double value2;
};
struct STRUCT ptmp;
void func(struct STRUCT **p);
void func(struct STRUCT **p)
{
ptmp.value1=123;
ptmp.value2=456;
*p=&ptmp;
printf("kakuninn %d %g ¥n", (*p)->value1, (*p)->value2);
}
int main()
{
struct STRUCT *p;
func(&p);
printf("kakuninn %d %g ¥n",p->value1, p->value2);
return 0;
}
イクルオネルスオブヌン
論よりソース。日本語でぐだぐだ説明するよりソースを出すのが
一番早い。
たしかに。
473 :
デフォルトの名無しさん:2012/11/04(日) 19:09:16.49
>>469 おまえ ioccc に出てみないか?
コードがキモさの素質で漲ってるぞ
>struct STRUCT ptmp;
この辺とかあんまりだろw
まあまあ、押さえて押さえて。
初心者の学習意欲を削ぐようなことを言うなや。
476 :
472:2012/11/04(日) 19:24:54.29
>>473 joccc だったらいいところまでいきそうですね<私
初歩的な質問ですみません
数値の範囲指定なんですがどのように書けば良いのでしょうか?
例えば0以上〜8未満、5以上7以下と言う感じです
入門書を見てるのですがいまいちわからないもので・・・よろしくお願いします
>>477 xが0以上かつ8未満
x>=0 && x<8
xが5以上かつ7以下
x=>5 && x<=7
みたいな?
480 :
478:2012/11/05(月) 01:39:18.75
訂正
x>=5 && x<=7
481 :
デフォルトの名無しさん:2012/11/05(月) 02:30:54.70
「C++ クラスと継承」という本のC言語の復習パートで疑問があり、
こちらで質問させてください。
http://codepad.org/bCnoXDJM 上記のようなコードで、構造体のポインタを戻り値で返す説明をしているのですが、
struct Jugyoin* GetJugyoin() の構造体の関数で、なぜポインタにする必要があるのでしょうか?
別にポインタでなくてもいいよ。
でもポインタなら4バイトとかでstaticな構造体のアドレスだけ返して高速、
ポインタじゃないとstaticな構造体のコピーを返すから低速、と言うかコンパイラが自動生成するコピーコードと受け側で実体分のメモリを確保する必要があるからこの場合無駄だらけかと。
>>481 その本の質題の意図がわからないので、そのコードをだけを踏まえた一般論ですが、パフォーマンスでしょう。
ポインタなら大抵4〜8バイトのコピーで済みます。
88バイトコピーするのいやだし
しかし、関数名にセンスの欠片も無いな
struct Jyugyoin* GetJyugoin();
ではなく、
struct Jyugyoin* getTanaka();
だろ
矢沢 久雄の本か
>>478-480 ありがとうございます!お陰でなんとか形になりました
あと、もう一つ質問したいんですが少数第二位まで判定する場合はどのようにすれば良いのでしょうか?
x>=5.0 && x<=7.0 と書いているのですが7.5など入力すると切り捨てで7の扱いになってしまいます・・・
少数第一位でしたすみません
float f;
if (f > 7.5f && f < 7.9f)・・・
とかでダメなの?
ちなみに変数fとリテラルの最後のfは無関係だから
xが浮動小数点型じゃないオチ
>>485 そんなもん人の勝手だろう
ましてやただのコード片にセンスも糞も必要なわけない
どうせ突っ込むなら Jyugyoin じゃなくて Employee とかでしょ。
>>484 そこでケチってマルチスレッドで泣くパターン
関数呼び出しをスレッドで排他すればかわせるけどね
何かしらケチつけないと気が済まないって感じ
ケチつけるしか出来ないんじゃないの?
自分ではいいプログラム組めないもんだからさ
他人を貶めて自分が偉くなったような錯覚に浸る頭の悪い奴ってことだな
>>493 構造体をコピーして返しても、このコードならロックは不要。
マルチスレッドにしても何の問題もない。
シロートは知ったかぶりしないで余計な口出ししない方がいいぞ。
またおかしなのが出た
先輩はすーぐ最後の一行を書きたがるねー
はじめの2行もおかしい気がするけど
>>493 が毎回田中を初期化する仕組みを改善しないのが悪い。
昔から田中と畳は新しいほうがいいっていうよ
extern char *tanaka; //何やってるかわからない
char matsui[1]; //ろくに使えない
char *str_chr(char *str,int c)
{ for(;*str;str++){
if(*str==c)
return ((char*)str);}
return NULL;
}
int main(void)
{ char uletter[]={"ABCDEFGHIJKLMNOPQRSTUVWXYZ"};
char str[10],*p;@
printf("英大文字を入力してください。:");
scanf("%s",str);
p=str_chr(uletter,str[0]);A
puts(p);
return 0;
}
一文字入力してそれを関数に送るということで@をchar strAを(,str)と書いたらダメでした。
上記の通りに配列で宣言して配列の先頭アドレスを引数にしないと停止するのですが何故なのでしょうか?
scanf の %s は文字列を入力しますよ
実入力が1文字しかなくても文字列として読み込みますよ
char str[10];
scanf("%s", str);
char str;
scanf("%c", &str);
ダメでしたの具体的に何がどうダメなのかが伝わらないので
答えようがない。
508 :
デフォルトの名無しさん:2012/11/06(火) 17:38:51.20
>>506 コード見てわからない無能は答えようとしてくれなくて結構です
509 :
デフォルトの名無しさん:2012/11/06(火) 17:54:24.90
char に %s したらあかんやろ
しかも & なしで str だけ渡したら不定じゃハゲ
# 無能さんすごい!
str_chr()関数の第二引数にintを受け取るのに
str(ポインタ)を渡したら動かないのは当然。
>>504 str_charの第二引数はint型なのにchar型を渡そうとしてるからint→charに引数はへんこうしたらいいよ
scanfで文字を一つ入力するのに%sではエリア破壊を引き起こすから、getcでいいんじゃね?
str_charの戻り値はnullであることもあるので(この例ではエラーにはならんとおもうが)判定くらいは
した方がいいね。
>>504>>511 >str_charの第二引数はint型なのにchar型を渡そうとしてるからint→charに引数はへんこうしたらいいよ
>scanfで文字を一つ入力するのに%sではエリア破壊を引き起こすから、getcでいいんじゃね?
getcharを使ったら?それならstr_charの第二引数はint型と辻褄合うし。
int main(void)
{
char uletter[]={"ABCDEFGHIJKLMNOPQRSTUVWXYZ"};
char *p;
int ch;
printf("英大文字を入力してください。:");
ch = getchar();
p = str_chr(uletter, ch);
puts(p);
return 0;
}
513 :
504:2012/11/06(火) 23:37:53.84
皆さん解説ありがとうございます。
自分の書いたプログラムと回答の差異である宣言と呼び出しにばかり注目してscanfの問題に気づきませんでした。
char型は%sと短絡的に考えていて、文字列として読み込むことを意識していなかったようです。
>>511 一文字入力にはgetcがありましたね。scanfばかり使うので、入力はscanfで頭が固まっていました。
int型については私も疑問に思っていましたが(本にintと書いてあるので)、指摘があると言うことは何かのテクニックではないようですね。
Cで関数にcharを渡すと、自動的にintを渡すことに解釈される。
といいますと?
いけえ!インテグラルプロモオショオオオオンンッ!!!
処理なしは、どの書き方をしてます?
while ( 条件 );
while ( 条件 )
;
while ( 条件 ){
;
}
Windowsだったら
#include <conio.h>
getchar(); や kbhit();
があって、楽なんですけどね。
Linuxではどうすればいいのか…。
ところで余談かつ、散々既出だと思うけど、
char str[10];
scanf("%s", str);
で半角10文字以上入力するとバッファがあふれるので、
文字列の入力は
fgets(str, sizeof(str)-1, stdin);
などを使いましょう。
while(b)
{
Sleep(300);
}
char str[10];
fgets(str, sizeof(str), stdin);
>>518 訂正
×> #include <conio.h>
> getchar(); や kbhit();
> があって、楽なんですけどね。
○> #include <conio.h>
> getch(); や kbhit();
> があって、楽なんですけどね。
>>521 ああ、そちらが正解ですね。
fgetsは終端を考慮していますね。
訂正ありがとう。
>>523 出来ました。
ありがとうございます。
fcntl();でgetchar();を制御するのかな。
もっと精進します。
526 :
デフォルトの名無しさん:2012/11/07(水) 08:55:53.71
東京理三、慶応医学部→エース
東京理一、大阪医学部→レギュラー
早慶理工、新潟医学部→補欠
駅弁医学部、秋田医学部→二軍
その他→死刑、生きる価値なし
釣られないぞ
素朴な疑問なんですが、
>>518みたいな典型的な問題について悩まなくても簡単に解決してくれるライブラリは存在しないのですか?
他の言語だとキーの入力くらいは安全かつ便利なライブラリが存在しているのが普通だと思いますが、
どうしてC言語にはそのようなライブラリがないのでしょうか?これだけの利用者がいるのなら既にそういったノウハウが蓄積されたライブラリがあってもおかしくないと思うんですが
Cの標準関数は歴史的な経緯で問題の残る仕様があったりする。
処理系ごとの独自拡張ライブラリを使うのがいい。
>529
boost
>>529 >どうしてC言語にはそのようなライブラリがないのでしょうか?
OS というかハードウェアによるから
そういうのは標準には入れないだけで
標準にこだわらなければライブラリは在る
>>一連の文字入力
いやいや、scanf()でも"%c"もあるけどな。
"%s"の代わりに"%9s"を使えばバッファオーバフローの問題もないけどな。
>>処理なし
私は自分のコード内では1番目、他人もメンテナンスする前提のコード内では3番目。
>>仮引き数の型のchar
昔のプロトタイプ宣言のない時代のCではcharを渡そうとしてもintに昇格せざるを得なかったから、
charの引き数は敬遠されたと言う経緯はあるね。
>>529 その程度のものなら一回書いたら終わりだから。
ファイルの後ろから一行ずつ読み込みしたい、という場合に使う関数はC言語には用意されてないのでしょうか?
後ろから改行が見つかるまでシークして一行読み込み、と泥臭く栗返すしか無いのでしょうか
頭から1行単位で全部読む+記憶する
記憶列を逆順に、後ろから1行づつ喰いたいとしている処理へ渡す
つ[/bin/tail]
>>536ではないけど
なるほど
tailのソース読んでパクればいいのか
GPLには要注意だけどBSD版もあるし
540 :
デフォルトの名無しさん:2012/11/07(水) 20:43:08.61
RSTみたいに自分の陣地の様子は見れるのに
他の敵陣の様子は見れないのにも関わらず、いつのまにか繁栄してたりすることあるけど
これはc言語におけるマルチスレッドが関係してるの?
普通に無限ループでぐるぐる回りながら自分の陣地と敵の陣地で毎回処理が実行されてるだけだと思うが
int main(void) {
int data[10];
int* p = data;
printf("p:%d, data:%d, p-data:%d\n", p, data, p - data);
p++;
printf("p:%d, data:%d, p-data:%d\n", p, data, p - data);
return 0;
}
結果がこうなるんですけど、
$ ./a.exe
p:2280624, data:2280624, p-data:0
p:2280628, data:2280624, p-data:1
p-data:1のとこがなんでp-data:4にならないんですか
ポインタ同士の引き算は、その間の要素の個数を返す
1足したのに差が1っておかしい、4にならない!ってどんなわがままか。
>>536 シークは、おそい。リストをつかったら、はやくなる。
最後に追加した行から、順によみとる
ファイルが何GBあっても?
初心者のとき、おれがリストをつかってかいたプログラムが、
fseek()をつかったプログラムより、はやかった。よくおぼえてる。
ファイル形式やサイズ、どう読み取るのか、実行環境のスペックなどによるとしか言えないな
なんでストリームはひとつ読み取ると次の要素に進んでしまうんですか?
インクリメントと読み取りは分けた方がよい設計に思えるのですが?
ストリームだもの
みつを
>>552 その設計でAPI作って、ちょっとしたプログラム書いてみてよ
ベクターみたいなインターフェイスでストリームにアクセスしたいです
ストリームってのは流れだから
今時テープを再現する意味はないのでは?
>>555 それをCに期待するのは筋違いと言うものだ。
>>557 だから、君の考えるAPIを使って既存の読み込み処理を書き換えてご覧よ。
>>557 ネットワークから流れてくるデータなんかもストリーム。
キーボードから人間が入力する文字の流れもストリーム。
終わりがあるのかないのか、次がいつ流れてくるのか、そう言う事には左右されない抽象的な概念。
ベクターをストリームとして扱う事はできるけど、逆は無理。
fseek は 512 の整数倍を指定しないと遅くなるお
試してみたいからベンチマーク用のプログラムください
512じゃなくてBUFSIZの倍数じゃないの?
MS-DOS時代以前の話だがな
言語仕様じゃなくて完全に実装依存の話だな。
コンパイラの実装の話でさえない
しかもいまどきはディスクみたいな遅いデバイスにはキャッシュが乗っているから有意差が出ない。
バッファが幾重にも積み重なっていてもはや処理速度がどうこうとか関係ないレベル実測して確かめれ
570 :
デフォルトの名無しさん:2012/11/08(木) 19:36:33.56
おまえらそろそろ言語のことを聞け
明解C言語 入門編で勉強し始めたのですが、疑問があったので質問させていただきます。
int型とdouble型の話なのですが、
#include <stdio.h>
int main(void){
double d1, d2, d3, d4;
d1 = 5 / 2; d2 = 5.0 / 2.0;
d3 = 5.0 / 2; d4 = 5 / 2.0;
printf("d1 = %f\n", d1);
printf("d2 = %f\n", d2);
printf("d3 = %f\n", d3);
printf("d4 = %f\n", d4);
return(0);
}
実行結果が
d1 = 2.000000
d2 = 2.500000
d3 = 2.500000
d4 = 2.500000
となるのですが、なぜd1は
計算的には5.0/2.0と同じなのに
int型のように小数点以下が切り捨てられたのでしょうか?
d3とd4も小数点がどちらか片方ありませんが、
小数点以下が計算されています。なぜでしょうか?
d1 = (double)5 / 2;
d1 = 5f / 2f;
>>572 異なる数型の演算ではpromotion(日本語だと昇格だっけか?)というものが行われる。
d1 = 5 / 2;では5/2をintで行った結果の2がdoubleにpromoteされて代入される。
d3 = 5.0 / 2;は 2がdoubleにpromoteされて5.0 / 2.0が計算される
整数の演算にもpromoteはあるから規格書を読んで理解しておくといい。
>>575 ありがとうございます。
d1はdoubleという変数の箱に入る前に整数で計算しているから
そうなるんですね。
本には格上げと書いてありましたが、
どのタイミングで処理されるかわからず混乱してました。
ずぶのトーシロです。
表示させた5つ数字の平均値をもとめるプログラムなのですが
for分の中にscanfを突っ込むのは合理的ですか?
5回繰り返せばいいという安直な考えなのですが
その5回分足す作業をどこに書けばいいのかよくわかりません。
さしつかえなければ、参考までに書いていただけないでしょうか?
ちなみに数学的教養がほとんどないです。
特に一番自分がやばいなと思うのが一体変数が
いくつ必要なのか自分でなかなか考えれないということです。
これはどう解決すべきですか?
5回足すとは
0にしておいた変数に1回足す
またそれに1回足す
またそれに1回足す
またそれに1回足す
またそれに1回足す
だ。
> for分の中にscanfを突っ込むのは合理的ですか?
合理的です。
scanfを5つ書くのはマヌケです。
変数がいくついるかなんて設計前に完全に予測するのは無理だし、
予測してもあんまり意味ないよ
個数の話じゃなくて、何を変数とすべきかという意味なら、
最初はまごついて当然なんで、たくさん書いて早く慣れろとしか言えない
>>577 最初の頃はやりたいことをそのまま、例えば入力→加算の処理を5回書いてみて、
「あれ?これ同じ文の繰り返しじゃん」と思ったらforにまとめてみるような流れでおk。
変数も同じ。出来上がった後に、この変数{必要 or 不要}じゃね?と思ったら追加・統合・削除していく。
慣れたら最初からそれらを考慮できるようになる、はず。
#include <stdio.h>
int main(){
int iSum = 0;
int iInput = 0;
int iLoop;
for(iLoop = 0; iLoop < 5; iLoop++){
printf("%d : input >", iLoop+1);
scanf("%d", &iInput);
iSum += iInput;
}
printf("sum = %d\n", iSum);
return 0;
}
>>581 最初はそうもいかんのよ。
scanf("%d", &v1);
scanf("%d", &v2);
scanf("%d", &v3);
scanf("%d", &v4);
scanf("%d", &v5);
sum = v1+v2+v3+v4+v5;
となって、繰返しにできずに行きづまる。
583 :
581:2012/11/09(金) 01:05:37.47
>>582 おうふwww
>>577 ごめん要件見落としてた。入力個数が決まってて平均ならこうだわ。5を定数化して、整数変数を実数変数に。合計表示はついで。
#include <stdio.h>
#define INPUTNUM 5
int main(){
double dSum = 0;
double dInput = 0;
int iLoop;
for(iLoop = 0; iLoop < INPUTNUM; iLoop++){
printf("%d : input >", iLoop+1);
scanf("%lf", &dInput);
dSum += dInput;
}
printf("sum = %f, average = %f\n", dSum, dSum / INPUTNUM);
return 0;
}
>dSum
>dInput
>iLoop
システムハンガリアンはそろそろやめたほうが
585 :
デフォルトの名無しさん:2012/11/09(金) 01:55:16.09
0〜Nまでのランダムは個体を10個作成したいのですが、どのような関数にすればいいのですか?
CryptGenRandom();
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define N (5963)
#define KOSUU ( 10)
int main()
{
int i, r[KOSUU];
// 乱数初期化
srand(time(NULL));
// 乱数生成
for (i = 0; i < KOSUU; i++) r[i] = rand() % (N + 1);
// 生成された乱数で行う処理(例)
for (i = 0; i < KOSUU; i++) printf("[%d] %d\n", i, r[i]);
// 付録
printf ("\nrand関数が生成する値の範囲(処理系により異なる) = 0 〜 %d\n", RAND_MAX);
return 0;
}
589 :
587:2012/11/09(金) 03:31:05.35
>>588 なるほど。
rand();の下位ビットはあまりあてにならないのですね。
初めて知りました。
> rand() % (N + 1);
↓
> (int)((double)rand() / ((double)RAND_MAX + 1) * (N + 1));
とすれば良いですね。
乱数生成などは素人が自前で作らない方がいい
本当に乱数が欲しいなら、random()使うより/dev/randomを使うといい
素人でもぐぐりゃすぐ作れる
初心者は初心者らしく
「擬似」乱数だって理解して使うなら桶
>>593 それはそうだ。
意図しているのは「どんな乱数生成器を使ったかを明示するために」既存のコードを自分で書いておく、というもの。
knuth の例の成書や奥村さんのものから引用するなりしてね。
/dev/random を使うより MT を明示するほうが説得力があると思う。
引用元があるなら自分で書く意味ないやん
あの場合は、完全なる一様分布関数を作成してダメアルゴリズムであることを指摘するのが正しい。
バカ丸出し↓
「最強のMT エイッ」
2要素ずつ順番に取り出すから規則性が現れてしまうんであって、
2要素ずつ取り出しつつランダムに時々1要素間引いてやるだけで、
当初の規則性は現れなくなる。
その代わり、間引くのに使う乱数の規則性の影響を受けた規則性が現れると。
/dev/random
603 :
デフォルトの名無しさん:2012/11/09(金) 13:45:24.25
うききっ
/dev/randomってエントロピーが足りないとブロックするんだな
どの乱数を使うかより、乱数を使ってどう書くかのほうがよっぽど重要
ところで
「ランダムは個体」
が何か、みんな合意できてるのか?
>>589 C FAQは20年以上前の情報だから。
いまどき下位ビットだから極端に周期が短い処理系とかない。
逆に、変に工夫してバグってる例を見かけるから素直に rand() % N でいいよ。
それつかえないよ
乱数の話をしてるとrand君を思い出す
20年以上前は、へんなバッドノウハウみたいのいっぱいあったけど
なんでrand()の下位ビット使うなだけ生き残ってるんだろうな。
rand()は大抵は全部のビットが使える実装に置き換わってるけど、
新たに書くコードならrand()の代わりにrandom()を使えという事になってると思う。
>>611 floatは遅いからdouble使えみたいな
GPGPU使うとグラボによってはfloatだけ圧倒的に速かったり
だが float を維持したままでの演算コードを書くのは辛い
グラボにマンデルブロ描かせると一瞬なんだけど
やっぱdouble精度が欲しくなる
iPhoneなんかはCPUでもfloatの方が速い。
>>611 どんな実装なのか調べるより下位ビット使わないように書く方が楽。
rand_s()
>>619 他のライブラリだってそれなりの品質だって信用して、いちいちソース見ないでしょ。
>>621 > 他のライブラリだってそれなりの品質だって信用して、いちいちソース見ないでしょ。
はあ? お前バカだろ。バグと実装上の問題を混同するな。
>>618 要はプロセッサが何に対応しているか
一時期はdoubleしか対応してなかった
>>622 なんで混同してることになるんだろ。
いまどき下位ビットだから極端に周期が短い実装とかないでしょって話。
今時ダメな実装があるかないかはどうでも良くて、
rand()はobsoleteだから代わりにrandom()使ってちょうだいよ、
とマニュアルに書いてある事が多い。
>>625 そういう環境もあるだろうけどrand()は標準関数で、そのrandom()だと環境依存になるからね。
rand()を使うならって前提の話ね。
まあPOSIXもアウトだっていうならそうね。
ググると古くて化石みたいな情報にヒットするのが厄介
rand() の実装を random() にすりゃ良いのに
以前カルドセプトってゲームでダイスの目が偶数と奇数が交互にでるってバグが話題になって、
ネットだと乱数の下位ビットを取ってるからだって話が氾濫したけど、たぶん、実際は
乱数ルーチンを自作して自爆だろうね。
xboxの開発環境はMSのコンパイラみたいだし単純に、rand() % Nだったらそんなことにななって
なかったはず。
>>611 knuth の例の聖書にはいっぱい書いてありますよ
>>633 線形合同法だけど、単純に前回の値に掛けたり足したりしてそのまま返すって
処理じゃないから大丈夫。
VCの場合だと下位ビットでも周期は6万以上。
>>633 その表だとVB6は最下位ビットは0と1が交互にくるような実装になってるのかな。
.NETじゃないVB使ってゲームとか作ってる人は要注意だな。
完全な乱数関数があったとしてもQZみたいなバカには豚に真珠
>>632のときもバカ相手にさらにずれた論理で話があさっての方向にずれてたし
639 :
デフォルトの名無しさん:2012/11/09(金) 19:25:44.46
グロ中尉
>>636 そうですね。
掛けて足した後の結果は保持しておきますが、公開するのはその途中のビット、すなわちすでに下位桁を削っていることになるわけですね。
つまり C-FAQ を汲んで変更が加えられているわけです。
線形合同も C-FAQ も今でも十分に現役であり、
>>608「C FAQは20年以上前の情報だから。」は少々乱暴。
>>633 をみると下位桁を削らずに公開している例もある。
質問です。
シェルのオートコンプリート機能でタブキーを押すと文字補完で、文字が勝手に出力?されますよね?
標準出力で出すとあんな感じに、削除できたり、そのまま入力文字として使えたりしませんが、あれってどうやったら実現できるのでしょうか?
分かる方解答お願いします。
>>641 いや、C FAQは今となっては古い情報も含まれてるよ。
rand()どうこうもそのひとつ。
>>633 の表のまずい奴は古い環境で最近のメジャーな奴なら大丈夫。
>>644 readlineですか
ありがとうございます。調べてみます
>>645 もうこの話やめときます。
メジャーの基準とか揚げ足取りの話になるとつまらんから。
>>647 具体的な話ができない、いやそもそもない、ということですね、よくわかります
分布の偏りや単純な規則性があると致命的ならば
演算結果を含めて素性の良い乱数か悪い乱数か一度は調べておきましょうね
ついさっきまで線形合同法を使ってるrand()は、返す値はC FAQに載ってるような
質の低いものだって思ってたような人と話をしても、こっちは一方的に教えてあげるだけで
得るものもないしね。
「教えてください」みたいな態度ならまだしも、わかってるよな口ぶりで挑発して、相手から
発言を引き出して、その場その場でググって自分の浅はかさがばれてないって思ってる
ような人がよくいるけど、もうそういうのもうんざりだし。
651 :
デフォルトの名無しさん:2012/11/09(金) 22:00:06.61
____
/⌒ ⌒\ ホジホジ
/( ●) (●)\
/::::::⌒(__人__)⌒::::: \ はいはい
| mj |ー'´ |
\ 〈__ノ /
ノ ノ
653 :
デフォルトの名無しさん:2012/11/09(金) 22:29:14.20
質問お願いします(行がギリギリなので、コメント内にて質問)。独習C第4版より
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
int count[26];/*これがグローバル変数でなけれなならない理由が分かりません*/
int main(int argc,char *argv[])
{
FILE *fp;
int i;
char ch;
if(argc!=2){
printf("ファイル名の指定がありません\n");
exit(1);
}
if((fp=fopen(argv[1],"r"))==NULL){
printf("ファイルを開くことができません\n\n");
exit(1);
}
while((ch=fgetc(fp))!=EOF){
ch=toupper(ch);
if(ch>='A' && ch<='Z')
count[ch-'A']++;
}
fclose(fp);
for(i=0; i<26; ++i)
printf("%c は %d 回\n",'A'+i,count[i]);
return 0;
}
別にグローバルじゃなくてもいいべ。
>>654 ローカルにしますと、結果が変わってしまいました
例
グローバルの時
A は 7 回
B は 4 回
C は 2 回
D は 5 回
E は 3 回
F は 10 回
G は 4 回
H は 6 回
I は 3 回
J は 3 回
K は 7 回
以下略
ローカルの時
A は 4201583 回
B は 516 回
C は 1638146 回
D は 4199438 回
E は 515 回
F は 1638178 回
G は 4208752 回
H は 518 回
I は 4239363 回
J は 8 回
K は 4241083 回
以下略
656 :
デフォルトの名無しさん:2012/11/09(金) 22:44:57.62
>>655 ローカルの時は自分でゼロに初期化しないとダメだべ。
int count[26] = {0};
とかしとけばいいんじゃないの?
>>652 ああそうなの。
線形合同法のrand()だとC FAQに書いてるように下位ビットは周期が極端に短くなるって
つい
>>633まで思ってたのに、ログを読んでそうでないって学べてよかったね。
初期化した?
>>656 >>657 >>659 >>654 お答え頂きありがとうございます
解決いたしました
グローバル変数では、0に初期化されますが
ローカル変数の時は、自分で0に初期化しなければならないのですね
配列の初期化という事が、頭から完全に抜けていました
大変ありがとうございます
>>653を見て思ったけど、
> char ch;
…
> while((ch=fgetc(fp))!=EOF){
これって、正しくEOF判定される保証ありましたっけ?
int ch;
なら分かるけど。
>>662 EOFが入力されたら問題なく終了されると思う
でも 0xFF が入力されても終了されてしまうと思う
今日は一時間かかってchar (*p)[n]の意味を理解しました
>>661 線形合同法が使われてるというのを知ってるってのはそれでわかるけど、それは反論になってないのでは。
線形合同法の乱数では周期が短いと
>>633まで思ってて、必ずしもそうでないと知ったのは
>>641だというのは
確認できますね。
あと、たとえば、こちらは「線形合同を使ってない」とか言ってないのに「線形合同がつかわれてますねー」とか
変な反論してきたりとか、そういう微妙にずらしてるのはわざとですかね。
あんまりこのスレ見てないけど、あなたいつもそういう論法でやってるの?
>>663 ありがとうございます。
while((ch=fgetc(fp))!=EOF){
は、書き換えると
while((ch=(char)fgetc(fp)) != (char)EOF){
ですね。
つまり、EOFは
#define EOF (-1)
なので、
int fgetc(); の戻り値がEOFだったら判定は
(char)EOF != (char)EOF!
といった具合に「真」になるので大丈夫…と。
ああっ
全然大丈夫じゃない。
ファイルの途中に0xFFがあったらそこでwhileループ抜けて、
それ以降の文字を読まない。
669 :
662:2012/11/09(金) 23:53:06.59
if文の質問です。
int x;
scanf("%d", &x):
if( x % 5 );
puts("5で割りきれない数字");
のようにifの条件式の中で
x % 5 > 0;
と書かなくても成り立つのはなぜでしょうか?
0か否かを判定してるから
int a, x;
x = 15;a = (x % 5 > 0);printf("(%d %% 5 > 0) = %d\n", x, a);
x = 11;a = (x % 5 > 0);printf("(%d %% 5 > 0) = %d\n", x, a);
の実行結果も見てみたら、理解が深まるかな。
ちなみに、
> if( x % 5 ); // ←「;」はいらない
> puts("5で割りきれない数字");
条件式の値が 0 なら偽、それ以外はなんでも真なの。
皆さんありがとうございます。
0かそれ以外で判別してることを初めて知りました。
投稿後にセミコロン気づきました。申し訳ございません。
ちなみに
if( ■ )
while( ■ )
for( … ; ■ ; … )
の ■ の部分はどれも真偽値だね
>>675 >の ■ の部分はどれも真偽値だね
じゃなくて式。評価結果の真偽値によって動作が変わる。
forの第2式は省略可能なので、if, whileとはちょっと違うかな。
>>666 >こちらは「線形合同を使ってない」とか言ってないのに「線形合同がつかわれてますねー」とか変な反論してきたりとか、
下位ビットに問題のない線形合同法の実装は存在しないからね。
「今の処理系では下位ビットの周期が短くない」と主張すれば、それは、「今の処理系は線形合同ではない」といっているのとほとんど同じなのでは?
ライブラリ側で下位ビットを切って返す実装(javaとかはそうですね)でない実装も多々ありますから
>>608 「素直に rand() % N でいいよ。」とは口がさけてもいえない。
私は以前はM系列法を愛用していましたね。
>>669 ひとつ発展形をおしらせしておきましょうか。
char 型で書いていてもコンパイル後のコードは char 型で比較するコードになっていなくて、int 型に格上げされて比較に供するコードになります。
これを integral promotion / integer pormotion といいます。
今回の事例では直接には関係ありませんが、しかし
>>667 は厳密には正しくない。
余力と暇ができたら考えてみてください
charが符号付きなら0xffは格上げされたとき-1でEOFと等しくなるけど、
charが符号無しだと255になってEOFとは等しくならない。
681 :
669:2012/11/10(土) 03:53:59.08
>>679-680 なるほど。
>>667の
char ch;
while((ch=fgetc(fp)) != EOF){
は、
while((ch=(char)fgetc(fp)) != (char)EOF){
ではなく、
while((int)(ch=(char)fgetc(fp)) != (int)EOF){
ということですね。
また、
int ch;
であれば、
while((int)(ch=fgetc(fp)) != (int)EOF){
となり、特に問題ない。
そして、
unsigned char ch;
としてしまうと、
while((int)(ch=(unsigned char)fgetc(fp)) != (int)EOF){
となり、ファイル終端でfgetc()からEOFが返ってきたとしても、
比較は「0x000000FF != 0xFFFFFFFF」(intが32bitとして)
となり、whileはいつまで経っても抜けられない(無限ループ)。
ありがとうございます。
本に出てるソースでも結構ひどいのがあるもんだな。
進行形で本のコードに悩まされてる
>>653のコードはASCIIまたはShift-JIS文字の
テキストファイルを想定しているんだろうから、
ファイル中に0xffがあることを考慮していないだけ
なんじゃないかな。
そも、入門用として動きをまずは覚えるのに0xffがーとかってもうちょいあとに
理解が深まるものじゃね?
左右の論理シフトと四則演算だけでビットANDやビットORを作るにはどうするのが効率良いのか?
>>685 入門用ならなおさら
int fgetc(FILE *)
の返り値を char で受けるのがそもそもおかしいのでは?
intの戻り値をcharで受けてる時点で違和感を覚えないとだめだな。
>>689 たしかに
>>680 の時点ではきづかなかった、rand()が線形合同がよりもはるかに絶好の突っ込み場所だったのに逃してしまったのは返す返すも口惜しい
またも簡単な質問ですがお願いいたします。
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[])
{
FILE *fp;
unsigned count;
if (argc != 2) {
printf("ファイル名の指定がありません\n");
exit(1);
}
if ((fp = fopen(argv[1], "rb")) == NULL) {
printf("ファイルを開くことができません\n");
exit(1);
}
count = 0;
while (!feof(fp)) {
fgetc(fp);
if (ferror(fp)) {
printf("ファイルエラー\n");
exit(1);
}
count++;
}
printf("ファイルのバイト数は %u です", count - 1);
fclose(fp);
return 0;
}
のprintfのcount - 1は何を一つ引いているのかよくわかりません。
\0とかでしょうか
左右の論理シフトは無くて四則演算だけでビットANDやビットORを作るにはどうするのか?
>>691 ループの最後はfgetc()でEOFが読めてるはずなので。
>>691 countがファイルのバイト数だということは理解してるよね?
EOFを読み取るまでfgetcで1バイトずつ読み込んでcountを++している。
ということは while(!feof(fp)){ } のループを抜けた時点では、countの値は
ファイルサイズ +1 になっているということ。
つまり余計な +1 を引いて正しいファイルサイズにしているだけ。
非常に悪いサンプルコードではあるが。
>>693 >>694 ありがとうございます
納得いたしました
つまり、EOFを読み取る分までカウントしているので
無駄なカウントを引いているということでしたか
ありがとうございます
打算計算が露骨に表に出すぎw
だからいくら謝罪したところで疑われるんだよこの人
まあキャラ的には面白いんだけど
今日本に来てる韓国の男性アイドルよりよっぽどイケメンだった
feofのサンプルコードだろうけどサイズを求め事をお題としているのが致命的にセンスが悪い。
fgetcをcharで受けてる件といい、その本はゴミ箱に直行した方がいいと思う。
ブックオフに売るのは2次被害拡大につながるので禁止。
正規表現ってパッと見じゃあ理解できない魔法の記号だからな。
>>698 まったく同感。もしかしたら林 晴比古の著作なんじゃないかな。
>>632 そのスレの685だけど、バカにもわかるように偏りを数字で出してやっただけで何かを出し惜しみしたつもりはないんだけど、
何をもって出し惜しみだと思ったのか知りたい
それをコードが書かれなきゃ理解できないバカが乱数について語るのは滑稽だとは思わないのか
そのスレの753(!=685)だけど、出し惜しみしたとゲスの勘ぐりしたってわけか。
クズ中のクズだな。お前二度と現れるな。
>>700 林晴比古って悪いのか?
新訂 新 C言語入門シニア編 で勉強してるんだが
>>704 そうお考えなのならばそうなんでしょうね。
>>705 早く出していただければなあ、と思っただけですが、まあ書きようによっては下衆の勘ぐりですわな、気をつけます。
これからも出現しますので、よろしければどうかご指導ください。
708 :
デフォルトの名無しさん:2012/11/10(土) 20:09:12.32
>>706 goto を嫌う理由でバファリンがどうのという説明を見た日から不信感もってる
コンパイラも読者も科学的なのに、非科学的なのはこいつだけだと思った
> これからも出現しますので、よろしければどうかご指導ください。
ふざんけんな。
この板の会話に参加するだけの能力も技術もないんだから、テメーは一生ROMってろ。
↓確率分布を語る資格のないバカのタワゴト(理由は教えてやらん)
> それはそうとこの方式を「完全なる一様分布関数」と呼ぶのには抵抗があるねえ。
林 晴比古はプログラム技術本著者におけるお笑い芸人
みたいなもんだよ。
ものすごいとんちんかんな内容の本を出している。
例を挙げると「C プリプロセッサパワー」という本がそれ。
絶対にまねしちゃいけない例の集大成。
そんなに悔しかったのか
>>689 そうか?
なら、memsetの第二引数がintなのにも違和感を覚えるクチかい?
>>714 負の数がかならずしも2の補数とはかぎらないこと+char がデフォでは signed か unsigned かが処理系依存であること
への配慮じゃないの?
716 :
デフォルトの名無しさん:2012/11/11(日) 02:26:27.31
C言語のポインタを理解するにはどうしたらいいですか。
ポインタに関する書籍を購入して読んで理解すればいいですか。
でもそれだと時間がかかるので、C言語のもととなるアセンブラを先に学習したほうが、
ポインタを理解する最短ルートなのではと思うのです。
ポインタを完ぺきに理解するのにお勧めのサイト、本があればご教授いただきたいです。
よろしくお願いします。
718 :
デフォルトの名無しさん:2012/11/11(日) 02:50:28.81
大学の講義で初めてポインタについて学習していたときに、
最初の難題にぶつかったのは、scanfの引数に&をつけること。
&をつける理由が、ちんぷんかんぷんでどうにもならなかった。
しかし、ポインタの概念や簡単な使い方をマスターすることで、いまではなぜscanfに&を付与するのか、
その理由を説明できる程度です。
あえて正解いわせてもらうと、scanf自体が、受け取る値が参照渡しになっているためである。
scanの中で処理し、その結果を引数に返すんだってことを理解している。
ここまであっていますか。
>>716 目で見るのも大切だけど、手や口も動かそう。
具体的には、
・メモリイメージを紙に書いてみる
・理解したことを、ポインタを知っている人や知らない人に説明できるようになる
ことが、実は凄く効果的。
それと、そのうち覚える事になるかもしれないけど、
「関数ポインタ」は中身は変数のポインタの応用だけど、
表記方法がちょっと例外的なので、それはそういうもんだと思って
踏まえておくこと。
720 :
デフォルトの名無しさん:2012/11/11(日) 03:03:48.51
>理解したことを、ポインタを知っている人や知らない人に説明できるようになる
ことが、実は凄く効果的。
こういうことはすごく大切なことなんだなぁと思う。
話それるが、本の内容を理解して頭の中に入れるんだがそれが必要な時に取り出せなければいけません。
そして取り出したものを行動に生かす(たとえば人に説明することが一つの例に当てはまる)ことができる。
それができてこお、読書経験は私生活・仕事に生かすことができるのです。
手っ取り早い話読んだ内容を人に説明することが一番効果的なわけだが、本の内容を頭に入れる工夫も
考えないといけないです。記憶した内容は時間の経過とともに薄れていくので、
それを防ぐ意味で物事を長期的に記憶するようなテクニックが必要です。
完全に話がそれましたけど、、。
アセンブラをやる。
理解できなくていいから入門レベルやってからCに戻る。
なんでポインタなんてものが出来たかが少しは理解できるようになる。
>>718 ポインタ完全制覇でも買え
javaもc#もPHPも、現在主流の言語はどれも参照渡しで副作用あるよ
構造体やクラスを値渡しするのが珍しいほう
そして、はやく教員免許か公務員試験を受けろ。
間に合わなくなっても知らないぞ
K&Rのポインタ、派生型の項目で十分だろ
gdbつかって目ぼしいポインタの型を調べりゃ良い
>>723 javaには参照渡し(call by reference)はない。あるのは「参照の値渡し。」
>>725 へー。知らなかった。
参照渡しと参照の値渡しで、どんな挙動の違いあるんだっけ?
>>721 ポインタのインクリメントで悩むことがあるぞ
アセンブラとCで進み方が違う
ポインタを使った応用例について詳しく書いてある本が良いですね。
問題集みたいなのもあればなお良い。
私はBASIC→Z80のアセンブラからプログラムを始めたので、
Cを覚えるに当たって特にポインタではつまづかなくて
ポインタ学習向けの具体的な書籍は知りませんが…。
あと、IDE(統合環境)もあると良いですね。
Windowsだと、無料のVC++Expressがありますね。
Cのソースコード上で、
命令を1行ずつ実行して変数の値を見たり編集したり、
(ポインタ変数の加減算で変数値の変化を確認したり)
ポインタ変数の示すアドレスの先のメモリを見たり編集したり、
そういうのが出来るの。
Linuxではどういうツールを使えば良いのか知りませんが。。
729 :
725:2012/11/11(日) 03:30:40.71
>>726 >>725 はコピペネタらしいんだけれども、それはともかく。
java がいうところの参照は new で確保したポインタと等価。
new で確保するようなオブジェクトは、new で確保する以外に確保する手段がない。(ごめんいってることがわかりにくい)
したがって、-> 演算子はドット演算子に置き換わって、-> 演算子はなくなった。
参照の値渡しってたんにポインタを渡しているのと等しく考えていいみたい。
ポインタでつまづく
1.*がついたりつかなかったり、よくわからん。
2.ポインタはアドレス
int a = 5; int *p;
でアドレス演算子(&)
p = &a;
で紐付け、間接演算子(*)でアドレスが指し示す内容を操作できる。
*p = 10;
printfでaを表示しても、aも10。ふむふむ。
3.ポインタと配列
int a[10]; int *pa;
pa = a;
あれ、アドレス演算子はつかないの? 配列名はアドレス? []は?
そのうち文字列をコピーする関数を習作でやってみましょうとかで
char *StrCpy ( char *dst, char *src );
なんか*ばっかりなんですけどでさっぱりに。
自分は最近やっと理解できたけどint *aとかよりint* aみたいな考え方のほうが分かるかも
それとポインタにも型があるってことを意識したら多次元配列名のポインタ演算の意味が分かった
732 :
デフォルトの名無しさん:2012/11/11(日) 05:04:44.37
>>728 viで同じことが出来る。
しかも高速に。
>>730 典型的な初心者の躓きですね。
ポインタ変数宣言時の*と、参照時の*は全く関係がない。
宣言は、それがポインタ変数であるとわかればよいのだから
本当は*でない別の記号、またはpointerなどのキーワードで
よかったのであるが、言語設計者が手抜きしたのである。
このたった一文字の手抜きがもたらした弊害は非常に大きく、
設計者は批判されてしかるべきであるが、既に故人である。
734 :
デフォルトの名無しさん:2012/11/11(日) 05:35:47.16
そういう初心者はLinuxのインストールから始めないと
計算機の仕組みが理解できていないとポインタはわからない
BIOSってわかるか?
わからないだろ
そんなんじゃダメだ
Linuxがわかればポインタなどわからなくても問題ない
GUIならWikipediaで「統合開発環境」を検索したら色々出てくるけど、
Anjuta, Eclipse, KDevelop, Qt Creator, WideStudio
とかかな。
あと
NetBeansIDE
ttp://ja.netbeans.org/ (ページ内のリンクを開くと英語になったりするけど
右上のChoose page LanguageでJapaneseを選べば大丈夫)
どれも使ったことが無いのでアドバイスは出来ないけど、
IDEがあるとCの理解が早まるのは間違いないと思う。
>727
>アセンブラとCで進み方が違う
うそを言うな
int a[10];
int* p = a;
で、p = p + 1; ってやったら、(多くの処理系で) 4 とか進むことを言ってるんだろ。
それぐらい理解してやれや。
>>731 わかりにくくなる要因に「char *a」と書くから、というのがあるように思う
「char* a」と書いて「char*」と「a」を視覚的に分けてやると、視点的にも「char型のポインタ型」と
受け取ってもらいやすいんじゃないかな?
「*a」だと、その後の「実体を指す」という書き方とかぶって
しまって理解を妨げるんだと思う
まぁ、これは俺の過去の実体験だが、昔はこう書く本もあった
「*」を「char*」のように買いても、「char* pa, pb」とは書けないから結局・・・
typedef char * PCHAR;
PCHAR pa, pb;
とする
>>738 アセンブラでもword,dword,qwordは認識してインクリメントするだろ。
>727
それはアセンブラをやったゆえの弊害ではなく
C言語自体の問題では?
745 :
デフォルトの名無しさん:2012/11/11(日) 10:56:35.70
C言語なんて時代遅れ
これからはLinuxの時代
「マイコン技術なんて時代遅れ」
747 :
デフォルトの名無しさん:2012/11/11(日) 11:20:49.86
fread なら !feof
fgets なら != NULL
で while の終了判定しているプログラムを多くみます
素人が見ると feof だけで良いような気がするのですが
使い分けてる理由はなんでしょう?
ポインタの理屈を理解するには神に書いて勉強するのが早いね。
書式がわかりづらいのはK&Rの最初の設計がまずい。
だからtypedefなんてものが必要になった。
>>744 Cの問題でもアセンブラの問題でもなく、単にそれぞれの仕様というだけじゃないかな。
Cはどこの処理系でも同じく
char*pa;pa++;は1bytes分のアドレス増加、
long*pb;pb++;は4bytes分のアドレス増加
と統一。
アセンブラは良く分からないけど、CPUによって違うのかな。
神じゃねぇ紙だw
以下のLoad関数に要素数を渡さず引数のLPSTR(char*)型配列の要素数を取得する方法はありますか?
void Load(LPSTR FileName)
{
//ここでFileNameの文字数が知りたい
}
void Init()
{
Load("a.bmp");
}
C/C++に「配列の要素数を取得する」という言語仕様はない。
取得したいなら数えるしかない。
>>747 使い分けているというか、fgets();は文字列に特化している便利関数。
内部的にfread();やfeof();の処理が含まれているような。
fgets();は例えるならprintf();みたいに、中ではintやdoubleを文字列に変換して
putc();したりする便利関数のようなもの。
>>753 その例だとFileNameは文字列なので、Load();の中で
strlen(FileName);
とすれば要素数(文字数)が求められる。
FileNameのために確保されているバッファのサイズ=配列の個数(配列のサイズ)
をLoad();の中で知るのは
>>752の言う通り、C言語では、出来ない。
知りたければ、
void Load(LPSTR FileName, DWORD n);
などとして、バッファのサイズを引数などで与える。
755 :
754:2012/11/11(日) 12:07:32.72
freeすると確保した分を正しく解放するわけだから
確保してるメモリのサイズはシステム内部で管理されてるはず
本当はポインタを介してどうにかしてサイズを知ることができるのではないのか
もちろん可能。
ただやり方が処理系によって異なると言うだけのこと。
>>757 malloc→freeに関しては、確保された時のアドレスの近くにサイズ情報の痕跡も
残っているかも知れないね。mallocの実装に依存するけど。
グローバル変数ならsizeof()で分かるけど、ローカル変数の場合は不可能に近いんじゃないかな。
スタックに確保されているとして、スタックのどこがバッファのために確保されたところなのか。
760 :
759:2012/11/11(日) 13:13:43.59
かぶったし、先走ってしまった。
誤
> malloc→freeに関しては、確保された時のアドレスの近くにサイズ情報の痕跡も
> 残っているかも知れないね。mallocの実装に依存するけど。
正
> malloc→freeに関しては、確保された時のアドレスの近くにサイズ情報も
> あるかも知れないね。mallocの実装に依存するけど。
ブロック毎にサイズを記録してると仮定しても、ぴったりmalloc()に指定したサイズだけ確保されてるとは限らないじゃん。
それはそうだが、誰もそんなことを話題にしてない。
知りたいのは、「確保してるメモリのサイズ」だよ。
プログラムが「確保してるメモリのサイズ」はmalloc()に指定したサイズでしょ。
>>753 fgets と feof を混ぜて使うとバグるよ
char *hoge = (char *)malloc(...);
Load(hoge);
この場合は処理系によってはLoad側でhogeの確保されたサイズが判ることがあるが
char hoge[] = "a.bmp";
Load(hoge);
とかだったら判らないでしょ
>>763 確保するのはライブラリで、ユーザープログラムが指定してた通りに確保するかどうかは、
実装とその時の状況に依存する。
sizeofでサイズが取得できるのはコンパイル時に静的に
領域が確定している変数だけ。
というか自分で確保したんなら自分がわかってるし、誰かが確保したんなら
教えてもらうIFにしなさい
>>747 聞きたいのはfread, fgetsの違いじゃなくてfgetc, fgetsの違いじゃないのか?
> fread なら !feof
で判定しているプログラムがそんなに多いとは思えない。
>>742 参照先を抜き出すときは byte ptr や word ptr 等の修飾子で大きさを指定できるけど
ポインタに相当するレジスタのインクリメントは文意によらず1加算だよね?
>>771 > > fread なら !feof
> で判定しているプログラムがそんなに多いとは思えない。
ランダムリードで fread() を使うときは、feof() を使わないけど、
終端までのシーケンシャルリードだと終端の判定に ferror() と feof() の
組み合わせを普通に使うんじゃないか。
あらかじめサイズを取得して、読み込み量を計算して、、というのは無駄では。
>>772 それは全てのCPUアーキテクチャ共通なのかどうなのか
>>774 そう言われるととても自信が無いw
ポインタ特化のインクリメント命令セット(1加算 2加算 4加算 etc)を持つものがあるならゴメンだ
>>769 ダウト
sizeof "abcdef" とかもできる。
>>774 作れば出来るので非存在の証明は不可能。それの存在を主張するやつが実例を示せ。
x86のstring命令はそれに近いが。
>>778 > 領域が確定している変数だけ。
~~~~~~~~~~~~~
sizeof 1.5 とか sizeof 'a' とかも問題なくできるな
68Kのポストインクリメントとかはバイトかワードかロングワードかで足される数が変わる。
ほとんど禅問答だな。
>>782 そういう奴がいるかと思って、わざと p++ じゃなくて p = p + 1 って書いている。
さすがに、レジスタが指している先の型を認識して足される数を変えるプロセッサはないだろ。
おまえら引っ掛け問題みたいの大好きだな。
ぶっ掛けるのも好きだよ
>>785 重箱の隅のようだけど
初心者が見落としやすく(「知らない」ではなく「知っているつもりだったが見落とす」)、
動作への影響も大きく、デバッグでハマりやすい。
(エンディアンも知らないとハマるね)
今日も大漁ですね。
>>773 fgetsではeof/error判定しなくて、freadはする根拠ないよね。
両方するあるいは両方しないなら良いけど。
> あらかじめサイズを取得して、読み込み量を計算して、、というのは無駄では。
あらかじめサイズがわかっているn個以下のレコードを読むのがfreadなんだけど。
そういえば昔、DOSのLSI-C試食版だったかな。
10MBくらいのバイナリファイルを読んでデータ変換して別ファイルに書き出すプログラムで、
64kBまでしかmalloc()できないバッファでfread()〜データ変換〜fwrite()を
繰り替えす処理を書いたときにfeof()とferror()を使ったような記憶が。。
>>790 LSI-C86試食版だった。
そして、64kB制限はコードとデータの合計だったかな。
確かにmalloc()は32kBくらいまでしか指定しなかった記憶が。。
チラ裏ごめん
792 :
デフォルトの名無しさん:2012/11/11(日) 17:45:44.24
質問させて下さい
整数A、整数Bの全ての和を出す際にその範囲の整数全てを表示させたいのですがどうすればいいのでしょうか?
例えば整数A:25、整数B:18なら18,19,20,21,22,23,24,25の全てを足した和は%dである。
と言った感じです。
整数A、Bの和を出す事は出来たのですが、足す整数を表示する方法がわからなくて・・・よろしくお願いします。
>>790 そういうときは低水準 read() を使ったほうがいい。feof() とか ferror() とか正直いらない
>>794 ありがとうございます。
出来れば整数A,Bも実行画面に表示したいのですが、その場合はどのようにすれば宜しいのでしょうか?
質問ばかりですみません
> 25,の
だっせー
#include <studio.h>
>>801 何度もありがとうございます。
もう一度質問させて頂きたいのですがA:25,B:18で実行する場合にはどのようにすれば宜しいのでしょうか?
if、whileを使うのだろうと言うのはわかるのですがどのように挿し込めばいいのかわからなくて・・・
#include <stdio.h>
int main()
{
int a,b;
int n,t=0;
puts("二つの整数を入力してください。");
printf("整数1:"); scanf("%d",&a);
printf("整数2:"); scanf("%d",&b);
//scanf("%d%d", &a, &b);
for (n = a; n <= b; n++) {
printf("%d,", n);
t += n;
}
printf("の全てを足した和は%dである。\n", t);
return 0;
}
ほとんど答え出てるじゃん
CPUのファンがうるさくなるでしょ
>>804 遅くなりましたが無事出来ました!
本当にありがとうございました
808 :
デフォルトの名無しさん:2012/11/12(月) 01:22:00.15
このWeb(
http://japanese.joelonsoftware.com/Articles/Interviewing.html)を読んで、
「文字列をインプレイスで反転させる」を作ってみたのですが、
この著者?の方が求めるコードってこんな感じなのでしょうか。
ポインタ演算使うの?って思って。
1 #include <stdio.h>
2 #include <string.h>
3
4 void reverse(const char* c)
5 {
6 int len;
7 len = strlen(c);
8
9 while(len != -1){
10 printf("%c",*(c+len));
11 len--;
12 }
13 }
14
15 int main()
16 {
17 char *str = "This is a pen.";
18 puts(str);
19
20 reverse(str);
21 printf("\n");
22
23 return 0;
24 }
void reverse(const char* c){
char *p = c;
while(*p!='\0')p++;
while(p>c)putchar(*--p);
}
>?関数の実行速度は充分速いか? strlen を何回呼ぶ事になるのか考えてみよう。
>かつて私はO(n)であるべきstrrevのアルゴリズムがO(n^2)になってしまっているアルゴリズムを目にした事がある。
>彼らは繰り返しの strlen をループの中で呼んでしまっていたのだ。
どっかのバカもこうういクソコード書いてたな
>>811 まあまあ、勘弁してやってくだしゃあ。
時々油断してしまうんです。今はしないように気をつけています。
油断じゃなくて、それがいい書き方だと思ってたじゃねーかw
char *str = "This is a pen."; と
char str[] = "This is a pen."; って何が違うん?
>>814 おおざっぱにいって、
"This is a pen."
が格納される領域が異なります。
またこの格納領域の属性も異なる場合があります。
>>814 このスレで質問するときは「Qzは回答禁止」と書いておくこと、回答する能力がないのに
見当はずれのレスつけてひっかきまわすだけだから。
こっちばOK
char *str = "This is a pen.";
...
str = "You is a big fool man.";
こっちばだめ
char str[] = "This is a pen.";
...
str = "You is a big fool man.";
こっちばOK
char str[] = "This is a pen.";
...
strcpy(str, "You is a big fool man.");
snprintfのnってどういう意味?何の略?
snprintf 〜 n文字指定のsprintf
strncpy 〜 n文字指定のstrcpy
みたいなもんじゃないかな。
strcmpi, stricmp 〜 ignore(大小文字区別無し)のstrcmp
strncmpi 〜 n文字指定かつignore(大小文字区別無し)のstrcmp
Write formatted output to a character array, up to a given maximum number of characters
_vstprintf_s の出番か
variable string text print formatted - secure
stricmp と strcmpi は
どう使い分けるのが正しい?
strcmpiって使ってるの見たことないなぁ
大抵stricmpかstrcasecmpだ
strcmpiはstricmpを使ったマクロだからstricmpだけ使えば良いよ。
strcmpi: posix
stricmp: ISO
そもそも文字列リテラルを書き換えられないようにしてるコンパイラの設計がおかしい
そこはリテラルっていうくらいだし…
835 :
デフォルトの名無しさん:2012/11/12(月) 18:57:10.03
仮に書き換えられたとして
これでは Abc にならない
"abc"[0] = 'A';
puts("abc");
アクセス先の同一性を保証させるためには
ポインタが必要になるだろ
char *p = "abc";
p[0] = 'A';
puts(p);
そんなつまらんことせんでもほれ
static char p[] = "abc";
煮るなり焼くなり犯すなり
べつにstaticはいらないような
書き換えられたら困るだろ。
せやな
せやろか
せやせや
printf("aho\n");
これがmancoとか出力する可能性が出てくるんだぞ。
なんでよ
異なるところに出現した文字列リテラルが別々の実体をもつことは規格上要求されていない。
コンパイラは同一の文字列リテラルの実体をひとつにまとめてもよい。
どれがどれに対する突っ込みなのかぜんぜんわからんw
おパンティー殿
システムコールについてですが、子プロセスで端末から標準入力した値を親プロセスで使うプログラムが書けません。
スレ違いだったらすみません。
848 :
846:2012/11/12(月) 23:33:15.16
fork, waitのみではできないのでしょうか?
出来ない。何らかのIPCを使わないとダメ。
850 :
846:2012/11/12(月) 23:42:33.62
>>849 ありがとうございます。また詰まったら質問にきます。
そういうの標準ライブラリだけで出来るんですか?
IPCはOSが提供している。
標準ライブラリだけで出来るが、複雑な構造のデータを渡すならば
標準じゃないライブラリの検討もした方がいい。
Inter Planet Communication
iPC
ips
標準ライブラリ使いたいなら、ファイル経由で
dupしてforkだろ
dupフwwwwwwwwwwforkヌポゥwwwwwwwwwwww
assert()で偽のときに実行時にソースコードの一部が表示されますが
コンパイラはどんな仕組みで実行ファイルにソースを埋め込んでいるのですか?
あれと同じようなことを自分の関数でもやってみたいです
assertはマクロ。定義を見ればわかるが#つかって式を文字列化している。
できました
本当にありがとうございました
いえいえ
うちうち
質問スレ……、で合ってますよね?
C言語を用いて配列を使ってスタックの実装を行う課題が出されました。
要素はchar型です。
push,popの実装は特に問題ないのですがtopという
『スタックの先頭要素を参照する。返値の型はchar。
スタックが空の時どうするかは,データが7bitしか使わないことに着目して工夫すること。』
という関数を実装するよう指示がありました。
char型がデータを7bitしか使わないことを利用して工夫するということが
どのようなことか見当がつかないので、どなたかにご教授お願いしたいです。
866 :
桃白白:2012/11/13(火) 18:33:06.67
>>865 桃白白の国語辞典能力をフル活用して考えた結果、7bitしか使わないというのは
7bitは少ない数値であると評価する意思があることを示すものであるわけだから、
つまり、あれだろ、そういうことなんじゃないか、余分なデータをなんかあれしとくんじゃね。
-1でも返しとけ
スタックが空なら負号を返せってことじゃね
top関数の戻り値
・スタックが空じゃない 0〜127
・スタックが空 -1
最上位ビットっていうとエルメスとかララァとかと関係ありますか?
語源は一緒だね。
くりあがるとファンネルになります。
874 :
デフォルトの名無しさん:2012/11/13(火) 21:36:22.19
C言語でも文字列型って実装可能なんじゃないか?
例えば
if(x==1)printf("山");
else if(x==2)printf("谷");
って可能じゃん。
対応付けられるじゃん。
でっていう
876 :
865:2012/11/13(火) 21:39:55.97
Cの配列は要素数固定ですが
Cで作られたスクリプト言語では
要素数上限なしのリストなどの機能が実現できているのは
どういうからくりなのでしょうか。
領域が足りなくなったら動的に確保して増やしてるから
>Cの配列は要素数固定ですが
まずこの認識が間違ってるよ!
正しいだろ。C99の可変長配列でも要素数の増減は出来ない。
881 :
デフォルトの名無しさん:2012/11/14(水) 11:43:51.46
>>877 C でもリストを作れば要素数上限なしになるぞ
# 上限なしつってもメモリ空間がそもそも有限なのは置いといて
置いといてね
馬鹿には無理
変数を配列として宣言する前提なら要素数は固定だね。
動的に確保した領域をポインタ経由で配列的に使うのなら
また話は違うけど。
配列っていったら純粋な配列のことだけだと思え
勝手に拡大解釈するな
次にお前は
Cの配列のインデックスは整数のみですが
Cで作られたスクリプト言語では
連想配列などの機能が実現できているのは
どういうからくりなのでしょうか。
という
連想配列はキーをhashで整数に変換した配列だと思えば良い
hashの衝突回避についても勉強汁
888 :
デフォルトの名無しさん:2012/11/14(水) 20:36:38.71
計算量についてなんだが
for(1000回)
for(100回){1万回+1万回+1万回}
くらいだとやっぱり1分以上実行にかかっちゃう?
>>888 処理内容によるだろJK
30億回だから並列化とかも考えると1秒〜くらいとしか言えない
890 :
デフォルトの名無しさん:2012/11/14(水) 21:02:40.38
それをアンロールするコンパイラって具体的にどれだ?
なぜ急にアンロール
いまいちfor文が回る条件が分からないのですが
@
for(i=0; i<10 ; i++){
〜〜〜〜
〜〜〜〜
cnt ++;
}
と
A
for(i=0; i<10 ; i++){
〜〜〜〜
〜〜〜〜
i=i+1;
}
は違いますよね?
for(i=0; i<10 ; i++){
〜〜〜〜
〜〜〜〜
}
だけでは回りませんよね?
だけでブンブン回るよ!
やっぱりそうなんですか?
i=i+1;を追加したらちゃんと動作したんですが、なんなんでしょうか?
なんどもすいません、これです
int i, n = 6, work;
int data[] = {10, 3, 8, 2, 6, 7};
for(i = 0; i<n; i++) {
work = data[i];
data[i] = data[n-1-i];
data[n-1-i] = work;
i=i+1;
}
for(i = 0; i < n; i++) {
printf(" %d", data[i]);
}
puts("");
return 0;
}
7.6.2.8.3.10と逆順に表示させるわけなのですが
i=i+1;をいれたらそういう風に表示されました。
>>895 たまたま上手く動いてるように見えてるだけだね
紙に書き出してみればすぐわかるよ
ヒントは、半分でOK
そもそも
work = data[i];
data[i] = data[n-1-i];
data[n-1-i] = work;
がうまくいってないってことですよね?
ゆえにprintfで配列の順番順にただただ表示されてしまう。
10と7、3と6、8と2を交換するようにすればいいんでしょうか?
>>897 いや、そこは正しいよ
交換は、インデックスの半分まで実行すれば良いと言う事に気付くかがポイント
後ろ半分を実行しちゃうと、前半で交換した内容を、元に戻してしまうのだね
つまり、forの継続条件は i<n/2 が正しいんだな
すいません意味がわかりません。
前半で交換した内容を、元に戻してしまうのはどこで指示してるんですか?
あと何故i=i+1でもどうような事がおこったのでしょうか?
>>899 だから、書き出して見ろっての
頭で理解できなきゃ、体を動かせ
data[] = {10, 3, 8, 2, 6, 7};
i=0: 7,3,8,2,6,10
i=1: 7,6,8,2,3,10
i=2: 7,6,2,8,3,10
これでわからんか?
>>900 同じ様に、forの各回の最終結果をかいてみればすぐわかる
書くのがめんどくさければ、毎回data[]全てprintfしてみ
これ例えば012345を543210にするのではなく
0と5、1と4、2と3をいれかわる動きだったのですか?
正直workって何の為にあるかのもわからずに考えていました。
書き出していましたが
6-1-0=No5
6-1-1=NO4
6-1-2=No5の順に並ぶものだと思っていたので
>>902 あっ…っごっめーん
俺が見間違えてたわ
てへっ(赤面逃亡
>>902 そうだよ
iの動きとn-1-iも書き出してみれば、もうわかるよね
>>903 ちょっ、おまっ、何言っている?
すいません、自動的に入れ替わるのは配列の特性でしょうか?
例えば
○×△□という配列で
<先頭にこいよ、□
□「分かりました、○さん交代しましょう」
○「いいよ」
みたいなことですよね?
個人的にはひとつひとつの値に順番を指定するものだと思っていました。
自動的に入れ替わったりはしない
>>895 自分も忘れる時在るけど、i < n / 2ってしないと一周してもとの位置に戻ってるんだよ
i < n-1-i の間はやりたい交換をおこなってる
i >= n-1-i から せっかく交換したものをまた交換して元に戻しちゃってる
いや、これは忘れるとかいう問題じゃないだろ。お前ら向いていない。
なぜ
for(int i = 5; i >= 0; i--)
printf("%d\r\n", data[i]):
ではいかんのか?
forで変数宣言すんな
> forで変数宣言すんな
>>909 最初に書く時はじっくり考えながら書くので間違い少ないけど、違う言語に移植する時とか、ウッカリミス多くならないか?
>>910 X
>for(int i = 5; i >= 0; i--)
>printf("%d¥r¥n", data[i]):
O
>for(int i = 5; i--; )
>printf("%d¥r¥n", data[i]):
標準的イディオム
>for(int i = 4; i >= 0; i--)
>printf("%d¥r¥n", data[i]):
>>914 リーダブルコード読めよ。読者に考えさせるコードは駄目なコードだ
正解
for(int i = 5; --i >= 0; )
printf("%d\r\n", data[i]):
n=6だからn-1である5から始まってるんだけど
ああごめん
>915 だけ見て脊髄反射してもうた
配列のケツ側から順に何かするのは好きじゃない。
その必要があることもある
if(int i = 0; i < strlen(str); i++) hogehoge
みたいなコード書くよりも
if(int i = strlen(str); --i >= 0; ) hogehoge
のが速いというのは本当ですか?
923 :
デフォルトの名無しさん:2012/11/15(木) 16:59:55.09
釣りだろうけど
strlen の実行回数が全然ちがう
釣り認定厨乙
int len = strlen(str);
if (int i = 0; i < len; i++) hogehoge;
としとくのが妥当だろうな
>>922 ウソの場合もある。
最近のコンパイラ(たとえばVC2010)はhogehogeの内容によるがstrlen呼ばずに
直接strを参照するコードを生成できる。
> if(int i = 0; i < strlen(str); i++) hogehoge
副作用のない関数だと、同じ引数を与えて何回も呼び出すコードは、
1回に最適化されてしまうことがあるね。gccでもそう。
あと、0以外の定数との比較より0との比較の方が速いというアーキテクチャは存在する。
変数(レジスタ)との比較より正負判定の方が速いというアーキテクチャも存在する。
x86じゃ有意な差は出ないと思うけど。
928 :
デフォルトの名無しさん:2012/11/15(木) 19:29:12.19
この場合、副作用は i++ であって strlen は哀れな被害者
グロ注意
ばぶー
935 :
デフォルトの名無しさん:2012/11/15(木) 22:37:29.59
結局色んな専門書読んだけど日本語のレベルで意味が分からなかったから
挫折した。いくら時間があっても足りないわ。
分かりやすい本って本当に無いな。
何読んだ?
これまで学んだ言語は?
937 :
デフォルトの名無しさん:2012/11/15(木) 23:09:10.58
>>936 これまでに学んだ言語はC言語とJavaだけ
Javaは継承とか多様性までは理解できたけど
ジェネリクスとか内部クラスとかシンクロナイズドあたりから
ほとんど意味が分からなくなって勉強が頓挫した
でCに戻ったけどスレッドを勉強して意味が分からなくなって
挫折した
938 :
デフォルトの名無しさん:2012/11/15(木) 23:11:31.93
関数ポインタという概念を理解するのに1週間もかかったのに
これじゃ辞めたほうがいいかな 単位だけ取れたらいいか
939 :
デフォルトの名無しさん:2012/11/15(木) 23:18:59.12
きも
えらく抽象度の違うものを一気に勉強しようとしすぎだな
ちょっと難しくなると理解できた試しがない
>>927 0との比較は自分自身とのAND比較に最適化されるから
普通どのアーキテクチャでも速いんじゃね
て言うか、大抵のプロセサで演算結果が 0 かどうかでフラグ立つから、
比較すら必要ないでしょ。
68系みたいに、ロードするだけでフラグ立つプロセサもあるし。
ああ、そりゃそうだな・・・
0との比較は速いといっても、配列の方が要素の数が固定か
スタックのような使い方に限られてしまってそうな。
x86じゃロードで0フラグ立たないのよ
イマドキのアーキテクチャなら、
スーパースカラーでそんな1命令くらいふっとぶんじゃね?
ちなみに、0と比較せずに、-1と比較しやがったw
つまり、0との比較に拘る必要がないんだな、x86は。
乙
丙
955 :
デフォルトの名無しさん:2012/11/16(金) 21:06:49.81
http://i.imgur.com/E1yrk.gif これ、テストの過去問なんだが、↓であってる?
1: printf 6:5*a*a+2*a*b+b*b 11: if
2: scanf 7: 5×%d+2×%d+%d 12: v<-8.5 || 8.5<=v
3: %d\n 8: a*a,a*b,b*b 13: printf("エラー")
4: &a 9: %f\n 14: else
5: &b 10:&v 15: -8.5<=v && v<0.0
16: printf("-1.3×vの値") 21: i++ 26: sum+=i
17: printf("1.3×vの値") 22: printf("*") 27: i++
18: for 23: i=1 28: sum
19: i=1 24: sum=0
20: i<=10 25: sum<=10
2-a:
int n,a;
a=1;
printf("正の整数:");
scanf("%d\n",&n);
while(n>=a){
printf("%d " a);
a+=2
}
956 :
デフォルトの名無しさん:2012/11/16(金) 21:11:53.53
ゴメ、スペースってこうなんのな。
にわかチャンネラーだから許してくれ
スペースを_に直してやってみた。
ズレんのも承知だが・・・
2chの先生方よろしくたのむー
1: printf_______6:5*a*a+2*a*b+b*b________11: if
2: scanf________7: 5×%d+2×%d+%d______12: v<-8.5 || 8.5<=v
3: %d\n_________8: a*a,a*b,b*b___________13: printf("エラー")
4: &a___________9: %f\n__________________14: else
5: &b___________10:&v____________________15: -8.5<=v && v<0.0
16: printf("-1.3×vの値")____21: i++___________26: sum+=i
17: printf("1.3×vの値")_____22: printf("*")___27: i++
18: for______________________23: i=1___________28: sum
19: i=1______________________24: sum=0
20: i<=10____________________25: sum<=10
958 :
デフォルトの名無しさん:2012/11/16(金) 22:41:48.32
>>957 さんきゅ、
(3)はキーボードで打つ時にエンター押すから、「\n」はいらん訳ね。
&ampとかしっかり勉強しま
959 :
デフォルトの名無しさん:2012/11/17(土) 00:24:23.58
powがプログラム全体にエラー引き起こす可能性ってありえますか?
powを使うと実行時に局所的ではなく全体に影響を及ぼすエラーが
出るんですが.......
>>959 説明が意味不明。
そもそも「全体に影響を及ぼす現象」の原因がpowだということを
何を根拠に判断したのか?
エスパーーーッ
962 :
デフォルトの名無しさん:2012/11/17(土) 00:34:04.84
>>959 pow(-1, 0.5);
とかやったの?
エヴァの制御系もC言語で書かれてるんですか?
printfはint型の戻り値があると聞いて、
下記のようなコードを見せられました。
#include <stdio.h>
int main ( void )
{
int i;
if ( ( i = printf ( "Hello World\n" ) ) > 0 ){
printf ( "成功:%d文字\n", i );
}
return 0;
}
実行すると、
Hello World
成功:12文字
printfが画面に文字を出力するのは戻り値というか、そういうものではないのですか?
うまく言えませんが、何か変な感じがして・・・
純粋に関数としてみると、printfは書き込まれた文字数を返す関数。
画面に文字を表示するのはprintfの副作用。
whileの中で値をいじってないのに
while終了後値が変わっているんですが原因は何が考えられますか?
KOUZOUTAI[10]
KOUZOUTAIは要素にint a と double bを持ちます。
初期値として全てのKOUZOUTAI[i].bを1.0にしてprintfでwhile文の前に
確かめたら1.0と表示されます。
whileの中で書く文は単にKOUZOUTAI[i].bを表示するだけの命令です。
ところがwhileを抜けた途端0.0になってしまいます。
何故でしょう?
>>966 すみません、その副作用とはなんでしょうか。
ごちゃごちゃ書いてないで、コード晒せよ。
>>967 書式指定のミス
不正なポインタ操作
のいずれか
現象が再現する最小のコードを作ってうp!
>>970 ありがとうございます。例えば
KOU[0].IN[1][1]はいじられたくないんですよ。
KOU[0].IN[x][y]をwhileでx=1,y=1を避けるように
計算したら何故かKOU.IN[1][1]が書き加えられてます。
計算はKOU.HAI[X][Y]=KOU.HAI[X][Y]+1000;です。
ちなみにちょっと変わった事をしていてXとYは X[TEN] Y[TEN]で
X[TEN]={0,2,3,4,5,6,7,8,9,10,11}
Y[TEN]={0,2,3,4,5,6,7,7,8,10,11}で与えています。
でX[TEN]とY[TEN]は必ず{1,1}を排除するようにしてるのです。
つまり
KOU[0].IN[X[w]][Y[w]]=KOU[0].IN[X[w][[Y[w]]+1000
をしてもKOU[0].IN[1][1]は変わらないと思うのですが......
書き換えられてないかチェックのために
for(w=0; w<=9 w++)
{
printf("[%d %d]\n",X[w],Y[w]);
KOU[0].IN[X[w]][Y[w]]=KOU[0].IN[X[w][[Y[w]]+1000
}
としています。
そうすると
[0,0] [2,2] [3,3] [4,4 ]..............
と[1,1]は排除されています。
しかしKOU.HAI[1][1]は書き換わっています。
>>972 配列の範囲外にアクセスしてるんじゃないの?
hoge_type IN[10][10];
の変数があるときに
IN[0][11]=hoge_value;
みたいにしてるとか
◆JWhSl75IiON1
コードは意図したとおりではなく、書かれたとおりに動く。
>KOU[0].IN[1][1]はいじられたくないんですよ。
あなたの意図はそうかもしれないが、コードはいじるようになっているんでしょ。
とにかく再現する最小のコードを作ってアップしてみなよ。
再現するコードを作っている段階でバグに気づくなんて、よくあることだ。
>>968 int x;
int foo(void)
{
x = 100;
return 200;
}
で、xの値が書き換わってしまうのはfooの副作用。
int bar(void)
{
printf("%d\n", 300);
return 400;
}
で、数字が表示されてしまうのはbarの副作用。
>>976 ありがとうございます。
エラーが出る範囲で簡略化してみようと思います。
少しお待ちください。
>>977 うーん、return で返す値以外は、関数にやらせることが"副作用"なんですかね。
引数void戻り値なしなら、関数の処理は全部、"副作用"?
>>964 magi は「int の C 」らしいですよ、誰がそういってたっけ?
>>979 >引数void戻り値なしなら、関数の処理は全部、"副作用"?
そのとおり
あんまり関係ないが、グローバル変数ばかりで引数戻り値voidの関数ばかりのコードを見たときは
悪い意味で衝撃を受けた
void func(int *a){
*a = *a + 1;
}
を副作用って言うのは、正直微妙な気がする。
#include<stdio.h>
int main(void)
{
struct kou{double in[10][3];};
int i;
struct kou out[10];
i=0;
printf("%.30f\n",out[0].in[1][0]);
while(i<=1)
{
out[0].in[0][3]=out[0].in[1][3]+1;
i=i+1;
}
printf("%.30f\n",out[0].in[1][0]);
return 0;
}
これです...
1増えてしまっています。
>>984 ちょwwww
自己解決しましたw
3が原因ですか...
左の10に注意してるだけで右忘れてた.....
ありがとうございます....
1日考えて分からなかったのがばかばかしく思えてきた......
自己解決?
自己解決してねージャン
まあ一人で入れ込むバグなんてえてしてそんな程度だよね
2回同じ部分を指摘されてようやく「自己解決」ってんだから触らないほうが良い
基本的な事を教えて下さい。
A,B,C.cという3本のソースファイルがあります。
この3本はそれぞれマイコンメーカから提供されるツールによって
吐き出されるヘッダファイル(DEV.h)を取り込みます。
※DEV.hは頻繁に変更される。
このDEV.hの中に以下の様な変数を初期化している箇所があり、
複数のソースファイルでインクルードすると「multiple define」のエラーがでます。
data[] = {初期値};
仕方ないのでB,C.cではDEV.hをインクルードせず、DEV.hに変更がある度に、
DEV.hから必要なdefineをコピペしています。
このコピペの操作を無くしたいのですが何か良い方法はないでしょうか?
>>989 ラッパーを作って
DEV.h に依存するファイルを一つだけにしてしまう
ヘッダに実体書くなよバーカバーカってマイコンメーカに言う
DEV_Include.h
#ifndef DEV_H_INCLUDED
#define DEV_H_INCLUDED
#include DEV.h
#endif
>>989 A, B, C は最終的にリンクして一つの実行ファイルにまとめるのですか?
であれば
>>991 が正解、というかしかたがないので、DEV.h の該当部分をコメントアウトして、data[] = { .. } をA, B, C のなかの一箇所だけにかいておくようにするしかないですね。
>>989 そんな阿呆メーカのファイルに依存するものを三箇所に分散させた馬鹿に文句を言うべき。
でないと、今後もメーカが修正したときにも修正を強いられることになりかねない。
強いられているんだ!!!
ume
そもそもそんなメーカのマイコン使うなよ
使うことを強いられているなら
>>991でメーカ側を矯正すべき
static付けとけ
1001 :
1001:
このスレッドは1000を超えました。
もう書けないので、新しいスレッドを立ててくださいです。。。