1 :
デフォルトの名無しさん :
2009/05/12(火) 21:04:52
2 :
デフォルトの名無しさん :2009/05/12(火) 21:41:28
もつ
Cをコマンドライン版(DOS窓とか)で勉強したら、 VCとか使えるようになるの?
>>3 VCを使うっていうのが、Windowsアプリを作るってことなら、使えるようにはならない。
VCでC言語を使えるようになる
>>4 Windowsアプリを作るなら、
VBのほうがカンタン?
>>7 VB.NETもC#も大差ないと思う。Cは難しい。マネージドのC++方面はよく知らない。
(VB6は論外として)
CLIだけ使うなら大差ない。
10 :
デフォルトの名無しさん :2009/05/12(火) 23:34:59
擬似的なコードで書きます。 int c[6]; int a[6] = {"5","1","2","3","4","5"}; ソートして int b[6] = {"1","2","3","4","5","5"}; int c[6]; で、 for(i=0;i<6;i++) for(j=0;j<6;j++) {if(a[i] == b[j]) c[i] = j;} から、 c[i]の中身を{ "1","6","5","4","3","2"}ってして、 for(i=0;i<N;i++) a[c[i]] = x; って感じでa[i]の中身を変えずに降順にa[i]にアクセスしたかった のですが、実際は"6","6","5","4","3","2"ってなってa[0]にアクセス できませんでした。配列に同じ要素がいくつもある時に、配列の要素が 降順である順番で、配列にアクセスする方法ってどうやるのでしょうか?
結局2重ループって活用性あるの? ゲーム製作で良く使うって言われるけど、ドットとかの連番ファイルの読み込みぐらいでしか使わないよな?
文字列と数値の違いがわかってないな 恐らく文字との違いも分かって無いだろう
O(n^2)のアルゴリズム
16 :
10 :2009/05/13(水) 00:30:32
>>11 さん
int *a;
a = malloc(sizeof(int)*N);
と、いうように動的に配列を作れって意味でしょうか?
たぶん違うのでしょうが。もうちょっとヒント頂けると嬉しいです。
>>16 いやはいれつのそれぞれの要素を指すポインタ配列を作って
それを通して間接的に操作すべきという事
for(i=0; i<6; i++) { for(j=i; j>0 && a[i] > a[c[j-1]-1]; j--) c[j] = c[j-1]; c[j] = i + 1; } c[6] = {1,6,5,4,3,2}にはなる。
>>16 int comp(const void *a, const void *b)
{
return **(int **)a - **(int **)b;
}
int main(void)
{
int a[6] = {5, 1, 2, 3, 4, 5};
int b[6] = {1, 2, 3, 4, 5, 5}, c[6];
int *ap[6];
int i, j;
for (i = 0; i < 6; i++) {
ap[i] = &a[i];
}
qsort(ap, 6, sizeof(int *), comp);
for (i = 0; i < 6; i++)
printf("%d ", *ap[i]);
putchar('\n');
for (i = 0; i < 6; i++)
for (j = 0; j < 6; j++)
if (*ap[i] == b[j])
c[i] = j;
for (i = 0; i < 6; i++)
printf("%d ", c[i]);
putchar('\n');
return 0;
}
20 :
19 :2009/05/13(水) 01:21:09
あれえおかしいなあ どんな風にプログラム書いても動作が変
>>19 同じ数字があった場合結局
>>10 の問題は解消されないってのはおいといても、
ソート済みのものと比較してどうすんだよw
22 :
デフォルトの名無しさん :2009/05/13(水) 01:35:01
すいません 教えてください doubleの初期化で0xFFFFFFFFFFFFFFFFをセットする方法を教えてください よろしくです
>>22 union u {
double d;
char c[8];
};
union u a;
int i;
for(i=0;i<8;i++) c[i]= 0xff;
for(i=0;i<8;i++) a.c[i]= 0xff; だった それかmemset(&d, 0xff, sizeof(d));
double d = (double)0xFFFFFFFFFFFFFFFF;
ビットを全部onにしたいんじゃねーの?
わざわざそんなことやる理由がわからん doubleだとちゃんとした数字になるのか?
前スレ
>>998 一時ファイルでも作業領域に使えば楽じゃん
マージソートを使えばできる
30 :
デフォルトの名無しさん :2009/05/13(水) 01:55:32
>>24 素早い回答ありがとうございます
さっそく試して、できることが分かりました
どういたしまして
32 :
デフォルトの名無しさん :2009/05/13(水) 01:56:50
>>28 ならないけど、ビット処理の都合必要でして・・・
33 :
10 :2009/05/13(水) 02:09:21
>>17 ,18,19
ヒントありがとうございました。
>>32 どうせ可搬性のある方法は存在しないから、double*を64bit整数へのポインタにキャストするなり、
共用体つかうなり、好きにすればいいよ。
わざわざunion使わなくても、memset()でいいじゃん。 0xffで埋めるなら。
この話題でunion出す意味がわからんね。
char const *const a, *const b; bの型は(char const *const)ですか?
>>38 Yes.
ってか確認するコード書いてコンパイルしろよ。
>>32 double 型の値にビット処理を施す ってのも奇妙ではあるね。
浮動小数点フォーマットを決め打ちして NAN 立てたいとか そういう用途なのかな?
43 :
デフォルトの名無しさん :2009/05/13(水) 16:17:36
>>42 処理内容は絶対値の取得です
正確な内容はSSEを使用して計算途中に発生する負の値を正の値に読み替えるというものなんですよ
ですから本当は0xffffffffffffffffではなく0x7fffffffffffffffでこれと数値とでandをとって正の値を取得するというものです
もっと良い方法ありましたかね?
(SSEにfabsは無いと思います)
long longを知らないだけというオチのような…
>>43 それって C言語で記述するより インラインアセンブラで記述したい要求じゃないかい?
SSEを使用して計算の記述は インラインアセンブラっしょ?
SSE なら どーせ packed 演算だし 各pack に 0x7fff* 突っ込んで ANDPS する
アセンブルコードを挟めば良いんじゃyないの?
46 :
デフォルトの名無しさん :2009/05/13(水) 17:11:11
>>45 それでもいいんだけどアセンブラは苦手なもんで
intrinsicで記述してます
そろそろアセンブラも始めるかな・・・
この先アセンブリは廃れる できるに越した事は無いけど
何十年さきのことやら・・・
アセンブラでしか記述できない場面は数限りなくあるのに 廃れるわけがない
アセンブラはしぶとく生き残るだろ 組み込みがアホみたいに性能あがったけど省電力になればいらないだろうけど
完全には無くならんが細々と生き残るだけだろうな
コンパイラを作る人がいる限りアセンブラは死なない
>>53 難読性を要求するプロテクトプログラムや
厳しいリアルタイム性を要求される計測装置など
コンパイラはこのような場面を全く保証していない
#define A (0.1) #define B (0.5 * A) #define C (20 * B) と定義したCをソース内部で使う際どうも計算誤差(小数点以下切捨て?) が起きている感じなんですが回避する方法はあるんでしょうか? Cを受け取る変数はfloatのエリアです。
>>55 0.1が二進数では無限小数になってるので、表現しきれず途中で打ち切りになってる
0.0999999999・・・
みたいな値になってる、当然これを掛け算に使うと・・・・
1, 5 にして最後に100で割るような整数計算に置き換えるしかない
>>55 誤差が許されないなら浮動少数使うなってこと
数値計算ライブラリ使え
58 :
55 :2009/05/14(木) 06:03:18
>>56-57 処理的には小数点以下3桁程度あればいいのですが、どうも小数点以下がまったく存在しない状態なんです。
つまりintにでもキャストしたような感じでして・・・
>>58 それはその#define文だけではありえない
再現できるソースを出さない限り誰にもわからない
%gで表示してるとか?
また、あからさまな釣りがwww A、Bがintだってオチなんだろ。
>>55 こうすれば?
#define A (0.1f)
#define B (0.5f * A)
#define C (20.0f * B)
で、Cはfloatだから表示するならprintfの中は"%.3f"。
20 * 0.5 * 0.1 = 1
有理数ライブラリ作れ
>>54 組込み用途のRTOSはC言語で書いてあるぞw
Cで書いてアセンブラ出して それを修正してコンパイル
>>65 20 * 0.5 * 0.1 = 1.0
今はC++のコンパイラをC#で書く時代 機械語なんかいらんのや
getcharで配列の各インデックスに文字を代入して、 文字コードを1シフトさせてa→b c→dのようにするには どうしたらいいのでしょうか?
>>72 それぞれ順番にやれば宜しいかと。
それぞれの遣り方が判らないのなら、質問し直して。
考える気もないなら宿題スレへ。
それは環境によって、 いや、それよりもzの場合どうなるのかが知りたくなった。 そうか、bをシフトしないから、zもシフトしないのか。 いやまてまて、それよりgetchar()で受け取ってそれを配列の各要素に入れるようだが、 オーバーランしないようにしておかないといけないではないか。 いやそれより、その配列は基本型または派生型または複合型の複合型なのかはっきりしないとわからない気がしてきた。
putchar( 'a' + 1 );
'a'の次が'b'だとは限らんわけだが
putchar((ch-'a'+1)%26 +'a');
'a'の次が'b'でない処理系なんてそうそう無い
つ[EBCDIC] コンピューターの世界を舐めちゃいけませんぜ
EBCDICなんて化石マシンくらいしか使ってないだろ
まあEBCDICも'a'の次は'b'だけどな 'm'の次は'n'ではない
論破とかw
おれはあいつじゃねえ
そもそも規格票にも書いてない事で偉そうに主張するなw
'a'の次が'b'でない処理系なんて「そうそう」無い
規格票に書いてないことくらい知ってて言っとるわ
>>87 顔が真っ赤ですよ
とにかくお前みたいな奴には仕事は任せられんな
とニートが申しております
とニートが申しております お前ら一丁前に働いてから物を言え
,r;;;;ミミミミミミヽ,,_ ,i':r" + `ミ;;, __,、 ≡ 彡 ミ;;;i 〃ニ;;::`lヽ,,_ ≡ 彡 ,,,,,、 ,,,,、、 ミ;;;! 〈 (lll!! テ-;;;;゙fn __,,--、_ .. ,ゞi" ̄ フ‐! ̄~~|-ゞ, ≡ /ヽ-〃;;;;;;;llllll7,,__/" \三=ー"."ヾi `ー‐'、 ,ゝ--、' 〉;r' ≡ 自分自身を客観的に見ることはできるんです >、/:::/<;;;lllメ \ヾ、 ヽTf=ヽ `,| / "ii" ヽ |ノ j,, ヾて)r=- | ヾ: :ヽ;;: | l | l ''t ←―→ )/イ^ ≡ >75-82 とは違うんです ,イ ヽ二)l(_,>" l| ::\;:: | | | ヽ,,-‐、i' / V i、ヽ--イll"/ ,, ,//,, :;; l // l く> /::l"'i::lll1-=:::: ̄\ ヾ==:"::^::;;:::/;;;;;;;;;:::::::::::::: :::::ゞ ノ/ L/〈:::t_イ::/ll|─-== ヾ \__::::::::/::::::::::::_;;;;;;;;;;;;;;;;;ノノ ヘ >(゙ )l:::l-┴ヾ、ヽ )  ̄~~ ̄ ̄/ :::|T==--::::: // / ト=-|:|-─ ( l / / :: ::l l::::::::::::::::::/ /:::::::::::/:::::(ヽ--─ / | / ヽ_=--"⌒ ゙゙̄ヾ:/ /:::::::/:::::::::`<==-- ノ / /
与えられた a→b c→d の変換は b→b で d→d 以下 a→b (b→b ?) c→d (d→d ?) … と類推すれば良いのか?
そこまで考えてませんでした、って事だと思うよ。
低レベルな質問だとスレが伸びるなぁ。
>>93 まあこの程度の質問するってことは文字コードのこともろくにわかってねーだろうしな
96 :
72 :2009/05/14(木) 16:39:12
皆さんありがとうございます。 a→b b→cという風に入力をした文字を1つシフトさせて 次にループしたときは2シフト 次が3シフト…というように シーザー暗号を入力して、元の文字列になるようなものを作りたいんです。 本に沿って勉強していたのですが自分でも何か作ってみたかったので。 頂いたレスを読んでもう少し考えてみます、ありがとうございます。
a->b b->c .... z->??????
>>97 テキストとみるからそうなるだけでしょ。
暗号をかけるだけなら、zの次のコードになろうがぜんぜん問題ねえし
99 :
デフォルトの名無しさん :2009/05/14(木) 16:58:35
#include <stdio.h> void main() { char *p, a[] = "ABCDE"; p = a; while (*p++ = *(p + 1)); printf("%s\n", a); } 上のプログラムは、本に書いてあるとおりですが、自分のPCでコンパイル するとwhile( )のコードが 「警告 W8060 lsft.c 7: おそらく不正な代入(関数 main )」という警告を 受けます。実行結果も本では BCDE となっているが自分のPCでは CDE になります。 while (*p++ = *(p + 1)); のコードの解説に 「代入した文字が「\0」のときは式の評価結果が「偽」となり、繰返しを 終了します」とあるが、なぜこのコードにこの意味が含まれるのか分かり ません。
>>99 C言語が面白くなくなる典型のような例題だな…
>>99 Cは = と == が紛らわしいから
ちなみにその警告は無視して良い
無視してはいけない場合も当然ある
>>99 うわこれ副作用完了点について理解してない著者が書いてる
今すぐ本を窓から投げ捨てろ
英語の授業で言えば、本場の人でも一生の間に一回使うか使わないか という言い回しを問題としてやらせているって感じだな
これって確か動作の結果は未定義だったような 要するに鼻から悪魔だよな
>>99 a[] = "ABCDE";
この最後に実は\0(文字コードとしては0x00)が必ず置かれます。
でa[]のポインターを0x00がくるまで移動しています。
でその文字コードを真偽判定に使ってるんですが・・・
本は捨てた方がいいです。
これを薦めた人も捨てた方がいいです(可能であれば
whileの中の*p++がすでに未定義でトラップ
>>96 putchar((ch-'a'+shift)%26 +'a');
>>99 void main() じゃなくて int main() なんですが、それはさておき
私のところでは実行結果は BCDE ですね。
環境を教えてください。
>これを薦めた人も捨てた方がいいです(可能であれば ワロタw
>>107 「*p++ に p を用いた演算結果を代入してる」 がトラップだよね?
そもそもどういう動作を期待してるのかわからんのだが…
>>113 相当古い時期に書かれた本だと思うよ。
最近書かれた物ならマジで著者と本を薦めた人を捨てた方がいい
++インクリメント演算子は式の評価が完了するまでのどこかの 点で適用される事を意味している。 式の評価が全部完了している事を保証する場所を「副作用 完了点」と言い、この場合はセミコロンの直前である。 ところが =代入演算子の両側に同じ変数 p が出現している。 つまり++は左辺を評価した後で適用されるか、右辺を評価した 後で適用されるかは規格では定められていないのである。 こういう場合規格では未定義の動作が起こるとしている。
この短時間レス集中でわかるように、成功と失敗の境界領域にある レアな構文だから、構文テクニック大好きな文学少年達が目の色 変えて集まってくる。 こういうトリッキーな構文は怪しげなので避けて通るのが無難。 というようなことをその参考書は書いていたんじゃないのか?
なんか、例の文字列コピーみたいな奇怪なコードを書こうとして、失敗したようにしか見えんw
まずは書籍と著者を晒せ。
が、読み進めると 副作用完了点の話と未定義の話が出てきて
どういう結果になるかは保証できない って脚注にあったりして
でも
>>99 の本はマズイよなぁ…
柴田望洋まじオヌヌメ
122 :
デフォルトの名無しさん :2009/05/14(木) 17:22:07
なんだ俺が昔書いた本じゃね〜かよ
>>122 今すぐC業界から足を洗ってください
お願いします
こんなコード書くやつがあうの携帯ファーム作ってるんだろうな
while ((*p = *(p + 1))) p++; のように代入式を ( )でくくって代入式を評価してるんだとアピールすれば警告でないよね
a[i] = i++;が駄目なのはわかるんだけど、 a[i++] = i;も駄目なの?
>>126 だめだって
i++とか++iは途中に書くなってことだ
それはいい
つーかそこまで省略してどうなるっていうんだよ マシン語になったらたいした違いねーだろ
規格を厳密に知ってる奴ばかりじゃないんだからフェイルセーフでいこうぜ
133 :
デフォルトの名無しさん :2009/05/14(木) 17:33:31
99. 皆さんコメントありがとうございました。 102.さんのコメントを参考に = を == に変えたら コンパイル、実行結果とも正常になりました。
あーあ 変な本のせいでまた一人間違った知識を身に付けちまったぞ
>>133 その場合=と==ではやろうとしてることが違う
そもそもwhile()の中でそんな式入れるなってことだ
これだけいろいろレスがついてるのにそんな解釈しちゃうなんて、 本当にプログラミング向いてないか釣りかのどっちかだろ。
138 :
デフォルトの名無しさん :2009/05/14(木) 17:54:09
99. 99=133. すみません。 = を == に変更したのですが、実行結果はABCDEでした。 目的通りの結果と思いましたが、プログラムの目的は 文字列の左シフトですから勘違いしてしまいました。 もし133にコメントがありましたら、お手数をかけまして すみませんでした。
== は || や && や , と違って副作用完了点にはならんよね?
すみません、
>>99 で文字列の左シフトを
実現するにはどうしたらいいですか
俺なら while (*p) { p[0] = p[0]+1; p++; } ってな感じに書くかな。 特に代入のところで *p = *p+1; とか書いて あれ?って迷うぐらいならシンプルに ということで
>>141 while文のカッコの中だけで済ませようとするから無理がくる
ポインタ変数を二つ用意するか、文を二つに分けるかのどちらかだな
>>99 >>141 こんな感じでどちらか選べ
#include <stdio.h>
#include <string.h>
int main(void)
{
char *p, *q, c, a[] = "ABCDE", b[6];
strcpy(b, a);
/* ポインタ変数を二つ用意する方法 */
p = a; q = a + 1;
while (*p++ = *q++);
printf("%s\n", a);
/* 文を二つに分ける方法 */
p = b;
do {
c = *(p + 1);
*p++ = c;
} while (*(p - 1));
printf("%s\n", b);
return 0;
}
>>142 a[] = "ab9*765Zz";
とかでも大丈夫なの?
>>145 ポインタの指す中身を指定する*と文字列の*は全く無関係
というか入門書もう一回読みなよ
>>144 どうも、どうも
すみません、僕
>>99 じゃないです。
なんか、src、destポインタ二つの方が解りやすいですね。
>>147 普通はそうする
文を分けると可読性が著しく低下する
便乗 a[i++] = *p; /* 実は p == &i */ こういうのも悪魔召還?
150 :
デフォルトの名無しさん :2009/05/14(木) 19:03:46
初心者です C言語でマイコン研修をやっているのですが、 PICに入れるプログラムの周波数を大きく設定して実行してしまいました。 この場合マイコンやPICは故障したりするのでしょうか? すれ違いならすみません・・
>>150 故障したから聞いてるの?
故障しなかったから聞いてるの?
マイコンについて知らないけど、プログラムの周波数というのはどんなものなの?
>>151 故障したかわからないまま終わってしまったので不明です。。
いや、スレチを指摘やれよ
>>150 「プログラムの周波数」とは何のことですか?
つーか、鼬害だがな。
>>150 ようするに安易にオーバークロックやって壊したんでしょ?
新しいの買いなよ
>>156 言い方悪かったです
プロジェクトを作成するときに動作環境の周波数を決めるんだけどその時に間違ってしまった
という意味です
どうやらそれだけでは壊れないみたいなので解決しました
すれ違い盛大に失礼しますた
160 :
デフォルトの名無しさん :2009/05/14(木) 20:10:24
動作環境の周波数って何? コンベアとかの関係?
ヘルツだな
>>149 いや、i++ によって p の値が変わるわけではないから、書き手の意志でそう書いたのなら問題ないでしょう。
>>162 pじゃなくて*pの値がどうなるかわかんないでしょ
インクリメントされる前の値に決まってるが
>>164 *p は p = &i を実行したときの値のままですよ。i++ によって p も*p もかわらない。
だから、書き手がそう望んだのならそのとおりに動く、書き手の意図どおりのはず。
#include <stdio.h> int main(void) { int i=0; int *p = &i; printf("p: %x\n", p); printf("*p: %x\n", *p); puts("i++"); i++; printf("p: %x\n", p); printf("*p: %x\n", *p); } $ ./a.exe p: 22cce4 *p: 0 i++ p: 22cce4 *p: 1
>>167 それは当たり前。
p = &i;
a[i++] = p;
は、インクリメントという副作用がどこで発生するかによって結果がかわる、という問題にはあてはまらないのですけれども。
書き手の意志どおりにうごくので問題ないのでは?
>>166 だからi++が実行されるのが*pを読み出す前なのか後なのか
わからないと言っているんですけど
後置インクリメントなんだから*p呼び出した後に決まってるだろうがw
このレベルの低さはやばい
>>172 お前Cプログラマに向いてないよ
マジでそのセンスの無さやばいから
175 :
デフォルトの名無しさん :2009/05/14(木) 21:56:07
ベクトル空間モデルがわかりません 詳しく教えてください
>>172 ならば a[i++] = i; も 右辺側の i を参照した後にインクリメントされるの?
これを ポインタ使ったエイリアスで書き換えた形が
>>149 なんだよね
177 :
デフォルトの名無しさん :2009/05/14(木) 22:21:06
>>175 ベクトル空間の2直線は、そのなす角が小さいほど似ていると考えられる。
たとえば、xy座標で(1,1)を通る直線と、角度46度、44度を通る直線は
ともに角度のずれは1度だけ。
ベクトル空間モデルはこういうずれを計っている。
>>171 なるほど。やっと理解した。レベル低くしてすまない。
ポストインクリメント演算子++は、i++と書かれていた場合は iを参照した「後に」pの値を増やす事が保証されているだけで、 iを参照した「直後」に増やす事は保証されていない。 a[i++] = *p; /* p = &i */ の場合は副作用完了点はやはり セミコロンの直前なので、*pを参照する前にiが増やされるのか *pを参照した後にiが増やされるのか見ただけでは判断できない。 つまり処理系依存である。ANSI-C(C89)ではもっと厳しく 実行結果は「未定義」、つまり鼻から悪魔が出てくるとしている。
されてません。
>>180 C99を採用してるコンパイラでなければ意味無いだろ。
つまり使うなってことだよ。
もう10年経つんだから、C99じゃないコンパイラの方が珍しいんじゃないの
はあ?
>>183 つ[VS2008]
つ[CodeGear C++]
この二大メーカーがまだC89のままです
>>185 10年経つのに対応しないって...
結局C++のC部分で十分ってことだよね。
あと窓ではCユーザー少ないから対応しなくても問題なしってことかな
次ではそれらC99対応するん?
IntelとAMDの出してるのはC99準拠だよ。あと、Sunのも。
AMDのC・C++コンパイラなんて出してたの?
>>186 しません
多分永遠にしないでしょう
C++があれば十分だと思っているようですから
>>188 CPUメーカーの維持なんだろう
intel版がAMD CPUに最適なコードをはいてくれなくてCPUが遅いといわれる可能性もあるだろうし
その逆もしかり
でも確かgccベースじゃなかった?
GCCをベースにする以外、急には作れなかったのだろう。。。
マウスでいまクリック、もしくはドラッグしているファイルやディレクトリのパスを 取得する方法ってありますか?常駐ソフトのような形で、起動してからクリック、ドラッグ したファイルのパスをテキストログとして、出力するようなものを作りたいのですが・・・。
すいません、他行ってきます。
なんでスレタイ読めないヤツっているんだろうね。 書き込む前に考えないのだろうか。。。
C言語で N88 BASICのLOCATEような 事どうすればできますか? コンソールアプリケーションで作成して 一番下までいくと 次からは違うページになってしまうので 画面を固定したいのですが 毎回CLS(system("cls");) 掛けると 画面がチカチカして 堪らないので
>>197 エスケープシーケンスとか使うんじゃない。
制御コードは端末依存。
>>199 ・プログラムにバグがある(ESCが正しく出力されてない、等)
・ESCシーケンスの効かない端末を使っている(GUIアプリ等)
まあソース晒すのがいいと思う
コマンドプロンプトだからだろw コマンドプロンプトにエスケープシーケンスは効かねーよw そのページは古い、昔のwindowsではサポートしてたからな
>>203 えーと、APIですか?
APIは全く使ってないので関係ないと思うのですが。
>>205 ありがとうございます。
やってみたのですが出来ませんでした。
#include<stdio.h> #include<stdlib.h> int setstr(char **p, char *q){ *p = malloc(strlen(q)+1); strcpy(*p, q); return strlen(*p); } main(){ char **s; setstr(s, "test"); puts(*s); } setstr関数で文字列コピーをしたいのですがうまくいきません。。。なぜでしょうか。 コンパイルは通るのですがなぜか偉ーで落ちます。。。
とりあえずメモリ確保しろばか もしくはchar **s; じゃなく char *s; でやれクズ
>>202 ESCシーケンスの使い方は間違ってない
実際、cygwinでコンパイルしたら、ちゃんと動いた。(VC6は持ってない)
ただし-mno-cygwinを付けるとダメだったので、素のDOSプロンプトは
ESCシーケンスを使えないんだと思う。
WindowsでESCシーケンスが使うのは大変そうだけど、以下の2案挙げておく。
(1) 他の人がいうように ansi.sysを入れて DOSプロンプトを起動する
#自分は試してない
(2) teraterm + cygwin接続 (teratermはESCシーケンスを解釈する)
の環境でそのプログラムを実行する
#こっちは大丈夫そう。ただしVT100互換でないかも
>>207 main(){
char *s;
setstr(&s, "test");
puts(s);
}
でOk
多分 teraterm案はやらないと思うけど、念のため補足。 teraterm で試すなら CLS の部分は、 printf("\033[2J\033[0;0H"); とした方がいい。 ESC [ 2 J だけでは カーソル位置が戻らなかった。
じゃぁ俺も細かいこというとDOSプロンプトは受け付けるよ コマンドプロンプトは受け付けないけど
213 :
207 :2009/05/16(土) 15:41:21
早速のレスありがとうございます。
>>208 mallocでメモリ確保は行っていますが。。。
>>208 ,
>>210 おっしゃるとおり**sを*sにすると期待した動作になりました。
引数としては**sも&(*s)も同じに見えるのですが。
なぜでしょうか。
>>211 レスどうもです。
(1)はどうやっても効きませんでした。
なので(2) 試してみたいと思います。
最も、チカチカしないように出来ればエスケープシーケンス
使えなくても良いのですが、自分では他にいい案が思い浮かばず
それならLocateと同じ事が出来ればいちいちCLSを繰り返し
処理(書いては消すの繰り返し=チカチカ)しなくても、
いけるのでは?と思ったからです。
というのもブロック消す処理は入っているのでCLS不要なわけですし
NT系のDOSプロンプトでエスケープシーケンスを使いたいのなら、 WIN32アプリではなくDOSアプリにしないといけない。 9xはDOS/Winごちゃ混ぜだったので、 Win32アプリでもANSI.SYSのエスケープシーケンス処理が適用された。 NTは分離されている。
>>213 char **sはchar *に対するポインタでこの時点ではどこを指してるか不定。
>>21 確保できてねーだろ死ね
お前の書いた糞コードに近いやり方するとしたら
#include<stdio.h>
#include<stdlib.h>
int setstr(char **p, char *q){
*p = malloc(strlen(q)+1);
strcpy(*p, q);
return strlen(*p);
}
main(){
char **s;
s = malloc(sizeof(char *));
setstr(s, "test");
puts(*s);
}
こういうことだ、わかったかぼけ
218 :
210 :2009/05/16(土) 16:41:41
>>216-217 理解できました。
char **sを宣言したとき
sはメモリのどこかを指していてそれがどこかを指している
で、そのままsetstr関数に渡すと
不定な場所にmallocの返り血を書き込もうとして落ちていたわけですね。
どうもありがとうございます。
確かに返り血だな malloc「ゴラ!!変なエリア渡すンじぇねえよ。いてまうで」 プログラム「ふぎゃあ・・・」
>>219 malloc が 0 返してきたあかつきには、どうしていいかわかりません。みなさんどうしているのでしょうか。
システムをエラー終了させます
>>222 そんなんでいいのでしょうか。といっていいお作法はおもいつかない。
NULLを進呈されても被害最小に治める妥協点を見積りステートの保存を行って置きます。 妥協点がプログラムのゼロスタートになる場合も多々あります。
>>224 断片化されたんではどうしようもないですし。
メモリーが無くなってからの復旧は、ほとんど可能性が無い。 無理にがんばらずに、メモリがなくなったとエラーメッセージを出して終了が間違いなし
メモリは差し上げられませんねぇ って言われたらもう何もまともに続行出来ないじゃん。 あきらめが肝心。
断片化してるだけなら分割確保すればいける事も
>>223 コンパクション処理走らせてた時代もあったな。
使ってないデータはディスクに書き出して容量確保するとか、そういう努力もしてた。
Linuxあたりになるとmalloc()はNULLを返さないらしいから、 NULLチェック自体が無駄かも。
今そんな処理がアプリケーションをする時代でなくなってきちゃって 「メモリ?…ハァ?スタックでがまんしろよおい」って言われたら思わず噴出す(ブシャー)
?
なんで頭の中で言った文章と書き込んだモノが違うんだろうと悩んでる
>>230 アドレス空間って聞いたことある?
32bitのLinuxでmalloc(3*1024*1024*1024)出来ると思ってる?
俺もシステム全体での「物理メモリ(スワップ?)」が足りない時のLinuxの動作は知ってるけどさ。
用語すら怪しいレベルで知ってるとはおこがましい
お前が知らないのは日本語だな。 俺は、Linuxの「プロセスを有無を言わさず殺す動作」が起きるのが 「物理メモリが足りない時」と「スワップ領域が足りない時」のどちらの場合なのかを 知らないだけだ。
あ、用語か。 「OOM killer」 これでいいかな。
>>235 linuxのmalloc()がNULLを返さないってのは、いかなるときでも絶対返さないって意味じゃないよ。
じゃ別に無駄じゃないじゃん
>>239 ならば
>NULLチェック自体が無駄かも。
と書かれているのは何故ですかね。
ちゃんとわかってる人には今更説明するまでも無いけど
仮想記憶を使っているOSでは、普通mallocは、アドレス空間が足りない時に、NULLを返す。
その他、一般的には、malloc内で呼んでいるシステムコール(例えばWin32ならVirtualAlloc)が
メモリをくれなかった場合にも、mallocはNULLを返す。
ただ、Linuxは、システムコール自体では「メモリ不足エラー」を返さず、
その領域にアクセスした瞬間に、どこかのプロセスを強制終了させてメモリを確保する。
そのため、Linuxにおいては後者のケースでNULLを返すことはない。
しかし、一般的に「mallocがNULLを返す」というのは、アドレス空間不足によるものが殆ど。
(物理メモリが足りなくても仮想記憶で補っているため)
したがって、mallocを使っている限り、「NULLチェックしなくて良い」などということは無い。
返された領域(NULL)にアクセスして不正終了しても構わないというなら不要といえば不要かもだが。
繰り返すけど
mallocがNULLを返す状況というのは、アドレス空間の不足が殆どなので
「LinuxだからNULLチェック不要」などということはありえない。
C++ではnewが投げるbad_allocを拾うことにあんまり意味はないといわれてるが その話とごっちゃになってるんじゃないか
243 :
デフォルトの名無しさん :2009/05/17(日) 04:49:00
偽のときのびっくりマーク(!)って何て読めばいいんですか?
日本人相手なら「びっくり」で通じるよw
not
>>240 malloc()を読んだ時点では、メモリ確保に成功したか失敗したか
わからないから無駄だという考えもある。
あたまわる
>>241 ×アドレス空間
○プロセスに割り当て可能なメモリ
>>248 頭悪いね。NULLチェック必要だって固定観念を棄てられないんだから。
251 :
デフォルトの名無しさん :2009/05/17(日) 10:08:39
>>241 >ただ、Linuxは、システムコール自体では「メモリ不足エラー」を返さず、
>その領域にアクセスした瞬間に、どこかのプロセスを強制終了させてメモリを確保する。
これ本当?
linux の malloc について新しいカーネルでは /proc/sys/vm/overcommit_memory で挙動が変えられるみたい malloc の NULL チェックが必要ないと言ってる奴は 環境依存な話をしてるだけ
>>252 mallocしたプロセスの観点ではエラーにならないんだよね。
他の誰かが死ぬだけで。(それもどうかと思うけど)
>>254 他の誰かとはかぎらんよ。
自分が殺される可能性だってある。
>>253 だから最初からlinuxではって言ってるじゃん。
>>255 いや、ぜんぜん。
自分が悔しかったり、むかついたりすると、相手もそうだと思っちゃうよね。
>>257 プロセスごとに使用可能なメモリ量を制限することも可能だし
古いカーネルを使い続けるのでない限りは
linux でも NULL チェックは意味があるって事になってるんだって
黙ってNULLチェックする これで万事FAだろ。
文字列を入力して、そのまま出力するプログラムなんだけど これだと出力出来ないし、最後のprintfをforで回してa[i]にするとエラーが出る。 何が違うの? #include <stdio.h> void main(void){ char a[10]; int i; a[9] = '\0'; for( i = 0 ; i < 9 ; i++ ) scanf("%s",a); printf("入力した文字列は%s",a); }
入力をループでまわす意味がわからんw
ものすごい勘違いをしてるなw
>>260 ああw
intと違って連続で入力すれば良いだけかw
unsigned char型と宣言して、 scanfで%sとして全角で入力させた文字を、 10進数、16進数のコードで表示させるにはどうすればいいですか? ただ%dや%xとしただけではだめだったのですが…。
全角って何かわかってるのか
えっと、日本語で入力させてます。
アドレスとポインタの違いが判りません。 ポインタはアドレスを格納する変数という理解で良いでしょうか。
268 :
デフォルトの名無しさん :2009/05/17(日) 16:05:33
>>257 だから、
char *p = malloc(3 * 1024 * 1024 * 1024);
printf("p = %p\n");
を 32bit Linuxで実行してみろっての。バカ。
頭大丈夫?
誰が?
271 :
デフォルトの名無しさん :2009/05/17(日) 16:11:50
頭の悪さを指摘されて悔しくてたまらないもんだから わざと頭が悪い振りをしてるんでしょ。 理解できないわけないんだから。用語がどうとか言ってた無知も居るし。
アドレスの使い方なんぞ複数の戻り値以外に思いつかないぜ
>271 ありがと。 あとは、配列とポインタの違いだけど、 配列はアドレスだけどポインタじゃないから、任意のアドレスは格納できない。 ってところが違い?
配列はアドレスだけど、って日本語としておかしいと思わないか
配列はアドレスの「値」「定数」「ラベル」という認識でよい。 ただ、ポインタもそうだが、「型をもつアドレス」だからな。 それと、ポインタ変数だけでなく、ポインタの値のこともポインタと呼ばれる。
277 :
デフォルトの名無しさん :2009/05/17(日) 16:29:55
sizeof(...)の違いもある。
>275 ほんとだな。 俺、日本語でおk、だな。 >276、277 ありがとうございます。 ポインタや配列は型付きのアドレスなんですね。
>>278 完璧に間違ってる。
配列は配列。ポインタではない。
変更不可能な左辺値。普通のオブジェクト。
>>276 はアセンブラしか知らない人なんだよ。察してやれ
あれ、 ポインタは型付きのアドレスじゃないの?
283 :
デフォルトの名無しさん :2009/05/17(日) 17:11:09
void *
インクリメントしたときに、sizeof分アドレスが進むこととかを指して 型付きと言ってるんだよね? あってんじゃん?
>>284 俺は「アドレス」という語が出た時点で
機械的にこいつダメだなと判断する。
sizeofした時の結果は、どのようにして求めてるの?
しかもsizeofを全角で書いてくるとは。
普通に考えればsizeofはコンパイル中に値を出してる筈。 でもリテラル評価のタイミングでは数字になってない。
sizeofの値は、オペランドが可変長配列以外の時はコンパイル時に決定される。
コンパイル時にですか! と言うことはexeにはその値が埋め込まれているだけってことですね。
今更だけど、
>>249 って本当に全然わかってないんだな
うん、ただのゴミ。
Cなんてなつかしw
>>290 埋め込まれる保証もないよ。最適化で適当な値に換算されているかもしれないし。
2Dのゲーム製作って何が出来れば出来るようになるのか曖昧なんだけど どの程度のレベルから作り始められるのかが良く分からん。 コンソールを一通り扱えれば、後はライブラリの勉強すれば作れるようになるの? アルゴリズムさえうまく作れれば、作れる気がするんだが。 それともwinAPIの勉強も必要?
296 :
デフォルトの名無しさん :2009/05/19(火) 15:17:32
/*snapshot.c*/ 2 /*メッセージ出力関数*/ 3 #include <stdio.h> 4 #include <stdarg.h> 5 #include <time.h> 6 7 #define MAX_SIZE 512 8 static char *symbol[] = {"I","W","E"};/*メッセージレベル*/ 9 10 int snapshot(int type,char *fmt, ...){ 11 char tstr[MAX_SIZE];/*文字列化した時間を格納するchar型配列*/ 12 char buff[MAX_SIZE];/*出力メッセージを格納するchar型配列*/ 13 char message[MAX_SIZE];/*ユーザ指定のメッセージを格納するchar型配列* / 14 time_t ct; 15 struct tm *lst; 16 va_list ap; 17 int num = sizeof(symbol) / sizeof(symbol[0]); 18 19 if(type < 0 || type > num -1){ 20 type = 0; /*強制にtypeに0を代入*/ 21 }
297 :
デフォルトの名無しさん :2009/05/19(火) 15:18:23
22 /*時間の取得と書式変換*/ 23 time(&ct); 24 lst = localtime(&ct); 25 strftime(tstr,MAX_SIZE,"%Y/%m/%d %H:%M:%S",lst); 26 /*可変引数の初期設定*/ 27 va_start(ap,fmt); 28 /*指定されたメッセージの取り出しと独自メッセージの作成*/ 29 vsprintf(message,fmt,ap); 30 sprintf(buff,"%s [%s] %s",tstr,symbol[type],message); 31 /*可変引数の後始末*/ 32 va_end(ap); 33 /*独自メッセージの出力*/ 34 fprintf(stdout,"%s",buff); 35 return 0;
298 :
デフォルトの名無しさん :2009/05/19(火) 15:19:20
1 /*snapshot.h*/ 2 extern int snapshot(int type,char *fmt,...); 3 #define NORMAL 0 4 #define WARNING 1 5 #define ERROR 2
299 :
デフォルトの名無しさん :2009/05/19(火) 15:20:32
1 /*snapshot2.c*/ 2 #include <stdio.h> 3 #include "snapshot.h" 4 5 int main(void){ 6 int i = 10; 7 snapshot(NORMAL,"normal message. %d\n",i); 8 snapshot(WARNING,"warning message. %d\n",i++); 9 snapshot(ERROR,"error message. %d <%s>\n",i++,"final message"); 10 return 0; 11 }
300 :
デフォルトの名無しさん :2009/05/19(火) 15:25:21
これでコンパイルする gcc -o snapshot2 snapshot2.c snapshot2.c:(.text+0x2f): undefined reference to `snapshot' snapshot2.c:(.text+0x4e): undefined reference to `snapshot' snapshot2.c:(.text+0x75): undefined reference to `snapshot' となり、コンパイルすることができません。 このプログラムは教材のプログラムです。 何回も見直したので写間違いはないと思います。 多分僕が共通範囲を理解していないのかもしれません。 コンパイルできないものを質問するのは失礼ですが、どうしても分かりません。 ご指摘お願いします。
>>300 >>296 の13行目の * / を */ になおしたうえで、
gcc -o snapshot2 snapshot2.c snapshot.c
でやってみ
302 :
デフォルトの名無しさん :2009/05/19(火) 16:01:06
>>301 コンパイルすることができました。
コンパイル命令が違っていたのですね...
実行結果は教材に書かれていたのとは違いましたが
それは自分で考えて見ます。
本当にありがとうございました。
#include<stdio.h> int main(void) { int a = 5; if ( a < 10 ){ printf("10未満です。\n"); } else{ printf("10以上です。\n"); } } ビルドエラーが起きる どこが間違っているか教えてください 間違いは3ヶ所あるようです
全角スペース
305 :
デフォルトの名無しさん :2009/05/19(火) 17:45:26
306 :
デフォルトの名無しさん :2009/05/19(火) 18:23:03
>>303 メイン関数の返り血をintに設定しているのにreturnで整数を返さないのは
おかしいのではないでしょうか?
まあこれはエラーではなく警告になるようですね。
>>306 C99ならmainでreturnを省略すると0が返ると決められている。
C99じゃないならreturn 0;しとけ。
#includeと<stdio.h>の間にスペースが無い
{がある行の文頭に1を加えて表示させ、以降}がある行まで文頭に1を表示させ出力する。 {がある行の区間にさらに{が出てきた場合には、1を加え2を表示させ、}が出てきた場合には1を表示させるようなプログラムはどうやったら実現できますでしょうか? 例を書きますと、 元のtxt { } { { } } 出力txt 1{ 1 } 1{ 2 { 2 2 } 1} 行毎に読み込むまでは出来るのですが、行毎に読み込み元の文章に文字列を加え出力する、というのがわかりません。 どなたか教えてただけたら幸いです。
>>310 printf("%4d %s", no, line); とかじゃなくて?
>>311 さん、ありがとうございます。
当方の言葉が足りませんでした。プログラムに表示させるのではなく書き込んだ後ファイルとして出力します。
fprintfにすりゃいいだろw
>>310 作ってみたw
#include<stdio.h>
int main(int argc, char *argv[])
{
FILE *fp_in=stdin, *fp_out=stdout;
char buf[256];
int i, brace_count=0;
while(fgets(buf, sizeof(buf), fp_in))
{
for(i=0;buf[i];i++) if(buf[i]=='{') brace_count++;
fprintf(fp_out, "%2.0d %s", brace_count, buf);
for(i=0;buf[i];i++) if(buf[i]=='}') brace_count--;
}
return 0;
}
>>314 {}{}{}
に対して
1 {}{}{}
なのか
3 {}{}{}
なのか
負数はどうするとか不明なのに書いちゃダメだ
>>313 さん
>>314 さん
ありがとうございます。
>>314 さんは書いてくださって本当に感謝しています
>>315 さん
まずは書いてくださったコードを読んで、自分なりに理解してから検討したいと主思います。
>>295 @ウィンドウの出し方を調べる
A絵の出し方を調べる
B絵の表示位置をキー入力で変えられるようにする
あとは表示する絵を増やしていけばいいだけ難しくない
一通りC言語を覚えたので技術力を上げたいのですが Project Euler以外でなんか良い方法や問題や参考書ありませんか? 将来はソフトウェア開発関係の仕事を考えています
>>318 まあどういう方面に進むかわからないけど
・ゲームを一人でシステムだけ作ってみる。
・DBと連携したシステムを書いてみる
のどちらかかなあ?
まあハードウェアの制御用アプリを書くってのもあるんだろうけど
>>319 なるほど、参考にさせていただきます
ゲームはC言語とライブラリを使って作ったりはしているんですが
ライブラリよりWin32APIからDirectXで作ったほうがいいのでしょうか?
ライブラリ使ってで問題ない。それよりもきちんと完成させることの方が大事
>>320 ライブラリに関していえば所詮は環境依存なのでゲーム作るのであれば
たとえばDXライブラリの上で動いてるゲームであっても問題ないです。
なるほど、つまり流れを覚えてきちんと完成させるってことでいいんでしょうか?
>>321-322 さん ありがとうございます
>>323 まあそういうことですね
ためしに過去のゲームレベルを一人で作ってみるとか挑戦するのもいいかもしれないですね。
グラフィックとか音楽はあまりこだわらずに。
グラフィックとか音楽はハードの進化で確かに綺麗になったりしてますが、
ゲームそのもののシステムは実はそれほど進化してないんですよね。
DXライブラリは凄く初心者に取っ付き易くて助かる。 OpenGLはDXライブラリで作ってからじゃないとムリだw 俺もCやり始めて1ヶ月とちょっとだけど、DXで製作出来てる。 …どの程度のが出切るのか不安だけどね
326 :
318 :2009/05/21(木) 03:28:10
>>324 そうなんですか
最近はゲームがきれいになってきたので難しいものだと考えてました
過去のゲームを作る上ではやっぱりアルゴリズムなんかも覚えないといけないんでしょうか?
実際自分はまだ文法しか勉強していないのでソートなどのアルゴリズムとか覚えてないんですが…
>>326 まあドット絵や3Dモデルをバリバリ作れるわけじゃないのであんまり偉そうな
ことはいえないけど、プログラマ視点からすればさほど変わらんかなあ。
特にアクションが無いゲームの場合は表現方法が2Dか3Dかの違いだしねえ
>>326 まずは標準C++の仕様を学んだ方がいいんじゃない?
慣れも大きいが、C言語で書くよりC++で書いた方が
ライブラリなどもそろっているし楽かと。
329 :
デフォルトの名無しさん :2009/05/21(木) 10:58:58
あのですね、dosでclでコンパイルしてC言語やってるので、 dosのことで聞きたいことが2つくらいあるんですけどここじゃダメなんですかね? dos専用スレみたいなところってあるんですかね? オマケで教えてもらうことって無理すか? 叩きスレがなければこのあと質問させていただきます。
>>329 DOSスレか環境依存スレかVisualStudioスレへどうぞ。
331 :
デフォルトの名無しさん :2009/05/21(木) 11:15:33
それどこですか?
332 :
デフォルトの名無しさん :2009/05/21(木) 11:29:54
333 :
318 :2009/05/21(木) 15:47:23
>>328 C++ですか
やってみようと思います。
あとC言語から発展してWin32APIとDirectXは必ずやる予定なんですが、
これはどのように勉強すればいいのでしょう?
普通に文法を覚えていけばいいのでしょうか?
板違いだったらすいません。
今はもう Win32APIはあまりいらないかな。 DirectXでつくるゲーム入門みたいな本が大量にあるから、いくつか買って勉強。
335 :
デフォルトの名無しさん :2009/05/21(木) 17:02:21
APIとかやってたら何時になったらゲームに辿り着くんだろう
if文の判定式について質問です。 if(a == b || *(c-a) == d) hogehoge(); a!=bならc-aは触って良いことが保証されている場所だとして、 上の書き方はc-aを触らないことが保証されますでしょうか? それとも、最適化等の都合で、*(c-a) == dが先に評価されることが起きうるのでしょうか。
コンパイラ依存
338 :
デフォルトの名無しさん :2009/05/21(木) 17:21:59
ififにしたほうがいいような
>>336 ANSI準拠のコンパイラなら問題なしみたい
用語は「ショートサーキット」
>>337-340 ありがとうございます。規格上は問題ないのですね。gccを信用することにします。
ショートサーキット調べてみました。映画でした。……じゃなくて、オペランドに対する評価順序の規則でした。
最近は複数コアCPUが並列処理して一気に評価してたりするのかなってぼんやり思ってたんですが、
そうではないんですね。。。
ありがとうございました。
CというかObjective-cについてです。 以下のコードの流れについて知りたのですがよく分かりません。 行ごとに簡単に解説してくれると助かります。よろしくお願いします。 -(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event { Animations:nil context:nil]; [UIView setAnimationDuration:0.7]; [UIView setAnimationTransition:UIViewAnimationTransitionFlipFromLeft forView:selfcache:YES]; if ( enabled ) [[UIApplication sharedApplication] sendAction:@selector(buttonPushed:) to:target from:self forEvent:event]; [UIView commitAnimations];
やっぱいつ見てもObjectiveCはカオスだわ SmallTalkもカオスっぷりが禿しないけど
345 :
q :2009/05/22(金) 00:47:33
データの格納のアルゴリズムがわからなくて質問させてください。 *formatのデータをunsigend char buff[192]に格納し、buffを転送用関数の引数にセットし送ります。 例えば*formatがサイズが200の場合、buff[0]〜buff[9]は固定データを格納します。 buff[10]〜buff[192]までformatの中身を格納します。転送用関数で転送後(戻りなし)、 formatの残り18byteをまたbuff[0]〜[17]へ格納します。二回目の格納は[0]〜[9]までに固定データの格納はありません。 これをなるべく早く行いたいのですが、どのように行えばいいですか。よろしくお願いいたします。
>>345 意味がよくわからない。。。
void tensou(unsigned char *b, int length){
/*だみー*/
}
main(){
unsigned char format[200], buff[193], kotei[10];
memcpy(buff, kotei, 10);
memcpy(buff+10, format, 183);
tensou(buff, 193);
memcpy(buff, format+183, 17);
tensou(buff, 17);
}
347 :
345 :2009/05/22(金) 01:29:35
>>346 すいません。。
やりたいことはprintfで渡ってくるデータをいかに効率よく出力exeに送るかということを
やりたいんです。自作printfを作成していて・・
@出力exeに転送する前にprintfから渡ってきたデータの先頭に10byteに固定データを入れる。
A最大192byte転送できる転送用関数の引数としてバッファをセットする。
ということなんですが、転送用バッファの最大が192byteなのでそれ以上のときはどうすればよいかなと。
なおかつスピードが要求されています。
"格納のアルゴリズム"なんてスゲーことやろうとしてんな… っておもった *formatってのがよくわからん
349 :
345 :2009/05/22(金) 01:48:13
>>348 int printf(*format...){
}
の*formatです。
いや多分ボトルネックは*formatの分割とかではなく むしろ転送うんぬんの部分じゃないか? 何か不満のあるやりかたでもしてるの?
>>347 組み込みか何かでバッファを使いまわさないとダメなのか?
PC上の話ならこれでいいと思う
なんてったって printf は自作するにはハードルが高い
void tensou(char *b, int length);
int myprintf(const char *format, ...)
{
char buf[1024]={"固定データ"}; // 十分な領域サイズにすること
int i, whole_size, tensou_size=192;
va_list ap;
va_start(ap, format);
whole_size=vsprintf(&buf[10], format, ap)+10;
va_end(ap);
for(i=0;i<whole_size;i+=tensou_size)
{
if(tensou_size>whole_size) tensou_size=whole_size;
tensou(&buf[i], tensou_size);
}
return size;
}
352 :
345 :2009/05/22(金) 10:02:23
すいません。昨日は落ちました。転送用バッファは他人からの提供関数で仕様変更は効きません。可変データを固定バッファに入れるは難しいでしょうか?今、色々考えてるのですが。
リングバッファの変形だろう
初歩的なことで申し訳ない Aという構造体があるんだが A **aみたいに宣言した場合、このaのメンバにアクセスするにはどうすればいいんだ? 普通のポインタならa->numだからダブルなら *a->num という風にやるのかと思ったができない
優先順位見てみよう ->のが*より優先度高いので*a->numだと*(a->num)になる。 (*a)->numでやってみて。
(*(*a)).num
>>355 なるほど。優先順位で別の意味に解釈されてたのか
ありがとう!おかげで作業が進むよ
>>352 1.どういう手順でその関数を呼び出すのか分からない
(例.特定アドレスに送信内容を設定した後、送信用の関数を呼び出す)
2.printf の結果について最大サイズの計算は可能か
3.メモリ使用量の制限があるのかどうか
どっちにしろ
>>351 で大体おkだと思うんだがね
あるすげー長いテキストファイルのいくつかを コピー改行コピー改行 して追加書き込みしたいんだけど どれくらい領域確保すればいいのやら
テキストの中身の領域を調べるのって どうするの?
>>359 あんまりいいロジックではないかもしれないが
線形リストと構造体でなんとかなるんでない?
typedef struct hoge HOGE; struct hoge { struct hoge *next; //リスト用 int num; //構造体が持っている文字数(改行などの制御文字含む) } リストと文字数管理用の構造体はこんな感じにして 領域確保の際は malloc(sizeof(HOGE)+len); lenは改行コードまでの1行分の長さ
あーでもあれかメモリ上であれこれしなくてもそのままファイルに書き出すのであれば 入力側からちびちび読み込んで1行分の文字数をカウントしながら出力しつつ 改行する必要があれば出力側に改行コードを追加で出力するようにすればいいのか。 というか文字コードは何とか1行はどのくらいで区切るとかがわからないと コードがもらえないよな
最悪一バイト挿入する毎にズレる部分を採って入れて繰り返せば char tmp; で十分・・・
日本語でおk
質問者がインプットとアウトプットなどもうちょっと仕様にあたることを 書かないとどうしようもないわな。 文字が絡むと面倒なことが多いし。
よくわからんがプログラム書かなくてもマクロで解決できるような気がする
>>365 C言語でおk
日本語で説明するよりCでコードを書いて最適化してもらったほうがわかりやすい
369 :
デフォルトの名無しさん :2009/05/23(土) 15:05:59
来年春からプログラマとして働くけど、 それまでにある程度勉強しときたい通用しないだろうけど基本は 今ネコでもわかるC言語プログラムが終わって、これの次の難易度的な本はありますか?
未経験採用ならそんだけやっときゃ十分だよ
バグや納期遅れでもへこたれない胆力を鍛える これが一番かなあ
>>369 それくらい自分で探せるようになることかな。
373 :
デフォルトの名無しさん :2009/05/23(土) 15:22:35
若いのにドカタ一直線だな。他業種目指せばよかったのに
>>369 勉強より、強靭な体力、根性力をつける
先ず、今年の夏は冷房(エアコン、扇風機等)なしで過ごし
夏休みは日中の暑い中、毎日1時間以上走れ
それと徹夜力を身につけとけ 大体2日寝ないでも特に問題無く3日目活動出来るようにしとくべき 冗談じゃなくてマジで
#include<stdio.h> #include<math.h> int main(void) { double t,h,df,a,r,c,o,e,i,f,vc,dvc; t=0; h=0.000001; e=sqrt(2)*100; o=3.14*2*50; a=2; r=20; c=1.0*0.0001; for(t=0;t<=10;t=t+h) { df=e*sin(o*t)-vc-a*r*f*f*f*f*f; dvc=a/c*f*f*f*f*f; f=f+h*df; vc=vc+h*dvc; i=a*f*f*f*f*f; if(t>9.98){ printf("%f , %f \n",t,i); } } return 0; } このグラミングbcc32で実行しようとすると エラー E2206 a.txt 20: 不正な文字 ' ' (0x8140)(関数 main ) っていうのがでてしうんですが、どこがエラーを起こしてるんでしょうか? 20行目周辺みてもミスがわからないです。
どっからコピペしたのか知らんが、なんでそこにだけ仕込んであるんだろ
VCのコンパイラはclですよね なんでclという名前なんですか? bccとかgccは名前を略したものでしょうけど。
c languageの略らしい ごめんなさい嘘です
compileの略らしい ごめんなさいテキトーです
たぶん、はるか昔のMS-Cから連綿と伝わる…かな?
MSCのころからだね。LINKもするからlついてんじゃない? MASMはmlだしな。
まだ、マイクロソフトが中企業だったころだから、会社名はつけれなかったかも? なにせ、むかしのMSは営業力で伸びていったのだから、社名は出さない方が良かった
coolの略だよ
391 :
383 :2009/05/23(土) 17:48:01
392 :
377 :2009/05/23(土) 17:59:46
わかりました ありがとうございました 全角空白あるとエラー起こすんですね
>>391 それを言ったらコンパイルはc1、c2だろう。
今はdllだけど昔はexeだった。
>>388 masmは以前はmasm.exeだよ。
むしろcl.exeにあわせる為にml.exeに変更された。
masmとlinkを実行するドライバとしてだったと思う。
C言語の勉強法で悩んでいます。 入門本を2冊読んで基本はだいたい分かったのですが、いざ何かを作ろうと思っても何も手が進みません。 サンプルプログラムの本をAmazonで探してみましたが、JavaやRubyなどはたくさんあるのですがCは何故か全然見つかりません。 独学で勉強してる人は、入門本以降どのように勉強してるのですか?
コンソールじゃなんにも作れないのは当然だろw ちょっとしたデータの一覧表を出力出来る程度。 アプリケーション開発したいならAPIとかに移れ ゲームならなんかのライブラリ使え、OpenGLとかオススメだけど難しいかもしれん。 どっちにせよコンソールで関数ポインタとかぐらいまで使いこなせないと、開発は難しいと思う。
C++に移ってboostなどを学ぶのも良いかと。 いずれにせよ先はめっちゃくちゃ険しいけど、熱意を持ち続けられればいけるよ! 上の言う通り関数ポインタとかまではまだ入門レベルだから頑張ってね。
>>394 同様にclもmsc.exeからっだった。
ではMSCの前身となったLatticeCはどうだったのだろうか。
>>395 入門書の次は基本的なデータ構造とかアルゴリズムの勉強とかかなぁ
数値計算とかデータ処理したいだけならべつにいらないけど
windowsとかで普段使ってるような文字だけじゃないアプリとかゲーム作るんだったらwindows APIでぐぐるといい
401 :
デフォルトの名無しさん :2009/05/23(土) 23:02:55
数値計算とかデータ処理にデータ構造とかアルゴリズムがいらないって どういう世界だよ
<p>〜勉強とかかなぁ</p> <p>〜べつにいらないけど windowsとかで〜</p> ということでは?
>>395 データ構造・アルゴリズムとか。
あと自分で何かを作ろうとするのもいいですね。お題が見つからないのなら宿題スレはいかが?
405 :
345 :2009/05/24(日) 01:12:52
>>358 書き込み遅くなりました。
>1.どういう手順でその関数を呼び出すのか分からない
(例.特定アドレスに送信内容を設定した後、送信用の関数を呼び出す)
送信関数は転送用バッファにデータを入れ引数にセットすればよいです。
特に難しいことは考えなくてよいです。
>2.printf の結果について最大サイズの計算は可能か
すいません。質問の意味が理解できなかったです。
>3.メモリ使用量の制限があるのかどうか
Winプログラムなんで気にしなくてよいです。
ただありとあらゆるところから呼ばれるので、
処理速度を気にしてます。
やっぱり、固定ではmemcpyで処理したあと、引数で渡ってくる(printf(*format...))文字データは
一文字ずつ格納していくしかないのでしょうか?
考えたんですがそれしか思い浮かばなかったです。
C言語の授業で、「ブロック変数とは何か調べる.また,atuo変数と異なることを示す検証用のコードを書け」という課題が出ました。 まずブロック変数とは何か教えてください! ググっても、ヤフー見ても、具体的な単語の説明がなかったので困っています。
ブロック {} ブロック変数 {int a;} まあauto変数もブロック変数なんだけど。
>>406 #include<stdio.h>
int main(void){
int atuo=5;
printf("%d\n", atuo);
{
int atuo=100;
printf("%d\n", atuo);
atuo+=10;
printf("%d\n", atuo);
}
printf("%d\n", atuo);
return 0;
}
>>405 転送用の関数について
1.関数プロトタイプを書いてくれ
2.関数を呼び出す手順があるなら書いてくれ
例えば "ABC" という3文字の固定文字列を転送するだけのサンプルを
示してくれれば多分回答可能
エンディアンを気にする必要があるのって通信とファイル操作のときだけですか?
インディアン嘘付かない
>>411 union使うときも気にする必要があるかもしれない
下記のプログラムは実験用なので、入力範囲など、細かなチェックは、なしでいいのですがVS2005だと、こんな感じでscanfは正常に数値を入力できるのですが array[1]:1 array[2]:2 array[3]:3 gcc-4.4.0だと、 要素数:3 昇順に入力してください。 array[0]:1 array[0]:2 array[0]:3 となってしまします、何処がおかしいのか、教えてくださいませ。文字型%sで受けて、整数型にキャストするのが吉なのでしょうか? ↓コードの一部です
>>414 より
#include <stdio.h>
#include <stdlib.h>
int main(void) {
int num, key, idx, i;
int *array;
printf("要素数:");
scanf("%d", &num);
array = (int *)malloc(sizeof(int) * num); // 要素数numの配列
if(array == NULL) {
printf("メモリの確保に失敗しました。\n");
exit (0);
}
printf("昇順に入力してください。\n");
for (i = 0; i < num; i++) {
do {
printf("array[%d]:", i);
scanf("%d", &array[i]);
} while (array[i] < array[i - 1]); // 前の入力値より小さければ再入力
}
printf("探す値:"); // キー値の読込み
scanf("%d", &key);
idx = binSearch(array, num, key); // 配列xから値がkeyの要素を探索 if (idx == -1)
printf("その値の要素は存在しません。\n");
else
printf("その値はarray[%d]にあります。\n", idx);
free(array);
return 0;
}
for(i = 0, ・・・ ・・・ array[i - 1]);
OCRで文字読み取って、自動でコード生成するプログラムだれか作って
失せろゴミ
422 :
デフォルトの名無しさん :2009/05/24(日) 14:36:10
unsigned int i; i = 1U<<30; と i = 0x40000000; とどちらがスピードが早いのですか?
同じ
実測してくれ
これはさすがに実測する必要ないだろ。
コンパイルする速度だったら実測する価値があるかも
どっちが読みやすいかだな 大抵は上の方だから上で書く習慣にしておけばいいと思うけど
初期化するときみたいに{}で作る配列を関数の引数にしたいんですけどどうやればいいんでしょうか? int foo(int *p, int len){・・・;}; foo({1, 2, 3}, 3); こんな感じで使いたいんですけど、うまくいきません
ある環境でどっちかが速かったとしても 別の環境がどうなるかは分からない 結論:好きにしろ
>>429 C99でいいならできるけど
どうやるか忘れたw
>>429 gccなどC99対応コンパイラなら、foo((int[]){1, 2, 3}, 3);と書ける。
vc++でやってみましたができませんでした あきらめてgccを使いますね・・・
>>429 {
int bar[]={1,2,3};
foo(bar, 3);
}
副作用、副作用完了点について教えてください a[i] =i++;は使うなということくらいしかわかりません K&Rのp66の説明にある 関数呼び出しはたぶんcdeclとか呼び出し規約によって結果が異なると理解しています 入れ子になった代入文とはどんなものでしょうか? よろしくお願いします
>>435 後置インクリメント演算子++の働きについて考えてみるとよい
++ は適用されたオブジェクトの元の値を返し、オブジェクトの
値を +1 するという事はわかるよね
しかし、【いつ】オブジェクトの値を +1 するかという事になると、
副作用完了点の直前、としか定義されていない
つまり、a[i]を評価してから +1 するのか、 i++を評価してから +1
するのかどちらかなのかは、この式を見ただけでは判断できない
コンパイラのみぞ知るなわけ
C89より前ではこの振る舞いをunspecifiedとしていたが、C89では
undefined、つまり未定義とした
つまり鼻から悪魔
>>435 さらに関数呼び出しの引数の評価順については、関数呼び出しは
特別なケースになっていて、func(a, b, c) とあったらこの中の ',' は
カンマ演算子ではなく、単なる引数のセパレータとして働く
もちろん func (a, (b, c), d) とあった場合の (b, c) はカンマ演算子
である
C89では関数の呼び出しに際して各引数の評価順は右から左でも
左から右でもないとしている
つまりどのような順番で評価されるかわからない
a b c かもしれないし a c b かもしれないし b c a かもしれない
だから評価順に依存したプログラムを書いてはいけない
関数呼び出しに関しては副作用完了点は関数を実際に呼び出す
タイミングの直前にすべての引数の評価が終わっているという事になる
まあ、規格を杓子定規に読むとそうなるが 実際にはfunc(a, b, c)をa,b,c以外の順番で評価するような悪趣味なコンパイラはまず存在しない 評価順をそう仮定して依存したコードを書いても、問題になるようなことは普通はありえない 安心して依存するといい
自分で確かめたわけじゃないが VC++はDebugとReleaseで評価順が変わることがあるって記事を見たことあるぞ
てゆーかものすごい素直な実装だったところで、 むしろ c, b, aの順になりそうなもんだけど
>>438 >実際にはfunc(a, b, c)をa,b,c以外の順番で評価するような悪趣味なコンパイラはまず存在しない
はあ?
お前の足りない知識においてはそうなのかもしれないが・・・
>評価順をそう仮定して依存したコードを書いても、問題になるようなことは普通はありえない
そんなコードを回してきたヤツが居たら
もうそいつは信用できないと思うのは俺だけではないだろう。
とりあえず 分けてかけ その程度省略してなんになる。 今の時代はマネージドとかいってるんだぞ Cであっても安パイなコード書け
なにそれ規格信者こわい
>>445 規格を理解出来ないヤツは間違いなく無能。
>>446 だよな
コンピューター開発なんて規格との戦いだろ
いい加減文字コード統一しろ
エンディアンも統一しろ
世の中のコンパイラが全て規格通りに出来てるわけでもあるまいに
規格なんて法律じゃないし、絶対でもない
>>443 みたいな、そんなことで人の信用を決めつける奴の方が現場では迷惑
>>448 C/C++の世界ではお前が法律じゃない
規格票だけが唯一の法律だ
ほんと、無能ほど「現場」って単語が大好きなんだよな。 「自分が低能だからドカタになった」ことだけが唯一のよりどころ。
>実際にはfunc(a, b, c)をa,b,c以外の順番で評価するような悪趣味なコンパイラはまず存在しない これが現場の常識ですか。 ほんっと、世界が狭いですねぇ。
納期が迫ってるときに、根性の曲がった変態コンパイラの影に怯えて しょうもない冗長コードを書いて仕事を遅らせる奴なんていらないんですよ 世の中のありとあらゆるマイナーコンパイラで通るコードを書いた所で自慢になんかならないんですよ 規格厨はこれだから
>>453 遅れるほどの手間かよw
1行で書くところをせいぜい数行増えるだけだろ
455 :
443 :2009/05/24(日) 18:33:12
>>448 >そんなことで人の信用を決めつける奴の方が現場では迷惑
まわりもお前みたいなヤツばっかなら
まあ問題ないだろう。
そしてお前の会社(仕事くらいあるよな?)が倒産した時、
もう一度俺の書き込みを読んでくれ。
それをありとあらゆる関数呼び出しでやってたらどうなると思ってるんだ 実装したことないのかよ 想像力を働かせろ
int cdecl func(int,int,int); int a(),b(),c(); func(a(),b(),c()) で最初に呼ばれる関数はc()でおk?
>>453 はx86用コンパイラすべてを変態と仰せになった。
>>457 違う
最初に「積まれる」値がc()の戻り値にすぎない
>>453 納期迫る前に書いておけよ
てかコンパイラ沢山しっているようでございますが,
確認できているコンパイラは何十個そんざいしますか?
関数の引数に関数呼び出し文を直接書く場合で、引数設定値を作る 為の関数呼び出しがランダムな順序で発生することに依存したコーディング は正しい?
はいはいわかったよ 皆さんは好きなだけ時間をかけて完璧な規格超準拠コードを書いてて下さい そんな顔真っ赤にして反論しなくたって、俺は止めないから ただ、引数の呼び出し順が違うかもなんて意識したことはないし、 それで問題が起こった事なんて一度もないから、無駄な努力だと思うよーってだけ。俺はね
>>462 そうでございますが
当社としては動かないコードを安全だと豪語される方にはお引取り願わせていただいております
このやり取りも久しぶりだねぇ
>>463 一応お伝えしておきますが、安全性はテストによって保証するものであって、
規格に準拠してるかどうかなんてのはコードの安全性と関係ありませんよ
>>465 テストできないから安全だっつってるよーn…いやそうでもないか
>>465 え?品質チェックとかしてるの?
信じられないなぁw
>>431 先に<windows.h>インクルードしてみたらどう?
469 :
468 :2009/05/24(日) 19:17:38
すまん誤爆したOTL
windows.h が c99対応したのかとビビッタw
>>462 そりゃプログラム書いたことのないやつはそんなこと意識しないわな。
472 :
443 :2009/05/24(日) 21:51:58
>>462 のような低能&低脳の場合、
「現場では○○」
っていうと
自身の程度の低さの免罪符になるとカンチガイしているんだよね。
ま、お前の会社倒産寸前だろうけど、
せいぜい楽しくやりなよ。
w
正しくは、低脳&底辺だな
ちょっと質問させてください。 大域変数や関数をstaticにするとどのような効果があるのでしょうか?
ファイル内スコープになる
477 :
435 :2009/05/24(日) 23:09:24
レスが交錯して混乱しています インクリメントは式の中でいつ評価されるかわからない、 引数内の関数もどの関数が最初に呼ばれるのかわからない ということでおkでしょうか? 入れ子になった代入文とはどのようなものでしょうか?
>>477 >>インクリメントは式の中でいつ評価されるかわからない、
C言語の規格では、未定義
つまり何が起きるかわからない。評価されないかもしれない。
>>引数内の関数もどの関数が最初に呼ばれるのかわからない
C言語の規格で、不定
つまり順序は仕様上決められていない。分からないというのは
正しいけど、言いすぎな感じ
>>478 >C言語の規格では、未定義
>つまり何が起きるかわからない。評価されないかもしれない。
アフォ?
i=0; a[i]=i++; これはiが1になるかどうかすらも未定義って話だろ? 規格の上ではその通りだよ 実際上はiが1にならないコンパイラなんてまず存在しないが
>>481 ちょっと待った
俺のコンパイラでは2になるぞ
どのコンパイラ?
wahaha C++コンパイラだw
?
それはさておき、
>>481 で問題なのは i は式の評価後は必ず 1 に
なるが、果たしてa[0]にアクセスするのかa[1]にアクセスするのか
わからないという事だ
>>486 それは「不定」でしょ。そうじゃなくて今回の例は「未定義」だ。
>>486 未定義動作が1ヶ所でもあれば、プログラム中のありとあらゆる動作が未定義になる
>>489 世の中単純ループに見えるものが本当に単純なのかというところから
疑ってかかってみても遅くは無い。
>>490 本気でそう思ってる?
496 :
、 :2009/05/25(月) 10:50:34
教えてください。バッファに文字200文字のデータ格納する上でループで一文字ずつ格納していくのと、memcpyでサイズ100を2回とって格納するのとどちらが速いでしょうか? Windows、組み込み両方について教えて頂きたいです。また、両方の方法での懸念事項、他によい方法があれば教えて頂きたいです。
環境が違う以上実測比較するだけでは? 最適化で結局似たコードになってた なんてことも有りえるかもしれないがね
>>496 >バッファに文字200文字のデータ格納する
これってコピー元はすでに連続したエリアに文字データが入ってると思っていいのかな?
その辺がよくわからないのでなんともいえない。
状況がよくわからんが自分が作ってるプログラムで二通りの転送方法が
考えれるんだったら、
>>497 のいうように簡単な速度評価するプログラム
を用意して実測してみればいい。
で、私は別で質問。
最適なスレがよくわからないんですが、あれば誘導していただけると助かります。
皆さん開発してて、リビジョン管理とかどうされてますか?
500 :
498 :2009/05/25(月) 11:21:13
ありがとうございます。
VCでasm出力してみた。 -c -Ox -Fa 一文字ずつコピーした場合は、memcpy呼び出しになった。 memcpy呼び出しをした場合は、movsdに置き換わった。 ちょっと笑った。
>>501 先頭アドレスが8バイト境界かどうかで変りそうだね < movsd 使うかどうか
HOGE構造体を管理するポインタ配列の初期化について教えてください。 HOGE *hogelist[1000] = {NULL,}; こういう風に記述した場合に1000個全部NULLが入りますでしょうか?
てゆーか、()の省略は今時キザに思われるだけで、よーするにカッコワルイぞw HOGE *( hogelist[1000] )={NULL}; (hogelistは配列でありその要素はHOGEへのポインタである。)
見やすくなったとは思えないけどなw 自分の価値観を一般みたいに言うなよw
>>505 意味が変わってる。それは、配列へのポインタ。
508 :
503 :2009/05/25(月) 12:11:04
>>504 ありがとうございます。
>>505 ネットとかで見かける書き方は
>>503 の書き方が多かった気がします。
でも
>>505 のような書き方もできるんですね。勉強になりました。
ではちょっと別な質問なんですが
構造体のポインタではなく構造体の配列を初期化する場合は
HOGEの中はintが3つあると過程して
HOGE hogelist[1000] = { {0,1,0},};
とした場合1000個全部に0,1,0で初期化されるんでしょうか?
>>508 無理。
足りない初期化子は0で埋められる。
510 :
503 :2009/05/25(月) 12:14:47
>>509 なるほど
やはり初期化用関数とか作ってその中でfor文でまわすなどして
セットするしかないんですね。
>>508 さま
アンカーを使い、なおかつですます調で書く場合はですね、アンカーの後ろに
「さま」とか「くん」とか付けるとですね。
違和感が無くなって良いんじゃないかと思いますわ
>>503 >>504 >>505 みたいにかくと対等以下の呼び捨て見下し調であるというトーンは2chでは
既に形成されて久しいですわ
514 :
デフォルトの名無しさん :2009/05/25(月) 12:26:44
515 :
503 :2009/05/25(月) 12:42:18
>>511 さま
そのほうがいいですね。
さすがに「くん」もちょっとあれですし、「さま」もちょっと硬すぎる感じなので「さん」とか
くらいが丁度いいかもとか思いますがどうでしょうか?
>>515 たんへ
「さん」は男性の女性全体に対する敬語でしょ?目上の人に使う言葉で
2chじゃおかしいです。
たん がちょっと汚くていいとおもいまつ
519 :
4 :2009/05/25(月) 14:01:33
4さまブームはどこへ…
520 :
、 :2009/05/25(月) 19:27:38
教えて欲しいです。Windowsで標準出力で、printfがありますが、文字数制限ってありますか?MSDNを見たのですが特にのってなく。よろしくお願いします。 int printf(const char*format...);
ありません。確認中。
なんで文字数制限? そっちのほうが気になる。
どこの文字数?出力?
待て待て、質問はただのprintfじゃなく、windowsのprintfと限定されている つまりwindowsでは特有の制限がprintfにあるということだ
shortが2バイトでlongが4バイトじゃない環境って全体の何割ぐらいあるんですか?
死ね
質問なんですが c言語のfree関数でメモリを解放すれば タスクマネージャのメモリの使用量の数値は減少するのでしょうか?
処理系による
減少しないこともあるのですか。 ありがとうございます。
減少しないことのほうが多い
最初にメモリをたくさん確保して自分でマッピングするほうが速度が早いんですか?
>>531 標準のメモリ管理システムより高性能なものを作れれば。
>>534 デスクトップにbmp.hとbmp.cを保存する
次にCPadのアイコンにbmp.cをドロップ
おもむろにF9を殴打する
■C:\Users\ほにゃらら\Desktop> bcc32 bmp.c Borland C++ 5.5.1 for Win32 Copyright (c) 1993, 2000 Borland bmp.c: Turbo Incremental Link 5.00 Copyright (c) 1997, 2000 Borland Error: 外部シンボル '_main' が未解決(C:\BORLAND\BCC55\LIB\C0X32.OBJ が参照) って言われました。
>>536 test01.cとかtest02.cがあるだろ
test01.cとbmp.cを一緒にコンパイルするの。
>>537 一緒にコンパイルするには、どうすればいいですか?
bccわからん bcc32 test0.c bmp.c ってコマンド欄にいれてみたら?
>>539 C:\Users\ (省略) >bcc32 test0.c bmp.c
Borland C++ 5.5.1 for Win32 Copyright (c) 1993, 2000 Borland
test0.c:
エラー E2140 test0.c 22: ここでは宣言はできない(関数 main )
警告 W8070 test0.c 111: 関数は値を返すべき(関数 main )
警告 W8057 test0.c 111: パラメータ 'argc' は一度も使用されない(関数 main )
*** 1 errors in Compile ***
bmp.c:
ってなりました。
542 :
デフォルトの名無しさん :2009/05/26(火) 00:21:06
C言語わかる?
>>540 ええと。そうじゃないな。
自分で書いたソースファイルと、bmp.c とを一緒にコンパイルするんだ。
で、自分で書いたソースファイルでは bmp.h をインクルードすれば、bmp.h で宣言されている関数とかを呼び出せる。
付属品のtest0.cとtest1.cは、なんかポンコツな文法で書かれてるからコンパイル通らなくても気にしない。
(てか、bmp.cを見てないんだがこっちは大丈夫なのかなぁ)
test0.c、これCでコンパイルできるわけがない 22行目で宣言があるこいつを16行目にカット&ペーストすればおk しっかしこんな奴に教えられる学生がかわいそうだ 静岡大学がんばれ!
C99 だと main(int argc, char** argv) { が通らない。 戻り値の型が暗黙で int ってのは、C99では禁止されたからね。 だからポンコツと言ったのだ。どの規格でも通らないコードだ。
>>544 「自分で書いたソースファイルと、bmp.c とを一緒にコンパイル」する仕方がわかりません…
なんかtest0.cがポンコツらしいので、 #include <stdio.h> #include "bmp.h" void main() { img im; im.height = 256; im.width = 256; for(int y=0 ; y<256 ; y++){ for(int x=0 ; x<256 ; x++){ im.data[y][x].r = x; im.data[y][x].g = x; im.data[y][x].b = x; } } WriteBmp("w2b.bmp" , &im); } ↑こんなソース(w2b.cpp)作ってみた。
わざとへっぽこなコード書いて、学生に自習を促してるんだよ
void mainはないだろうさすがに
552 :
534 :2009/05/26(火) 00:36:50
>>551 mainに特に返してほしいものないから、いつもvoid mainでやってました…
>>548 bccの操作方法について聞きたいなら、俺はよく知らんけど
>>539 な感じでいいと思う。
あと、「一緒にコンパイル」てのは実は不正確な言い方で、厳密にいうと、
それぞれコンパイルしてからリンクするんだけどね。
このへんの知識があやふやなら、改めて聞いてほしい。
554 :
534 :2009/05/26(火) 00:41:13
>>553 「コンパイルしてからリンク」がわかりません。
bcc32を浸かったらobjてのができるじゃん、これがコンパイル この1つ以上のobjをくっつけてexeにするのがリンク
>>554 「分割コンパイル」といって、プログラムを作成するときに
ソースファイル(拡張子が c のファイル)を複数作成し、それぞれを個別にコンパイルした後で、
個々のコンパイル結果をまとめあげる(リンク)、という手法がとられることがある。
今回は、bmp.c を道具として利用するための、自分で書いたソースファイルがあるはずだ。
あるいは、
>>549 でもいい。
こういうソースと、bmp.c とを、それぞれ個別にコンパイルした後で、リンクすることによって、
まとまった1つのプログラムを得ることが出来る。
557 :
556 :2009/05/26(火) 00:47:51
まあ
>>539 みたいに書けば、勝手にリンクまで面倒みてくれるのが普通。
>>536 で言ってるのは、bmp.c のコンパイルには成功したものの、リンク時に失敗している。
プログラムを最終的に組み上げるときに、main関数がないからおかしいよ?って言ってるわけ。
558 :
534 :2009/05/26(火) 00:58:45
559 :
534 :2009/05/26(火) 01:28:14
でも、リンクの仕方がわからない…
CPadスレで(どこにあるのか知らんが)聞いたほうが良いのではないか。
CPad使わずに、bcc直接使った方がわかりやすいかも。
562 :
534 :2009/05/26(火) 01:46:10
>>561 それじゃ、リンクする時はbcc直接使うことにする。
bccだと、どういう風にリンクしますか?
リンクは勝手にやってくれる。
>>536 でも勝手にリンカを走らせて、リンクエラーを報告してくれてるわけでしょ。
普通は、「コンパイルのみ実行してリンクは行わない」という指示を出さない限り、リンクしてくれる。
564 :
534 :2009/05/26(火) 01:54:21
同じフォルダに
bmp.c
bmp.h
w2b.cpp(
>>549 の)
を入れて、bmp.cとw2b.cppをコンパイルして
bmp.obj
w2b.obj
が作られて、
その後どうすればいいですか?
よく知らないが、たぶん bcc32 bmp.obj w2b.obj でいけるかなぁと思う。 bccの使い方については、ここにいる人間もみんなが知っているわけじゃないから、 適当にぐぐるか、bccを知ってそうな人のところに行くか、 もしくはもっと多くの人が使ってそうなコンパイラに乗り換えるか(VCとか)がいいと思う。
566 :
534 :2009/05/26(火) 02:05:58
>>565 実行したら、
C:\Users\***>bcc32 bmp.obj w2b.obj
Borland C++ 5.5.1 for Win32 Copyright (c) 1993, 2000 Borland
Turbo Incremental Link 5.00 Copyright (c) 1997, 2000 Borland
Error: 外部シンボル 'WriteBmp(char *, img *)' が未解決(C:\USERS\***\W2B.OBJ が参照)
ってなりました。
C言語でいろいろやってるけど、CPadしか使ったことないから、
他のはよくわからないんだよなぁ
VCとかでも、CPadと同じプログラム書いてきちんと動作する?
というより、bccのマニュアルに書いてあるはず。
>>566 リンク自体の実行はできてるっぽいが……ちょっとbmp.cの中身を確かめてみるから待ってて。
ilink32 ,myexe.exe bmp.obj w2b.obj じゃね?
570 :
568 :2009/05/26(火) 02:09:39
bccに詳しそうな人が来たので、後は
>>569 さんの指示に従ってみてください。
bcc32 -ebmp.exe bmp.obj w2b.obj かな。 うまく行かなかったら.objを作り直してためしてみるとか。
572 :
534 :2009/05/26(火) 02:10:37
>>569 C:\Users\***>ilink32 ,myexe.exe bmp.obj w2b.obj
Turbo Incremental Link 5.00 Copyright (c) 1997, 2000 Borland
Fatal: 余分な EXE ファイル名が指定された : bmp.obj
こうなりました。
573 :
534 :2009/05/26(火) 02:12:18
>>571 C:\Users\admin\Desktop\taku\programing_original\bitmap_cpp>bcc32 -e bmp.exe bmp.
obj w2b.obj
Borland C++ 5.5.1 for Win32 Copyright (c) 1993, 2000 Borland
エラー E2194: ファイル 'bmp.exe' が見つからない
一応objは一度作り直してみました。
ごめん(´・ω・`)ゝ” ilink32 bmp.obj w2b.obj ,myexe.exe か でもbcc32.exe からやっても同じみたいだね
575 :
534 :2009/05/26(火) 02:13:55
\(^0^)/
576 :
534 :2009/05/26(火) 02:14:59
>>574 エラーは出なかったけど、w2b.bmpは作成されてないですね
>>573 -e bmp.exe と余分なスペースを入れるからだよ
-ebmp.exe としる
578 :
534 :2009/05/26(火) 02:18:00
>>576 えーと、プログラミングってどういうものかわかってる?
>>570 それでいいんだよ
プログラムbmp.cに誤りがあるって事だ
581 :
534 :2009/05/26(火) 02:21:44
>>579 よくわかってないかも…
ちなみに、myexe.exe実行してみたら、
C:\***\myexe.exeは有効な Win32 アプリケーションではありません。
ってエラーが出た。
>>581 そりゃそうだろ
リンクエラー起きてるんだからまともなexeが出来てるはずがない
しかしこのソースひでえな エディタで開くと改行がスペースに軒並み化けやがって unixのviでも使って編集したろ まあCコンパイラはこのようなソースでもちゃんと認識して コンパイルできるが、人間が読むと可読性が著しく損なわれる
584 :
534 :2009/05/26(火) 02:30:31
>>582 それじゃやっぱ、bmp.cが悪いって事?
>>583 そりゃそうだ。
コンパイラにgcc使ってるんだから。
あーわかった CとC++混同してるでしょ だから Error: 外部シンボル 'WriteBmp(char *, img *)' が未解決(C:\USERS\***\W2B.OBJ が参照) なんてエラーが出るんだよ #include <stdio.h> #include "bmp.h" void main() { img im; im.height = 256; im.width = 256; for(int y=0 ; y<256 ; y++){ for(int x=0 ; x<256 ; x++){ im.data[y][x].r = x; im.data[y][x].g = x; im.data[y][x].b = x; } } WriteBmp("w2b.bmp" , &im); } これを w2b.cpp でなくて w2b.c と名前をつけて保存してコンパイルしろ なんでかって言うとC/C++ではexternの意味が違っているからだ それと名前マングリングが起きてる どうしてもcppでやりたいなら extern "C" で囲まないといけないが 今は面倒なので.cで保存してみろ
587 :
534 :2009/05/26(火) 02:46:06
cで保存して、コンパイルして、 ilink32 bmp.obj w2b.obj ,myexe.exe したけど、やっぱ「有効な Win32 アプリケーションではありません。」ってエラー。 bcc32 -ebmp.exe bmp.obj w2b.obj をしてみたら、 C:\***>bcc32 -ebmp.exe bmp.obj w2b.obj Borland C++ 5.5.1 for Win32 Copyright (c) 1993, 2000 Borland Turbo Incremental Link 5.00 Copyright (c) 1997, 2000 Borland Warning: パブリックシンボル _Bmp_headbuf がモジュール C:\***\BMP.OBJ と C:\***\W2B.OBJ の両方に定義されている Warning: パブリックシンボル _Bmp_Pallet がモジュール C:\***\BMP.OBJ と C:\***\W2B.OBJ の両方に定義されている (以下、Warningがいっぱい) ってなって、一応bmp.exeができたので実行したら、強制終了になる。
>>587 よしよしいい所まできたぞ
あとは bmp.h のバグを取るだけだ
_Bmp_headbufは配列で bmp.h で定義されている
宣言でなくて定義だ
だから名前がかち合ってリンカエラーが出る
こういう場合はインクルードガードを使ってどちらか一方だけで
定義されるようにし、もう一方では extern によって宣言するだけに
しなければならない
要するに bmp.h を書いた奴はアホだという事です
589 :
534 :2009/05/26(火) 02:57:43
インクルードガードとかexternとか、初めて聞く言葉だ
インクルードガードは違うだろ。
>>590 厳密にはそうだな
"One definition rule"に従って欲しいのだ
同じ名前の配列が複数あると、どれを取ればいいのかリンカが
悩んでエラーを吐くわけだから、それを解決してやればよい
あとはわかるな
俺そろそろ寝る
592 :
534 :2009/05/26(火) 03:04:46
んーextern使わないと今回の問題は解決できないよ 要するにどのファイルからも bmp.h をインクルードしてて、 bmp.h の中で配列とか変数を定義してるので、同じ配列 や変数がかち合ってエラーが出るわけだ したがって例えば bmp.h をインクルードする前に my.h などを インクルードするようにし、my.h の中に #define DEFINITION 1 とか書いて、その時だけ配列や変数が定義されるように bmp.hを 書き換える 次に my.h をインクルードしない時は代わりに extern に置き換わる ようにしてやる マクロの仕事だ まずは extern については勉強が必要
594 :
534 :2009/05/26(火) 03:19:27
>>593 そうなのか…なんか大変そうだ…
とりあえず、bmp.hを#ifndefとかで囲んで
かちあってたのの頭にexternつけて、
bcc32 -e〜でコンパイルしたら、
Warningはなくなったけど、
_Bmp_info_sizeとかが、外部シンボルが未解決になった
途中からあんまり見てないけど 大変なことになってる理由は、その bmp.h 自体がポンコツだからだよな。 もっとまともなライブラリを使えば、こんな苦労はしなくて済むのだ。 とはいえ、まともなライブラリを探すのも面倒だろうし、俺もちょっと今から詳しく見てアドバイスしてみるよ。
ビットマップといえど仕様を理解して一から実装するとなると割と面倒だからなあ。 でも、それくらいは理解できないと正直なところ辛いと思うよ。
とりあえず、俺が正当だと思う方法は bmp.h の中で変数を定義している箇所 (unsigned char Bmp_headbuf[HEADERSIZE]; 〜 long Bmp_yppm;) を、bmp.c にコピペする。 そして、bmp.h の中のその部分は、すべて変数の宣言へ書き換える。 unsigned long Bmp_size; → extern unsigned long Bmp_size; char Bmp_type[2]; → extern char Bmp_type[]; など。 これでいけるはず。テストしてないけど。
いかん、自分の環境でやってみたら動かん。もうちょっと詳しく見ないとだめか。なんか見落としてるかなぁ
あ、分かった。img 型がでかすぎるんだ。 img型のサイズが大きすぎて、スタック上に自動変数として置こうとするとスタックオーバーフローで落ちるっぽい。 思いっきり環境依存な話っぽいが。少なくとも俺の環境ではそんな感じだ。
すげー作りだな。
>>534 のHPの最下部にある参考文献のところのように
ヘッダ部分を見やすくするための構造体がbmp.hにはいってるんだろうなと
思ったら変数がそのまんま定義されてやんの。
そりゃbmp.hを取り込んだソースで競合がおきるわな。
>>599 つくりが悪すぎる
固定サイズでピクセル情報部分を持ってる
typedef struct {
long height;
long width;
color data[MAXHEIGHT][MAXWIDTH];
} img;
#define MAXWIDTH 1000 /* 幅(pixel)の上限 */
#define MAXHEIGHT 1000 /* 高さ(pixel) の上限 */
これだけでも糞だよ
ヘッダ関連の情報もなんで構造体で管理せずにこんなことしてるのかもわからねーし
というわけで、「exeファイルは出来たが実行時に強制終了してしまう」の原因はたぶん
>>599 なので、
手っ取り早い解決策は bmp.hの MAXWIDTH と MAXHEIGHT の数字を小さくすること。
両方とも500くらいにすればよかろう。他のところをいじらなくても、俺の環境ではこれで問題なく動作した。
ただ、もちろんこれだと巨大な画像が扱えなくて困るだろうから、別の解決策としては
スタック上ではなくヒープに確保することだな。(mallocを使うということだ)
まあ、根本的な解決策は「もっとまともなライブラリを探せ、もしくは作れ」かなぁ。 車輪の再発明は良くないが、不良品の車輪を使うのは面倒だ。 特に、知識や経験の少ない人にとってはね。
で、質問者が初心者ぽいので注意点を置いておくと typedef struct tagBITMAPFILEHEADER { unsigned short bfType; unsigned long bfSize; unsigned short bfReserved1; unsigned short bfReserved2; unsigned long bfOffBits; } BITMAPFILEHEADER これがそのままだとおそらくアライメントの関係でそのままでずれるからそこだけ注意
>これがそのままだとおそらくアライメントの関係でそのままでずれるからそこだけ注意 これがそのままだとおそらくアライメントの関係でbfSizeの開始位置が2バイトずれるから
そういえば、俺も便乗で質問していい? bmp.h にグローバル変数の定義(宣言ではなく)を書いて、それが複数の翻訳単位でインクルードされちゃってると、 定義が複数あるからまずいんだよね? でも、それを g++ で処理したら多重定義エラーになるが、gcc で処理したらエラーにならずに ちゃんと動く実行ファイルが出来上がっちゃったんだ。 俺、普段はC++を使ってるからC自体は実はよく知らないんだが、これCだと認められちゃったりするの?
>>607 bmp.hを取り込んだソースのうち片方は使ってないんじゃないの?
なんでわざわざヘッダに入れたかわからないbmpヘッダに関連する変数を
>>607 CとC++は変数の定義ルールが異なる
デフォルトでスコープはローカル
bmpのバージョン関係なしにヘッダサイズきめうちか テスト用のプログラム載せるなよ
>>610 大学と個人の名前でてるけど教授か何かか?
こんな程度のプログラムしかできないのが偉そうにHPに公開しててOKなんだな
なんでここまで盛り上がってるんだよ・・・
>>613 よくあること
未定義とかその手はよく伸びます
逆に本気で高度な話だと伸びません
>>609 違うだろ
C++でデフォルトでローカルスコープなのはconst変数だけだよ
>>617 すごい端的にいうと
float型に0.1を入れると実際には
0.09999999..... に近い形になってる, つまり微妙に誤差がある
620 :
617 :2009/05/26(火) 16:19:48
指数部と仮数部がdoubleに比べて少ないって事でしょうか。
>>619 誤解を招きそうだ
doubleにも誤差はあるからね
floatの有効桁数がせいぜい7桁(10進で)ってこと
623 :
デフォルトの名無しさん :2009/05/26(火) 22:19:03
void main() { int count; double s=0; for (count = 0; count < 10; count++) { s=s+(1/2/10+count/10)*(1/2/10+count/10)/10; printf( "sは今%fです\n", s ); } } y=x^2のグラフを0から1まで積分したいんだけど すべてs=0.000000になります なぜ?
>>623 1/2/10は0だし、countが10未満ならcount/10も0
626 :
デフォルトの名無しさん :2009/05/26(火) 22:36:32
1/10=0.1ではないのですね
>>617 に関してなんですが、
浮動小数点はdoubleで事足りるのにfloatがあるの?
昔のショボいコンピュータの名残
いやいやw 組み込み系だとdoubleは遅いよ doubleでも速度が落ちないプロセッサばかりじゃないので
x86でもdoubleのほうがfloatより遅いことがる不思議について
最近のプロセッサはゲームや動画などのマルチメディア用途に最適化されてるんで、floatの方が確実に速いことが多いね。
>>629 使い分けを知らんとは、あんたド素人だな?
fgets(&wrd[][],MAXCHR_W,fp) として,文字列を読み込みたいんですがwrd[][]の括弧の中の記述をどうしたらよいかわかりません。 wrd[0][0]が,txtファイルの1行目1文字目,wrd[0][1]を1行目2文字目という形を取りたいんです。 最終的には,wrdで読み取った最後の改行部分にNULLを代入したいのですが。 どうやったら良いかご教授願えませんでしょうか。 素人な質問で申し訳ないです…。
そんなことできんから、一行ごとに読め
>>634 望んだ仕様になるXXXfgets関数を作れば良いだろう
>>634 です
関数は既存の規定されているfgetsで読み込み,後にASCIIコード順にソートを行う
ということで文字列の最後はNULLにして,上記の形を用いるように指定されているので…。
課題なんで,指定以外の形をとるわけにもいきませんし…
はああ?
>>634 です,すいません自己解決しました。
ご迷惑おかけいたしました。
#include <stdio.h> #include <string.h> #define MAXCHR_W (100) #define MAXCHR_L (10) void main() { FILE *fp; int i,n; char word[MAXCHR_L][MAXCHR_W]; fp=fopen("test.txt","rt"); for(i=0; i<MAXCHR_L; i++) { fgets(word[i],MAXCHR_W,fp); if(feof(fp)!=0) break; } fclose(fp); n=strlen(word[i]); word[i][n]=NULL; } ほらよ
釣りはいらん
642 :
デフォルトの名無しさん :2009/05/27(水) 12:27:14
学生でやった以来ひさしぶりにC言語やるんですが おすすめのエディタとかありますか?
>>642 VS2005かVS2008の無料のやつ
もしくは秀丸
秀丸って、どういうところがいいの?
フリーウェアじゃないところ。 (フリーウェアは原則使用禁止な会社は存在する)
そういう会社ってビールウェアとかワインウェアだったらOKでるのかなw
会社が経費出すんだろうし、ビールを数十杯提供するのかなw
648 :
デフォルトの名無しさん :2009/05/27(水) 14:26:40
1 #include <stdio.h> 2 #include <math.h> 3 4 int g_data; 5 6 double Get3integerAverage(int a,int b,int c); 7 double Get3integerAverage2(int a,int b,int c); 8 9 int main(void){ 10 double ave; 11 double ave2; 12 int a = 5; 13 int b = 10; 14 int c = 15; 15 static int p; 16 printf("address of main:%p\n",main); 17 printf("address of Get3integerAverage:%p\n",Get3integerAverage); 18 printf("address of Get3integerAverage2:%p\n",Get3integerAverage2); 19 printf("address of \"HELLO\":%p\n","HELLO"); 20 21 printf("address of g_data:%p\n",&g_data); 22 printf("address of p:%p\n",&p); 23 24 25 printf("address of a:%p\n",&a); 26 printf("address of b:%p\n",&b); 27 printf("address of c:%p\n",&c); 28 printf("address of ave:%p\n",&ave); 29
649 :
デフォルトの名無しさん :2009/05/27(水) 14:30:37
30 ave = Get3integerAverage(a,b,c); 31 ave2 = Get3integerAverage2(a,b,c); 32 33 printf("ave:%f,ave2:%f\n",ave,ave2); 34 return 0; 35 } 36 37 double Get3integerAverage(int a,int b,int c){ 38 double ave_local; 39 printf("address of ave_local:%p\n",&ave_local); 40 41 ave_local = (double)(a+b+c) / 3.0; 42 return ave_local; 43 } 44 45 double Get3integerAverage2(int a,int b,int c){ 46 double ave_local2; 47 printf("address of ave_local2:%p\n",&ave_local2); 48 49 ave_local2 = pow((double)(a*b*c), (1.0 / 3.0)); 50 return ave_local2; 51 }
650 :
デフォルトの名無しさん :2009/05/27(水) 14:40:14
このプロログラムを gcc object.c -o object でコンパイルすると、 /tmp/ccolKUUr.o: In function `Get3integerAverage2': object.c:(.text+0x1be): undefined reference to `pow' collect2: ld はステータス 1 で終了しました となり、コンパイルすることができません。undefined reference to `pow'はpow が未定義という意味です。#include <math.h>で定義しているのにできません。 math.hファイルがおかしくなっていると思って他のプログラムをmath.のpow 関数を使ってプログラムを動かすと、ちゃんと動きました。 どなたか教えてくれないでしょうか?
┗-lm
653 :
デフォルトの名無しさん :2009/05/27(水) 14:50:54
>>651 >>652 回答有難うございます。
libm?
┗-lm?
どちらもよく分かりません。調べてみます。
math.hでインクルードする関数の実態が入ってるのがlmとかlibmとかいうのになってる makefileのlibを設定するところに -lm とか-libmとか書いてないので math.hので宣言されてる関数が無いとgccが怒ってる
実態じゃねえ実体
/) ///) /,.=゙''"/ / i f ,.r='"-‐'つ____ gcc object.c -o object -lm って言っときゃいいんだよ!! / / _,.-‐'~/⌒ ⌒\ / ,i ,二ニ⊃( ●). (●)\ / ノ il゙フ::::::⌒(__人__)⌒::::: \ ,イ「ト、 ,!,!| |r┬-| | / iトヾヽ_/ィ"\ `ー'´ /
657 :
デフォルトの名無しさん :2009/05/27(水) 15:01:16
>>654 そうですね。思い出しました!!
math.h関数を久しぶりに使うので忘れていました。
しかし
1 #include <stdio.h>
2 #include <math.h>
3
4 int main(void){
5 double a = pow(2.0,3.0);
6 printf("a = %lf\n",a);
7 }
は-lmをつけなくても動きます。不思議です。調べてみます。
658 :
デフォルトの名無しさん :2009/05/27(水) 15:08:02
リンクオブジェクトは libほにゃらら.so とか libほにゃらら.a というファイル名だ それをリンクするのに -lほにゃらら をつける libm.soをリンクするのが-lmになる
>>657 環境は同じ?
cygwinだと
>>648-649 のプログラムも-lm無しでコンパイル通ったよ。
(cygwin1.dllにpow()があるため)
2番目の引数が整数になおせるとlibmのは呼ばないみたいだな 最適化で消えるんだろうな
引数がリテラルだとコンパイル前に計算するんじゃない
gcc賢すぎる
そういうことなのか
665 :
デフォルトの名無しさん :2009/05/27(水) 15:56:01
専門用語で難しいのって「花電車」くらいだろ。
667 :
デフォルトの名無しさん :2009/05/27(水) 16:15:07
>>665 引数がリテラル(定数)であるとうまくいくわけではないようです。試しに
1 #include <stdio.h>
2 #include <math.h>
3
4 int main(void){
5 double a = pow(2,3.1);
6 printf("a = %lf\n",a);
7 }
をコンパイルしようとしたらできませんでした。
>>661 さんの意見が正しいようです。
しかしなぜ2番めの引数が整数だったらlimb.soをリンクしてなくていいのかが不思議です。
>>667 整数乗が確定してれば 単純に整数回の掛け算に置き換えられるからかもね
浮動小数乗の場合だと リテラル演算とはいえアルゴリズム経由しないとリテラル値にならないわけだし
>>667 整数だったら単純にループにおきかえれるとか?
右側が整数なら
左側を右の回数だけ乗算するループにおきかえれそうだし。
かぶった
671 :
デフォルトの名無しさん :2009/05/27(水) 16:37:35
>>668 >>669 なるほど。
話が変わるのですが
>>660 さんとは違いpow関数は僕の場合はlimb.soをリンクしないといけない。
引数が整数でも、整数ではなくてもpow関数を使っているわけですよね?
なのにlimb.soをリンクしなくてもいい場合があるのはなぜなんでしょうか?
だからpow()呼び出し自体が消えるんだって。 呼び出してないんだから当然リンクエラーも出ない。
>>671 環境の違いってことで あまり深く考えない
>>671 gccの最適化の中で関数を呼び出すまでも無く代替計算式におきかえれる場合は
pow関数を使わないのでリンクしない。そのためエラーにならない。
この辺の基準はgccのみぞ知るなんで、確実に把握したければ
条件を変えて自分で試すしかない。
675 :
デフォルトの名無しさん :2009/05/27(水) 16:44:27
>>672 powを呼び出していないのに階乗の計算をどうやってしているのでしょうか?
>>671 さんの言う通り現時点では深く考えないほうがいいのかもしれません。
pow()の使い方習う前に、n乗をループで求めるやり方とか普通ならわねーか?
>>675 pow(a, 3)
をコンパイラが最適化して
a * a * a
に置き換えてコンパイルしている
678 :
デフォルトの名無しさん :2009/05/27(水) 16:54:29
>>674 なるほど。
例えばpow(2,3)なら2 * 2 * 2,pow(0.1,3)なら0.1 * 0.1 * 0.1と置き換えられるから
powを呼んでいないという訳ですね。
答えてくださった皆さん有難うございました。
679 :
デフォルトの名無しさん :2009/05/27(水) 16:58:38
>>676 習いました。ただpowを呼ばない場合、
そのn乗をループさせるプログラムをどこから手に入れているのかを
疑問に思いましたが
>>677 さんの言う通りに最適化されていることを知りました。
680 :
デフォルトの名無しさん :2009/05/27(水) 21:25:05
プログラムを実行したら、どこかでメモリがもれてるようで、 使用メモリ量がどんどん上昇します メモリを確保してるのに開放していないところがあると思うのですが、 いったいどこで漏れている(開放し忘れている)か分かる方法ってありますか? 開発環境:VisualStudio2008 言語:C 知識:普通のプログラムを書いてCtrl+F5でデバッグ実行するくらいで他の知識はない よろしくお願いします。
F5でやればリークしたのがどれか表示されるだろう
>>681 すみません、F5を押してもプログラム自体は動くのでエラーが
出ることなく実行できてしまいます。
本当に知識がないのですが…ブレークポイントか言われるものをつかうのでしょうか?
>>682 地道に・・・
malllocで確保したヒープのアドレスとfreeしたアドレスをファイルにfprintfでダンプする。
ダンプした内容をチェックしてfreeもれがあるかどうか調べる。
>>680 余裕があればmalloc/freeのラッパ関数をつくってみるのも一興です。
685 :
682 :2009/05/27(水) 21:53:57
ダンプってなんですか?
>>685 「ダンプ」は不適切だったかな?
「ファイル出力」でいいです。
ダンプの意味はメモリーダンプでぐぐってくれ。
>>682 終了時に出力ウィンドウにいろいろ出るだろう
malloc(0)ってどんな動作すんの?
原因がわかりました …が解決方法がよく分かりません。 プログラム的には以下のようにdouble型の配列を返す関数になっています。 double *test() { double *data = (double*)calloc(size, sizeof(double)); ・ ・ ・ return (data); free(data); } これだと、returnしたあとfree()は実行されていないことが分かりました。 しかし、 free(data); return (data); と順番を入れ替えると、当然returnする前にdataが消えてしまいます きちんと値を返し、かつ最後にmallocしたdataをfreeするにはどうしたらいいのでしょうか?
>>689 testを呼び出した関数でfreeする。
>>689 どんだけ入門者なんだよw
と思ったらここは入門者スレだったか。
じゃあいいのか。
double *test() { double *data = (double*)calloc(size, sizeof(double)); ・ ・ ・ return (data); } int main() { double *a; a=test(); free(a); } こういうことでしょうか? みなさまありがとうございました。
この段階で一旦、Javaに手を出してみるのがもしかして ベターかと。 C/C++のmalloc/free(new/delete)問題はかなりやっかい。 一般論が無い。 Javaである程度の構造を持ったプログラムがかける ようになってからのステップでやるべきことで Javaの初歩よりずっと高度な話になってくるし。
>>688 環境による.malloc(2)を読め.
例えば*BSDなら,アクセスするとSEGVになる,サイズが0のオブジェクトへのポインタが返る.
>>693 リソースの確保と解放っていう意味では、大抵の言語で使われるテクニックだよ。
696 :
デフォルトの名無しさん :2009/05/27(水) 23:42:21
dllのファイル名って取得可能? dll内で何かの関数コールして、自分自身のファイル名を取得したい。 簡単に出来るかと思いきや、3時間調べてもわからんかった。 exeの名前なら簡単に取れるんだが。 Linuxのlib〜.soでも同じようにファイル名取得出来ると更に嬉しい。
>>696 GetModuleFilename
に DllMain で貰ってきたハンドルを渡す
698 :
デフォルトの名無しさん :2009/05/27(水) 23:53:33
>>697 ありがとう
やっぱりそれが一番手っ取り早い?
DllMain 使いたく無いんだが、何か良い方法ないかな。
後出しでスマン
どっちにしてもインスタンスのハンドルがいるだろう 複数のDLL使ってたらどのDLLかをどうやって特定するよ 列挙して全部出す手もあるけど、使いたくないというのが意味わからん
>>696 CでDllを書く限り、ソースコード直書き__FILE__(マクロ)に勝る方法は無いと思われ
そもそも .so のファイル名に依存した方法ってどうかと思う
>>693 >C/C++のmalloc/free(new/delete)問題はかなりやっかい。
>一般論が無い。
確かに。
仕事でやるなら先輩もしくは配属先でどういうルールにしてるか確認。
個人で作ってるプログラムなら自分で決める。
C/C++はコンパイルにおける最低限のルール以外は自由にあれこれできるの
がいい点であり大変な点でもある。
とはいえど数ある方法が個々の問題に最適に選択されているとまではとても言えない。 初期開発者のスキルやその場の状況や見込みで決まってしまっている部分も 大きい。だからこそ難しいわけ。
開発を引き継ぐ際などに関数の関連を把握したいのですが 皆さんはどのようなツールを使われてますか?
vim
あ・・・すみません windows上で動くツール限定としておくべきでした。
doxygen, graphvizで静的解析。 gprofなどのプロファイラで動的解析。 必要なら、vtuneでリアルタイム解析。
>>708 そういうのが可能な場合はおおよそなんとかなるんですが、
昨今はそうじゃないケースも多いわけでw
>>710 あ、それは今調べて自分に合いそうなのを探してますので^^
スルーしてるわけじゃないですよ
>707は、doxygen(w/graphviz)と書くべきだな。 gprofに言及するのもどうかと。
こういう書き方ってあるんすか? 教えてえろいひと。 char *hoge[] = { [5] = "baka", [11] = "aho", [100] = "nuko" }
>>714 今のCの規格ならできますよ。旧式のおんぼろコンパイラだと駄目かも。
>>716 おんぼろコンパイラとは何だ
VS2008がおんぼろだと言いたいのか
だいたいC99に100%対応しているコンパイラなんて
数えるほどしかないんだが
gccですら部分的対応だし
いんてるはいってる
>>718 言葉に気を付けろと言っているんだ
現実を見ろ
>>721 何がまあまあ落ち着いてだ
自分で怒らせておいて
自演乙
名前空間があれば完璧なんだが… 標準にならないかな…
無くても困らないという印象 名前の競合は、ネーミングルールで実用上困ったことはないし、 ローカルスコープ限定で同じ名前を使いたい場合も static で十分。 1ファイルに1関数、というような制限のあるプロジェクトだと staticじゃ不十分だろうけど
もうさ最近C99厨が増えて仕方ないので この際2ch有志でC99コンパイラ作れや
>>727 いやどす
というかプログラマ適正を見る際の初期の目安に最適じゃん
C99に固執するやつ->向いてねえ
ゆとりが年寄りをおんぼろと形容するのは 別におかしくないし貶してる事にはならんと思うぞ。
>>730 その例えはちょっとおかしいな
C99コンパイラが全盛ならその例えもわかる
だけど現存するC99完全準拠コンパイラなんて
本当に限られてるんだぜ
Intel C++とか
他にあんの?
C99完全対応のCコンパイラができて飛躍的に生産性があがるならいいよ。 でなければ無駄。 こんな見極めもできないゆとりがおんぼろ呼ばわりするな。
Cコンパイラだってソフトの一種だろ おんぼろとか言ってるやつは無理無茶をいうエンドユーザーと一緒だろ。 お金くれないけど機能追加だけいう痛いエンドユーザー。 こんなこともわからないやつは開発者にいらねえ
>>735 >お金くれないけど機能追加だけいう痛いエンドユーザー。
wwwww
C99にこだわるような奴はCに向いてない。 もっと高級なスクリプト言語でもやってろ。
俺はC99にこだわってはいないわけだが。使えるなら使いたいけど。 C89にこだわってる奴が痛くないか?
開発に使うコンパイラがC99対応してない 頭を切り替えてC89でコーディング->普通 頭を切り替えできずコンパイラをこき下ろす->開発者に向いてない それだけ
そうだな、こき下ろすべきはコンパイラじゃなくてコンパイラベンダーだよな。
CはC89=Ansii Cで完成したということだ C89以上のものを望むならC++で
引数の型が(int, int)、返り値の型がintであるような関数ポインタを返す関数のプロトタイプはどう書けばいいんでしょうか?
typedef int (*My_Type)(int , int); My_Type foo(); だね。1つにまとめるなら typedef int (*foo())(int , int);
744 :
743 :2009/05/30(土) 16:13:37
1つにまとめるなら int (*foo())(int , int); か
課題でないなら、絶対typedefすべきだよな。可読性のために。
このシンタックス考えた奴はアホだ。
こうか なるほど頭が混乱する #include <stdio.h> int f(int x, int y) { return x + y; } int (*func(void))(int x, int y) { return f; } int main(void) { printf("%d\n", (func())(1, 2)); return 0; }
748 :
743 :2009/05/30(土) 16:28:15
みなさんサンクスです 素直にtypedefしたほうが身のためのようですね
ていうか、
>>743 のtypedefはあまりわかり易くなってないよ。
typedef int myfn_t(int, int);
myfn_t *foo();
の方が読みやすい。
見た目で「関数へのポインタ」が出ないで
「何らかのポインタを返す関数」があって、その何らかが関数、という形だから。
見た目だけだけど。
C++のメンバ関数なら仕方ないけどね。
751 :
743 :2009/05/30(土) 23:15:42
>>750 別に俺は
わかりやすさのためにtypedefしたわけではなく
説明のためだったんだが。
まあとにかく
>>750 のが分かりやすいことには俺も同意するがね。
おいらは頭悪いので、複雑な宣言はまずPerlで書いてみる。 いきなりCじゃ書けない。 ターパスならこんな苦労しないのに
list[]と言う配列にある入っているデータを、0.5秒ごとに出力したいと思っています。 この場合、どうしたら良いのでしょうか?
757 :
デフォルトの名無しさん :2009/05/31(日) 17:54:32
>>754 まぁ標準Cでやるっていうなら
time.hにあるclock() の値を使って、
無限ループの中から0.5秒ごとに出力だね
環境によりますが、signal は使えませんか?
clockだとプロセスが使用したCPU時間であって、実時間じゃないばあいがあるんじゃね?
うん。標準Cでは実時間の一秒未満を計測する方法はない。
761 :
デフォルトの名無しさん :2009/05/31(日) 18:20:38
いやぁこんなこと聞くぐらいだから、変に気を利かせて標準でやる方法を提案してみた次第で
ご指摘はそのとーり
>>758 それができるならそっちのがいいわ
762 :
758 :2009/05/31(日) 18:38:21
>>761 うん、話の選び方、苦労はわかります。unix なら signal ですが、Windows ではどうなるんでしょうね。
windowsもntあたりからPOSIXなんちゃらに準拠してたから あるんじゃね? かといってsignalは可用性なさそうだから嫌だけど
Windowsなら500msごとにシグナル状態になるタイマーオブジェクトを作成して (OpenWaitableTimer/SetWaitableTimer) WaitForSingleObject関数でにシグナル状態を待つ。
簡単に済ませたいのならsleep系でいいんじゃね? たいがいの環境で使えるし。 正確さが必要なら、sleepする時間を微調整するとかいろいろ方法はあるし。
俺これしかソート知らないんだけど、バブルソートってのも覚えておいたほうがいいの? ていうかバブルソートってどんなの? int a[5]; int i , j; int temp; printf("5個 適当な数字をいれて\n"); for( i = 0 ; i < 5 ; i++ ) scanf("%d" , &a[i] ); for( i = 0 ; i < 5 ; i++ ){ for( j = 0 ; j < 5 ; j++ ){ if( a[i] < a[j] ){ temp = a[i]; a[i] = a[j]; a[j] = temp; } } } for( i = 0 ; i < 5 ; i++ ) printf("%d ," , a[i]); }
signed ⇔ unsignedの型変換の際には二進数表現では変化しないことは規格で保障されてますか?
signed char の場合 FFは-1ですが unsigned charの場合 255です
771 :
デフォルトの名無しさん :2009/05/31(日) 21:24:47
>>766 別にソートアルゴリズムの内容なんて知らなくても大抵は大丈夫だろ
なにやる人か知らんけど
むしろ各ソートの性質をかるく知っとけ
安定ソートとかオーダーとか
>>771 ゲームプログラムを趣味でしたいだけ。
ポインタも微妙なんだけど、コレぐらい分かってれば良いの?
それとも関数ポインタまで抑えておくべき?
#include <stdio.h>
void kakeru(int *test , int *test2 , int *ans);
void main(void){
int a , b , ans;
ans = 0;
printf("入力して");
scanf("%d%d" , &a , &b);
kakeru( &a , &b , &ans );
printf("%d" , ans);
}
void kakeru(int *test , int *test2 , int *ans){
*ans = (*test) * (*test2);
}
>>772 ゲームなら、関数ポインタを使う場面は結構あると思う。
>>773 関数ポインタはちょっと手の込んだアルゴリズムではよくつかいますよ。qsort() とか。
さっきのをポインタとか使ってやってみたけど、どうもエラーが出る…。 int型の配列のアドレスを関数の引数に渡す方法が違うのかしら。 でも確か先頭のアドレスを渡せば全部参照してくれたと思ったけど、どなたか教えてください。 #include <stdio.h> void datesort( int *tes[10] ); void main(void){ int a[10]; int i; printf("ソートさせたいデータを入れて"); for( i = 0 ; i < 10 ; i++ ) scanf("%d" , &a[i]); datesort( &a ); for( i = 0 ; i < 10 ; i++ ) printf("%d" , a[i]); } void datesort( int *tes[10] ){ int i , j , temp; for( i = 0 ; i < 10 ; i++ ){ for( j = 0 ; j < 10 ; j++ ){ if( *tes[i] > *tes[j] ){ temp = *tes[i]; *tes[i] = *tes[j]; *tes[j] = temp; } } } }
インデントが整ってないから教えてあげない
>>775 for (i = 0; i < 10; i++) tes[i] = &a[i];
...
datasort(tes[i]);
とやらないと、tes[i]が指す先の内容が何か分からないので
未定義の動作になってしまう
質問です。 void func1(){ printf("hello world\n"); } int main(){ printf("%d \n", sizeof(func1)); return 0; } プリントされる値は1なんですが、これはなんで1バイトなのしょうか? (関数は256個以上定義できない??)
>>778 VC++だとエラーになってコンパイルできませんでした
sizeof オペランドが正しくありません。
>>779 だめみたいですか。
gccだと通るんですが。。
というかそもそも何がしたいのかさっぱりわからん ポインターのサイズを求めたいのか・・・・ 関数の数なんて上限きまってないはずだよ。
>>780 お前は何のサイズが欲しいんだ。
関数ポインタの大きさなら sizeof &func
戻り値の大きさなら sizeof func()
何がしたいというわけではなく、ただの気になっただけなんです。 アドレスサイズは4バイトのはずなのに、なぜ、sizeof(func)で 1バイトと表示されるのかが分かりません。
voidのサイズだろうが
>>783 未定義動作ってやつじゃないの
1と表示してもいいしエラーにしてもいい
>>784 sizeof( void )は0だったよ
787 :
デフォルトの名無しさん :2009/06/01(月) 16:27:36
関数ポインタのサイズに決まってるだろこのアホどもw
>>786 おれの環境ではsizeof( void )は1だよ。
>>785 が指摘しているように、
サイズが求められないものに対しては処理系依存なんじゃない?
間違っても void *p = xxx; p++; というコードが通るコンパイラ(オプション依存)の動作を 標準Cの挙動と勘違いしないように。
何でCスレってこうも話題が反れていくんだろうな
C/C++プログラマになりたいんですけど、とりあえずやっとけってことはありますか? いまのところはゲーム作りで経験値稼ぎ&ランニングで体力作りをやってます
793 :
デフォルトの名無しさん :2009/06/01(月) 21:08:44
>>792 ゲーム作りって何やってるのか分からないが、
とりあえず覚悟を決めることが必須。
険しい道のりであることは否めない。
途中で諦めると使えないゴミが完成するので、それだけは避けるべく覚悟が必要。
まあC/C++に限らず、
というかプログラマに限らず、
どの職業でもこれは同じだろうけど。
別にどんな職業でも同じ事をわざわざおっしゃらなくても結構です
>>795 途中で諦めちゃった使えないゴミさんですか?
人生 お疲れ様ですwww
>>796 脳内補完が進みすぎているようだ
これでは保守はむり
798 :
、 :2009/06/02(火) 17:54:40
教えて下さい。 char Buff[2]; if(Buff[0]=="\n"){ 処理 } これだとエラーが出ます。strcmpだと実行時、例外エラーがでます。やりたいことは、配列の特定の所に改行が入ったらという条件文を作りたいです。お願いします。
>>798 charとchar*って違うんだよね☆
801 :
798 :2009/06/02(火) 18:12:41
802 :
質問! :2009/06/02(火) 23:23:24
色々聞いていいですか?
803 :
ダメ!絶対! :2009/06/02(火) 23:27:47
お断りします。
804 :
質問! :2009/06/02(火) 23:38:11
ざんんねえん やっぱC辞めてJava逝ってきますノシ
コロコロ変えるやつはどんな言語も身にならないよ
806 :
デフォルトの名無しさん :2009/06/03(水) 14:06:58
バイナリファイルの操作で、更新・追加両方行いたいような場合はどのよう なモードでfopen()すると良いのでしょうか。 既にファイルがある場合はそのファイルを消さずにデータを追加したく、 なおかつ既存の部分の上書きもしたいです(当然読み込みもしたい)
808 :
806 :2009/06/03(水) 14:34:23
>>807 ありがとうございます。
1.ファイルが存在しない場合は空ファイルをまず作って閉じる。
2.モード "r+b" でfopen()する。
で目標の動作ができそうです。
ありがとうございました。
a+bしてfseekするんでいいじゃな
"r+b"で失敗したら、"w+b"で開けばいいよ。
>>809 残念、"a+"では追記しかできないんだな。
812 :
806 :2009/06/03(水) 15:24:16
>>810 それが一番よさそうですね。そうします。
a+ の失敗を「からだで学んで」いました…。
fseek() 、fwrite() 後の ftell() の戻り値を確認しながら、
「???」となっていました。
813 :
、 :2009/06/03(水) 15:44:58
printf(const char* format, ...) printfの...ってどういう意味ですか?
つ[stdarg.h]
815 :
sage :2009/06/03(水) 15:50:41
... vararg 可変引数 好きなだけ引数を取れる formatを解析して引数の数と型を推論している 対応が狂うと何がおきるかわからない printfは数ある標準ライブラリ関数の中でも特異な関数の一つ
817 :
813 :2009/06/03(水) 16:08:50
今、自作printfを作成しています。...の引数をどのように、展開し、文字データに組み込むかわかりません。ご教授お願いします。開発環境はVC2005エクスプレスです。...のウオッチすらままならないです。
818 :
デフォルトの名無しさん :2009/06/03(水) 16:09:33
>>817 printf のフォーマットを完全サポートするつもりなのか?
それなら vsprintf 経由でバッファに書き込んだほうが現実解っぽいけど?
>の引数をどのように、展開し
va_arg() で抜き出す
>文字データに組み込むかわかりません
値の可視文字化のフルスクラッチ実装は難易度がかなり高いと思われ…
sprintf 呼び出しで茶にごすか?
# VC2005EE って CRTのソースインストールできたっけ?
# printf の一部分ぐらいは見れると思うけど 追っかけるの面倒だわ
車輪を再発明するのはよしなさい。 スコット・メイヤーズというえらい人も 「Effective C++の初版ですまぽを公開した時は プロの開発者に散々チェックしてもらったけど その後何年もエラー報告が届いたよ〜」 と嘆いていらっしゃった。 今では「boost使ったら?」と笑顔で書いている。
822 :
813 :2009/06/03(水) 16:33:16
完全にサポートするつもりです。va_argはmsdnでわかりますか?
ばっちりだよ! …ただし、言語仕様のところは全部英語だけど。 (C#、VB、C++/CLIなどは完全日本語化されている) 先日MSKKはMSDNの日本語化を積極的に勧めるって発表してたけど MSKKの仕事の遅さは折り紙つきだから CやC++の言語仕様のところが日本語化されるのは1000000年後くらいじゃないかなぁ。 っていうか、いい加減C99に対応しろよ。いつまでC89で行くつもりだよ。
813とは違う状況だが組込みのファームウェアの仕事してた時は 社内で作った組み込み用OSに自作 printf() 、自作 malloc() などの コードがいろいろあった気がする。内容はもう忘れちゃった。 (printf()の出力はシリアル出力に出てきてデバッグに使用する)
>>825 コンパイラ・実行環境の都合上、標準関数はまず使えない ってこと?
それはそれで大変な作業だね (社内標準化されてて これ使え になってりゃ良いけど)
Whitesmith C
>>826 組み込みの場合ディスプレイ付きじゃない場合もあるから
printfを関数で作ってるだけでしょ。
牛のNASなんかもシリアルから標準出力と同じものが出てたはずだし
>関数で作ってるだけでしょ。 独自関数で作ってるだけでしょ。
>>826 そう。printf()はn進数への変換のコードも必要だったような気がする。
オレも組み込みでデバッグ専用でprintf作ったなあ
>>826 大変というか無ければ作る
タダそれだけ
833 :
826 :2009/06/03(水) 17:02:16
標準出力は塞がれてるけど vsprintf は使えるぜとかなら 独自実装はまだ楽っぽいが… その手の暗にスタック食いなやつが、(メモリの都合で)実質的に使えねぇ となると泣けるな 組み込みはどんな制限つくかわからんから大変だね
printfライクなものの実装は決して難易度は高くは無いが、かなり面倒。 拡張要求(欲望)で機能が肥大化しがち。 またこういったprintf上位互換コードが流出すると、一般的なC言語のライブラリとの間で 相互干渉が発生してトラブルを招きがち。 極めてプライベートな場所でそれを使用するのは止めないが、パブリック(商用)な場所で それを使う場合は十分な注意が必要。 印字書式を全く新しいものにするとか。 printfの印字書式は非常に小さいがある種のプログラミング言語であるとも考えられ 当然そこには意匠権や特許権とかも絡んでくるかも知れない。
printfは%sと%dを実装すればまあ使える。
仮にprintfの書式の特許なんかがあったとしても とっくに切れてるはずだから大丈夫
ここまで誰も指摘していないが、printfを自作するなら、vprintfも作っておけ。 printfはvprintfを呼ぶだけで済むから無駄にはならない。 int my_printf(const char *format, ...) { int ret; va_list va; va_start(va); ret = my_vprintf(format, va); va_end(va); return ret; }
while文で例えば i=0; while(i>1) のような場合、whileは一回も機能せずに終わりますか?
int count = 0; i=0; while(i>1) { count++; } //countを表示 という風に確認してみるといい。 というかその程度ならそういう癖をつけるほうがいい
int a,b,c,i,j; printf("整数1を入力してください:"); scanf("%d",&a); printf("整数2を入力してください:"); scanf("%d",&b); if(a>b) { c=a; a=b; b=c; } i=a; while(i>=a&&i<=b) { j=2; while(j>=2&&j<=i-1) { if(i%j!=0) break; j++; } if(i=j) printf("%d",i); i++; } これで整数1と整数2の間にある素数を表示させようとしているのですが、 できません…。 たぶんiとjが変なのだと思うのですが どこを直したらよいのか見当がつかないので教えてください。
整数1と2は入力できるのでscanfのところは大丈夫だと思うのですが、 たとえば10と5と入れたら7(あと5も?)と出てこなければいけないのに、 2とでてきてしまいます。
>とっくに切れてるはずだから大丈夫 とっくに切れてるはずだから注意が必要なわけ
切れた特許の何を注意する必要があるのか
>>842 うわぁはずかしぃ・・・
if(i=j) printf("%d",i);
>>845 ありがとうございました!!!
そこと、if(i%j!=0) break;
の!=が==だったみたいです。
間違いじゃないけど、i>=a とか、j>=2とかムダだから
なんだある数値の範囲内の素数を列挙するだけか // かきかえた #define SWAP(TYPE, A, B) do{TYPE tmp = B; B = A; A = tmp;}while(0) int readInt(const char * print) { int r; printf("%s", print); scanf("%d", &r); return r; } int isPrime(int n) { int i; for (i = 2; i < n / 2; i++) if ((n % i) == 0) return 0; return 1; } int main(void) { int a, b, i; a = readInt("整数1を入力してください:"); b = readInt("整数2を入力してください:"); if (a > b) SWAP(int, a, b); for (i = a; i <= b; i++) { if (isPrime(i)) printf("%d\n", i); } }
下記のそれぞれのsizeofとそれに関するコメント文の対応は正しいですか? よろしくお願いします。 printf("sizeof 1-1..%d\n", sizeof(double *[10])); /* doubleへのポインタ型の配列(要素数10)のサイズ */ printf("sizeof 1-2..%d\n", sizeof(double (*)[10])); /* double型の配列(要素数10)へのポインタ型のサイズ */ printf("sizeof 2-1..%d\n", sizeof(double *[2][3])); /* doubleへのポインタ型の配列(要素数3)の配列(要素数2)のサイズ */ printf("sizeof 2-2..%d\n", sizeof(double (*[2])[3])); /* double型の配列(要素数3)へのポインタ型の配列(要素数2)のサイズ */ printf("sizeof 2-3..%d\n", sizeof(double (*)[2][3])); /* double型の配列(要素数3)の配列(要素数2)へのポインタ型のサイズ */ printf("sizeof 3-1..%d\n", sizeof(double **[3])); /* doubleへのポインタ型へのポインタ型の配列(要素数3)のサイズ */ printf("sizeof 3-2..%d\n", sizeof(double *(*)[3])); /* doubleへのポインタ型の配列(要素数3)へのポインタ型のサイズ */ printf("sizeof 3-3..%d\n", sizeof(double (**)[3])); /* double型の配列(要素数3)へのポインタ型へのポインタ型のサイズ */
850 :
813 :2009/06/04(木) 10:42:55
皆さんアドバイスありがとうございます。 va_start使ってやってみます。
851 :
授業中 :2009/06/04(木) 11:21:13
public class Kansu_sum{ public static int sum(int n){ int i,s; s=0; for(?????????){ s=s+i; } return ???; } public static void main(String[] args) { int n; n=10; System.out.println("1から"+n+"までの和="+ ???????); } } これの???????に何がはいるかわかりますか?
852 :
デフォルトの名無しさん :2009/06/04(木) 11:28:13
for(i = 1; i <= n; i++) ... return s; ... System.out.println("1から"+n+"までの和="+ Kansu_sum::sum(n));
853 :
授業中 :2009/06/04(木) 11:33:50
>>852 ありがとうございます!!
System.out.println("1から"+n+"までの和="+ Kansu_sum::sum(n));
最後の+Kansu_sum::sum(n));
ここでうまくいかないのですが、何かおかしいですか?
うぜえ Javaはスレ違いだろ
855 :
授業中 :2009/06/04(木) 12:06:30
>>853 System.out.println("1から"+n+"までの和="+sum(n));
で、できました。
スレチすみませんでした
856 :
デフォルトの名無しさん :2009/06/04(木) 16:24:37
1#include <stdio.h> 2 3 int main(void){ 4 char *w[] = {"S","SS","SSS","SSSS","SSSSS","SSSSSS","SSSSSSS",}; 5 int k; 6 int i; 7 for(i = 0; i < 7; i++){ 8 printf("Bytes of w[%d] are %d\n",i,sizeof w[i]); 9 } 10 for(k = 0; k < sizeof w / sizeof w[0]; k++){ 11 printf(" %d:%s",k,w[k]); 12 } 13 printf("\n"); 14 return 0; 15 }
857 :
デフォルトの名無しさん :2009/06/04(木) 16:25:10
16 int i; 17 for(i = 0; i < 7; i++){ 18 printf("Bytes of w[%d] are %d\n",i,sizeof w[i]); 19 } 20 for(k = 0; k < sizeof w / sizeof w[0]; k++){ 21 printf(" %d:%s",k,w[k]); 22 } 23 printf("\n"); 24 return 0; 25 }
858 :
デフォルトの名無しさん :2009/06/04(木) 16:28:29
これを実行すると Bytes of w[0] are 4 Bytes of w[1] are 4 Bytes of w[2] are 4 Bytes of w[3] are 4 Bytes of w[4] are 4 Bytes of w[5] are 4 Bytes of w[6] are 4 0:S 1:SS 2:SSS 3:SSSS 4:SSSSS 5:SSSSSS 6:SSSSSSS となります。w[0]からw[6]それぞれに格納されている文字の数にも関わらず、 バイトの数が同じなのはなぜなのでしょうか?よくわからないので知っているかた教えてください。
ポインタの大きさ出力してるからだよ馬鹿
>>858 当たり前だろ
sizeof w / sizeof w[0]は単なるchar型へのポインタの大きさ
文字列の長さを知りたかったらstrlen()を使え
sizeof w[i] これだとポインタサイズになるんじゃないかな? 32bit環境なんで4バイト それにstrlenとかで調べるしかないんじゃない?
862 :
デフォルトの名無しさん :2009/06/04(木) 16:39:14
わかりました。 回答有難うございました。
#defineしたものを一度#undefしてまたもとに戻したい場合はどうすればいいのでしょうか?
foo.hに宣言してある関数をbar.hで使うとします この場合main.cでfoo.h bar.hを両方インクルードするのか foo.hに二重インクルード防止をつけてbar.hに#include "foo.h"を書いてしまうのか 一般的に好まれるのはどちらのスタイルですか?
ケースバイケース 自分で書いてるだけならお好きなように
> foo.hに宣言してある関数をbar.hで使うとします bar.cで使うの間違いか? いずれにせよ、二重インクルード防止は常につけるように。 基本は、そのファイルで必要なヘッダだけを includeする。
センチネルをおくのが普通なのでは? #if !defined XXX #define XXX ... #endif とか
それ番兵って呼ぶの?変なの。
>>865 インクルードガードで
_SEX_H_
のようにベンダでもないくせに先頭にアンダースコア入れる奴にはなるなお
// / ̄ ̄ ̄\ // / ─ ─ \ /// (●) (●) \ //| \(__人__)/ | ← //\ | ` ⌒´ | / /// \ // ┼ヽ -|r‐、. レ | // d⌒) ./| _ノ __ノ // _______ // 製作 ○○ ↑いつも俺がコードの最後に貼ってるヤツ
頂きました
マクロで定義して使える文字列化演算子とトークン連結演算子ってのがあるが、 これのうまい使い方というか、どんな風に使うと便利なのか誰か例を示してくれないか?
TEXT()
void func_a(char *a[]); void main(void){ char *a[]= /* ←ここを変えたいのです*/ { "あいうえお", "かきくけこ", "さしすせそた" }; func_a(a); printf("%s\n",a[1]); return; } void func_a(char *a[]){ printf("□■□func_a開始□■□\n"); printf("%s\n",a[0]); printf("%s\n",a[1]); printf("%s\n",a[2]); strcpy(a[1],"12345"); printf("□■□func_a終了□■□\n\n"); return; } 迷える子羊をお救い下さい 上記のテーブル定義を char a[3][14]= にした場合、関数func_cを正常に呼び出すには、どこをどう修正したらいいのでしょうか? 色々試してはいるのですがさっぱり分かりません。 どうかご教示をお願い致します
876 :
875 :2009/06/05(金) 03:18:56
すいません func_cじゃなくてfunc_aです
あきらめた void func_a(char [3][15]); int main(void){ char a[3][15]= { "あいうえお", "かきくけこ", "さしすせそた" }; func_a(a); printf("%s\n",a[1]); return; } void func_a(char a[3][15]){ printf("--------------\n"); printf("%s\n",a[0]); printf("%s\n",a[1]); printf("%s\n",a[2]); strcpy(a[1],"12345"); printf("-----------\n"); return; }
ポインタの配列と配列の配列と配列のポインタはそれぞれ違う型なので char [3][15] は char (*)[15] では受け取ることができるけど char *[3] では受け取れないよ。 char *[3] は char** で受け取る。 ちなみに関数引数ではそれぞれ char [][15], char *[] と書いても良い。
>>877 普通はそういうデータはこう持つ。
staic char const * const array[] = {
"あいうえお",
"かきくけこ",
"さしすせそた",
};
あ、書き換えもしたいのか。んじゃchar a[][15]でもいいか。
# 16にしておくのが無難だけど本質的じゃないし。
880 :
875 :2009/06/05(金) 15:16:26
>>873 構造体のメンバ ⇔ 表示用シンボル テーブルの実体を記述するときとか
struct MyStruct {
int a;
double b;
};
#define IMP(name) { #name, (void*)&((struct MyStruct*)NULL)->##name }
struct SymbolTable {
char *caption;
void *data_ptr;
} Tables[] = {
IMP(a),
IMP(b),
};
こんな感じ。
882 :
デフォルトの名無しさん :2009/06/05(金) 19:07:47
main文のreturn 0;って、どんな使い道があるのか?
>>882 あんまりない
自分のプログラムを呼び出す側にリターンコードが必要な環境の場合は有効
そんなあいまいな
886 :
デフォルトの名無しさん :2009/06/05(金) 19:12:19
初心者です。 以下の2つのテーブルがあるんですが、 int D_TBL00[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; int D_TBL10[] = {10,11,12,13,14,15,16,17,18,19}; int D_TBL20[] = {20,21,22,23,24,25,26,27,28,29}; int *D_TBL_ADR[] = { D_TBL00, D_TBL10, D_TBL20, }; D_TBL_ADRからいずれかのテーブルアドレス参照し、D_TBL??からデータを取得するプログラムを教えてください。 では、よろしくお願いします。
>>885 実際そうだしw
呼び出し元が特にリターンコードを見ないなら
return 0;でOK
必要ならそれなりのコードを返せばいいだけ。
>>886 #include <stdio.h>
#include <string.h>
void main(void){
static int D_TBL00[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
static int D_TBL10[] = {10,11,12,13,14,15,16,17,18,19};
static int D_TBL20[] = {20,21,22,23,24,25,26,27,28,29};
int *D_TBL_ADR[3] = {
D_TBL00,
D_TBL10,
D_TBL20
};
int x,y;
printf("x=");
scanf("%d",&x);
printf("y=");
scanf("%d",&y);
printf("DATA=%d\n",*(D_TBL_ADR[(y-1)]+(x-1)));
}
890 :
889 :2009/06/05(金) 20:23:06
int *D_TBL_ADR[3] = { の前に static を付けないとコンパイルが通りませんでした(LSI-C86) int *D_TBL_ADR[3] = { は int *D_TBL_ADR[] = { ですね すいません
>>890 そんな過去の遺物でコンパイルなんかしないでください。
コンパイラがどうとかいう問題じゃないけどな
>>882 コマンドインタプリタに積極的に値を返すこともある。
例えば、Unixなどのgrepコマンドは対象が見つかったときは0を返し、見つからなければ1を返し、異常があれば2を返す。
また、trueコマンドは常に0を返し、falseコマンドは常に1を返す。
894 :
デフォルトの名無しさん :2009/06/05(金) 21:36:00
じゃ、ANSIでは、main が intで、voidじゃないのは、そういうわけ?
>>894 main() の呼び出し元がそういう風になっているからでは?
896 :
デフォルトの名無しさん :2009/06/05(金) 22:16:06
>>894 もともと、C言語は関数のデフォルト型がintだった。
その名残でもある。
たとえば、myint をある型(例えば int )として扱いとき、 #define myint int と typedef int myint; のどちらでも可能ですが、どっちだとどんなときに都合がいい、困るっていうことがありますか?
typedefはスコープを持つ #はポインタ型の別名に使うとひどいことになる
そうでなくともtypedefのほうが意図が明確だな。 #defineを使わないですむならそれに越したことはない。
// A.java #define LONG_INT java.math.BigDecimal #define STR java.lang.String #define PRINTF System.out.printf class A { public static void main(STR[] args) { LONG_INT a = new LONG_INT("10"); LONG_INT b = new LONG_INT("10"); PRINTF("%s %s", a, b); } } みたいな
typedefの方が常に優れてるのでそっち使いなさい
903 :
デフォルトの名無しさん :2009/06/06(土) 12:14:07
freadとfwriteって使い道あるんですか? fscanfとfprintfの方がわかりやすいんですがね。
>>903 fread/fwriteの使い道
mp3のエンコード、デコードや構造体の読み書きなど
テキストデータを読み書きするときはfgetsで読むかな
905 :
デフォルトの名無しさん :2009/06/06(土) 13:31:43
for文だけど、実数型変数でカウンタ変数作っても、問題ないのですか 動作保証ないですか
>>905 ほとんど問題はないが、うるさいことをいえば避けておいたほうがいいですね。
>903 テキストじゃなくてバイナリでデータを読み書きする時。
908 :
デフォルトの名無しさん :2009/06/06(土) 14:16:21
超抽象的な質問で申し訳ないのですが 配列、関数の扱いまでなんとか理解して、次はポインタについて習得しようと考えています ただ、全然その、C言語を使えばゲームやらアプリやらで使われているいろんなことができちゃうぜ〜って実感が沸いてこないのですが、そういうレベルに至るまであとどれくらいなんでしょうか 「いろんなものが作れるぜ」ってのを100とすると今の自分はどのあたりなのかなあと
>>908 2とか3とかそのくらいじゃね?
どの言語にしてもアプリ開発とかはライブラリ群やAPI使ってなんぼなので
APIやら開発環境使いこなせるようになれば+20とかって感じじゃないかと
http://dixq.net/ ここだってとりあえずDXライブラリ使えって言ってるだろ?
いまやってる基礎を習得した上でライブラリを覚えれば「いろんなものが作れるぜ」
ソースから出現する機械語の想像がつきポインタがただの整数に見えたころが第一段階、普段の意識から無くなって無意識のうちに使い始めたら第二段階 どうでもよくなって別の言語に移行したら第三段階
>>908 ポインタをまだしらないなら2じゃないかな。
たぶん俺たちですら100ではないわけだし。
C/C++の深遠さはヤバイ
>>910 俺C言語がやになってC++に移行したら
めっちゃ気に入ってハマった人間なんだけど。
・・・それでも時折別の高級言語もやってみたくなる。
言語を覚えてもアプリは作れないよ。 必要なのはライブラリやAPI。その背後にあるプロトコル。 そこさえおさえておけば、言語を何かに絞る意味はない。 選択肢が広がり、C言語なんか見向きもしなくなる(過言)。
Javaはグラフィック表示機能までを含めて言語仕様の中に入っているけど CやC++にはないから、ハードやOS、開発環境ごとに異なるグラフィックライブラリを それぞれ習得していかないとゲームを作るところには到達できない。 ウルトラ遠回り^^
開発環境ごとにあわせられないヤツなんて使えないだろw
プロならね。
プロじゃないなら自分の環境だけで、他の環境なんて気にする必要はないと思うが。
そうだね。別にCやC++がだめといってるわけじゃない。 遠回りだといってるだけ。 実際、VBとかの方が簡単でしょ。 素人にはオールインワンの方が簡単って意見にも反対? それなら、しょうがない。^^
919 :
デフォルトの名無しさん :2009/06/06(土) 16:24:25
プログラミングの知識だけじゃ、ダメちゃう 適用分野の知識が必要 2,3かも知れんが、あるところから急激に自信が付くもの
ゲームならC++が作りやすいよ!っていわれたから勉強してるけどいつもほんとかよって思う
922 :
デフォルトの名無しさん :2009/06/06(土) 16:32:54
なんつーか、どこまで行ったら「プログラムが組める」って言えるんだろうかなあ
>>921 どの言語も一長一短あってこれがベストなんていえないけどな。
むしろ環境に依存する部分の初期化とかいったお作法の方が面倒
>>922 言語は所詮道具だしな。
道具を使ってどれくらいの規模のソフトを作ったかによるんじゃない?
規模と内容か
これからゲームを作るという癖をつけたいのならDXライブラリとかでもいいんじゃね? あれならかなり楽だし ゲームってどんなことをしてるかというのを掴まないと厳しいしね。
>>922 自分が何を分かってて、何が分かって無いのかがわかるようになったとき。
何も分かってないことが分かってる初心者はプログラムを組めるのかw
>>928 何も分かってないことは分かってても、何を分かってないかは理解してないだろw
あんたったら研究者ね!
とりあえずの目標はFC時代くらいのRPGやSTGを作れないとな。 最近のハードをフルに活かすとなるとグラフィックの比重がめちゃくちゃ高いので 素人は大変。プロでさえ人数と金と時間かけてようやく出来る状態なんだし
ゲームプログラムなんてグラフィック以外でFCからなんか進歩したの?
>>932 してないな
音楽も音源に音符データ渡す方式からPCM録音してそれを鳴らす方式になって
どこにでもある音楽になって特徴なくなったし。
まあ、3D計算が高速になって多少幅は広がったよね。
>>932 NPCにAI入るようになってるし、ネットワーク対応するようになったし、
音楽も単に流すだけじゃなくてシーンに合わせてスムーズに変化するようになってるし、
物理演算やモーションキャプチャの利用とか(これらはグラフィック面の強化という意味もあるけど)
詳しく観察したらいろんな事が行われてるよ。
そろそろゲーム性とか ぼくのかんがえるさいきょうのげーむ とか出てきそうな気配
936 :
デフォルトの名無しさん :2009/06/06(土) 17:48:12
ファイルを書き込みするとき たとえば abcと書き込むと ファイルに abc と書き込まれます。 そのあとにdefと書き込むと abc def となります これを def abcと新しく先頭に書き込みたいんですがどうやればいいんですかね?
別ファイルに書いてもとのファイルを消す。 又はそれようのファイルシステムライブラリーを作る
>>936 本当にそういうことしないとどうしようもないのか
というところから検討した方がいいかもしれないが。
1. abcとかかれたファイルを別の名前に変更
2. 目的のファイルにdefと書き込む
3. 1.で別の名前に変更したファイルを開く
4. 3.のファイルからデータを読み出して、目的のファイルに追加書き
(もっと楽にやりたかったら、mmap系で)
ファイル内のデータを直接移動することは出来ない。 必ずいったんメモリに読み込んでからの書き直しになる。
940 :
デフォルトの名無しさん :2009/06/06(土) 18:01:59
>>938 perlでできたきがするんですがね。
たしかfseekを使ってアンケートの書き込みを昇順にするみたいな
あれをCでやりたいわけですが。
>>940 perlでできていても
それは中で泥臭いことやってるのを,蓋をしてきれいに見せているのしか見ていないからだとおもう
942 :
デフォルトの名無しさん :2009/06/06(土) 18:08:14
fseekっていうのはファイルの先頭などとうたっているので fseek(fp,0,SEEK_SET)で ファイルの先頭 abc def abcの場所に来て defが先頭へ書き込めるかと思ったら全然違いましたね。
よく分からんが、あらかじめ昇順にしてから書き込んだらいけないのか?
fseekを使った上書きなら出来る。 abcとdef のように長さが同じなら、 abc def abcをいったんメモリに読み込み、 abcをdef で上書き。 def def そして、abcで上書き def abc ただし、あくまでも上書きなので、同じ文字数のときにしか使えない。
同じ文字数でなくても、隣り合っているならば入れ替え可能か。 応用すれば、バブルソートのようなやり方で離れた位置の文字列同士の交換も可能だろう。 ただし、一旦ファイルをメモリに読み込んで、新たにファイルを作り直すほうが単純かつ確実。 速度的にもそのほうが有利だろうな。
結局メモリ上での操作とほとんど変わらん 開いた直後 先頭指してる・末端指してる 末端以降の追記は、そのぶんだけファイルサイズが増える ってだけで、途中からの書き込みは挿入操作ではなく上書き操作だし
>>945 > バブルソートのようなやり方
なんか↑って
> 一旦ファイルをメモリに読み込んで、新たにファイルを作り直す
ってのを具体的に書いただけじゃまいか
948 :
デフォルトの名無しさん :2009/06/06(土) 18:23:08
掲示板みたいな感じで新規に書き込んだものを先頭に表示させたかったんですが。 もう1個ファイル作るみたいですね。 むずかしそうですが頑張ってみます。
>>947 いや、全部読み込むのではなく、単語単位で読み出し書き込みを繰り返すって意味。
瞬間的には、高々2単語分しかメモリにない状態。
質問者はそういうのをイメージしているだろうと思って。
もちろんキャッシュがあるから、意図したとおりにはなっていないだろうけど。
>>948 >掲示板みたいな感じで新規に書き込んだものを先頭に表示させたかったんですが
入力データーを保持するという意味では
ファイルの書き出し順は入力が新しいほど後のほうが都合良い
# 追加は末尾に書くだけ (a+ で開いてそのまま書き出しで済むしな
表示というのは、あくまでデータを可視化する作業だから、分けて考えたほうが良いと思うよ
いまどきのPCなら数メガ、数十メガ程度のファイルは全てオンメモリで処理できる。 下手なこと考えずに、ファイル全部読み込んで処理しとくが吉。
データと表示を分離するという発想は 初心者には難しいのかもしれない。 昔、○×ゲームを作るという課題で、 プレイヤーが打ち込んだ○(または×)を 「どうやったら画面から読み取れるのか」 と必至に考えている人がいた。 興奮した。
#!/bin/bash echo $1 > temp_text_file cat text_file >> temp_text_file mv temp_text_file text_file ./test.sh aaa ./test.sh bbb cat text_file bbb aaa
なぜbash限定・・・
int main() { system("./test.sh aaa"); system("./test.sh bbb"); return 0; }
>>905 ちゃんと分かって、あえて使うならOK。
ただし、バグの原因になることが多いから、
セキュリティ的にも避けるべきということになってる。
バイナリモードでファイルIOするときにEOFとただの-1ってどうやって見分けるんですか?
fgetcとかは、ただの-1は(unsigned charとして読み込まれるので)255として取得される。
任意のenumを受け取る関数の引数の型は何にするべきかな? enum NUM1 { A, B, C }; enum NUM2 { D, E, F }; 〜 enum NUMX { X, Y, Z}; 〜 void func(??? e) { switch(e) { case 0: 〜; break; case 1: 〜; break; case 2: 〜; break; default: 〜; break; } } 暗黙のキャストが安全なのかどうかわからんです
>>959 fgetc() の戻り値は int でとります。
>>961 enum をわけてしまったのでは不可能
あえてするとすれば、 enum NUM1{ A=0, B=1, C=2}, enum NUM
>>961 int
enumって実質intだから、intで受けてかまわない。
ファイル分割について質問。 構造体をとあるヘッダーで宣言して、実体を別のヘッダーで宣言した場合(勿論構造体宣言はインクルードしてある) subと言うソースファイル内で実体のヘッダーを読み込んで、関数内で使った場合 mainのソースファイルで実体を読み込めない。 mainの方にも実体を宣言したヘッダーを置くと二重定義になるし subの方を消すと、今度はsub内で構造体にアクセス出来なくなる。 externを使ってもエラーが出た。 説明ヘタで申し訳無いけど、どうすればいいの?
そういうのは、日常語の掲示板で日常語を媒体として教わるな。 処理系付属のヘッダファイルとか、オプソなコードのヘッダとか 眺めてたら色々と工夫してあるのでそれを盗め。
実体をヘッダで宣言するな。
実態をヘッダーからsubと言うソースファイルに移してextern
#ifdef HOGE_PUBLIC #define HOGE #else #define HOGE extern #endif HOGE int hoge; とヘッダにしておいて(便宜上ヘッダ名はhogehoge.hとする) hogeの実体を置きたいソースに #define HOGE_PUBLIC #include "hogehoge.h" hogeの実体を置かないソースには #include "hogehoge.h"
>>970 >>969 が何をやってるか理解できてないなら使わない方がいいよ。
あと個人で作るプロジェクトならいいけど、仕事でするなら探りを入れた方がいいかも
ヘッダーは宣言のみ つまり extern 付き ソースのどこか1箇所でextern 無しの実体定義を行う
>>971 2人ぐらいで同人ゲーム作る為に、基盤となるソースとヘッダー作ってたんだぜ。
ifdefとか便利だって聞くからちょっと勉強しとくよ。
>>972 それで完璧だった。
どのソース内でも関数内でも構造体のメンバが呼び出せるようになった。
const int TEISU = 100; とかの実体もヘッダに書かない方がいいの?
static ってつければOK
ヘッダファイルの使い回し? 出来ればやめたほうが良い。公開用ヘッダ領域には置かないほうが良い。 しかし現実にはやらざるを得ない。 大抵、ライブラリコンパイル用のヘッダは公開用ヘッダと同じ名前だが includeディレクトリの奥深くに「隠されるのが」普通。 公開用ヘッダも最初はその大部分を参照するが、やがて独立していき 最終的にはライブラリコンパイル用のヘッダは公開ヘッダ領域からは 除かれるというのがセントラルドグマ。
978 :
、 :2009/06/07(日) 17:18:53
教えて下さい。 @ある処理がA関数コール200文字データを引数で渡す AA関数実体で200文字処理し、Bタスクへ100文字ずつメッセージ送信。 BBタスクは100文字受取、100文字を保持し、残りの100文字が来たら200文字データに成形する。 C200文字データをパイプでexeに流す。 という処理を作成しています。 Bの100文字データを保持するという処理がどうすればよいかわかりません。 というのも次の100文字データが来る前に、前の100文字データ消えてしますようなきがして。 よろしくお願いします。
>>978 > A関数コール200文字データ
なにいってんの?
構造体だけが記述してあるヘッダーから error C2143: 構文エラー : ';' が '<クラスヘッド>' の前にありません。 ってエラーが出る…。 構造体の書式は間違ってないんだけど、この場合何処でエラーになってるの?
}; ととじてないとか
>>980 あ、自己解決。
関数のプロトタイプ宣言に「;」が無かっただけだった
>>978 int datacount;
char data[200];
でいいんじゃないかな。
datacountが0ならdataは空。100なら100文字分保持。200なら200文字分保持。
datacountが100のときに次の100文字が来れば、dataの100番目から格納して
datacountを200にしデータ成形しCを実行。
Cが終了したらdatacountを0に戻す。
984 :
978 :2009/06/07(日) 18:32:07
>>983 ありがとうございます。
これって、順番を守って1回目のデータ、二回目のデータを受け取れるでしょうか?
例えば、初めにデータを送ったタスクより、高いプライオリティのタスクがデータを送って
途中データが書き換えられるようなことはないでしょうか?
話に出てくる単語が抽象的に成っているぞい
>>984 プロセス構成がわからないからなんともいえない。
プロセス構成はこれでOk?
プロセスA(A関数を含む)
プロセスB(Bタスク)
プロセスC(プロセスBよりpipeでデータを受け取るexe)
パイプで考えれば Aは100区切りをBの都合お構いなしで垂れ流す。 OSが垂れ流されたデータを一時保管 Bは次の100くれとOSに頼む。 Bのなかで前の100が消えるとか知ったこっちゃねぇ
988 :
978 :2009/06/07(日) 18:53:22
すいません。
>>984 問題ないです。
なにをしようかというと、自作printfを作成していて、あちこちから
自作printfは呼ばれるのでデータの保障について考えています。
うわお前か
990 :
sage :2009/06/07(日) 21:02:38
タスクとかC言語の範囲じゃないけど、 多分呼び出し元で確保した領域(文字列など)であれば呼び元が異なっても 干渉することはないと思う。 タスクの構造体見るとスタックの領域があるよね?printf()が呼ばれたときの 引数の領域もこのスタックの領域を使用して作成され、それぞれのタスクで別々 の保存場所になっている。 なので関数の中でstaticみたいなのを使って状態保存 (例:関数が何回呼ばれたかなどの情報を関数内のstatic変数で カウントしてるなど)しているようなのを使っているとタスク間で干渉する。 ちょっと質問の意図を勘違いしてるかもしれないけど。
どうして多次元配列は多次元配列にも関わらず,一重の[]で初期化できるのでしょうか?
992 :
991 :2009/06/07(日) 22:06:02
[]ではなく{}でした
仕様
994 :
991 :2009/06/07(日) 22:42:04
やっぱり仕様ですよね、こんなの。 これ聞く教授陣もアホですよ。
>>994 多次元配列なんてCの便宜上の話であってたとえば
内部的には連続したメモリだし
>たとえば はゴミです。消し忘れ
うめ
うめ
999 !!!!!!!!!!!!!!!!!!!!!!!!!
うめ
1001 :
1001 :
Over 1000 Thread このスレッドは1000を超えました。 もう書けないので、新しいスレッドを立ててくださいです。。。