manよりMSDNの方がいいぜ!!ワンワン
それはジョークで言ってるんだよな?
4 :
C言語 :2007/03/19(月) 16:56:18
↑ ウイルス
6 :
C言語 :2007/03/19(月) 16:57:26
↑ ウイルス
8 :
C言語 :2007/03/19(月) 16:59:38
>>5 ごめんね。
今度君の狂った脳みそのためのアンチウイルスソフト作ってあげるから許して。
9 :
デフォルトの名無しさん :2007/03/19(月) 17:40:32
c言語を始めたいと思っていますが 無料でc言語をコンパイルして実際に ゲームとかできる環境になるのでしょうか? できるのならソフトとかのURLはってください 今は無料で手に入れたソフトを使っていますが 使い勝手が悪いのでいいやつをおしえてください。
10 :
9 :2007/03/19(月) 17:45:34
自己解決しました スルーしてください。
>>9 お前には無理だ
あきらめて学業に専念するか働きに出なさい
Cでゲームを簡単に作れると思ってるなら辞めとけ。
多分、
>>9 が考えてるようなゲームを1人で作るには10年かかる。
せめてVC++,C#とかなら・・・スレ違いだけど。
13 :
デフォルトの名無しさん :2007/03/19(月) 20:20:35
C言語を触りだけしかやったことのない初心者ですが これから本格的にC言語を学びたいと思っています 使用用途はロボット等を制御する事です 何かお勧めの入門書はありますか?
シミュレーションで学ぶ自動制御技術入門
15 :
13 :2007/03/19(月) 21:06:02
>>14 ありがとうございます
明日本屋で探してみます
test
どっちかっていうとC言語そのものより 開発環境の作り方とか制御の仕方とかの方がしんどいと思うよ
18 :
13 :2007/03/19(月) 23:34:55
あのー僕が13なのですが・・・ でも15と言いたい事は同じですw なんか影の自分が暗躍してるのかと思ったw
なんか前スレから乗り替わる奴いるから、大事な質問ならトリップつけた方がいいかもね
てす #うんこちんちん
#include <stdio.h> int main () { char c; scanf("%c", &c); if (c == 'a'); { printf("入力値はaです。"); }/*警::コードは関数をもたない*/ else if (c == 'b') { printf("入力値はbです。"); }/*エラー:elseの位置が間違ってる*/ else if (c == 'c') { printf("入力値はcです。"); } else { printf("入力値はa,b,c以外です。") n; }/*エラー:ステートメントにセミコロン(;)がない*/ return 0; } と出るのですが、どうしてなのでしょうか? if else構文の最後のelse文の「どれにもあてはまらなかった場合に行う処理」の正しい書き方がよくわからないです。
>if (c == 'a'); { printf("入力値はaです。"); }/*警::コードは関数をもたない*/ セミコロンが余計。
>>21 >if (c == 'a'); {
セミコロンがあるので、そこに空文があると見なされている。
他にもTypoがあるな。
/*標準入力とswitch構文sample19.c*/ #include <stdio.h> int main () { char c; scanf("%c", &c); switch (c) { case 'a': printf("入力値はaです。"); break; case 'b': printf("入力値はbです。"); break; case 'c': printf("入力値はcです。"); break; default: printf("入力値はa,b,c以外です。"); break; } return 0; } 21は22をif else構文の形に書き換えてみようと思ってやったものです。 どなたか詳しい方ご教授ください。 コメント部分の箇所にエラーや警告文を書きました。
26 :
デフォルトの名無しさん :2007/03/20(火) 13:10:20
printf("入力値はa,b,c以外です。") n; nがこんなところに!?
素早いレスどうもです。 ちょっとやってきます。
22として書く前にソッコーでレスが付いたなw
21ですがおかげさまでできました。 参考書の例文に「else{ 処理n;}」と書かれてたので↑でやってたのですが、 どうやらnはn番目という表記だったようですね。勘違いしてたみたいです。 ありがとうございました。 また聞きに来るとは思うのですが、その時はよろしくおねがいします。
1行にいろいろ詰め込むと、どのエラーかわかりにくくなるぞ。
for(;;;) printf("\a"); と、ビープ音鳴らしまくったら、 ハードの方とかおかしくなったりします?
音波振動によるダメージがあるかも
ねーよ。
>>31 デバッガで実行するなら兎も角、環境によってはかなり止めにくくなるからやめた方がいいよ。
>>31 ビープ音を聞き続ける人間というハードがおかしくなるかもしれない。
VisualStudio2005にしたけどVS2002の時のソース、コンパイル普通に通るんだね。。 (全て_s付きの物に変えないといけないかと思った。 けど唯一、経過時間のところでtime_tがどうとか言われて通らない・・
>>36 で、何が聞きたい?
解決策が知りたいならエラーメッセージをコピペしてちょ
VC++ 2005のtime_tは通常64ビットになったが、 _USE_32BIT_TIME_Tを定義しておくと今までどおり32ビットになる。 試しにプロジェクトオプションでそれを追加してみたらどう? でもこうすると当然2038年問題の影響を受けることになるから、 それで動くようになったとしても早めに直せよ。
39 :
36 :2007/03/20(火) 21:06:26
>>37 すまそ、
>>38 の言うとおりにしたらコンパイルできたよ。。
ただの実行日時(JST)と経過秒数が出るだけの、
2038年まで使う予定もないテストプログラムだから別に今はいいや・・orz
/*sample49.c*/ #include <stdio.h> int main (void) { printf("%s %d %d\n", str, &str, &(*str)); str = "日本語"; printf("%s %d %d\n", str, &str, &(*str)); return 0; } strが未定義のシンボルと判断されてしまうのですが、どこがいけないのでしょうか? ポインタ変数を使ってアドレスをを表示させるというのをやっています。
char* str; がなくね?
/*sample49.c*/ #include <stdio.h> int main (void) { char *str = "abc"; printf("%s %d %d\n", str, &str, &(*str)); str = "日本語"; printf("%s %d %d\n", str, &str, &(*str)); return 0; }
43 :
デフォルトの名無しさん :2007/03/21(水) 21:24:03
>>40 strを宣言してください
char *str;
3人も同時にレスありがとうございます。 「char* str」を書いたら大丈夫でした。 参考書通りにやったのに駄目だったのでほんと助かりました。
さあ、その参考書名・著者をさらすんだ。
普通に1文わすれてただけっぽ〜い
実は図書館で借りた本で、既に次版で修正されてるとか正誤表に載ってるとか そうじゃなかったら その参考書名・著者をさらすんだ。
「次のプログラムの空欄に適切なコードを入れなさい」って穴埋め問題の宿題なんじゃないか? (と、かんぐってみる)
なんかレスいっぱいついちゃってますね。 著者が坂下夕里さんの「これならわかるC 入門の入門」ってやつの194Pです。 2006年7月5日の初版第3版だそうです。 値段は1,600+税。
入門書なんて書くと BCCがインスコできませんとか パスが通せませんとか VC++で実行したらいきなり画面が閉じましたとか 見るだけで嫌になるFAQがいっぱい来るんだろうな・・・
C99以前の規格で質問です 変数の宣言はブロックの最初でなければならないとのことですが、 void hoge(void) { int i; //なんだかの処理 for(i = 0; i < 10; i++) { int value;//←ここで変数宣言 //なんだかの処理 } } 上記のvalueの変数宣言はOKでしょうか? 関数の最初に変数が宣言できることは覚えているのですが、ブロックの中でもfor文などの中の先頭で宣言できるのか忘れて島しました 手元にあるコンパイラだと、独自拡張されているのか、処理中の変数宣言もOKになってしまいます。 よろしくお願いいたします。
ブロック先頭での変数宣言はOKです
for文の{}もブロックっていうんじゃないのか?
途中に { } 入れて宣言してたこともあったなあ
まだ初心者だった頃caseの後でなぜ宣言できないのが不思議だった。
特定のcaseだけでしか使わないローカル変数を定義したくて case xxx: { } なんてすることもあるかもしれない。 とりあえず52はブロックという言葉の意味を正しく知るべき。
レガシーCでは通るがC++では通らない(かも知れない)コード。 switch (0) { int i; case 0: printf("foo\n"); case 1: for (i = 0; i < 10; ++i) { printf("%d\n", i); } }
/************************************************************************/ /* ぬるぽ */ /************************************************************************/ ↑こういうコメントをVisualStudio2003を使って楽に入力する方法ってありませんか? /*********************************************************************/ って部分はIMEに登録(60文字超えるんで前半部分と後半部分に分けて)したりしてるんですが、 二行目の/*の自動挿入とか文字列の中央ぞろえとか終端の*/の入力の仕方がわかりません
文字列の中央揃えや終端の*/の位置調節などといった 無駄なことはやめた方がいい
確かに 考えるだけ時間の無駄
エディタをvimを使うようにしてmapで登録すればいいIDEのエディタは総じてくそ
Sakura等のマクロ使えば一発なのに・・・
IDEのエディタは総じてくそ
vimのcindentのオプション使ってると、勝手にコメントの * を揃えてくれるから /***************************** . * コメント . *****************************/ . ↑ここを揃えてくれる こんな書き方してるけど、これって一般的な書き方なのかな? コメントの書き方で定番みたいなものはあるんかな…
>>59 GreatCode でディレクトリ内のソースコードを一括変換すると楽
表記の揺らぎもなくなるし
>>65 次のようなコメントを見かける。
#等幅に見せるために2バイト文字に変換済み。
/*******/
/*□ぷげら□*/
/*□もげら□*/
/*******/
/*******
□*□ぷげら□*
□*□もげら□*
□*******/
/*******\
*□□ぷげら□□*
*□□もげら□□*
\*******/
/*******
□*□ぷげら
□*□もげら
□*******/
/*******
□*□ぷげら
□*□もげら
□*******
□*/
/*
□*******
□*□ぷげら
□*□もげら
□*******
□*/
先ほどCを始めたのですが,いきなり行き詰ってしまいました. 逆斜線ってどうやるのでしょうか? \で代用すればいいのでしょうか? お願いします
いいです。半角でな
>>65 定番のコメント記法をただ探すんじゃなくて、
定番のドキュメント生成ツールを探して
それが要求するコメント記述方式に従うのがいいと思う。
勝手に*を揃えてくれるのだって、
ドキュメント生成ツールを意識した動作だろうし。
>>65 そういうコメントは、ファイルの先頭で使うくらいだな。
いっぱい使ってると、かなり素人くさい。
玄人好みのコメントplz
/* You are not expected to understand this */
コメントに罫線やら装飾の多いヤツは素人。
>>74 訳するとこんな感じ?
/* あなたがこれを理解できるなんて期待してないです */
/* これ見ても分からないっしょ? */
/* 分かるかな〜? 分かんね〜だろ〜な〜 */
VC++ って VBA マクロ使えなかったっけ?
*/の位置を気にして半角スペースを駆使するような奴は負け
端的に言えば
>>59 なわけだが
40カラム〜80カラムは問答無用でコメント、という規約のプロジェクトがあった。
カラムなんて言葉を聞くと FORTRAN を思い出して嫌になる
>>79 某大手が未だにそんな規約を持っている。
極悪なのは、関数内の最初のインデントと二段目のインデントの量が違うと言う……
つ c-set-offset
/*******************************
* 俺はよくこれを目にするんだが
* たぶんずれるからポップうp
*
>>83 */
俺も>83形式だなー 但し一行目の * の数は5個固定で、その右にコメントの頭を入れるんだが。
86 :
65 :2007/03/23(金) 20:15:44
コメントにも色々あるんもんですね >定番のドキュメント生成ツール これってDoxygenみたいなやつですか?
doxygenは /** で始まり */ で終わるコメントにも対応しているな。 俺は大抵/*! 〜 */を使うが。
javadoc形式に対応してるんだっけか
どうして構造体はmain外のグローバルなところに書くのが多いのでしょうか
main の外で使うから
関数内で定義したら関数内でしか使えないから
doxygenは///や//!にも対応しているからC99なら///で書ける。
xmlコメントにも対応してるんでしょうか?>doxygen
//コメントを/*コメントに変換するツールないかなぁ。 // printf("///"); // return 0; /* ぬるぽ */ こんな行のこと考えると結構面倒だ。
つPerl
>>95 Perlで書いても面倒だと思うんだけど。
そもそも今時規格に乗っ取ってないという理由で//コメントを禁止する某芝の某氏が阿呆だと思うのだが。
つーか、人には禁止しておいて自分では使ってるしおまけにprintf()で"%lf"なんか使うし……
そこでJIS-X 3010:2003ですよ
エディッタなりIDEなりの機能使ってマクロ組めばいいよ エンター押した瞬間にその行の文字列評価して置き換えるようにすりゃ手軽
他人の書いたコードの整形を自分好みに直すためだけにxyzzy使ってる
取り敢えず、//→/*と$→*/を変換して>94に挙げたような怪しげな行をリポートするスクリプトをawkで作った。
リポート行を(コンパイラのエラーと同じように)xyzzyで取り込んでタグジャンプすれば後は手作業で何とか、かな。
>>97 kwsk
>>98 30ファイル30000行もあるとやってられない。
>>99 私も普段使っているのがWin2kなのでWinSCPのエディタをxyzzycliにしてLinuxのファイルも整形して読んでる。
#編集はvimですることが多いけど。
//コメント禁止って酷いよね・・・
/* */ 使われてるから、全体的に広くコメントアウトしたい場合、#if 0 〜 #endif を使うが そんな環境に限って VC6.0 だったりするから色が変わってくれない
そういうスクリプトや小物ツールを自前でサッと組めるようになりたい・・・
>>103 生の//を変換するだけで、/* // */ とか "//" を考慮しなくていいならawkでこれだけ。
一応、/* *//* */は大丈夫。
awk '/[^*]\/\// || /^\/\// {sub("// *", "/* "); sub(" *$", " */");} {print;}'
実際には他にも、3個以上の/の連続ををどうするとか、//で終わる行をどうするとか、
行頭//が複数行続いたらどうするとか、考え始めると切りがない罠。
/**********************************/ はまだいいとして、 右側をそろえて */ するのって意味あるんかいな? 本当に重要な内容を書きにくくするだけなんだが。 100歩譲っても /********************************** * ほげほげ **********************************/ あるいは /////////////////////////////////// // ほげほげ /////////////////////////////////// って社内で言ったら「右をそろえたほうが見やすい」といわれた。
社内にはプロポーショナルフォントで組んでる変態とかいるから、 行頭のインデント以外は桁をそろえるようなことはしないなあ。
右端を揃える奴はキモイ どれぐらいキモイかっていうと GNUのコーディング規約の中括弧の1000分の1くらい
入門編にいる僕にはわかりません><
最近のエディタならコメント部分の色が変わるのが普通なんだからわざわざ /********************************** * ほげほげ **********************************/ とかやってコメントを目立たせる必要はないんじゃまいか。 /* * ほげほげ */ で充分ですよ。解ってくださいよ。
>>105 漏れのところでは、「右側を揃えたいなら揃えてもいいから、間違ったコメントを書くな」という方針にした。
で、実際に不適切なコメントをリリース版に残した香具師には右側揃え禁止措置を取った。
……そして誰も右側を揃えなく(揃えられなく)なった。
>>100 ISO C 1999のJIS版
//コメントは仕様に入ってるし%lfも全力でおk
>>109 色がついてなくても、下ので十分だよ。
行頭になんか印がついてれば、すぐわかるだろ。
/* これでもいいかゐ? */
それで十分
なんで?(^ω^;)
/* * じゃあこれからコメントの標準はこれで。 */
>>116 grep で引っかかったときにコメントかどうかが判らないから。
とはいえ、1行でも全部みれば判るけどね。
おまえら楽しそうだなw おれも楽しいけどw
#ifdef _DEBUG #define DEBUG_ONLY #else #define Paste(a, b) a##b #define DEBUG_ONLY(fn) Paste(/, *) fn Paste(*, /) #endif こんなマクロを作ったんだが、これって邪道?
>>120 自己レスだがどう考えてもこっちの方がいいです。
本当にありがとうございました。
#ifdef _DEBUG
#define DEBUG_ONLY
#else
#define DEBUG_ONLY(fn)
#endif
漏れはこんなの作ってみた。 #ifdef DEBUG #define IF_DEBUG 1 && /**< 常に有効 */ #else #define IF_DEBUG 0 && /**< 常に無効(このマクロの右辺は生成されない) */ #endif 警告は出ちゃうけどね。
俺はいつもこれ使ってる。 release 時は最適化で消えるはず。 #ifdef NDEBUG #define DEBUG if(1); else #else #define DEBUG if(0); else #endif
俺は C で書く時は // は使わんな。 -ansi -pedantic -Wall で警告すら出ないように ガチガチに書くようにしてるから、 // 使うとエラーになる。
そこで-std=c99ですよ
わざわざCで書く理由ってのは移植性やpoorな環境の問題、レガシーコードの 保守などがメインだと思うんだが…… C99なんて使う機会あるか? C99使えるぐらいならC++が使えないか?
int (*f(int argc, char* argv[]))(int argc, char* argv[]), (main); ↑ こういう変態な書き方ってどうやったら読めるんすか? っていうか何やってるんすかこれ?
Filename_ni_comment_wo_kakeba_iijyo.c
/* 読み込んだ実数値と0.1との和・差・積・商を表示 */ #include<stdio.h> int main(void) { double num; printf("実数を入力してください:"); scanf("%1f",&num); printf("0.1を加えると%fです。\n",num+0.1); printf("0.1を減じると%fです。\n",num-0.1); printf("0.1を乗じると%fです。\n",num*0.1); printf("0.1を除すと%fです。\n",num/0.1); return(0); } なぜかどんな実数を入力しても0を入力された扱いになってしまいます。 どこが悪いのでしょうか?
%1f %lf
%1f
>>131-133 ありがとうございます!!!
ってか0とOを間違えるくらい恥ずかしい…orz
なんだ、floatで精度指定してんのかと思ったらdoubleだったんだ。
C言語ゲームを作成中です。他スレから移動です。
6つのファイル公開中しています(読みやすくしたつもりです。>_<;)
ここならCの意見を・・・記述スタイル、変数名など・・・
一通り完成しましたが、大幅に改修している初期の段階の内容です。
現段階は自機が動いて弾を撃つまでです。その他の内容はReadme.txtより
コンソールシューティングゲーム
http://gamdev.org/up/img/9215.lzh
>6つのファイル公開中しています(読みやすくしたつもりです。>_<;) 先ず、日本語の勉強をすべきかと。
C++ じゃん・・・と思ったら、中身はほとんど C だな。 グローバル変数使い過ぎというのが先ず目につく。クラス化汁。 Console みたいに内部変数にすると不便だというなら、 Singleton パターンを使えば、そのクラスのインスタンスを1つに保証できる。 関数でデータ処理させる際のオーバーヘッドが気になるなら inline 関数にすればいい。 (って、C のスレの回答じゃないな、これじゃ) 名前のローマ字はまあいいとして、player のメンバ名が気になる。 px, py, pspd の p は player の、 ptx, pty, ptflg の pt は player の tama の略だと思うけど、 プレイヤーの情報と弾の情報が同じレベルで混在してるのはどうなのかと思う。 struct tama { float x, y; char fHassha; }; struct player { float x, y, spd; struct tama tama; }; という風に切り分けた方がいいんじゃないかな。 x, y も、座標構造体やらクラスやらにした方がいいと思う。 GetRandom は、もうちょい double でキャストしないと、オーバーフローが怖い。 (eny + ei)->ex は eny[ei].ex じゃダメなのか? まあ、このあたりは趣味も関わってくる話かもしれんが。 SYori は Syori だよね? 0, 1 のフラグは、char じゃなくて bool にしようぜ(って、これも C じゃないな)。 InitFunc の中身は全部機能別に関数化した方が読みやすいかもと思った。 まあ、関数化してない部分は短いから、別にいいかもしれんが。
ゲームの場合、綺麗に書く必要はそれほど無いので、 とにかくゲームとして仕上げることが大事。 一本完成すると自信になる
>>136 ヘッダファイルの読み込み順を意識しないといけないのは嫌いだ
レス有り難うございます^^
>>137 すまそ >_<;
>>138 C言語は一定のレベルになると、まったくわかっていない!調べます。
構造体、double、(eny + ei)->ex は eny[ei].ex とか・・・あと変数名も検討する
自機と自機弾は分けようかとしたが・・・現在は暫定ような感じです。t は弾の略です^^
PlayerSYoriですよね!直しました。気づかんかった…
機能別関数化は大きくなった時など考えていきます。
クラス、インスタンス、Singleton パターンinline 関数この辺は
Cの後に挑戦したいと思っています!
>>139 確かに…結構挫折が多かったのでよくわかりますorz 一つ完成させるのが大事!
一応一通り形はできたのですが・・・(そのほうが質問しやすいと思ったから)
しかし、理解せずに進んだため信じられんほど、時間が
かかり過ぎた >_<;毎日泣きそだった。ぐぐりまくってもわからんし…
>>140 見直してみます><
まずは、グローバル、構造体、ヘッダーをみてみます。
>>136 向こうのスレを見ている者だが、最初に比べると随分上達したな。
個人的にはローマ字命名はちょっと…だが。
144 :
デフォルトの名無しさん :2007/03/28(水) 18:50:32
ある人が書いたソース見ていたら、ヘッダファイルに以下のような部分を 見つけました。 #if _MSC_VER > 1000 #pragma once #endif // _MSC_VER > 1000 #ifdef _MSC_VER #include "resource.h" #endif 私の疑問は、 "resource.h" というファイルを探したのですが、 見当たらなかったのですが、エラーなくコンパイルできます。 その理由がわかりません。教えて下さい。
必要とされてないからでしょう
>>144 #ifdef _MSC_VER
#include "resource.h"
#endif
もし _MSC_VER が定義されていたら
resource.h をインクルードする
_MSC_VER が定義されていないならインクルードしない
君の環境では_MSC_VER が定義されていないので resource.h がなくても問題ない
K&RのP270に 「宣言中の最初の添え字は配列が消費するメモリ量を決めるのには役立つが、 添え字の計算には関係しないということである。」 という文があるのですが int array[2][4][6]; と宣言した場合の2,4,6はそれぞれ配列の要素数を決めているだけで *(array[2][4]+6)のシンタックスシュガーな訳ではないってことですか?
「最初の添え字」つまり、その例では2のこと。4,6は関係する。
arrayの各要素のメモリ内での位置を計算するのに2は必要ないというだけの意味。
150 :
147 :2007/03/28(水) 20:36:24
>>148 添え字の計算には関係しない、の意味がよくわからないんですが
array[1][2][3]は*(array[1][2]+3)に読み替えられて、array[1][2]は配列だから
(array[0]+1)[2]になるんですよね?
151 :
147 :2007/03/28(水) 20:39:32
すいません更新してませんでした
>>149 どういう風に必要ないのかいまいちよく分からないです…
たとえばarray[1][3][5]のアドレスはarrayの先頭要素から、 (1)*4*6+(3)*6+(5)要素サイズ分だけ離れていると計算できるから、 最初の添え字のサイズである2は計算に必要とされない。 array全体のサイズを決めるためには2も必要。
153 :
152 :2007/03/28(水) 20:49:36
152の説明だと正確ではないか。 array全体が一塊で割り当てられているときは152の計算でいける。 まあ、そうでなくて、 array = (int***)malloc(2*sizeof(int**)) array[.] = (int**)malloc(4*sizeof(int*)) array[.][.] = (int*)malloc(6*sizeof(int)) みたいになっていたとしても、やはり最初の添え字サイズは必要ない。
154 :
147 :2007/03/28(水) 20:50:43
>>152 あ、最初の添え字の数-1までしか必要とされないって意味ですか
>>153 たいていのコンパイラはint array[2][4][6];って宣言してたらまとまった領域を割り当てると思うがな
156 :
デフォルトの名無しさん :2007/03/28(水) 20:57:33
147 の質問に対して153のメモリ確保の説明は、関係ないんじゃあないのか? 147は int array[2][4][6]; と宣言した場合の質問をしているんだよな。
>>154 「添え字の計算」というのは例えばarray[0][1][2]みたいにindexが与えられた時に
それはメモリ上のどこにあるのかを計算するって意味だ
その計算には配列の最初の次元の大きさは必要ないよってK&Rは言っている
158 :
152 :2007/03/28(水) 21:02:03
159 :
147 :2007/03/28(水) 21:06:46
>>157 あ、array[1][3][5]の添え字計算だと(1)*4*6+(3)*6+(5)みたいに
当然(式の中の)最初の添え字の1も含めて1,3,5は当然使うし
元の宣言にある4と6も使うけれど、同じく元の宣言の中にある2は使わないってことですね
ようやく分かりました、皆さんどうもありがとうございます
要するにint a[5];でa[x]とアクセスするのに、 5という情報は要らない(要るのはintという型情報)、ってだけ。
161 :
デフォルトの名無しさん :2007/03/30(金) 01:20:50
↓のようなことって技術的に可能ですか?
何分↓スレに専門知識を持った人間がおらず、真偽が分からなかったので
ここで質問させていただきました
558 名前: 麒麟です ◆qJFjoQ6aTk 投稿日: 2007/03/29(木) 22:06:29 ID:ENSP49sq
そうだ
一応書いておくわ
CとかJavaとか言語でわけてる現状がそもそもおかしいから
ソースコード翻訳機作ってやってるよ
おまえも参加しろwww
役に立たない下っ端を使えるようにする秘策だぞwwww
561 名前: 麒麟です ◆qJFjoQ6aTk 投稿日: 2007/03/29(木) 22:12:11 ID:ENSP49sq
意味分からないのか??
コンパイラじゃなく
ソースコードをそれぞれに変換するってことだぞ
意味分からないかな??
564 名前: 麒麟です ◆qJFjoQ6aTk 投稿日: 2007/03/29(木) 22:14:33 ID:ENSP49sq
たとえば
Cで書いたコード100万行を
自動変換で
Javaコードに変換するって奴だwwwwww
分かるかな???
ttp://human6.2ch.net/test/read.cgi/dame/1174933496/l50
>>161 多少手作業部分やなんらかの制限等は生まれるだろうが、
いったいどこに本質的に不可能だとされる可能性があるんだ?
しまった。マルチにマジレスしちまった。orz
実例の1つとしてあげておくけど、初期のC++コンパイラは、 まずCへ翻訳してからコンパイルしていた。
言語的には難しくない、100万行のlibcのみ依存のソフトなら自動変換できる。 でも、たとえば、Win32とか、BarkleySocketに依存していたら、 ライブラリの流儀をJavaに直すのは難しすぎる。 ましてやハードを叩いてたりすると。
ちゃんと動いたプログラムのソースに、大きな配列を追加してBCCでコンパイルしたら、 全く関係ない所でアプリケーションエラーで終了するようになったのですが、 メモリ不足でしょうか。mallocとか面倒だけどしないとだめでしょうか。 ><わかんないんです。おしえてください。
>>167 アプリケーション エラー
エラーが発生したため、(ファイル名).exeを終了します。プログラムをもう一度開始する必要があります。
エラーログを作成しています。
>>169 3000行超えちゃうので無理です><
とりあえずグローバル変数宣言だけで50行で、
int型の要素が100個ぐらいの配列と、
char型で256文字入る配列を4個ほど宣言してあります。
どこかにアップロード汁
グローバル変数多過ぎだろ。
>>172 グローバル変数にしないと各関数の引数に変数や配列のポインタを
10個ぐらい渡さないといけなくなっちゃうんで…
大小まとめて数えて関数を30個ほど作ってあるので大変です…。
>>170 10分の1くらいにおさえたら、どうか?
>>173 釣りうぜえ
さっさとソース&エラーうpしろやクズが
構造体作ってポインタ渡せばいいじゃん。馬鹿?
あっ、すいません、変数名がかぶってたのが原因みたいです>< お騒がせいたしました
同じ名前で大きさが違う配列に無理やり値を詰め込んだのが原因でした>< 皆さん、本当にありがとうございました
>>178 結果的に「釣りだった」という見解が・・・
作り方が下手糞だと、ちょっとした間違いにも 気づきにくいという典型例だな。
><ほんとうにすいませんでした
特定の関数を特定の関数からしか呼び出せないようにすることって可能ですか?
>>176 次からはよくつかう変数を
構造体に詰め込むことにします><
苦手意識のせいで気付かなかったです
アドバイスありがとうございました
>>182 もしマジレスだったなら、謝る必要はないよ
>>184 続けることが大事だから頑張って!^_^;マジレスならね・・・
ところで
>>170 のいうように3000行を越えてるのに、
>>173 でいうように関数が30個って少なすぎね?
もうすこし論理的意味単位で分割した方がいいと思うよ。
>>183 呼ぶ側と呼ばれる側の関数だけからなるファイルを作って、
呼ばれる方はstaticにする。
もう一つ質問しても良いでしょうか? lccで行数の多い関数が入ったファイルをコンパイルすると out of memory とエラーが出るのですが 関数を短くしないといけないのでしょうか?><
つーか、データの依存関係が強すぎだろ。
>>189 LSICを使っているのなら、窓から投げ捨てろ。
あれは、関数を評価する為のコンパイラが使用するメモリ空間をたった32KBだか64KBだかに抑えている。
192 :
183 :2007/03/30(金) 19:46:08
>>188 関数に付けるstaticってこういう時に使うんですね、ありがとうございました
193 :
デフォルトの名無しさん :2007/03/30(金) 19:54:31
194 :
183 :2007/03/30(金) 20:02:13
ついでで申し訳ないんですが、関数は何も指定しないと自動的にextern指定されるということでいいんでしょうか?
そうでs
>>194 いえす。
関数はファイルの外部から見える(extern)か見えない(static)かの2通りで
省略時はextern扱いされる。
外部に見せる必要がない関数は積極的にstaticを付けておくのはよい習慣。
>>194 staticをつけない限り、そうなる。
従って、ソースファイル外から使いたい関数以外は無条件にstaticをつけた方がいい。
#最近のコンパイラはstaticな関数は積極的にインライン展開しようとすることだし。
198 :
183 :2007/03/30(金) 20:08:08
windowsから消しておきました><
質問です if( a[7] != 0 ) { cnt = 16 ; while( (a[0] & 0x0f) == 0 && cnt != 0 ) { for( ct = 0 ; ct != 8 ; ct++ ) { ((struct ST4bit *)&a[0+ct]->4bit_0 = ((struct ST4bit *)&a[0+ct])->4bit_1 ; ((struct ST4bit *)&a[0+ct]->4bit_1 = ((struct ST4bit *)&a[1+ct])->4bit_0 ; } ((struct ST4bit *)&a[7])->4bit_1 = 0 ; cont-- ; } } struct ST4bitはunsigned型で{4bit_0 ; 4bit_1}がメンバ(各4bit) この時、このプログラムの意味することは、 a[0]〜a[7]で後ろ詰めに格納されているものを 前詰めにしている、というのでいいでしょうか? またこうすればもっと簡単にできるというのがありましたら、ご教授お願いします。
printfってプリントフって読むの?それともプリントエフって読むの?
プリントエフがデフォ
>200 forループの中でa[8]にアクセスしてるみたいだけど、いいの?
>202 THX
正式には プリント ウィズ フォーマット だっけ?
はあ?
識別子の先頭に数字はないだろ・・・ 常識的に考えて・・・
常識というか、それが通るコンパイラがあったら是非私に知らせて欲しい。 頼んだぞ。
識別子をプレゼントつ「unko_program」
>>200 データサイズが膨大 or 組み込み用途 or 学習目的
のいずれでも無いならビットフィールド使うのをやめるのが吉
long long に対応しているコンパイラならシフト演算一回で終わる
※但し、データの並び順が変わるのに注意
213 :
212 :2007/03/30(金) 23:47:05
データの並び順が変わる ↓ コンピュータのバイトオーダによってはデータの並び順が変わる
標準入力のフラッシュは非標準らしいですが、 これをサポートしてない環境の例ってあります? たとえば組み込み用の一部ではサポートしてないとかそういうのでしょうか?
>>214 バッファリングしない環境では実装されてないってことは普通にあるかもね。
ファイルをリダイレクトされた標準入力をフラッシュされたらどうなるんだって話があるしな。
217 :
212 :2007/03/31(土) 00:02:43
>>214 linux のターミナルだと使えなかったよ
>>214 fflush(stdin)のことを言ってるならWINXPでできなかった記憶がある
>>191 LSI-C の用途があなたの想定する用途と違うだけ
>>219 MS-DOS用コンパイラをWindowsで動かす積極的な理由は何かある?
まさか、製品版のLSI-C80の話をしているわけじゃないよね?
>>220 そんな理由はあるかどうか分からない
ただ DOS で動くプログラムがごく稀に必要になることはある
元になったレスは lcc って書いてあるから lsic86 とは関係ないっぽい
制御系なら DOS の方が楽 リアルタイムOS として DOS を使う場合もある 再起動も早いし
int ascii_to_integer(char *ascii) { int i; int integer; for (i = 0; *(ascii+i) >= '0' && *(ascii+i) <= '9'; ++i) integer = 10 * integer + (*(ascii+i) - '0'); return integer; } これってasciiをポインタと配列のどっちで書いたほうがいい? それともどっちでもいい?
>>223 ついでに変数 integer の初期化が必要
>>221 、
>>222 で、元質が制御系だとかDOSプログラムを作ってるだとか言う根拠は?
ちなみに、LSI-C86ならコンパイラの実行モジュール名がlccだな。
他にもlccはあるが、ちょっとした関数で音を上げることから察すればLSI-Cだろう。
>>227 根拠も何も無い
DOS が好きなだけなんだ
だから DOS で使えるコンパイラが貶められるのが嫌だった
それだけ
好きなものは好きなんだ、理屈じゃないんだ!
そういうもんだろ?
だったら、窓(Windows)だけ投げ捨てろ?w
ここといい宿題スレといい争いが絶えませんね
テキトーなことを言う奴が後を絶たないせい
/* 期待する出力は ababababab */ #include<stdio.h> /* こんな時 func_t はどんな型で typedef すればいいのしょうか? */ typedef void *(*func_t)(void); func_t a(void); func_t b(void); func_t a(void){putchar('a');return b;} func_t b(void){putchar('b');return a;} int main(void){ func_t func=a; int i; for(i=0;i<10;i++) func=func(); return 0; }
どう見ても入門者の質問じゃありません。適切なスレへどうぞ。
期待する出力はあばばばばぶ
>>232 typedef func_tA;
typedef func_tA (*func_t)(void);
func_tA a(void);
func_tA b(void);
func_tA a(void){putchar('a');return (func_tA)b;}
func_tA b(void){putchar('b');return (func_tA)a;}
int main(void){
func_t func=a;
int i;
for(i=0;i<10;i++) func=(func_t)func();
return 0;
}
これでうまくいったけど
たぶん改善の余地ありだろうな
再帰みたいになるのか。
いや戻りとして相手の関数ポインタを返してるだけだから再帰とは違うでしょ 自分が相手を呼び出してるわけじゃないし
ポインタpに対して p[2]が使えたんだけど これは文法的にok?
>>237 文法的にはok
論理的(規格の用件に合致する、正常に実行できるなど)な観点からは
okかどうかそれだけではわからない。
func_t a(void); void b(void); func_t a(void) { putchar('a'); return b; } これで、ここまで、ならば通る。 func_t b(void); に変えると typedef func_t (*func2_t)(void); func2_t a(void); にしなければならなくなる。 すると今度は・・・ 難しいね。
>>237 p[2] の領域が確保されていればおk
例.
int a[10]={0}, *p;
p=&a[3];
p[2]=0x1234; // p[2] == a[5] なので O.K.
p=&a[9];
p[2]=0x5678; // p[2] == a[11] なので N.G.
大学でC言語を習った人がプログラマになってからよくやってしまう間違いや 効率の悪いプログラムの書き方とかあれば教えて下さい(-_-;)
>>232 下でキャスト無しでいけるけど、関数の型が変わったらダメ?
typedef void *(*func_t)(void);
void *a(void){putchar('a');return b;}
void *b(void){putchar('b');return a;}
しかし質問者が無反応なのが恐ろしい
>>241 よくある失敗はバッファオーバーラン
効率の悪いプログラムの書き方は標準関数を自作してしまう
strcpyの代わりにsprintfをよく使っちゃうけど問題ない?
>>244 よく自作しようとしてしまう関数って
どんなものがあるんでしょうか(-_-;)
>>241 局所変数のポインタを返すとか。
値を受け取るための引数に未初期化ポインタを渡すとか。
てか、大学関係ない単なるC言語初心者か。
>>245 sprintfはstrcpy並に問題ある。
バッファオーバーラン防止のため、snprintf使え。
>>232 です
>>234 すみません。
キャストしなくても警告の出ない方法があればと思い質問しました。
>>239 そうなんです。ループしてしまうので宣言の仕方がわからないんです。
>>242 void * にすると代入する時の型チェックが無くなってしまうので
できれば関数の型を残したいです
char a[]="1,2,3"; int i; のとき sscanf(a,"%d,%s",&i,a); とか sscanf(a,"%s,%d",a,&i); って大丈夫?
>>241 エラーチェックをしてないのも多い気がする
fopen が失敗したかどうかチェックしてないとか
>>252 あぁ…確かにソケット通信のプログラムで
関数のエラーの戻り値を知らずに大変なことがありました(-_-;)
>>247 文字列操作する時に多いと思う
str??? 関係 (strrchr strcat とか)
is??? 関係 (isdigit isalpha とか)
あと scanf 系の書式指定で対応できるところを自作するとか
printf の %*d 書式相当のものとか
255 :
251 :2007/03/31(土) 21:23:45
あと sprintf(a,"%d,%s",i,a); とか sprintf(a,"%s,%d",a,i); みたいに上書きしても大丈夫ですか?
>>250 ん〜
無理じゃないかなぁそれは
typedef func_t (*func_t)(void);
こういう宣言が許されない以上キャストするかvoid *使うかしかないと思う
それ以前に関数ポインタを戻りとして返さないとダメかな?
つまりこういうのじゃダメ?
typedef void (*func_t)(void);
void a(void);
void b(void);
void a(void){printf("a");}
void b(void){printf("b");}
int main(void){
func_t func[]={a,b};
int i;
for(i=0;i<10;i++) func[i%2]();
return 0;
}
>>257 無理なようですね。
書き方を変えることにします。
>>回答を下さった皆さん
どうもありがとうございました。
259 :
255 :2007/03/31(土) 22:51:37
>>256 sscanf(a,"%d,%s",&i,b);
sscanf(b,"%s",a);
とか
sscanf(a,"%s,%d",b,&i);
sscanf(b,"%s", a);
とか
sprintf(b,"%d,%s",i,a);
sprintf(a,"%s",b);
とか
sprintf(b,"%s,%d",a,i);
sprintf(a,"%s",b);
でやればいいんですかね?
>>259 まあそうだが、
信頼できない入力に対して%sを使うのはバッファオーバーランの
危険があるから、やめといたほうがいいとはおもう
>>260 %100.100sとか書けばええだけちゃうの?
%as
じゃこうだね まあ練習用のプログラムだから int ascii_to_integer(char *ascii) { int i; int integer; integer = 0; for (i = 0; *(ascii+i) >= '0' && *(ascii+i) <= '9'; ++i) integer = 10 * integer + (*(ascii+i) - '0'); return integer; } *(ascii+i)とascii[i]ってどっちが普通? 括弧が少ない分, ascii[i]がよく使われるのかな?
ascii[i]; の方が俺としては読みやすい
C FAQを読んで 配列 = ポインタ + 書き換え可能なメモリー じゃないことが分かった さっきまでの自分が恥ずかしい
行列の積を解くプログラム教えてください
ヘッダの中にヘッダをインクルードするのは、 通常どういう見解ですか?Cソースだけにしたほうが良いですか?
どういう見解も何も、必要だからインクルードしているんだろう。 インクルードガードはちゃんと付けとけよ。
#ifndef _INCLUDE_ADD_
#define _INCLUDE_ADD_
//内容
#endif
>>269 おそらく、こうゆガードですね。有り難うございました。
>>270 _INCLUDE_ADD_は予約済み識別子なので使わないほうがいい
使用すると未定義動作になる
_で始まって大文字や_が続く識別子は全部予約されているので念の為
>>257 i%2 -> i&1
のほうが速いかも
srand()の存在意義が分かりません。rand()にseedを渡す設計にすれば 済みそうなのに、何故わざわざ別の関数にしたのでしょう?
アフォ rand()呼ぶたびにいちいちseed渡さにゃならんかったらめんどくさいだろうが
278 :
276 :2007/04/01(日) 08:16:45
仮に rand(seed); とするすると、()の中を毎回書くのが面倒ってこと ですかね? そんなに面倒かなぁ
じゃなくて毎回同じseedを渡していたら、 randから返ってくる値がおなじになるじゃないか。
rand(&seed) とすれば seed は変わる。 ただ、こういう実装にすると、 rand のアルゴリズムに制限がかかる。 あるいは、結局 srand みたいなものが必要になる。
int my_rand(int seed) { srand(seed); return rand(); } で別れていれば自分で実装できるじゃん。なのでやりたければどうぞ。 おれはsrandとrandに別れている方がいいので、 my_randしかなければ困ったことになる。
282 :
276 :2007/04/01(日) 08:52:16
>>280 の回答が親切で比較的納得しやすいと思った。
>>281 の回答は疑問に対する答えになっていないのでは……
rand(time(NULL)); とでもすればseedは毎回変わるし、これで良いので
は? と思ったのが疑問の出発です。レス見て分かったような分からな
いような気分だけど、そのうち実感できるときが来るかもしれない。回
答ありがとうございました。
>>282 それだと、時間が立たない限り
何度読んでも同じ値しか返ってこないよ
同じ種で始めれば同じ乱数列が得られるというのも疑似乱数列の 性質としては重要(再現性)なので、基本となるライブラリにある 関数が毎回勝手に裏で種を変えるような造りだと不便な気がする。 必要なら自分でそこにある素材から作れるわけだし。
>>282 ん。そうか? 別れていれば
・別れている方がいいよ派
・毎回seedを渡したいよ派
の両方の要求を満たせるということをかいたつもりなんだが、
わかりづらかったかな…
配列でできることってすべてポインタでできるなら配列はいらないと思うんだけど そこんとこどうよエロイ人
だから、毎回seedを設定してたら乱数にならないんだってば。
>>286 配列で出来ることでポインタで出来ないことがあります。
なので配列は必要です。同様にポインタも必要です。
>>287 「一連の乱数を得る」という単位での「毎回」と読むのであろう。
毎回seed渡すrandって単なるハッシュ関数だな
>>289 一連の乱数を、どうやって一回の関数呼び出しで実現するんだ?
一連の乱数を必要な回数の関数呼び出しで実現するのなら、どうやって連の先頭でのみseedを渡すんだ?
それに対する真っ当な回答が、連の先頭でのみsrand()を呼び、以降rand()のみを呼ぶことなんだが。
int a[10]; これをポインタで実現できる?
>>294 ポインタだけじゃないけど
struct linked_list {
struct linked_list *next;
...
};
を定義してmallocで動的にメモリーを割り当てればおkじゃない?
>>295 せめて a = malloc(sizeof(int) * 10) を使おうよ。
# より配列らしく使うならallocaにしたいが。
>>296 alloca?
int a[10];がどういう文脈で使われてるか分からんし、
スタックに割り付けることが配列らしく使うことになるとは思えんのだが。
callocなら分からんでもないけど。
どういう文脈で使われるかわからんのにcalloc()ならなんで「わからんでもない」なんだろ。
allocaのほうがfreeせずに済む分配列っぽいということか。 ただし、ローカル変数なら。
callocなら要素サイズと要素個数を別個に指定して割り付けるから配列宣言っぽい、という意味で分からんでもない。 使いどころが限られているallocaよりも、int a[10];がどういう文脈で使われていても、とりあえずcallocはヒープに取れるし。
>>299 ああ、納得。確かにfreeが不要っていう点ではallocaは配列と共通点を持ってるね。
>>281 これは seed が更新できないから使い物にならない
>>294 の意図しているところがワカランのが困る。
どこまで再現して欲しいのか。
[ ]のオーバーr(ry
int b[10],*a=b;
[]もオーバーライドできるのか…
int (*a)[10] = malloc(sizeof (int) * 10); こういう事がやりたいのか?
calloc()は0クリアされるという仕様である時点で、ローカル配列とは似ても似つかないのだが。
それ以前に「要素のサイズと、数を別々に指定できるから、alloca()より配列に近い」ってのも、あれじゃね?
エイプリルフールも終ったね ネタは乱数の種と配列をポインタで実現だけか つまらん
ネタスレじゃないし
今年は偽RFC来なかったの?
4824
手旗信号かワロタ。アブストしか読んでないけど。
VCExpressでCW_USEDEFAULTが定数として呼び出せないのはなぜなんだぜ? : error C2664: 'CreateWindowExA' : 4 番目の引数を 'LPCSTR' から 'DWORD' に変換できません。(新しい機能 ; ヘルプを参照) 教えてください。お願いします。
HWND CreateWindowExA( DWORD dwExStyle, PCTSTR pszClassName, PCTSTR pszWindowName, DWORD dwStyle, int x, (ry
>>316 ズレてたわけですか。
hWnd = CreateWindow(szClassName,
"猫でもわかるWindowsプログラミング", //タイトルバーにこの名前が表示されます
(LPCSTR)WS_OVERLAPPEDWINDOW, //ウィンドウの種類
CW_USEDEFAULT, //X座標
CW_USEDEFAULT, //Y座標
CW_USEDEFAULT, //幅
CW_USEDEFAULT, //高さ
NULL, //親ウィンドウのハンドル、親を作るときはNULL
NULL, //メニューハンドル、クラスメニューを使うときはNULL
hInst, //インスタンスハンドル
NULL);
引用スマソ。EXAではないのですが、EXにして第一引数を加えると
: warning C4002: マクロ 'CreateWindowA' に指定された実引数の数が多すぎます。
: error C2664: 'CreateWindowExA' : 2 番目の引数を 'long' から 'LPCSTR' に変換できません。(新しい機能 ; ヘルプを参照)
と出ます。ウィンドウクラスはEXなんですが、なぜでしょうか?
お願いします。
CreateWindowEX': 識別子が見つかりませんでした 違った。こっちがエラーだ
解決しました。誤字があったようで ありがとうございました。
質問文を作るだけで疑問が解決する事も結構あるのね…
質問しようとして疑問点を整理していくと何が問題なのかわかっちゃうことって結構あるよね
それがデバッグじゃね?
デバッグというより洗い出しというか整理というか
何か格言ぽいのなかったっけ 「人に聞く前に目の前のクマさん人形に説明してみろ」 とかなんとか
うんk
コンピュータ系の演習室か何かにゴムのアヒルちゃんがおいてあって、 常駐してる相談員に質問する前にはそのアヒルちゃんに質問してから、 というルールがあるという話をどっかで読んだ。
「ゴムのアヒルに質問する」という設定だけなら 「達人プログラマー(The Pragmatic Programmer)」 にあった。 なんでアヒル?
「ゴムのアヒル」ってのが小さな子供が遊ぶおもちゃの象徴だからじゃないか? 幼児に馴染みのある人形って日本だと何だろう? アンパンマンとか?
その辺に置いてあったからじゃね? 別にダースベイダーのボトルキャップでもいいわけで
ビット列の上位から下位までを逆順にしたい。 例えば、 01100111 -> 11100110 というように。 (0bit目が7bit目に、1bit目が6bit目に…) 何かスマートなやり方はありますか?
これでよくね? int y = 0; if(x & 1) y |= 128; if(x & 2) y |= 64; if(x & 4) y |= 32; if(x & 8) y |= 16; if(x & 16) y |= 8; if(x & 32) y |= 4; if(x & 64) y |= 2; if(x & 128) y |= 1;
全然スマートじゃないけどな
10 進法で考えたら分かりやすくね? int a = 1365; int b = 0; while (a>0) { b *= 10; b += a % 10; a /= 10; } これを応用して int a = 1365; int b = 0; while (a>0) { b << 1; b |= a & 1; a >> 1; }
スマートって結局主観だろ。 他人のことなんてわからん。 余計なことして気分的にスマートって思いたいだけだろ。
それに加え「速いのが良ければ実測しろ」だしな。
int test8bit(int x)
{
static BYTE table[16] = {0,8,4,12,2,10,6,14,1,9,5,13,3,11,7,15};
int y = table[x
>>4 ] | (table[x&15]<<4);
return y;
}
int test16bit(int x)
{
int y = test8bit(x
>>8 ) | (test8bit(x&255)<<8);
return y;
}
intは32ビット以上前提で
そんな言い訳ばかり並べて逃げるやつからは何も生まれてこないと思うんだ。
339 :
330 :2007/04/02(月) 23:57:19
LUT作りました。 皆さん、ありがとう。
まあ
>>332 をスマートだと思う奴なんていないだろうけどな
そんなことに時間かけるくらいなら 可読性も速度も無難なのがいい。
342 :
330 :2007/04/03(火) 00:12:13
可読性と速度を考えてLUT。 実測はしてないですが。
まあ、速すぎて調べても誤差程度にしかならんけどね。
344 :
デフォルトの名無しさん :2007/04/03(火) 23:57:14
文字列を戻り値に指定するときに char ch[] = " "; return ch; だとエラーが出て char ch[] = " "; return &ch[0]; だと通ったんですが、戻り値に配列を指定するときは return ch; のように省略して書いてはいけないのでしょうか?
関数内で宣言した変数は静的変数(static付けた奴)以外、 関数を抜けると同時に破棄される。 呼出元に戻ったらもうそんな変数を指すポインタは無意味と化している。 だから前者ではそのことを警告されただけだと思う。 無論後者の書き方をしたところで問題の解決にはなっていない。
>>344 エラーがでるでないはともかく関数内で宣言したローカル変数を戻り値にしちゃだめだよぉ
return で戻ったときにはchar ch[] はもう亡くなっているだろうから
結論、Cでは文字列を単純には戻り値にはできない。
なんでそういう結論になるのか
後者は&リテラル返してるじゃん
呼び出し元で確保しておけと。
>>344 C言語で関数から文字列を返却したいときは、戻り値にしないで引数で返す
つまり、呼び側関数内で配列の領域を確保し、呼ばれる関数に渡す
被ったorz
超初心者で申し訳ないんですけど、 コンパイルしようとしたときに、cant open: stdio.hっていうエラーが出るんです。 解説お願いします。
すいません、自己解決しました。
>>347 は要するにC言語では配列そのものをreturn文で返すことはできない、
ってことだろ。
自動的にポインタに変換されてしまうから。
357 :
デフォルトの名無しさん :2007/04/04(水) 04:33:37
BinarySearchTreeの勉強をしてるんですが 階層の数はどんな感じで出せばいいですか?
350 デフォルトの名無しさん sage 2007/04/04(水) 00:45:26 後者は&リテラル返してるじゃん
356 デフォルトの名無しさん sage 2007/04/04(水) 03:58:31 自動的にポインタに変換されてしまうから。
358 名前:デフォルトの名無しさん[sage] 投稿日:2007/04/04(水) 12:04:32 350 デフォルトの名無しさん sage 2007/04/04(水) 00:45:26 後者は&リテラル返してるじゃん 359 名前:デフォルトの名無しさん[sage] 投稿日:2007/04/04(水) 12:05:34 356 デフォルトの名無しさん sage 2007/04/04(水) 03:58:31 自動的にポインタに変換されてしまうから。
自分で考えろ
ソケット通信ってchar型以外のデータを送信できるのでしょうか? 構造体でデータをまとめて通信したいんですけど…
送信する関数のポインタの型を良く見ろ
>>362 「ネットワークバイトオーダー」でググるよろし。
365 :
344 :2007/04/04(水) 16:54:10
ローカル変数だってことすっかり忘れてました… staticにするか引数に渡すかしないといけなかったんですね。。 皆さん分かりやすい説明ありがとうございました。
前者がリテラルへの参照、後者がリテラルの先頭アドレスを返してる。 char* moji(){ char ch[] = "a"; return ch;//もしくはreturn &ch[0]; } int main(){ char* b=moji(); return 0; } これで、各所にブレークポイント置いて、メモリとレジスタを見てみりゃわかる。 ローカル変数はベースポインタ(EBPレジスタ)からのオフセットで決まるから、 moji()からmain()に戻ってくりゃ、ベースポインタが変わるから、リテラルへの参照chは意味を成さなくなる。 ただし、戻り値(EAPレジスタ)の残骸が残っている場合、一見何事もなく済んでしまう場合もある。 ch[0]というのは、リテラルそのもの、文字がメモリにセメダインで張り付いてるようなもので、値を変えようとすると AccessViolationでOSから怒られる。&ch[0]は参照じゃなく直接リテラルのアドレスを返している。
>>366 >リテラル
何か混乱しているようですが、そのコード中の文字列リテラルは "a" のみです。
ch はリテラルではなく、単なる char[2] のローカル変数です。
真っ赤な間違い乙
真っ赤な間違いは>366ね。
>>367 だから、chは文字リテラル"a"への参照だよ。
chは、単なるch[2]のローカル変数?
だから違うよ、ch[2]の先頭を参照するローカル変数。
参照ってなに?
>>366 Cならいついかなる場合でも配列chに対して、chと&ch[0]は同じ。
どちらも配列の先頭要素を指すポインタが式の結果として得られる。
安価間違ってない?
vipperはカエレ
安価とか言うのは高確率で おっさん
>配列ch だからchはアドレス参照だと それと、結果は同じでも過程は違うとはよくいったもんで
なんか恥ずかしいやつが混じっているなぁ。 char ch[2] = "a"; char foo[2] = {'a', '\0'}; printf("%p, %p\n", ch, foo); を実際にコンパイルして(アセンブル出力を見るか)実行してみれば直ぐに判ることだろうに。
行火
>>377 そのプログラムを実行して結果を見たところで何がわかるのやら
何も判らないならプログラミングは止めたほうがいい。
>>366 ちなみに文字列リテラルそのもの(の先頭要素)を指すポインタを返したければこうする
どちらも結果的には同じこと
char* moji() {
return "a";
}
char* moji() {
char* ch = "a"
return ch;
}
>>380 当然過ぎる結果が返ってきたということだw
上の方のレスはカオス過ぎて読んでいない。
どうせなら char *p = "a"; も付け足しとけ。
「配列とポインタは同じ」 って罪な言葉だな…
385 :
344 :2007/04/04(水) 18:31:09
つまり ch → "a"の先頭アドレスを参照 ch[0] → 'a'を参照 &ch[0] → 'a'のアドレスを指す と言うことで、これらは全部 'a' '\0' を参照しているからアドレスは同じってことですか?
なんつーか、参照って言葉をむやみに使わないほうがいいと思うんだ。
配列の初期化子に使う場合でも文字列リテラルって言うの?
>>389 そう言う。
規格上、charの配列を文字列リテラルで初期化できるという規則になっているから。
ch → 配列の先頭を指すポインタとして見なされる ch[0] → char型の値 &ch[0] → ch[0]のアドレス
>>390 いやリテラルであることに疑問の余地はないんだけど、文字列リテラルってなんか微妙に違和感あったもんで…
>>391 規格じゃあしょうがないね
394 :
344 :2007/04/04(水) 18:56:51
>>388 少し調べたんですが、
参照ってC++だと特別な意味があったんですね。。
これから気をつけます。
>>392 ありがとうございます。
自分が考えていたことと全然違いますね…
http://kmaebashi.com/programmer/pointer.html より引用
" で囲まれた文字列を、文字列リテラルと呼ぶ。
通常は、文字列リテラルは、「char の配列」を意味する。 よって、式の中では「charへのポインタ」に読み換えられる。
しかし、char の配列を初期化する場合は例外である。 (こちらを参照のこと) この場合の文字列リテラルは、中括弧内に文字を区切って書く初期化子の 省略形として、コンパイラに特別に解釈される。
char str[] = "abc"; /* この宣言は、下の宣言と同義 */
char str[] = {'a', 'b', 'c', '\0'}; /* 配列の最外周なので、要素数は省略できる */
…だそうだ
コード上で"で囲まれてれば全部文字列リテラルなのねー 感覚としてはあたかも文字列リテラルのように書くことが許されてるって感じだった
でも現実的には初めそう教えておくほうがいいと俺は思う。
オレはC言語はきちんと理解できていないが
ゲームなんかのクラックをして変な知識だけはある
しかもアセンブラの意味も分かっているわけではなく
シンボルを見て分かった気になっているだけの
スクリプトキディみたいなもんだ
言っとくがオレは
>>366 でも代弁者でもないぞ
400 :
デフォルトの名無しさん :2007/04/04(水) 19:44:49
>>399 どういう流れでその書き込みなのか頭の悪い俺に教えてください。
>>399 いったい、誰に対して何の主張をしてるんだ?
それをこれから書くところなんじゃないか
スレ違いはスルー汁
とりあえず
>>370 の
char ch[] = "a"; は文字リテラル"a"への参照だよ。
ってのはおかしいよね・・・?
argv[1][2]って*(p+2)みたいに表現できないの? > エロイ人(愛を込めて)
>>405 もしくは
*(*(argv+1)+2)
argv[ i ][ k ] = *(*(argv+i)+k) と等価って意味ね
2[1[argv]]
argv[i][k] == *(*(argv+i)+k) == k[i[argv]]
a[b]におけるaとbの可換則だけは釈然としない こんなの使って可読性が上がる場合なんてあんの?
>>412 その仕様は初期のコンパイラの都合によるものと思われる
でも、できるからといって使う必要はないじゃないか
char *argv[]に対して *(argv+i)って言うのはargv[i] *(*(argv+i))って言うのはargv[i][] と同じと考えておk?
下は *(*(argv+i)) == *(*(argv+i)+0) == argv[i][0] ?
うん。 *p == p[0]
構造体ってのは最初に宣言しないといけないの? #include <stdio.h> int main(void){ struct person{ char *sei; int age; }taro; taro.age=13; taro.sei="山田"; struct person hanako; printf("太郎の姓は%s、年齢は%dです\n",taro.sei,taro.age); return 0; } これコンパイルできないんだけど
struct person hanako; を削ってみ。
>>417 Cの場合宣言(struct person hanako; )は関数スコープの最初に
taro.age=13; taro.sei="山田"; の後で宣言はダメ
あれがコンパイルできるC99は残念ながら普及していないのさ
gccが普及してないとでも?
GCCは普及しているものの、社会がC99を使う風潮になっていない。 見たことあるか?C99で書かれたプログラム。
FreeBSDのソースがC99でかかれてたなー。
拡張子をcppにすればいい
>>423 コメントが//のCのソースコードをよく見るんだが
C99で書かれたものは、C89でも書ける。 極端な事言えば、C++でusing namespace std; をグローバルで宣言して、あとはCの様に書けば 事足りる。 なんだよ、_BOOLって (w
極端な事言えば、 で書かれたものは機械語でも書ける。
ふつうにboolにしてくれた方が使いやすい
int *a; ってやったら aにはたとえば0x123456ff みたいなアドレスが入ってるんだよね? だから、a=12みたいなことはできないってことはわかったんだけど char *c c="abcdef"; みたいなことができるのはなんで? char *cって指定した時点で cには0x12345678みたいなアドレスが入ってんじゃないの?
"abcdef"は、文字列abcdefのアドレスの意味
int *aもchar *cも宣言した時点では(有効な)アドレスは入ってない。
あれ? アドレス表示しても6桁なんだけど… なんで?
a=12だってできる。
438 :
435 :2007/04/05(木) 13:02:00
#include <stdio.h> int main() { int a = 1 ; printf ( "%x" , &a ) ; return 0 ; } で実行すると 12fed4 どういうこと?
>>432 そういうC言語の仕様。
「char型の配列はダブルクォーテーションで囲む文字列(これを文字列リテラルと言う)で初期化できる」
っていうルールがあるの。ただおまいはその書き込みから色々誤解してそうなフシがあるから注記しとくと
・初期化が無い宣言の時点ではその変数の値は決まってない。
その変数を格納するためのメモリ領域に元々入ってるデータがそのまま値になる。
・文字列リテラルで出来るのはあくまで初期化であり、代入は出来ない。
つまり、char c[] = "unko";はできるけどchar c[20]; c = "unko";はダメ。
・ポインタに対しても同じ事が出来るけどそれはchar *cのに対して静的なリテラルのアドレスが代入されたのであって
↑のルールとは無関係。だから厳密に言えば↑のレスは的外れになる。
%p ならなんとかしてくれるかもしんない。 あ。 ゼロサプレスしてたっけか?
なるほどー。 char c[20]; ってやって、初期化しなかった場合に代入したいときは scanfとかstrcpy使わないとだめなのかな? c="asdf"はできなくてstrcpy(c,"asdf")はできるんだよね。。。 なんでc="asdf"はだめでstrcpyは良いのかよくわからないけども、まぁいっか
>>443 char c[20];
char *p=c; cのアドレスをpにコピー
コピーしたのは「アドレス」であってデータそのもの("ABCDE")ではない
このときpには c のアドレスが入っている
次に p="ABCDE";
を実行すると p は"ABCDE"というリテラルの「アドレス」が代入され
cに"ABCDE"がコピーされるわけではない
c(=p)にコピーしたいのなら strcpy(p,"ABCDE"); としなければいけない
>>443 > なんでc="asdf"はだめでstrcpyは良いのかよくわからないけども、まぁいっか
c="asdf"は、char型の20個の領域にアドレス(="asdf")を代入しているからだめ
strcpyは、char型の20個の領域に文字列asdfをコピーしているから良い
>>443 Cでは配列間での代入はできない。また、"asdf"は'a'を指すポインタと解釈される。
従って、c = "asdf"は配列へのポインタの代入と言うことになり、当然できない。
どうしても代入したければ、要素を一つずつ代入すればよい。
#そしてそれを、ナル終端文字列専用にしたのがstrcpy()だ。
c="asdf" ← というか、そもそも、c = で使えない。(cは配列の先頭を表してるってだけ) strcpy(c,"asdf") ← c(配列の先頭のアドレス)とリテラルのアドレスを渡して、 'a','s'・・・を順次入れているだけ。
>>443 "asdf" は文字列が格納されている先頭メモリ番地
c="asdf" はアドレス値をコピーしようとしている
strcpy(c,"asdf") はアドレスが指すデータをコピーしようとしている
for (i = 0; i < THREAD_COUNT; i++) { /* スレッド生成 */ if (pthread_create(&thread_id, NULL, threadFunc, (void *)thread_arg) == 0) { thread_count++; } } とやって、THREAD_COUNTの数をいろいろ変えているのですが ある一定の数以上は、必ず失敗するようになります。 自分の環境では303個めまでのスレッドは作成できますが それ以上は作成できません。 どこかでスレッドの上限というのは決められているのでしょうか?
/* 1000以下の素数を求める(第1版) */ #include <stdio.h> int main(void) { int i, no; unsigned long counter = 0; for (no = 2; no <= 1000; no++) { for (i = 2; i < no; i++) { counter++; if (no % i == 0) /* 割り切れると素数ではない */ break; /* それ以上の繰返しは不要 */ } if (no == i) /* 最後まで割り切れなかった */ printf("%d\n", no); } printf("乗除を行った回数:%lu\n", counter); return (0); } これでnoが3の時二個目のfor分のところのiが<演算子なのに3になるんですか? 3にならなければ3素数なのにprintfで表示されないですよね
no = 3, i = 2 → 割り切れない no = 3, i = 3 → i < noを満たさないのでループ終了 no == i なので3は素数
<これでも 3<3までいくんだ? <=じゃなくても
3になったからループを抜けるわけで
ループの流れ i = 2 i < no の判定 処理 i++ i < no の判定 処理 i++ i < no の判定 処理 i++ ・ ・ ・
>>450 =452 ...か?
妥当なインデント付けて、最初のforループの中を一行ずつ追っていけば
何となく分かるかもね。
>>452 そうじゃなくて
no=3 のとき iのループは3になったら抜けるわけでループ内では2までしか処理されない
ループを抜けているのはiが3だからループのあとiは3になっている
printf()が負値を返すのはエラーが発生した場合とのことですが 具体的にエラーが発生するのってどんな状況のときなんですかね?
>>457 厳密には、printf()は出力に失敗するとEOFを返す。
リダイレクト先の出力がなんらかの制限のあるデバイスにでも振り向けられていなければ、
一般的には出力は必ず成功する。
てか画面以外は失敗する可能性あるよね。
>>459 画面って何?
/dev/consoleのこと? 必ずしも画面とは限らないのだけど……
要は、下位のwriteが失敗するかどうかが大体のキモだね。 printf(NULL)みたいなどうしようもないようなものをのぞけば。
>>457 普通にファイルに書いてたって空き領域がなくなることはあるだろうし
リムーバブルなメディアなら途中で引っこ抜かれるかも試練。
実は、バッファリングされているから必ずしもエラーにならない罠。
必ずしもの使い方が間違っている希ガス
463ではないが、必ずしもエラーになるとは限らない、かな?
容量オーバーした瞬間にエラーにならない可能性はあるが、 失敗する可能性は十分あり得るということでFA?
>>467 grep で検索しても dFF はどこにも宣言されて無いようだ
整数mからnまでの和を、公式n(n+1)/2を使わずに求めるプログラム作ったんですけど #include <stdio.h> int main(void){ int m,n,i,ans=0; printf("数値入力>");scanf("%d",&m); printf("数値入力>");scanf("%d",&n); if(m<=n){ for(i=m;i<=n;i++){ ans=ans+i; } printf("%d",ans); } else { for(i=n;i<=m;i++){ ans=ans+i; } printf("%d",ans); } return 0; } このプログラムって、答えをansという変数に代入してるんですが ansを使わずに求めるにはどうしたらいいんですかね
mかnに加算していけば?
>>469 再帰処理で
#include <stdio.h>
int mysum(int a,int max)
{
if(max<=a) return a;
return mysum(a+1,max)+a;
}
int main(void){
int m;
printf("数値入力>");scanf("%d",&m);
printf("数値入力>");scanf("%d",&n);
if(m<=n){
printf("m=%d\n",mysum(m,n));
}
else {
printf("n=%d\n",mysum(n,m));
}
return 0;
}
472 :
471 :2007/04/05(木) 22:03:22
あっ printf("m=%d\n",mysum(m,n)); printf("n=%d\n",mysum(n,m)); m= と n= 消しといて
>>469 ansを思いっきり使ってるので無視してくれて構わないが簡略した
int MtoN_Add(int m, int n)
{
int i = (m>n)?n:m, ans = 0;
while( (m>n)?m:n >= i ) ans += i++;
return ans;
}
#include <stdio.h> int main(void){ int m,n,i; printf("数値入力>");scanf("%d",&m); printf("数値入力>");scanf("%d",&n); if(m>n) m^=n,n^=m,m^=n; for(i=m+1;i<=n;i++) m+=i; printf("%d",m); return 0; }
ハッカーの楽しみに載ってるやつかww
m^=n,n^=m,m^=n これでスワップが出来るとは知らなんだ。勉強になったぜ
勉強するのはいいが、実用性はないに等しいから使わないようにね。
do while文ってつかわないほうがいいの?
while文よりは利用機会は少ないと思うけど、 使わないほうがいいってことはない。 ただし、do while文の最後を } while (条件); のようにwhileが先頭に来るように改行するのは好ましくない。 こう書いてしまうと、一軒、新たに while文が始まったように見 えてしまう。 } while (条件); とするのがよい。
サイズの指定たとえば#define BUF 256とかを 複数のファイルで共有するにはどうすればいいの? ヘッダに書いちゃっていいものなの? 優しく教えてくれる東ちづる似のお姉さん回答お願いします。
共用するヘッダに書いて#includeする。
483 :
481 :2007/04/06(金) 09:21:17
>>482 すみません
それは新しくヘッダのみのファイルを作っておくって事でしょうか?
common.hみたいな名前のヘッダファイル作って、そこに#define全部書いて 定数使うソースに#include "common.h"書けばおkって話。
485 :
481 :2007/04/06(金) 10:50:30
>>484 そうしたいと思います。
回答ありがとおおおおおおおおおおおおおおおおおおお。
>common.hみたいな名前のヘッダファイル作って、そこに#define全部書いて 勘弁してくれ。
今の時代、ヘッダ直しただけで毎回フルビルドになってもOKダヨー
本当に時代は進化したなぁ
>>486 へ?何が勘弁してなの?煽りじゃなくてマジで・・
>>487 それが理由じゃない。俺様マクロが氾濫する原因になるから
利用したいソース群ごとにインクルードファイルは分けて欲しいだけだ。
つーか、>484の方針だとプロトタイプ宣言も全ソース共通のインクルードファイルでやってそうだな…
プロトタイプ宣言は普通全ソース共通のインクルードファイルに書くだろ prototype.hとか作って
普通にモジュール化してたらそうはならないだろ
なるだろ
で結局どうやるのが正解なわけ?
>>492 勘弁してくれ。
その方針じゃ、必要のないインクルードファイルまで全部インクルードする羽目になる。
標準インクルードも片端からインクルードすることになるジャマイカ。
例えば20本くらいのソースのうち、時間(time_t)を取り扱う関数がソースAにあるとする。
それを利用するのは、ソースBとソースCだけだとする。
ソースD以下はtime_tなど全く頓着する必要はないのだが、プロトタイプが全部共通だと
全てのソースでtime.hをインクルードすることになるということだ。
time_tならそんな心配はないだろうが、環境によっては他とぶつかる可能性のある
マクロを定義しているインクルードファイルもあるだろう。
#たとえばBoolという定数マクロと関数マクロがぶつかることがあるOSの標準インクルードで実際にあった。
>493が言うように、きちんとモジュール化していたらそんなことになるはずないんだがな。
#つーか、C++でクラス設計していたら有り得ないだろ。
>>496 なんとなく共通のヘッダファイルは、さけてきたけど・・・
では、そうゆう方向で >_<;
>>498 プロトタイプ宣言を纏めるためには、引き数や戻り値で使う型の情報が必要になる。
それらをインクルードすれば同じこと。
ポインタ型はすべてchar*に変換すればいい というか業務だとそうしてるよな?普通 そうしないとくだらない依存関係で悩むことになる
16進を2進に変えるのって ただ単に桁ごとの数字を二進法にかえればいいだけですか? たとえば0x65なら6を二進にした0110と5を二進にした0101を並べて 01100101ってやりゃいいの? どんな数でもこの法則成り立ちますか?
4進数なら 00 00 8進数なら 000 000 16進数なら 0000 0000
>500は釣りだろ。いくらなんでも業務で型無しプログラミングなんて有り得ない。
インターフェイスをchar *で統一するとデータ型に依存しないから、 仕様変更があった場合、修正個所少なくなる。というのはあるかもね。 作業が進んでから「データ型変更されますた」とかあるしw
そして、仕様変更でデータ型が変わってもその事実が伝達されずにそのままビルドされて納品される罠。
>>508 どこが愚かが具体的に言わないと反論になってない
さらに自分の改善案も出さないとただの愚痴
>>509 >507
>504
>496
>493
>>502 2進数を3桁で区切ってその3桁を1桁づつにすると8進数、4桁で区切って1桁づつに
すると16進数。というのは、2進数3桁だと8種類の重みを表現可能だからで、これを
一桁で表せば8進数ということになる。2進数4桁で16進数というのも同じこと。
>>509 反論ではありません。あまりの愚かさに衝撃を受けて出た一言です。
外人がよく言う "Oh My GOD!" に近いものです。
ああ。あなたに神の許しがありますように。
_____ /::::::::::::::::::::::::::\ _ /::::::::::::::::::::::::::::::::::::::\ /  ̄  ̄ \ |:::::::::::::::::|_|_|_|_| /、 ヽ |;;;;;;;;;;ノ \,, ,,/ ヽ |・ |―-、 | きみ頭だいじょうぶ? |::( 6 ー─◎─◎ ) q -´ 二 ヽ | |ノ (∵∴ ( o o)∴) ノ_ ー | | /| < ∵ 3 ∵> \. ̄` | / ::::::\ ヽ ノ\ O===== | :::::::::::::\_____ノ:::::::::::\ / |
>>500 何社か渡り歩いたけど、そうやってる会社もあった
大手電機メーカーでした
>>506 せめてvoid*
何も事態は改善しないけど
え?悪化してるような気がする。 char*ってことは、一旦シリアライザ・デシリアライザを挟もう、って意図じゃないの? いまどきのIPCがみんなXML使ってるみたいに、関数の引数もXMLにしよう、みたいな話ではないの?
_____ /::::::::::::::::::::::::::\ _ /::::::::::::::::::::::::::::::::::::::\ /  ̄  ̄ \ |:::::::::::::::::|_|_|_|_| /、 ヽ |;;;;;;;;;;ノ \,, ,,/ ヽ |・ |―-、 | きみ頭だいじょうぶ? |::( 6 ー─◎─◎ ) q -´ 二 ヽ | |ノ (∵∴ ( o o)∴) ノ_ ー | | /| < ∵ 3 ∵> \. ̄` | / ::::::\ ヽ ノ\ O===== | :::::::::::::\_____ノ:::::::::::\ / |
>>468 ありがとう。どうやらIDEが別の似たファイルを参照していたらしいです。
解決しました。
521 :
デフォルトの名無しさん :2007/04/06(金) 20:05:31
>>476 XOR使ったスワップは、同一だとちゃんと機能せんから
せめて
a +=b, b = a - b, a -= b
とか使うようにしましょう。
一方俺はバッファを使った…
叔母風呂
同一( &a==&b )の場合は
>>521 の方法でも 0 になってしまうよ
for文の途中に return 0などがあると 関数に0を返したあとに、関数の処理は終わってしまいますか?
もちろん
#include <stdio.h> #include <math.h> int sosu(int); int main(void){ int i,m; printf("数値入力>");scanf("%d",&m); if(m<=0) return 0; printf("2 "); for(i=3;i<=m;i+=2){ if (sosu(i)==1) printf("%d ",i); } return 0; } int sosu(int n){ int i; if(n==2)return 1; if(n%2==0) return 0; else{ for(i=3;i*i<=n;i=i+2){ if(n%i==0){ return 0; } } } return 1; } 入力した数までの全ての素数を表示するプログラム作ってみたんだけど これだと横一列に表示されて見づらいので、5個ずつ表示して改行\nつけたいんだけどどうしたらいいですかね 2 3 5 7 11 13 17 19 23 29 31 37・・・といった感じです
>>528 これでどう?
if (sosu(i)==1) printf("%d ",i);
↓
if (sosu(i)==1){
static int sosu_count=1;
sosu_count++;
printf("%d ",i);
if(sosu_count%5==0) printf("\n");
}
void MyPrint(int i) { static cnt; printf("%d ", i); cnt++; if(cnt == 5) {printf("\n");cnt=0;} return; } こんな関数をprintfの代わりに使うのはどう?
できたー ありがとうございます
int main(void) って int main() と C言語は略しちゃいけないんだよね?
>>532 int main();はお勧めできませんが、
int main()ならどうでもいいと思います。
規格をあたってみたところ、関数の定義なら問題ないと読めた。 参照したのがはJIS X3010:2003 (C99翻訳)なんで、C89とかだとどうなのかは知らんが。
C89でも同じ事です。
536 :
デフォルトの名無しさん :2007/04/07(土) 03:51:54
素数そっすうそっすうーーー #include <stdio.h> #include <stdlib.h> #include <string.h> void sieve(char *p,int d); int main() { int d = 0,i,k; char buff[256] = {'\0'}; char *p = NULL; fgets(buff,sizeof(buff),stdin); sscanf(buff,"%d",&d); if (d <= 0) {fprintf(stderr,"input positive number and less than INT_MAX number.\n");exit(1);} if ((p = malloc(d))==NULL) {fprintf(stderr,"failed to allocate %d bytes of memory.\n", d);exit(1);} memset(p, '\0', d); sieve(p,d); printf("primes up to %d\n", d); for (i = 0, k = 1; i < d; i++){ if(p[i] == 2){i++;} if (p[i]==0){printf("%-4d ", i+1); k++;} if(!(k%5)){ putchar('\n');k++;} } return 0; } void sieve(char *p,int d) { int i, j; p[0] = 2; for (i=2; i <= d/2; i++) for (j=2; j <= d/i; j++) p[i*j-1]=1; }
インデント無いとこれほどまでに読みにくくなるんだな…
C言語で駄目文字ってどういう時に発生するの?
駄目文字って何?
Shift_JISで表したときに2バイトめに 0x5c が来る文字を俗に 駄目文字と呼ぶらしい。
表とか?
カタカナの「ソ」とかな。
>>538 への答えとしては、扱うエンコーディングにShift_JIS(CP932など
類似品も含む)があるときは常にその必要があると思え、くらいか。
543 :
デフォルトの名無しさん :2007/04/07(土) 15:33:49
sizeof演算子 の意味がわかりません。教えてください。
544 :
デフォルトの名無しさん :2007/04/07(土) 15:54:25
意味ってw 変数の使用バイトを調べる為にあるんだよ マロックとかで変数渡すときに、4って書くよりsizeof(int)って書いた方が分かりやすいからだよw
sizeof(int) : int型のサイズ(4バイトとかそんな感じ) sizeof(hoge) : 変数hogeのサイズ(char hoge[260]なら260) 前者は型のサイズが違っても対応できるように、後者はmalloc(sizeof(hoge))みたいな感じに使う
典型的な応用例: int array[10]; for (int ic = 0; ic < sizeof(array) / sizeof(* array); ++ic) array[ic] = 0;
質問者のレベルだと *arrayのところは、array[0]と書いた方が分かりやすいだろう。
構造体でもパッキングの値に対応した本当のサイズが出るので sizeof は不可欠
sizeofはエロイ
inlineよかまし
>>548 いや、詰め物なくてもsizeofは使うだろ。
メンバ変数のサイズを個別に求めて、合計するわけ?
552 :
デフォルトの名無しさん :2007/04/07(土) 19:55:09
4って書くよりsizeof(int)って書いた方が分かりやすいからだよw ?intは2バイトじゃないのですか???
釣りだろうけどマジレスするとintサイズは環境依存、一般的には 8bit, 16bit cpu では2の 32bit cpuでは4 64bit cpuでは4, 8 に分かれる。
555 :
デフォルトの名無しさん :2007/04/07(土) 20:03:30
コンパイラが決めてるってことですか? どーやって決めてるんですかね?
556 :
デフォルトの名無しさん :2007/04/07(土) 20:06:58
釣りじゃないです。 勉強し始めて、一ヶ月。 わからないことばかりです。 本には、intは2バイトって書かれてるから。 環境依存? むつかしい。前途多難です。
Javaだと身動き取れないくらいカッチリとサイズが決められてるけど、 Cのintは最低2バイトでshort以上long以下のCPUに都合の良い(が扱いや すい)幅。以上/以下とあるから、どちらかと同じであってもよい。
C99だと「最低でも32bit以上で、一番速い型」とか指定できるからいいな。
intが最低2バイトと書いてしまったが、ちゃんと書くと、 1. short: 最低2バイト、longよりは小 2. long: 最低4バイト、shortよりは大 3. short <= int <= long 1.2.からshortとlongの幅が同じになることはないので、3.の等号は 成り立つとしても片方しか成り立たない。
longとintでサイズ同じなら二つも作って紛らわしくさせんじゃねーよ! とか憤ってた学びたての頃の俺をDQNといわないで下さい
>>555 実行環境のCPUその他アーキテクチャにとって都合の良い大きさに決まる
CPUが64ビットだとややこしいな。 int=64ビット long=64ビット int=32ビット long=64ビット int=32ビット long=32ビット long long=64ビット
>>558 のカッコのなかの「が」は
CPUに都合がよい、しかし扱いやすい
じゃなくて(逆接になる意味がない)、
CPUに都合がよい(CPUが扱いやすい)
の意です……
>>560 それ間違ってないか?
手元の本にはそんなことは書いてないが。
shortはshort int、longはlong intの略記であり、 無印intはshort intかlong intのどちらか処理系に都合がよいほうと同じ、 だっけ?
手元の本って何だよ。JISのプリントアウトか?
まぁ、もちろん規格にも
>>560 のような最低hogeバイトとは書いていないけどな。
>>560 > 1.2.からshortとlongの幅が同じになることはないので、3.の等号は
> 成り立つとしても片方しか成り立たない。
実際に sizeof(short) == sizeof(int) == siezeof(long) == 4 な処理系は実在する。
>>566 intがshort intとlong intのどちらかと
同じ大きさである必要があると定められてはいなかったと思う。
>>567 しかし<limits.h>の定数は少なくともxxx以上・以下でないといけないという規定があり、
そこから必然的にshortとintが16ビット、longが32ビットなければならないということが導かれる。
1バイトが8ビットである環境なら当然2バイトと4バイトになる。
「3.の等号は成り立つとしても片方しか成り立たない」は違うような気がするけど。
知っているつもりのことでも、きちんと知らないことってあるんだなあ。
572 :
デフォルトの名無しさん :2007/04/07(土) 20:52:41
すごい細かいんですね。 大丈夫かな?? 無理かな??不安になってきた。
「どこでも同じとは限らない」ということだけ知ってればOK。
つまり sizeof(short)=2 sizeof(int)=3 sizeof(long)=4 な処理系があればいいんだ、過去の俺を納得させるだけの為に
575 :
デフォルトの名無しさん :2007/04/07(土) 21:13:02
だからどーやってCPUがバイト割り当ててんだよ その仕組みを教えればいいだろ
説明しきれないんだろ? 少なくとも俺はわからん
CPU < short形が2バイトだの、charが8ビットだのってのは、俺が決めてるわけじゃねーよ。
誰がきめてんだよ
設計者じゃねーの?
580 :
デフォルトの名無しさん :2007/04/07(土) 21:20:05
何になるの?? こんな質問方法では、だめか・・。
設計者なわけないだろ あたらしいCPUがでたら また設計者があたらしく定義しなおすのか?
>>575 CPUを設計する人が「これは32ビットCPUだ(1バイト=8ビット)」と言えば、
コンパイラを設計する人はそのCPUで動くコードを出力するコンパイラはintを4バイトにするという具合。
コンパイラを設計するひとは CPUが新しくできるたびに設計しなおさないといけないってこと?
CPUのレジスタサイズと、コンパイラの整数型は必ずしも一致してないんだな。 32bitCPUでも、int8のコンパイラがあったり、int64のコンパイラがあったり。
すんげぇめんどくさいんですね 出来たばっかりのCPUだとプログラミングできないんじゃん
毎度新しく決める必要はない。 たとえば80386から続くIntelの32ビットCPUシリーズはIA-32と一括りにされるという具合。
587 :
デフォルトの名無しさん :2007/04/07(土) 21:27:27
なるほど
もちろんCPUが全てではない。 x86-64では、WindowsはMSがWindows APIをLLP64にすると言い、 VC++もLLP64(long longとポインタが64ビット、intとlongは32ビット)になった。 しかしUnix系では一般的にLP64(longとポインタが64ビット)が採用されていると言う具合。
入門者には難しい >_<;
>>574 そんな環境はないだろうけど、
short = 2
int = 4
long = 8
なら、普通にあるだろ。
591 :
デフォルトの名無しさん :2007/04/07(土) 23:12:07
char K1[]="abcde"; は、 sizeof は、何になるのですか?? 6??なぜ??
>>591 配列はその全体のサイズになるから。
文字列の場合は最後に0がつくから、みかけのサイズより+1の大きさになる。
規格でそう決まっているから
594 :
デフォルトの名無しさん :2007/04/07(土) 23:21:50
591 \0 じゃなくてですか?
NULLぽ
配列の平均値を求める関数aveを作ってみたんですが これで表示が1としか表示されないんだけどなんでですかね・・・ #include <stdio.h> void ave(int array[]); int main(void){ int a[5]={1,2,3,4,5},i; ave(a); return 0; } void ave(int array[]){ int sum=0,i,m; m=sizeof(array)/sizeof(int); for(i=0;i<m;i++){ sum+=array[i]; } printf("平均=%d\n",sum/m); } 調べてみたら、ave関数のm=sizeof(array)/sizeof(int) がおかしくて、mに1が入ってみるみたいなんです。 配列aの要素数は5だから、mに5を入れたいんだけどどうすりゃいいんですかね?
>>599 Cでは配列を関数に渡すことはできない。素直に個数も渡すしかない。
cf.
void ave(int * array, int nOfArray) {
...;
}
>>599 void ave(int array[]){
これはダメだな
int *array と同じでポインタのサイズしか渡さない
int *array のポインタサイズ(4バイト) / int のサイズ(4バイト)=1
void ave(int array[],int size)
{
int sum=0,i,m;
m=size/sizeof(int);
・・・・・
}
int main()
{
・・・・
ave(a,sizeof(a));
とするとか
you! c++でいっChinaよ
C言語では、関数に配列を渡して、渡された配列の要素数を調べる関数ってのは作れないのか。。。 main関数で要素数を入れなきゃダメなんですねどうもありがとうでした
出来ん事も無いけど STLとか使ったら一瞬で出来ることをなんで悩まないといけないのか って鬱になるから普通はしない
課題でeggx(C言語)てので正五角形を作って来いって言われたのですが途方にくれてます。 多角形を描く関数(fillpoly)もあるようですが、頂点の座標がわからないと描けないようで困っています。
頂点の座標なら 円の式と、直線の式の交点を求めるとか sin、cosを使うとか
プログラムと何の関係があるのか分からんが、 正五角形の頂点なら、 k=0, 1, 2, 3, 4 として x = cos(2π/5 * k) y = sin(2π/5 * k) で求まるだろう
608 :
デフォルトの名無しさん :2007/04/08(日) 08:32:47
Cのライブラリ全てが説明されている本って無いですか? 言われて分かる人なら X680x0 libc みたいな本を探している、と言えば早いですかね。 使用する関数名が分かっていれば、man して使い方を知る事は出来るものの、 どんな関数があるのかが分からずで困ってます。 対象は Linux / FreeBSD で、ソツ無く使える本を。
man2とかman3のディレクトリをlsしちゃだめなのか?
標準Cの範囲なら規格書で充分だろ。
セクション2はCの規格じゃないけどな。
以後、配列を扱う場合はかならず構造体の単一メンバにすること。
オーライリーのC Pocket Referenceに種類ごとに標準関数の説明が載ってるよ
>>608 は、Unixのシステムコールも含んで、載ってるやつがほしいんじゃないか?
>>608 あんまりない無い。
http://www.linux.or.jp/JM/index.html 結局これが一番いいんじゃないかと思う。
入門書としては、UNIX-Cプログラミングを唱っているもので、プロセス・スレッド、
mmap、socletなんかを扱っているものもあるが、中途半端なものばかり。
最終的にはmanみろってことなのかもしれない。
UNIX共通に通用するベース技術・仕様の本といったら、POSIXの規格書とか
解説書あたりがお望みのものに近いか?
BSD系はソースが公開されているんだからそれを読んでコミニュティで
解決しろというスタンスが濃い。
Linuxはアプリケーションソフトばかりがとりだたされる傾向にあって、
コアなライブラリ解説なんて皆無に等しい。
オライリーのカーネル本とか、デバドラ本くらいか。
「ふつうのLinuxプログラミング」あたりでファイルシステムとかストリーム とかシグナルとか、考え方から理解しておいて、あとはmanなんだろうなぁ。
スティーヴンス本も知らんのか君達は
(´・ω・`)知らんがな
C言語500の極意(うろおぼえ)みたいな本で十分だろ。
608です。
皆様からのレスは本屋で携帯から読めて大変参考になりました。
>>615 >オーライリーのC Pocket Referenceに種類ごとに標準関数の説明が載ってるよ
C Desktop Reference なる本は見掛けたのですが、これの事?
内容は本の厚さに比例してそこそこと言う感じでした。
初めてCを使う人には良いかも。
>>623 >C言語500の極意(うろおぼえ)みたいな本で十分だろ。
これを見掛けた時は「これか!?」と思ったのですが、内容が・・・
参考になる点も多かったのですが、今求めている物とは大きくずれてました。
いざ探してみると満足の行く物は確かに無いですね。
みんなどうやってプログラミングしているんだろう?と不思議になってきました。
今にして思うと X680x0 libc は偉業と感じます。
これには標準的な関数ならバッチリ載っているので、残りは
>>617 を参考にするのがベターの様です。
本屋で探した感じでは C言語大辞典 がわりとイイ線行ってたので
今度は神保町あたりでじっくり探してみたいと思います。
レスしてくれた方々、有難う御座いました。
配列って、絶対アドレス順にしかできないの? a[0]とa[1]はメモリ上となりあわせで a[0]アドレスが100ならa[1]は99といった感じで使いづらい・・・ malloc関数を使ったら、a[0]〜a[それまで]のものが全部初期化されちゃって使いづらい。 今までの配列の要素を変化させずに動的に配列の要素数を変化させることはできないですか? scanf関数を使うたびに配列の要素をひとつずつ増加させるのを作りたいんだけど。 int ct=0,m,*data; data=(int*)malloc(100*sizeof(int)); while(1){ scanf("%d",&m); if(m==0)break; data[ct]=m; ct++; } たとえばこれだと100個以上の入力されるとエラー起こすし、 5個しか入力しないと残りの95個もったいない どうすりゃいいですかね?
そのための線形リストだ。
>>625 ・realloc
・std::vector (C++ 限定)
628 :
デフォルトの名無しさん :2007/04/08(日) 22:09:43
ビット演算の意味がわからない。
629 :
デフォルトの名無しさん :2007/04/08(日) 22:11:34
#include<stdio.h> void main(void){ int x,y; scanf("%d,%d",&x,&y); printf("%d",x/y); } 5行目:0で割っています と出るんですが、何故なんでしょうか? x,yには0以外の数字を入力しています
"%d,%d"のフォーマット通りに入力してる?
>>620 >>603 の
>C言語では、関数に配列を渡して、渡された配列の要素数を調べる関数ってのは作れないのか。。。
に対して
>>604 が
>出来ん事も無いけど
って答えているので、STLってかテンプレート使わずにC言語の機能だけでできるのかなぁと思って聞いてみたわけです。
なんか粘着みたいですいません。
>>624 いや"C Pocket Reference"
もれは英語版を使ってるけど一応ISBNは
0-596-00436-2
633 :
629 :2007/04/08(日) 22:22:42
>>630 すいません、フォーマット通りとはどういうことでしょうか?
>>630 じゃないが
たとえば
$ 4,2
にように入力してるかってこと
10,2 とか
123,456もだな
637 :
629 :2007/04/08(日) 22:29:46
>>636 いやwwwそれいったらintの範囲のその範囲乗までレスがつくぞ
scanfの戻り値みろよ…
640 :
デフォルトの名無しさん :2007/04/09(月) 10:18:00
すいません、どなたかわかる方がいれば回答お願いします C言語のコマンドラインから引数を渡すプログラムで ちゃんと動いてくれませんorz #include <stdio.h> #include <stdlib.h> int main(int argc,char *argv[]){ FILE*fin,*fout; char ss[256]; if(argc!=3){ printf("引数の数が違います\n"); exit(1); } if((fin=fopen(argv[1],"r"))==NULL) { printf("入力ファイルをオープンできません\n"); exit(1); } if((fout=fopen(argv[2],"w"))==NULL){ printf("入力ファイルをオープンできません\n"); exit(1); } while (fgets(ss,256,fin) !=NULL){ fputs(ss,fout); } fclose(fin); fclose(fout); return 0; }
641 :
デフォルトの名無しさん :2007/04/09(月) 10:21:03
これをコマンドプロンプトやbcpadなどで実行しても最初の引数の数が違います、 としか表示されなくて・・・ 色々調べて試行錯誤したのですが結局一晩かけてもわかりませんっでした こんな自分は問題解決能力がないからPGむいてないのでしょうか(´Д`;)
>>640 >これをコマンドプロンプトやbcpadなどで実行しても最初の引数の数が違います、
>としか表示されなくて・・・
漏れの環境では、引き数を指定しないで実行したらそうなった。
期待通りの動作じゃないのか?
学びたての頃一日かけてやっとセミコロンが一つ足りないことに気付いたことがある俺の勝ち
セミコロンが一つって思うだろうがたかが1日じゃないか 3日悩むよりずっといい まだまだだな
>>640 のfinの宣言部で
FILEと*finがくっついて1つの単語になってるように見えるのはオレだけ?
俺の三倍とはこやつやりおるわ… hoge.exe piyo.txt のようにコマンドプロンプトに入力すればファイルの中身を表示できるはずです。 くらい書いとけばいいのに、不親切なテキスト(かどうか知らんが)だなぁ
漏れなんて、ソースファイル末尾の改行がないためにNULLポン消えなくて一週間悩んだぜ。 #コンパイラが生成するアセンブリ出力の改行が足りなくなると言う素敵なバグの所為だったんだけど。
>>641 >これをコマンドプロンプトやbcpadなどで実行しても最初の引数の数が違います、
ってことは
printf("引数の数が違います\n");
が実行されて表示されてるってことで
それが実行される条件はプログラムに与えられた引数の数
だからtest.exe a.txt b.txtのようにプログラムに与える引数を変えればいいんじゃない
問題解決能力じゃないと思う
たとえばできるだけ客観的に説明する能力とか不足を補う理解力とか
誰もが通る道だけどな向き不向きなんてすぐにはわからん
PGに不向きな奴は1年持たない 1年持てば問題なす
もれなんて一切コメントがないという芸能人の浮気疑惑のようなプロジェクトを引き継いで マイプライベートタア〜イムを返上して解読&コメントつけていったのに 1ヵ月後に会社が清算を迎えたo... rz
654 :
デフォルトの名無しさん :2007/04/09(月) 15:35:11
655 :
デフォルトの名無しさん :2007/04/09(月) 20:53:17
フリーウェアの秀丸のサイトを教えてください
は?
658 :
デフォルトの名無しさん :2007/04/09(月) 21:15:23
#include <stdio.h> int main(void) { /*文*/ return 0; } 入門書では上のように学んだんですが、コンパイルできれば次のような形式でも 問題ないのでしょうか? #include <stdio.h> main(){ /*文*/ }
いや、下のでも問題ないよ。
戻り値の書かれていない関数定義はintを返すと見なされる(Cではだっけ?) ので、いいっちゃいい。(許容されるという意味で)
return 0のほうか。
戻り値を使う予定がないならなんでもいいよ。
型は
>>661 にあるようにintになるがどんな値になるかは不明。
>>659-
>>662 レスありがとうございます。他の人のプログラム見せてもらったとき
たまたま見つけて疑問に思った程度なんです。とりあえず、
自分で書くときは習ったやりかたでやっていこうと思います。
>>662 >intになるがどんな値になるかは不明。
あれ?return書かない場合は0返すんじゃなかったか?
クラスのstaticで宣言したメンバー関数の関数ポインタを持つ事って可能ですか?
>>665 C++では前からそうだが、CではC99から
>>666 C++はスレ違いだが、静的メンバ関数は、非メンバ関数同様に扱える。
ようするに静的メンバ関数へのポインタはただの関数へのポインタで扱える。
>>666 可能
VCで試した
メンバーへのポインタじゃなくてC言語のように普通の関数へのポインタ
参考書とかネットの記事とか見てるとmain()内の最後で、 return 0; return (0); って2種類の書き方見るんだけどこれらに明確な違いってあるのか? 低レベルな質問ですまん ><
>>669 括弧いらない
あっても結果は変わらない
違いはない。ただし括弧を付けない書き方が一般的。 昔はreturnに括弧を付けなければならなかった。 現在、括弧は不要になったが、あっても式の一部として扱われるのでコンパイルは通る。
>>670 レスありがとう。やたら気になってたんだ
>>669 returnは関数じゃなくてステートメントだから付けないてよい。
付けてもエラーにはならないが a = b + c を a = (b) + (c) などと書くのと同じことで冗長。
お作法的な話で言えば、綴りを間違って retrn 0 と書けば即コンパイルエラーだが、
retrn(0) と書いてしまうとそういう関数があるものと仮定されリンク時までエラーが発覚しない。
sizeof expr はつけなくてよいと分かっていても括弧つけてしまうな…
これは確かに使い分けに迷う。 sizeof(型); sizeof 変数;
演算子もいってみりゃ関数みたいなもんじゃん ってことで()付けてるけどいいのか?
>>677 別に構いませんよ。
++(*(&(i)));
激しくうっとうしいわw
式だったら尚更()つけないとね
sizeof は、長い行の中に入ることもあって () なしだと見づらくなる場合があるからな
でもsizeof() じゃなくて、sizeof () にしてるな。
>>671 return に括弧が必要なときってあったか?
mem = malloc(len * sizeof * mem);
arrayという2次元配列にintの数値が入っています for(i=0;i<array[0][j];i++)という風for文の条件式にしようとしても出来ませんでした こういう場合はどうすればいいのですか
685 :
640 :2007/04/10(火) 16:10:53
やはりちゃんと動いてくれません(´Д`;)
>>650 さんの意味がよくわからないのですが
>>if((fin=fopen(argv[1],"r"))==NULL) の所のargv[]を1ではなくて他
の数値を渡せということでしょうか??
ちゃんと動かないって…もうちょっと他人にわかるように説明しろよ。 * どういう方法で起動していて、 * どういう挙動をして欲しいのか、 * そして実際はどういう結果になっているのか
687 :
362 :2007/04/10(火) 16:38:24
>>363 型を見てみたらsignedcharでした。
この型しかソケット通信では送れないのでしょうか?
>>364 ぐぐってもデータの転送順がかわることしかわかんなかったです><
多くのデータを一度にsendで送るいい方法はないのですか><
bcpadから直接起動してるから引数渡せてないと予想
趣味で麻雀をやってるんだけど、自分の打ち方がどれぐらい強いのか試そうと思ってC++のコンパイラさえあればあとは言語が書ければ代打ちソフトが作れるってdllを見たんでCをしてみようと思うんですけど。 これを読めばとりあえず素人はなんとかなるとか、このコンパイラが素人向けでわかりやすいなどありましたら教えてください。 一応Delphiは触るだけ触ったことはあるので言語そのものにアレルギー反応なんかは起こしませんけど、実用的なソフトを作ったことがないのでアルゴリズムなどちんぷんかんぷんです。
にh
691 :
:: :2007/04/10(火) 19:00:55
C言語習ったばかりなんですが、システムを組んでみたいと思ってます。 システムを組むための参考書や問題集は売ってますかね?自分で一から システムを作るのはやはり難しいですか?
システムの定義を教えてくれ
>>690 わかりにくかったなら省きますけど要は、素人におすすめできるコンパイラ(いつまでも使えるのならなおいいけどわかりやすさ優先。)と素人向けの参考書を教えてくださいってことです。
OKですか?
眠いのでちょっと日本語がおかしかったのは見逃してください。
>>693 おまいは、
>>690 を見て
>にほんg(ry
って分かったのかよw
だったらなぜ、そもそも改行が出来ないんだ
WindowsならBCCでおk
695 :
687 :2007/04/10(火) 19:58:19
キャストしてもデータが途中までしか送れません>< どうすればいいんですか
696 :
デフォルトの名無しさん :2007/04/10(火) 23:22:31
C言語で、char型の配列を確保する時に 領域を指定しないで宣言する方法ってありますか? char *s[]; ←のように宣言してもsのサイズが不明、もしくはゼロとか出て うまくいかないんですが、何かいい方法ありますか? 因みにこの問題ではmallocを使わないでやるという事が前提になってます。
callocもしくはreallocを使えばいい
質問です AまたはBならCをする if( A || B ) { C ; } という条件文をA、Bわけて記述した時に、 if( A ) { C ; } else { if( B ) { C ; } } こう記述できると思いますが、Cを1回だけ使うような記述の方法はあるでしょうか?
最近、こんなトンチみたいな問題だす学校、多いのかね?
>>689 それはつまり1人用の麻雀ゲームを作ろうというわけですね
それなら簡単なGUIと思考ルーチンが必要です
思考ルーチンは現在の状況, つまり引いた牌と持ち牌(っていうのか?もれは麻雀やらないから言い方違うかも)
と相手の打った牌などから次にどの牌を打つかを決める一連の思考の手順のことです
これは一般的に一種類あるいは数種類の思考パターンを用意し, これらのような決まった処理のことを
アルゴリズムと言う
アルゴリズム(思考手順)そのものは言語に依存しないので(もちろん言語によって書き方は異なるかもしれないけど)
すでに知っている言語があったら新たにCとかC++を勉強しなくてもOK
思考手順そのものを研究するのが目的ならVBやJavaなどの簡単にGUIが作れる言語が(個人的には)おすすめ
これを足がかりにほかのゲームや実用ソフトを作りたいなら将来にわたって使っていけるような言語を選ぶのもあり(CとかC++)
もしLinuxなどのUNIX系OSや, プラットフォーム非依存をターゲットとするならJavaが一番手っ取り早い
GTKやwxWidgetなどのクロスプラットフォームのツールキットを使うこともできる
(こういったツールキットは大抵複数の言語に対応している)
あるいはPythonなどのスクリプト言語を使ってみるのもあり
でも, ひとこと言わせてもらうと
> 自分の打ち方がどれぐらい強いのか試そうと思って
の意図はいまいちよくわからないが
作ったプログラムと自分で対戦すると言うなら
それは一人二役でゲームをするのと同じだからちょっと無意味っぽいと(個人的に)思う
また自分の思考をプログラミングしてほかの人やプログラムと戦わせたいのなら相当の覚悟が必要
人の思考は想像以上に複雑で, 無意識や勘なども作用してくるから
完全に自分の思考回路をプログラミングすることは(現実には)不可能に近い
したがって出来上がったプログラムは君自身より弱い
また, 何手か先を読むような(ありふれた)機能を盛り込む場合でも
計算しなければいけない手数は爆発的に増えるから(計算量とメモリーの増加), それをいかにして押さえるかとか
いろいろとテクニックも必要になってくる
ここまで考えるとかなり手間がかかる
もれは大学の卒論がチェスのゲーム理論だったからよくわかる
>>699 do
{
if( !A )
{
if( !B )
{
break ;
}
}
C ;
}while(0);
>>699 なぜそうするのかはわからんが
単純にフラグをつけるのもいいんじゃない?
Aが真ならflag = TRUE;してBのところでflag == TRUE;ならCを実行しないとか?
>>699 if( A )
{
C ;
}
else if( B )
{
C ;
}
これじゃダメなのか?
705 :
704 :2007/04/10(火) 23:52:50
>>699 if(A) {
goto l;
} else if(B) {
l: C;
}
>>699 if(A) goto label1;
if(B) goto label1;
goto label2;
label1: C;
label2: ;
で、本当にこれ宿題なのか? だとしたらこんな腐った問題を出す教師ってどんなやつなんだ。
Q.腐った問題を出す教師自体が腐ってる確率を求めるプログラムを作りなさい
>>710 int main()
{
printf("腐った問題を出す教師自体が腐ってる確率=%d%%",100);
return 0;
}
>>701 えっとですね、あんまり必要ないかと思って省いてしまったんですけど。
東風荘っていうネット雀荘みたいなものがあるんですけど、そのゲームの画面の状況から変数を作るdllを見つけてですね。
上がりや聴牌の判断もそのdllの関数がやってくれるので私はその変数の扱いを設定するだけで麻雀の代うちソフトが作れるようになるわけなんです。
だから、相手は人だし麻雀というゲームを遊ぶための土台の部分は配布されているので単純にアルゴリズムを考えるだけでOKってことなんですよね。
テクニックとしては、プログラムのテクニックよりは麻雀のテクニックのほうが重要だとおもうので簡単という言葉を使わせてもらってます。
そんな面白そうなものがあるのか。 ちょっと探してこよう……と思ったら一発で見つかった。
714 :
701 :2007/04/11(水) 05:22:28
>>712 ほほー便利だなー
それなら自分がどんな風に思考しているのかと
どうやってそれをアルゴリズムにするのかを悩むだけでいいのかw
if (A) { if (B) { C; } }
>>715 おちつけ
それは、A||Bは(又は)ではなくてA&&B(喝)だ
実際こういう場合はどうしたらいいの? 素直に判別式に論理演算使えってこと?
switch (x) { case A: case B: C; }
逆に論理演算を使いたくない理由ってのがわからない
というかその為に論理演算子があるんだから使ってやれよ… 論理演算子が泣いてるぞ。
AまたはBならCをする。 => AでないかつBでないならCはしない。 というド・モルガンの法則を理解するための課題であった。 なわけはないか。
>>719 caseは定数しかとらないので
A, Bのような式はだめ
>>699 void f(void){
C;
}
int main(void){
if(A){
f();
}else if(B){
f();
}
}
#define SHE C void main(void){ if(A){ SHE; }else if(B){ SHE; } }
↑訂正 ×void main(void){ ○int main(void){
>>723 setjmp&longjmp関数の有用性を教えるための課題
729 :
デフォルトの名無しさん :2007/04/11(水) 10:08:09
invalid digit "8" in octal constant invalid digit "9" in octal constant このコンパイルエラーって何ですか?教えてください!
>>729 8進数なんだから0〜7までで表せよ、
8や9なんてねーよバーカ
っていうエラー。整数の頭に0をつけてるだろ。
>>729 #include<stdio.h>
int main(void){
printf("%d\n", 012); /* 数値の頭に 0 が付くと 8進数 */
printf("%d\n", 12);
return 0;
}
732 :
729 :2007/04/11(水) 10:22:40
>730さん >731さん ありがとうございます! 参考になりました。
733 :
695 :2007/04/11(水) 10:35:06
整数やら文字列が入った構造体を、ひとつの文字列にするいい方法はないですか?><
735 :
733 :2007/04/11(水) 10:48:45
整数やら文字列が入った構造体を、ひとつの文字列にする関数を作りたいのですが、いい方法はないですか?><
いつまでこのアホタレを甘やかす気ですか?><
738 :
735 :2007/04/11(水) 11:02:14
struct test { int i; char c[10]; struct kouzoutai { int seisuu; double kazu; int suu; char moji[10]; }kou; };
739 :
デフォルトの名無しさん :2007/04/11(水) 11:04:39
740 :
735 :2007/04/11(水) 11:04:41
全部snprintfとかstrcatで繋ぐのはめんどくさいです 要するにバイト列と文字列を相互変換できる方法が知りたいのです><
741 :
735 :2007/04/11(水) 11:05:18
自己解決しました><
742 :
753 :2007/04/11(水) 11:06:53
爆釣ありがとうございました><
743 :
740 :2007/04/11(水) 11:07:14
>>741 してないです><
とりあえず16進数でずらずらと数字を並べてみることにするです><
744 :
743 :2007/04/11(水) 11:08:48
できました><
745 :
743 :2007/04/11(水) 11:21:14
>>744 まだやってません><
ところで、
sprintf(text, "ABC");
と
sscanf("ABC", "%s", text);
って
strcpy(text, "ABC");
と同じですか?
746 :
743 :2007/04/11(水) 11:39:57
隣の後輩が教えてくれました>< ありがとうございました><
747 :
745 :2007/04/11(水) 11:44:37
>>746 ><
なんとか自分でやってみます。ありがとうございませんでした><
カオスすぎです><
749 :
747 :2007/04/11(水) 12:26:13
初心者なのですいません><
750 :
749 :2007/04/11(水) 14:57:11
構造体へのポインタをunsigned char*型にキャストして 1バイトずつ2桁の16進数に直したら 構造体と文字列の相互変換ができました>< unsigned char *p; unsigned char text[1024], buf[1024]; strcmp(text, ""); p = (char *)&test1.kou; for(i=0; i<sizeof(test1.kou); i++) { sprintf(buf, "%02x", (unsigned char)p[i]); strncat(text, buf, 2); }
751 :
749 :2007/04/11(水) 14:59:26
p = (char *)&test2.kou; for(i=0; i<sizeof(test2.kou); i++) { strncpy(buf, &text[i*2], 2); sscanf(buf, "%02x", &((unsigned char)p[i])); }
752 :
749 :2007/04/11(水) 15:00:31
以上オナニーでしたありがとうございました><
753 :
749 :2007/04/11(水) 15:01:26
また初心者を装った釣りに来ますのでよろしくです><
もうこなくていいよ
755 :
751 :2007/04/11(水) 15:04:22
756 :
735 :2007/04/11(水) 15:06:39
すみませんなんか偽物がレスして話進んでるんですけど><
>>738 から全部偽物です><
757 :
755 :2007/04/11(水) 15:09:48
>>735 1バイトづつ16進2桁の文字列にしてしまうとか、あるいはコントロールコード
などの表示不能な文字はエスケープして表示可能な文字にして、表示可能な
文字はそのままにするとか、あるいは表示する必要が全くないのなら気にせず
全部 write() や fwrite() で出力してしまうとか、方法は色々あります。
759 :
757 :2007/04/11(水) 17:43:19
>>758 >表示不能な文字をエスケープして表示可能な文字にして
文字列←→構造体で相互に変換したいので、文字列から戻す時に
もともと表示可能な文字だったのかエスケープして表示可能になった文字なのか
分からなくなってしまうと思うのでこの場合は使えないです><すいません
ソケットプログラムでsendするときunsigned char型を使うので、
構造体を文字列にしたかったのですが後は何とか自分でがんばってみるです><
バイナリを可視なASCII列にするにゃ Base64 エンコが手っ取り早いような気がしないでもない が、構造体の中身をそのまんまエンコして送るのも抵抗があるな。 受け側のアライメントとエンディアン、基本型のサイズの全てが一致してないといけないしね。
>>759 エンコードした文字列は当然、デコードできる。
例えば不可読文字に遭遇したら%に引き続く二文字を16進の文字コードになるようエンコードする。
デコードするときは当然、その逆をやればいい。注意すべきは、%に遭遇した場合もエンコードしておく必要があることだけだ。
Ex.
source: SOH "abc%" LF "def" ETX 20(4バイト整数) EOT
encoded: %01abc%25%0adef%03%00%00%00%14%04
762 :
759 :2007/04/11(水) 18:06:10
>>760-761 ありがとうございます><すごく勉強になります
%をつける方法だと文字列の長さが一定にならないから送受信のとき大変そうですけど
なんとか考えてやってみます
>>762 ソケットの送受信は長さ決め打ちして読むと泣きを見るわけだが…
プロトコルを自前で規定してるか?
# fgets 等を使わずに fread と fwrite で同じことを記述できるようにしてから、
# ソケットへ移行したほうが良いと思うぞ。
バイナリ値主体なら>760、テキスト主体なら>761だな。 #どちらも定番だね。
765 :
762 :2007/04/11(水) 18:43:32
つい最近ソケットプログラムとかを勉強し始めたばかりなのでわからないことばかりで…。 とりあえずBase64というのをやってみることにします><;すいませんでした。
766 :
765 :2007/04/11(水) 18:58:09
今は文字列と数値を全部snprintfでそのまま繋げてやっていますが 構造体内の変数名とかを全部書かないといけないので ソースが汚いうえ無駄が多いです><
どういう風にやっているのかは知らないが、 そうやって単なる文字列にするのも一般的だと思うぞ。
構造体のシリアライズは一大テーマで、 ここで扱うには余白が狭すぎるとは思うんだよなあw
>>713-714 亀ですけど、もし興味わいたなら最強の麻雀のアルゴリズム作ろうぜスレで一緒に最強のアルゴリズムつくりませんか?
亀がしゃべった!
C始めて3日目の俺がきましたよ。 研修でダンプ出力するPGを作成する課題やってるんだけど、 ファイル開く→開いたファイルから16バイト読み込む →読み込んだデータの16進数変換を行いHEXに格納する までは出来たんだが、その後の置換処理がさっぱり分からん('A`) 置換処理はHEXに格納されたデータの表示できないコードを ピリオドに置換してCHARに格納するんだが、検討もつかないし_| ̄|○ 助けてくだしあ
772 :
デフォルトの名無しさん :2007/04/11(水) 21:40:26
>>771 isprint関数を使う
isprint(c)? c: '.';
>HEXに格納された 意味が不明すぎる char配列に16進数の文字を入れてるって事?数値?
776 :
771 :2007/04/11(水) 22:20:05
参考書片手に悩んでた。
>>772 レストンクス
ちと考えてみるわ。
>>774 HEXには
sprintf(HEX,"%X",ss)
でss内の文字列を16進表示で入れたんだが。
おそらく数値?
>>768 浮動小数点数を有効桁いっぱいいっぱいまで伝達しようとすると悩ましいね
778 :
714 :2007/04/11(水) 23:14:51
>>769 いやオレはもうチェスで懲り懲りだよww
プログラム部はだいたい解決策が決まってるけど
思考の部分は定石と言えるような方法がない
(まあ思考とプログラムも明確に分けれるもんじゃないけどね)
これ以上はスレ違いなんでそのスレの住民と一緒にがんばれ!
779 :
771 :2007/04/11(水) 23:39:22
>>774 自分でも問題の意味を分かってなかったらしい。すまぬ。
HEXDATA CHARADATA
| ̄| ̄| ̄| ̄| ̄| ̄| ̄| ̄| | ̄| ̄| ̄| ̄| ̄| ̄| ̄| ̄|
*|54|45|53|54| | | | | *|T|E|S|T|. |. |. |. |
 ̄  ̄  ̄  ̄  ̄  ̄  ̄  ̄  ̄  ̄  ̄  ̄  ̄  ̄  ̄  ̄
見づらくてスマヌ('A`)
こんな感じで格納したいわけで。
置換処理でisprint使うっていうのは大体分かったけど、for文で回してなにかしろ
みたいなことを講師が言っていた希ガス。何回したらいいの(;´Д`)??
780 :
771 :2007/04/11(水) 23:40:09
なんてこったい。 ステキにずれてらっしゃる_| ̄|○
数値をCHARADATAにそのまま書けばいいじゃん
回すものといえば皿ぐらいしか
783 :
771 :2007/04/12(木) 00:06:20
レストンクス。
>>781 CHARADATAに書き込むってisprint使ってですかい?
>>782 俺の頭の中で星が回ってるよ。
>>783 isprintで表示できないコードを判別して表示できないのならピリオドを、
表示できるのなら、そのコードを代入
785 :
771 :2007/04/12(木) 00:15:09
>>783 なるほど分かってきた。
isprintで表示できるって判断したときに返す値って何?
表示できないってときは多分0返してくるんだよね?
786 :
771 :2007/04/12(木) 00:17:48
784の安価ミス
>>785 そこまでヒントもらってるんだからマニュアルみなよ。ぐぐってもいいしさ。
788 :
771 :2007/04/12(木) 00:49:03
ある程度分かったから参考書片手に頑張ってみるわ。 おまいらありがとう
>>785 Cの真偽値の基本は、0でない=真、0=偽
真の場合、0でない値として必ず1を返すケースがいくつか定義されているが、
明言されていない場合は、0でないことだけが保証される。
なんで*(s+1)とs[1]の二つの書き方をつくったのよ>K&R *s++は*にしかできない書き方だし *(*(s+1)+2)は読みにくいからs[1][2]と書くんだけど なんか一貫性に欠けてるぞオイ なんでアメ人は人工言語にこんな汚い要素を持たせるのよ 完璧主義で潔癖症なオレはポインタと配列を使うとき、毎回迷うじゃん
>>790 *を使わなければいい。
*s++なんてロジックは却って最適化を阻害しかねない。
s[offset++]でいいジャマイカ。
792 :
デフォルトの名無しさん :2007/04/12(木) 11:56:03
読み込むファイルにひらがなあったら駄目だけどね #include <stdio.h> #include <string.h> #include <ctype.h> #define BUF_SIZE 16 int main() { FILE *fp; char filename[1024] = {'\0'}; char buff[BUF_SIZE] = {'\0'}; char *temp = NULL; size_t len = BUF_SIZE; fgets(filename,sizeof(filename),stdin); if(temp = strchr(filename, '\n')) *temp = '\0'; fp = fopen(filename, "r+b"); while(len == BUF_SIZE){ unsigned int i; len = fread(buff, 1,BUF_SIZE , fp); for(i = 0; i < len; i++) printf("%02x ",(unsigned char)buff[i]); for(; i < BUF_SIZE; i++) printf("-- "); for(i = 0; i < len; i++){ int c = buff[i]; if(isspace(c)) c = ' '; putchar(c); } putchar('\n'); } fclose(fp); return 0; }
>>791 そうなんだけど
*s++ = *t++みたいな記述は確かに便利だし
s[i]は添え字の分のメモリーも必要だし
ちと読みにくくなるけど
*(*(s+1)+2)でいくか
>>793 >s[i]は添え字の分のメモリーも必要だし
ダウト。
今時のコンパイラはどっちで書いても同じコードを吐いてくれる(ことが期待できる)。
795 :
さいきち :2007/04/12(木) 13:05:57
教えてください。C言語を勉強し始めたひよっこです。 Cコンパイラ(Borland C++)をPCにインストールして、コンパイルしようとしたら 以下のようなエラーがでてウマく行きません。何が原因なのでしょうか? エラー E2209 sample1.c 5: インクルードファイル 'stdio.h' をオープンできない 警告 W8065 sample1.c 10: プロトタイプ宣言のない関数 'printf' の呼び出し(関数 main ) 10日でおぼえるC言語入門 という本を見て勉強を始めたのですが勉強を進めきれず 困っています。 どなたか教えてください。
* は直接参照する時しか使わないな。 インデックスを使うときは必ず [ ] を使う。 その方が読みやすい。 全てのループは if と goto で書けるが そう書かないのと同じ事だ。 分かりやすく書くのが至上。 後の事は最近のカシコイコンパイラが最適化してくれる。
798 :
さいきち :2007/04/12(木) 13:17:18
大変申し訳ありません。795で質問しました さいきち です。 わたくしはルール違反をしてしまいました。過去ログを調べていません。調べて見ます。 795の質問は『無視』でお願いいたします。
>>798 つい最近まったく同じ質問があって、インストールしたbccがアップデート版だった
というのがあったな。
argv[1]とargv[1][0]ってどう違うのですか? どちらも一つ目のオプションを指してると思うんですが printf( "%p %p\n", argv[1], argv[1][0] ); で表示させると違う値になります
>>791 >>794 >>796 コンパイラがちゃんと最適化してくれるのか 知らなかった
これからは[]で統一する
やっぱ*(*(s+1)+2)なんて書かれたらウザいよねw
>>800 argv[1] はchar*
argv[1][0] は char
argv[0]は&argv[0][0]と同じってことですね
804 :
766 :2007/04/12(木) 16:36:19
構造体のなかのintをcharに全部変えたらbase64の文字列が短くなって通信ができるようになりました
>>760 さんありがとうございました。><
805 :
デフォルトの名無しさん :2007/04/12(木) 18:42:57
入力した数字が0ではない間ループするってやつで int aho[100]; int i=0; while(aho[i]!=0){ scanf("%d",&aho[i]); i++;} ってやると0入力してもおわらんのだけどなんでじゃ?
>>805 標準入力からaho[0]に数値が入力されてるのに、while文の判定ではaho[1]
見てるからじゃね?
>>805 「入力した数字」なのだから、入力前に検査しちゃダメだろう。
do {
scanf("%d", & aho[i]);
++i;
} while (aho[i - 1] != 0);
or
int tmp = 0;
do {
scanf("%d", & tmp);
aho[i] = tmp;
++i;
} while (tmp != 0);
いずれにしても、scanf()をそのまま使うのはお勧めできないが。
808 :
デフォルトの名無しさん :2007/04/12(木) 20:37:29
>>800 別に配列にしたからって、より最適化してくれるってわけでもないがな。
お前は何を言っているんだ
811 :
デフォルトの名無しさん :2007/04/12(木) 22:40:57
サーセンwもうちょっと質問したいんですけど
>>805 のやつを
int aho[10],i=0;
scanf("%d",&aho[i]);
while(aho[i]!=0){
scanf("%d",&aho[i]);
i++;}
って変えてみたんですけど一回目のscanfに0を入力するとそのまま終了するんですが
一回目のscanfに0以外の数字を入力するとそのままループから抜け出せれなくなるんですけど
これってなんでじゃ?
i++;
ループ内で aho[i]に値を入れる i++ aho[i] != 0の判定(入れた所の次) をしてるから
>>811 この場合は関係ないが、scanfの戻り値は必ず見ろよ
815 :
デフォルトの名無しさん :2007/04/12(木) 23:03:39
>>813 うほw
i++;の位置変えただけで解決しました。ありがとう
ちと聞きたいんだが、 int toBuff(char code){ return (' ' <= code) && (code <= 126 ) } ってどんな動きをするんだ? 調べてみたけど見つからんかったんで。
>>816 たぶん可視文字(半角スペースを含む)かどうか判断
>>815 みたいのがプログラマになったらきっとバグてんこ盛りのコードが量産されるんだね
toBuffのBuffってどういう意味なんだろう。 とりあえず if ( toBuff('S') ) は、 if ( (' ' <= 'S') && (code <= 'S' ) ) と同じ意味になるんだろうな。 MSDNより抜粋 2 項関係演算子と等値演算子は、最初のオペランドと 2 番目のオペランドを比較して、 指定された関係が有効であるかどうか評価します。 関係が真のとき、関係式の結果は 1 になり、偽のときは 0 になります。 結果の型は int 型になります。
>>819 &&が抜けてた
MSDNより抜粋
&&
両方のオペランドが 0 以外の値のとき、論理 AND 演算の結果は値 1 になります。
どちらかのオペランドが 0 のときは、0 になります。
論理 AND 演算子の最初のオペランドが 0 のときは、2 番目のオペランドは評価されません。
>>819 if ( (' ' <= 'S') && (code <= 'S' ) )
じゃなくて
if ( (' ' <= 'S') && ('S' <= 126 ) )
だとおもいます><
引数消えてるー!!
消えていたのはマジックナンバー
半角スペースから~までかどうか判断してるってこと? それじゃあ126が'~'になるんじゃないの?
どっちでもいいじゃん
マジレスしておくが、126なんてマジックナンバー使うよりも'~'の方がいいのは当然。 但しこれがバイナリデータ操作用の処理かなんかで、126という数値自体に意味があるなら話は別だが。 #その場合はその場合で、126に対する説明のコメントか、126をdefineかenumで名付けるかして欲しいもんだが。
*(int *)&a これは配列aをint型にキャストして、その先頭アドレスを指しているのでしょうか?
a はどういう宣言なんだ? a をint のポインタにキャストしてその中身を示している
いいえ。
>>828 a の宣言は?
a の本体のメモリ上のありかを取ってきて : &a
そういつを勝手な解釈で int 用の大きさがある場所だ と仮定して : (int *) へのキャスト
その仮定の元で int の値を得る : ポインタが指している場所の実体値の参照 *
少し微妙だった a のアドレスををint のポインタにキャストしてその中身を示している
>>828 aの型による。場合によっては鼻から悪魔
面白そうでC言語はじめて独習Cを一通り勉強やり終えたので 次の段階に進みたいと思ってます。自分で本探してみているんですが 入門書は大体どれも同じ内容ばかりです。入門書の次に読むのに お勧めの書籍とかあるでしょうか? 一人で始めたあくまで趣味なのでまわりに聞ける人がいないので ちょっとスレ違いかもしれませんがよければ教えてください
趣味ならC++行っちゃえば?
>>834 趣味ならWindowsプログラミングとかに行けば?
Accelerated C++でC++を軽く覚えてあとはゲーム用ライブラリとか使いながら
>>837 全部を全部見るわけにはいかないけどそれはもう大体やってしまった感じです
>>836-
>>837 自作でなにか汎用性の高いプログラム作ってみたかったんですが学生ということも
あり他の経験に乏しく特定の条件で動くものしか思いつきませんでした(´・ω・`)
それがこの質問をした理由でしたが今度面白そうと思うプログラミング探してみることにします。
レスありがとうございました
840 :
828 :2007/04/13(金) 21:41:49
色々とありがとうございます。 aはunsigned char型の配列です unsigned char a[20]; struct kouzoutai { unsigned short a ; unsigned short b ; }; この時に、 *(struct kouzoutai *)&a は何を示しているか、というのを簡略して書いてみたのですが わかりにくくしてすみません。 a[0]からa[3]までのa[0]を指しているkouzoutai型ポインタ変数aの値 ということでしょうか?
>>840 実質&aはaと同じ値になるのでしょうけど
配列やポインタの次元数的には間違っているよな。
>>840 アドレスとしては同じになる
でもどれがどこを指すかは環境によるんじゃないかと
バイトオーダやアライメントによって
そういう強引なキャストはどうかと思うぞ
意図しない動作する可能性も出てくるんじゃないかな
>>840 > a[0]からa[3]までのa[0]を指しているkouzoutai型ポインタ変数aの値
> ということでしょうか?
ごめん
意味わかんない
844 :
828 :2007/04/13(金) 22:08:49
特殊なC言語なので他のソースを真似ながらやってます。 先頭の*は値表示、()内の*はポインタ変数というのはわかりました。 キャスト変換した後のポインタ変数aのメンバbの値を見たいときは、 上のが構造的に使えるものとすると、 *((kouzoutai *)&a)->b であってますでしょうか?
>*(struct kouzoutai *)&a 実験したら戻り値がkouzoutai型になった
>>844 unsigned char a[20];
kouzoutai * pKouzoutai = (kouzoutai *)a;
pKouzoutai->a = 10;
&aだとポインタのポインタなので厳密にはあってない。
a->bは、(*a).bのことだ。
アロー演算子使うなら unsigned char c = ((kouzoutai*)&a)->b でコンパイラ通った、けどVSのインテリセンスが働いてくれないから俺は使いたくない
>>847 VS2005で試したらは効いたけど。
ちょっとしたことで効かなくなることあるよね。
((kouzoutai *)a)->a 態々ポインタ型にキャストした上でアロー演算子という二度手間が 途轍もなくダサい気がするんですが どういった用途でこの構文を使うのか、良ければ教えてくださいませんか?
>>849 ポインタでキャストじゃないと無理じゃん
配列aをコンテナにして kouzoutaiをそのコンテナにアクセスする為のインターフェースとして使ってるってこと? なんかいまいち用途が分からん
普通に考えれば違法だろ…
ちゃんと動くコードとしてはこんな感じ。 構造体をバッファにつっこんだり取り出したりするときに こんなコードになる。 #include <stdio.h> #include <string.h> int main(void) { unsigned char a[20]; struct kouzoutai { unsigned short a ; unsigned short b ; }hoge = {12, 34}; memcpy(a, &hoge, sizeof(hoge)); printf("a:%u, ", ((struct kouzoutai *)a)->a); printf("b:%u\n", ((struct kouzoutai *)a)->b); return 0; }
スクリプトかなんかでシリアライザを自動生成すれば。
855 :
デフォルトの名無しさん :2007/04/14(土) 07:18:31
castを使わないでunionを使うという手もある
>>847 VS2003でも普通に効いたんだけど。
857 :
デフォルトの名無しさん :2007/04/15(日) 01:12:47
http://www.cybercom.net/~dcoffin/dcraw/dcraw.c ここにある、dcraw.cってソフトの関数だけ使いたいんだけど、
こいつは色んな関数もmainも全部一緒のファイルに書いてある。
なんだけど、自分でいくつか関数を追加して、
mainも自分の好みに変更してから使いたい。
そこで相談。
自分でmain.cみたいなのを作って、
main.c内のmain()からdcraw.cのmain()以外の関数を使うことってできますか?
元のdcraw.cはあまり弄りたくないんで(オリジナルとして残したい)、
うまくやれる方法があれば教えて下さい。
main同士がぶつかっちゃうから無理?
859 :
858 :2007/04/15(日) 01:23:49
「元も」じゃなくて「元の」だ。
>>857 コンパイラオプションで対応できる
例 gcc -e _mymain mycode.c dcraw.o
あなたが使っている開発環境のヘルプを読んでみては?
消したくないなら dcraw.cのmainにstatic付けるだけでもいいのかな。
>>857 行儀の悪い方法
#define main main_dummy
#include"dcraw.c"
#undef main
int main(void){
printf("Good-luck!\n");
return 0;
}
863 :
857 :2007/04/15(日) 01:40:15
864 :
857 :2007/04/15(日) 01:41:52
>>862 消したいmainのあるファイルを編集していいのなら、
mainを消した方がいいんじゃね?
>>865 政治的な理由があるときは元のソースコードの完全一致が必要だったり、
流用するソースコードのバージョンアップに伴う手間がかからないようにしたりするトリックも必要になるもんさ
>>857 #ifdef ORIGINAL
main()
{
}
#else // !ORIGINAL
main() // my main
{
}
#endif
とか素直にやっとけ。
>元のdcraw.cはあまり弄りたくないんで(オリジナルとして残したい)、
にこだわるのはよっぽどの事情がないなら無意味。
正直ifdef方式もあまりお勧めできないが。
Subversionなんかのバージョンコントロールシステムを使うのがベスト。
せめてディレクトリ分けてWinMergeなんかの差分ツールの使い方覚えとけ。
Linux Cのプログラムから外部プログラムを起動し、起動したプログラムの 終了を待たずに呼び出し元のプログラムを終了させたいのですが、 どうすればよいでしょうか。 Windowsで、CreateProcessを呼んだときのような動きにしたいです。 よろしくお願いします。
>>867 >866
>>868 system()は中の処理を/bin/sh(など)に委ねるから、
system("/bin/sleep 86400 &")などと&つきで実行するという手もある。
>>869 >>870 ご回答ありがとうございました。
systemで&を付ける方法を試してみたのですが、起動した子プロセスが
終了しないと親プロセスは終了できない動きをしているのですが、
これはそういうものでしょうか。
親プロセスは子プロセスが動いていても黙って終了させるような
ことは可能でしょうか。
872 :
871 :2007/04/15(日) 08:39:44
すいません。なんか意味が分からないですね・・・ 実は親プロセスはCGI、子プロセスは処理に時間がかかるプログラム なのですが、CGIは処理に時間のかかるプログラムを呼び出したら とりあえずレスポンスする、ということを実現したいのです。
873 :
871 :2007/04/15(日) 09:01:44
すいません。解決しました。 system("/bin/sh 〜 > /dev/null &"); としたら解決しました。 どうもありがとうございました。
874 :
871 :2007/04/15(日) 09:14:35
すいません。解決してませんでした・・・ CGIがすぐに終了しなくなったのを見てできたと早とちりしてしまったのですが、 そもそも目的のプログラムを起動できていませんでした。 すいませんが、引き続きよろしくお願いします。
daemonを作るときなんかは、2段forkという方法を使う。
>>874 そうなるともう、OS板の方がいいのかなぁ。
漏れの知ってるUnixではその方法でできるのだが。
#尤も、子プロセスの終了を検知する手段を別途用意するのが面倒で余り利用しないが。
877 :
871 :2007/04/15(日) 10:13:35
>>876 psで見ると、CGIのプロセスがゾンビになっているみたいです。
CGIから処理時間の長いことをさせたい場面って結構あると
思うのですが、世の中の人はどうやっているんですかね。
>>877 長い時間ってどのくらい?
10秒とかそのていどなら、ajaxで、しばらくお待ちくださいとかだしておくとか。
2段forkというのは、 1. 親→子を生む(fork) 2. 子→孫を生む(fork) 3. 孫→本命プロセスを実行(exec)する。 4. 子→孫を生んだら自殺(exit)する。 5. そうすると親は子の死を看取る(wait)ことが出来る。 6. 孫は、自分の親である子がいなくなっているので、initの養子になる。 という方法。
880 :
デフォルトの名無しさん :2007/04/15(日) 11:53:00
すみません、パート1か2辺りで質問させて頂いた初心者ですが いつの間にかパート10とかなって教えて頂いた事がみれなくなってしまっていましたorz 申し訳ないですが C言語を実行できるヤツを無料でダウンロードできるお勧めサイト教えて頂きたいです 携帯からですが今ネット喫茶でメモリーカード持って待機中です よろしくお願いします
つ microsoft
883 :
880 :2007/04/15(日) 12:24:58
ありがとうございます メアド登録させられたけど無事にダウンロードできたみたいです ありがとうございます
intとlongのサイズは仕様でどう決まっているのでしょうか。 8086->IA32の流れでintはCPUに自然なサイズで longは4バイト固定だと勝手に思い込んでいたのですが、 gccの64bitな実装ではintが4バイトで longが8バイトになっていたため疑問になりました。 処理系に依存せずにlimits.hから4バイト符号付き整数の最大値を得たいのです。 この場合、自分で0x7fffffffと記述するしか無いのでしょうか。
intは [-0x7fff, 0x7fff] の範囲の整数を表せる型。 long intは [-0x7fffffff, 0x7fffffff] の範囲の整数を表せる型。 1バイトが8ビットとは限らないから、4バイト符号付き整数型の最大値が0x7fffffffであるとは限らない。 そもそも4バイトの符号付き整数が使用可能かどうかも処理系に依存する。 (sizeof(long)==4?LONG_MAX:sizeof(int)==4?INT_MAX:sizeof(short)?SHORT_MAX:(abort(), 0)) かw
>intとlongのサイズは仕様でどう決まっているのでしょうか。 せいぜい大小関係が決まっているだけで具体的な仕様はない。 C99ならstdint.hのUINT_MAX, UINT32_MAX使っとけ。 てかintはともかく4バイト符号付整数の最大値は処理系に依存しないぞw
>886
>>885 にあるように、1バイト=8ビットとは限らないので、
4オクテットといった方がいいな。
>>884 > 4バイト符号付き整数の最大値
これは定数でしょ。#defineなりで定義すればいいけど。
質問の意図は、
「longの最大値を得たい」のではないかと?
それだったら、
long a;
a = 1 << (sizeof(long) * 8 - 1);
だけど。違うッスか?
>>888 違うッス
1. 1バイトは1オクテットとは違うッス
2. 限界まで使えるとは限らないッス
>>888 longの最大値なら普通にLONG_MAXだろ。
longの最大値はlimits.hにLONG_MAXで定義されてると思うんだけど それ使っちゃ駄目なの?
>>857 なんだこのソースw
コメントがぜんぜんねぇ
オレはこんなソースのメンテなんてしたくねぇ
ま, ソース自体が汚くないのが唯一の救いかなw
893 :
884 :2007/04/15(日) 14:53:29
皆様ありがとうございます。 32bitに固定したかったので886のINT32_MAXで良さそうです。 問題はVCに移植する時にstdint.hが無い事ですが。 迷わず0x7fffffffって書いちゃった方が良さそうですね。
894 :
888 :2007/04/15(日) 14:54:08
バイトが8ビットじゃない場合だって? long a; a = 0; a = (long)((~((unsigned long)a)) >> 1);
>>893 VC なら limits.h の _I32_MAX
#ifdef _I32_MAX
# ifndef INT32_MAX
# define INT32_MAX _I32_MAX
# endif
#endif
ああ、もう解決したのな。 って、文字通りの32bitかよ! 初心者の質問は侮れない。
別に莫迦晒さなくてもいいよ
>>896 わかったわかった。こちとら1分毎に更新してるわけじゃないんだよ。
ちなみに、限界まで使えない処理系を知ってたら教えてくれるかな。
900 :
888 :2007/04/15(日) 15:17:02
>>896 なんだ。教科書バカが偉そうにツッコミ入れてただけか。
この分じゃ、1バイト=1オクテット以外の処理系も知らなさそうだな。
そこまで気にしなきゃいけない処理系って実際あるの? 組み込み用でも主要なものだと1byte=1octetが殆んど多いんでしょ?
902 :
884 :2007/04/15(日) 15:20:05
>>895 そんなのが。ありがとうございます。
関連した質問として接尾辞についてなのですが
32bitのCPU上でgcc 4.0.1を使って試した結果
long long a = 0xffffffffL;
printf("%lld¥n", a);
が4294967295と出力され
long long a = (long)0xffffffffL;
printf("%lld¥n", a);
が-1と出力されます。
Lを付けた時点でlongにはならないのでしょうか。
負数が2の補数でない事はまずあり得ないので
上で出ているようなバイトとオクテットの関係を考慮してこうなってるのかな。
>>902 MAX_LONG < 0xffffffffLL な環境では 0xffffffffL という表記がどういう値を表すかは未定義/未規定(どっちか忘れた)だったはず。
904 :
888 :2007/04/15(日) 15:29:30
(long)0xffffffffLは、符号付きとみなされて-1 それを代入するからビット拡張が勝手にされてaに-1が代入されるということ。
905 :
888 :2007/04/15(日) 15:39:50
>>901 PICだと12ビットの型があるんじゃないかな。
あと、型のビットをフルで使えないC処理系は今のところ見たことがない。
>>889 =
>>896 はウザイこと言うから実務者かと思えばただの学生かヒキだよ。
一生ANSI Cの教本でも読んでてくれ。
無視すればいいのに…
908 :
884 :2007/04/15(日) 15:46:23
>>903 決まって無いのですか。
>>904 Lがlongになるのであれば前者もlongとして扱われて-1になっても良いのではないか
もしくは逆に補数やバイトとオクテットの関係で0xffffffffが
どんな値を示すか分らないのであれば両方4294967295になっても良いのではないか、
というのが疑問だったのです。
909 :
888 :2007/04/15(日) 15:56:33
>>907 いや、自作自演でもなんでもないす
そんなことする意味もないです。
その全レスするかのような勢いなのをどうにかすべきだと思うよ。 大変見苦しい。
911 :
888 :2007/04/15(日) 16:02:41
それは、俺が名前欄に番号書いているからであって
書いてなければ気にもならんハズ
っつーか、
>>910 も一言いわずにおれないタイプ
ちょっと突っ込まれると煽りモードのスイッチが入っちゃうやつが多いな。
臭い人はどこにでも居るもんさ。いちいち目くじら立てても無駄。
914 :
デフォルトの名無しさん :2007/04/15(日) 19:08:14
初心者です。1週間目。入門書も買った。 その通りにやっていて疑問が。 表現法と言うかなんと言うか。 コマンドプロントでしか動かせないんですか? プログラムをひとつのアプリみたいに映し出せないのでしょうか。 こうなんて言うかjavaみたいにできないんですかね。 理解して無いので質問すら何を聞いてるかわからないでしょうけど。 お願いします。
できる。 逆に、Javaでもコマンドプロンプトで文字が出るだけってのを作ることも出来る。
>>914 基礎としてコンソールアプリを作ってるからであって、環境にあったものを使えばGUIアプリも作れる
917 :
デフォルトの名無しさん :2007/04/15(日) 19:30:22
>>915 ありがとうございます。
で、どうやるのですかね?
そのCで作ったプログラムを何かに組み込むってことなんでしょうか?
例えばHTMLにjavaは組み込んで動くのは知ってます。
そんな感じなのでしょうか?
すいません。お願いします。
918 :
デフォルトの名無しさん :2007/04/15(日) 19:32:38
>>916 ありがとうございます。
コンソールアプリ、GUIアプリ、今から調べてきます。
糸口が見つかったような♪
あえてTkを勧めてみる
>>917 Cでウィンドウを出してプログラムを動かすには
Win32APIっていうWindowsが提供してる関数を使わないといけない。
質問の内容から察するに、これらの使い方の説明をしても今は理解できないと思う。
とりあえずコマンドプロンプトでしか動かせないもの、として
C言語を習得する事を優先した方が結果的に近道だと思う。
921 :
デフォルトの名無しさん :2007/04/15(日) 19:38:58
>>920 お察しありがとうございます。
振り向かずコマンドプロントにてC言語を勉強します。
アプリとか調べてみましたが、見た瞬間、まだ早いなと感じましたですw
ぼくペゾルド
C言語よりも先にC++Windowsプログラミングから入りましたぁ
>>923 ちょ、オチを用意しろよ。つまんねえぞブーブー(w
初めてプログラミングするんですがコンパイラは MicrosoftのVisual Studio 2005 Service Pack 1 Update for Vista で良いと思いますか? 授業でC言語やるんでPCにコンパイラを入れたいんですけど… これってインストール無料ですよね?
なぜサービスパック
すんません… ほんと良くわかんないんですよ
928 :
923 :2007/04/15(日) 23:15:08
>>924 こんな自分はダメ?て聞こうとした
>>925 Update版じゃダメじゃないの?
MSの無料のやつにしたら?
929 :
デフォルトの名無しさん :2007/04/15(日) 23:15:56
再帰関数がよくわかりません。 階乗を計算するプログラムなんですが int kaizyo(int n)
>>925 Visual Studio 2005をインストールしないとサービスパックは適用できないぞ。
SP1適用済みパッケージなんて売られていない。
(自分で作ることは可能だけど)
931 :
929 :2007/04/15(日) 23:20:08
すいません、途中で押してしまいました 再帰関数がよくわかりません。 階乗を計算するプログラムなんですが int kaizyo(int n) { if(0==n) return 1; else return n*kaizyo(n-1); } 仮にnが4に場合、nに4が代入され、その後kaizyo(3)が再び呼び出されるのはわかったんですが、 何故これが4*3*2*1になるのかわかりません。 kaizyo(3)が呼び出されたらnには3が代入され、4は消えると思ったんですがそうならないようで・・。
自分自身を呼び出す関数 階乗 再帰 でググるとアラこんなにサンプルが
933 :
923 :2007/04/15(日) 23:20:20
>>929 int kaizyo(int n)
{
if(n==1) return 1;
return kaizyo(n-1)*n;
}
934 :
931 :2007/04/15(日) 23:22:11
すいません
nが4に×
nが4の○
>>932 サンプルはよくこれが載ってるんですが、よくわからなくて・・。
>>931 関数が呼び出されるたびに仮引数であるnの実体は新しく作られる。
kaijo(4)と呼び出されたときのnと、その中でkaijo(n-1)と呼び出されたときのnと、
……、それぞれのnは別物。
kaizyo(4)の途中でkaizyo(3)の途中でkaizyo(2)の途中でkaizyo(1)ここでreturn 1 kaizyo(2)return kaizyo(3)return kaizyo(4)return とスタックが巻き戻っていく
おすすめの無料で良いコンパイラありませんか? できればMSのがいいんですけどURL貼ってくれたら嬉しいです…
939 :
931 :2007/04/15(日) 23:29:58
ありがとうございます。関数が呼び出される度にメモリに新しくつくられて、 最後にすべて掛け算されたものが戻るということですね
941 :
デフォルトの名無しさん :2007/04/15(日) 23:32:31
配列の要素数を変数で決めたいんですけど、どうやればいいんでしょうか? int width = 100, height=100; arr[width][height]; ってやったらVCさんに怒られました。
942 :
923 :2007/04/15(日) 23:34:58
>>931 あれま
続きを書けという命題かと思ったよ
じゃ 3 で試したら
n=3
return n*kaizyo(n-1); の kaizyo(n-1); でn-1=2 が入る ・・・@
n=2
return n*kaizyo(n-1); の kaizyo(n-1); でn-1=1 が入る ・・・A
n=1
return n*kaizyo(n-1); の kaizyo(n-1); でn-1=0 が入る ・・・B
n=0
return 1; で Bに戻る
Bのkaizyo(n-1)の戻り値は1だから Bのkaizyo(n-1)の部分が が 1 に置き換わると思っていい
return n*kaizyo(n-1); は return n*1; となり return 1*1;
Aに戻る.Bと同様にkaizyo(n-1)の戻り値が1だから Bのkaizyo(n-1)の部分が が 1 に置き換わる
return n*kaizyo(n-1); は return n*1; となり return 2*1;
同様にkaizyo(n-1)の戻り値が2だから Bのkaizyo(n-1)の部分が が 2 に置き換わる
return n*kaizyo(n-1); は return n*1; となり return 3*2;
最後@では3*2=6 が戻り値としてかえる
>>943 ああやっぱりそれでメモリ確保しないとだめなんですね。
めんどくさいもんですね・・・
>>942 動きがそうなるってのは、たぶん、デバッガとかで追っかければわかるのだろうけど
たぶん、stackが理解できないと、本質は理解できないんじゃないかな?
一回、stack overflow起こしてみれば?再帰理解できるんちゃう?
946 :
931 :2007/04/15(日) 23:42:03
>>942 詳しくありがとうございます。nが0までいったら、そこから3に戻ってくるんですね
947 :
デフォルトの名無しさん :2007/04/15(日) 23:42:33
>>938 >>940 ありがとうございます
>>940 の方をインストールしてみようと思うんですけど
Visual C++ 2005 Express Edition 日本語版
でいいんですか?
無料ですよね?
948 :
923 :2007/04/15(日) 23:43:16
>>945 えっ?いや俺はばっちり理解しているんだけど・・・
これは
>>931 に説明をと思って・・・
さぁ?
950 :
デフォルトの名無しさん :2007/04/15(日) 23:47:02
ぷろぐらむを勉強するときって Cから勉強したほうがいいんですか?
>>950 IMEを使えるようになってから来たまえ
952 :
923 :2007/04/15(日) 23:52:41
>>946 どういたしまして
ただ0までやると 1*1 という無駄なことをしているので
途中でやめることも考えたほうが勉強になりますよ
n=0 の時 return 1 としているけど
n=1 で return 1 とすれば 1回分の省略
n=2 で return 2 とすれば 2回分省略できる
ただしこの場合n=1、n=0 が与えられた場合の時も書かないといけなくなるので・・・
などと試行錯誤するといい思います
n=2147483647 で・・・
954 :
デフォルトの名無しさん :2007/04/16(月) 00:07:52
955 :
923 :2007/04/16(月) 00:12:09
>>953 やめてぇ〜そんなおおきいのはぁ〜
でもそうやってその型の表現できる最大値を覚えていくよね
>>954 メモリの動きを手にとるように理解できるようになって、メモリ効率とか処理性能の最適化とか
そ〜ゆう方面鍛えるなら、Cかな?
そうでなければ、最近の言語でいいんじゃない?
、
>>955 $ ./kaijo 5591992
n = 5591992
rtn = 0
$ ./kaijo 5591993
n = 5591993
Segmentation fault: 11 (core dumped)
再帰使わずにnの階乗として double ans = 1; while (n>0) { ans *= n--; } じゃ駄目ぽ?
959 :
923 :2007/04/16(月) 00:19:45
960 :
923 :2007/04/16(月) 00:24:12
>>958 えぇ〜多分だけど
階乗という命題が出るのは再帰関数を学ばせるためじゃないかな?
再帰関数を理解しやすい問題ってやつ?かな
スタックを無駄使いしないのと再帰に比べてオーバヘッドが小さいからいいと思うけどね
末尾再帰に書き換える課題とかはあるな。
ほうほう、なるほどなー 逆に再帰じゃないと死ぬ!!つーか効率悪くなる!みたいな例は無いかな?
964 :
923 :2007/04/16(月) 00:40:24
>>961 あっあるあるぅ〜forかwhile文の処理を再帰処理を使って示せ.とか
>>962 んんんn〜
コードが見やすくなる.
深さ優先探索をするとき.(別に再帰じゃないと死ぬわじゃないけど)
考え中...考え中...考え中...
二分木、directory検索とかかな
966 :
923 :2007/04/16(月) 00:51:26
>>962 再帰処理のいいところは明示的に配列とか用意しなくても以前の状態を記憶できること....かな?
あと、階乗ぐらいの小さく、呼び出し回数が多くなる可能性のある関数を再帰させるとオーバーヘッドも増えてストックも無駄遣いするけど
たとえば構文解析とかでネストを許しているものを解析するときとかにはいいんじゃないかな?
forの中にまたforがあってifがあるとか
あとは数式処理とか?
a+b*c って式を計算するときに....って再帰じゃなくてスタックだけでもいいけど
>>965 うん
ふと思った。末尾再帰で書いたらコンパイラはちゃんとループにしてくれるのかね?
968 :
923 :2007/04/16(月) 00:52:11
きゃぁぁ〜〜 ストックじゃなくて スタック ぅぅ〜〜
969 :
923 :2007/04/16(月) 00:58:13
>>967 ごめんたいこ
末尾再帰ってどんな感じのコード?
関数の最後で再帰呼び出し?
>>969 そう。
末尾再帰は、関数先頭へのジャンプで置きかえられるので、
最適化するとスタックを消費せずに済む。
971 :
923 :2007/04/16(月) 01:10:43
>>970 int kaizyo(int n)
{
if(n==1) return 1;
return n*kaizyo(n-1);
}
これじゃ末尾再帰とはいえない?
return kaizyo(n-1); にしてみたけど(意味ないけど)
call される jmpには最適化されていない
スタックも消費されてた
972 :
923 :2007/04/16(月) 01:22:04
ただ単にコンパイラの性能差かもしれないけど... みなさん、おやすみなさいデス
>>970 それだと、nとkaizyo(n-1)の結果を得るまでkaizyo(n)のスタックはありつ
づけるので、深くなっていく。そういう場合、補助的な関数を裏方で使うよ
うに書き換えると末尾再帰に変換できる。
int fact(int n)
{
return fact0(1, n);
}
int fact0(int result, int n)
{
if (n <= 1) { return result; }
return fact0(result * n, n-1);
}
そしてこれが最適化によっておそらく
int fact0(int result, int n)
{
loop:
if (n <= 1) { return result; }
result = result * n; n = n - 1;
goto loop;
}
相当のコードに変形される。
gccでもループに置き換えられなかった。 最適化オプションにもよるかもしれない(この辺詳しくない) ソースレベルでループに置き換えるならこんな感じになるのかな? int kaizyo(int n) { int t=n; while(--n)t*=n; return t; }
実際には、補助関数を使った書き換えの部分も含めて最適化の仕事になるのかな。
976 :
967 :2007/04/16(月) 02:00:19
>>974 ふとした疑問につきあってくれてありがとう。
というか疑問を出したまましばらく放置しててすまなんだ。
取り敢えずぐぐってみたら、gccの最適化オプションに
-foptimize-sibling-calls というのがあることがわかった。
-O2以上を指定するとこのオプションが有効になるらしい(gcc4.0.1)。
階乗程度じゃわざわざ再帰使うのも、ねぇ…
再帰関数の概念を教えるにはシンプルでいいかも知らんけど、 再帰を使って見通しの良いロジックになる例ではないもんな。 やはりそこは二分探索やクイックソートあたりでリベンジかな。
そこでハノイの塔ですよ。
式の構文解析 expr := term [-+] term term := factor [*/] factor factor := '(' expr ')' | digit ループにばらせるけど再帰が楽
>>956 レスありがとうございます!
やっぱりCから初めて、C++をすることに決めました
親切にどうもありがとうございました。
982 :
デフォルトの名無しさん :2007/04/16(月) 15:25:51
構造体に入れ子ってのがあるけど あれってなんか意味あるの?
分かりやすくなったり、一部分だけを渡したりできるようになる。
別の構造体にすると、特定の構造体中だけで使いたい場合でもそれを抑制できない。 一方、入れ子構造体をコピーして外に出しても、コンパイラは入れ子構造体と同じとはみなさない。 #C言語ではその程度の意味しかないので、あまり重要視されないけど、 #C++とかになると結構な違いになりますです。
has aってやつですかね、C++の場合。
986 :
923 :2007/04/16(月) 18:07:27
>>973 だめだったよ
やっぱりcallされてる
コンパイラが古いってのもあるかな?
C++Builder5のBCC32でコンパイルしてるんだけど
最適化オプションは速度優先
それはbccの最適化能力の低さを知ってて言ってるんだよな?な?
988 :
923 :2007/04/16(月) 18:30:59
>>987 まったく知らない
やっぱりそうなんだ
最適化とか気にしてなかったから
いいコンパイラじゃないってのはうすうす感じてはいたけど
入門篇
1か0しか値を扱わない変数が沢山ある時って、 ビットフィールドとかいうのを使った方が良いの?
ビットフィールドに潜む問題をきちんと理解してるのであれば、 ビットフィールドを使ってもいい。
想定メモリ搭載量に対して、その変数の数が問題になっているなら 手を付けてもいいとはおもう。
ビットフラグで十分ならビットフラグの方が便利だとは思う。 一度に沢山のフラグを変更できるし、 引数に直接値を書く事もできるし。
>>993 今はビットフラグ使ってるから、そのまま使うね
ありがとー
ノシ
Unko
CとC++は別個にあったほうがいいだろ。
1001 :
1001 :
Over 1000 Thread このスレッドは1000を超えました。 もう書けないので、新しいスレッドを立ててくださいです。。。