└0^0┘ < これをグラディウスの後姿と書いた君!素晴らしい、そういう想像力はぼくちん好きだお♪ そういわれたら、なんかメガネじゃなくて後姿にしか見えなくなってきた。これが脳を刺激する アハッ体験なんだね、良い勉強になった。
ビッ○バイパーだろ
6 :
デフォルトの名無しさん :2007/06/25(月) 09:48:17
C言語なんですが 文字列の中の文字数を調べるstrlen()のように ファイルの中の文字数を調べる関数ってありますか?
8 :
デフォルトの名無しさん :2007/06/25(月) 10:44:15
OS:Linux 言語:c言語(posix準拠のC言語) socketについて質問です。 socketを生成して、 bindせずにrecvfrom(ブロッキング)した場合、 終了方法(recvfromのブロックを解除する方法)はどのような方法がありますか?
読み初めの位置が半分ずれてるんじゃない?
11 :
デフォルトの名無しさん :2007/06/25(月) 16:21:55
>>6 こんな感じかな
unsigned NumLen()
{
unsigned c = 0,num=0;
FILE *fp = fopen("text.txt","r");
while( (c = fgetc(fp)) != EOF)
num++;
return num;
}
wcコマンドのソース見てそっからパクりゃいいんでねぇべか?
conio.hがないといわれました。 debian:~$ gcc ch05-04.c ch05-04.c:2:19: error: conio.h: そのようなファイルやディレクトリはありません はじめてconio.hというのを見ました。ちなみにconio.h というのは必要ですか? 独習cに下みたいなのがあったのですけど、これってgetchar でできますよね? #include <stdio.h> #include <conio.h> int main(void) { char mess[80]; int i; printf("input message (less than 80 letters)\n"); for(i=0; i<80; i++){ mess [i] = getche(); if(mess[i] == '\r')break; } printf("\n"); for(i=0;mess[i] != '\r' ;i++) printf("%c",mess[i] + 1); return 0; }
あ、できた。 conio.hの存在意義を教えてください。
コンソールI/Oはもっと色々できるのじゃよ
>>14 文字色変えたりとかもconio.hで出来るよ。8色しかなかったっけ?
別にconio.hでなくてもできるのあるだろうけど。標準ではもちろん無理。
ソースを見ずに回答すると、たぶんスタックを壊してる
>>18 test()で、x, yに対してノーチェックでx - 1などとしているので配列外を参照してしまっている。
ところで、いつからオセロは10x10になったんだ?
22 :
18 :2007/06/26(火) 02:03:26
スタックというのは変数のエラーなんだろうか (違ったらスマソ) 確かに多次元配列を全ての関数に渡したりしてるけど printfを入れると解消する問題なので、原因は別かなと思います
24 :
18 :2007/06/26(火) 02:36:57
>>23 thx。。
どの部分がスタックを破壊しているのか教えて頂けませんか?
もしくはスタックが破壊される原因を教えて下さい
スタックっていうか、そこかしこで配列外の領域にアクセスしてる気がするが。 とりあえず落ちるときの入力パターンぷりーず。
>>24 取り敢えずロジックをとばし読みして疑問に思ったところ
関数testの中で
> if(array[x-1][y]==2){ //上
ってやってるところがあるけど、xは0になる可能性があるよね。
てことは配列の領域外を参照していることになるけど、これは大丈夫?
配列の添え字にy-1を与えているところも同様。
次に関数test2の中で
> for(;y<=9;n++){
ってやってるところがある。でもyの初期値が設定されていないような気がする。
これだと(yに割り当てられた)スタックにたまたま積まれていた値の違いで動作が変わる可能性がある。
この辺の初期化してない変数なんかは言ってる問題が起きる典型的なパターンなんだけど。
あと質問には関係ない小さい点 void ai (int array[][10]) { srand(time(NULL)); array[rand() % 10][rand() % 10] = 2; } srandはここでやるべきではないと思う。mainの先頭で一度やれば十分というか、そうすべき。
ソース丸ごと投げて見てもらうと自分のダメなとこ突っ込んでもらえるんだな。 オレも今度投げてみよう。
ソースも出さない、エラーメッセージも正確に書かないよりは答えてもらえる確率は高くて当然だろ。
{1,2,3,....,n}の中から要素数がl以下になる組み合わせをすべて求めよ 例えばn=3,l=2のときは{0,1}{0,2}{0,3}{1,2}{1,3}{2,3}{1}{2}{3}となるようなものです お願いします
阿部さんに○×を出すともれなく△□を突っ込んでもらえますよ?
>>28 暇つぶししたいくらい暇なときには突っ込んであげるよ。
いやいやmainでsrandなんてしたら関数aiを知らない人は意味分からんじゃん やっぱり関数ai内に入れておくべき
>>34 time(NULL) が返す値が、前回呼び出されたときと同じになるような、1秒以内に
連続して呼び出されるときは rand()が返すパターンが同じになるぞ。
>>36 フラグを入れるんだよ
static int flag;
if(flag==0){
srand(time(NULL));
flag = 1;
}
これでおk
>>37 先に言え、後だしで自分の落ち度を補って逃げるのは卑怯だぞ
ごめん
>>37 flagの最初の値は?呼び出されるたびに if(flag==0) を評価するの?無駄が多い。
mainで一度やっとけ。
>37 関数呼び出すたびに無駄なチェック入れんの?
>>37 他の関数でも同じことやるの?
有り得ないよね。
乱数ってのは何度も初期化されないから乱数なんだよ。 初期化は一度のみ。 それを保証するには main で初期化するのが一番。
44 :
18 :2007/06/26(火) 08:44:31
寝てしまった。。
答えてくれた方、申し訳ない&thx!
そ し て
問題点分かりました!
>>26 の言うとおり、配列の要素が-になるのを回避、x,yを0で初期化したら
直りました!初期化しておかないと駄目なんだな!
あと、srandはとりあえずmainでやっておきます!
既に>20で指摘されている罠。
46 :
18 :2007/06/26(火) 09:44:16
そこは、
>>20 で変更したんですが、(case8が出来てないけど)
問題は、x,yの初期化という事です。
VisualC++ExpressEditionを使ってるんですが、 #include <stdio.h> main() { printf("私の名前は、山本一郎です\n"); } (名前はrei1_2)というプログラムをビルドすると、 ------ ビルド開始: プロジェクト: START_C, 構成: Debug Win32 ------ コンパイルしています... rei1_2.c リンクしています... rei1_2.obj : error LNK2005: _main は既に rei1_1.obj で定義されています。 C:\Users\tokimaru\Documents\Visual Studio 2005\Projects\C\START_C\Debug\START_C.exe : fatal error LNK1169: 1 つ以上の複数回定義されているシンボルが見つかりました。 ビルドログは "file://c:\Users\tokimaru\Documents\Visual Studio 2005\Projects\C\START_C\START_C\Debug\BuildLog.htm" に保存されました。 START_C - エラー 2、警告 0 ========== ビルド: 0 正常終了、1 失敗、0 更新、0 スキップ ========== というエラーが出てしまいます。 何所がおかしいのかよくわかりません。 教えてください。お願いします。
>>47 > _main は既に rei1_1.obj で定義されています
そりゃだめだ。リンクさせないで別物のソースとしてコンパイルせい
rei1_1.c をどっか別の所に移動するか、 新しくプロジェクトを作るか。
1を消さないんだったら同じソリューションで別プロジェクト作るのがいいかな
51 :
47 :2007/06/26(火) 10:17:04
C:\Users\tokimaru\Documents\ って貼っちゃいましたけど、この情報から個人情報が割れたり、PCに侵入されたりしませんよね?
IP 分かんないから侵入とかは大丈夫だとは思うけど、あまり貼るべきではないな。
>>52 よかった〜(汗)
ところで、48さん、49さん、50さんの言うようなやり方以外の方法ありますかね?
僕は初心者なのでよくわかりません。
>>53 だから他と被らない関数名にすりゃええやろ。
>>53 じゃあいったんプロジェクトから1を外せ
選択してDELキーで消える
ファイルそのものは残るから、あとで既存の追加で戻せる
typedef struct node* link; struct node { int item; link next; }; typedef link Node; link deleteNext(link x){ link t = x->next; x->next = t->next; return t; } link t=x->next; 新たなlink tを作り、tにxの指し示すリンクと同じitem,リンク先を持たせている x->next = t->next; xのリンク先はtが指し示すリンク先にする で合ってますか? だとしたらreturnでtだけ返すのだからx->nextを指定しても何の意味もないと思うのですが、何か記号の意味を履き違えている気がします
malloc も free もないんだが。 恐ろしいコードに見える。
>>57 関数の動きはこんな感じ。
・xの指す先をtにコピー。xの指す先をtの指す先に変更。tを戻す。
つまり、リンクリストからxの指す先を外し、それを返している。
>>58 削除関数だからmalloc()は要らないわけだし、tを返すのは呼び出し元でfree()するためだろ。
>>57 link はポインタだから作るわけじゃないよ、アドレスを保存してるだけ。
A→B→C
の状態を
A→C
に変えてる
Bは宙に浮いてる状態で返してる。消すためだろう。
書き換えるとこうなるのか。 -- link t = x->next; // 削除対象(へのポインタ)を一旦保存 x->next = x->next->next; // 削除対象を迂回するように接続しなおし return t; // 削除対象を返却
62 :
デフォルトの名無しさん :2007/06/26(火) 13:03:00
feof()はファイルの終わりをどこで判定してるんでしょうか? 例、ファイルの中身が This is a pen の場合は、nに達した時点で0を返すのか、EOFで0を返すのか
やれば分かる。
確かにこの程度なら実際に試してみるのが一番かもしれない
l = 0; while(!feof(fp)){ ch = fgetc(fp); printf("%c : %d \n",ch,ch); if(ferror(fp)){ printf("ファイルの読み込みエラー\n"); exit(1); } l++; } を実行してみたら-1も出力したのでEOFの次でループ終了ですかね
おいおい
「EOF」 という言葉はどこを意図して使ってる?
-1じゃないんですか?
EOF を読み込んだら終了、だよね?
意図しようとしてるのは同じことなんだろうか? ならいいんだけど。
EOFを読み込んだら終了ならEOFが出力されるのはおかしい
EOF を読み込んだら feof が真を返すようになるんだっしょ?
while(!feof(fp)) だからEOFに達した時点でループ終了してないとダメなんじゃないの?
EOF に達しはしたけど、読み込んではないよね?
何か二人で同じことを言おうとしてる気がしてならない。
実行すると-1返って来るよね 読み込んでるってことじゃないの?
とりあえずこんな感じだ。 #include <stdio.h> #include <ctype.h> int main() { int ch, b; FILE *fp = fopen("hoge.txt", "r"); if(fp == NULL) { return 1; } do { ch = fgetc(fp); b = feof(fp); printf("%c : %02X / %d\n", ch, ch, b); } while(!b); } T : 54 / 0 h : 68 / 0 i : 69 / 0 s : 73 / 0 : 20 / 0 i : 69 / 0 s : 73 / 0 : 20 / 0 a : 61 / 0 : 20 / 0 p : 70 / 0 e : 65 / 0 n : 6E / 0 ← n が読み込まれて、ファイルポインタは EOF に達しはしているが、まだ読み込んでないためそこが EOF かどうか分からないでいる ? : FFFFFFFF / 1 ← EOF が読み込まれたため、EOF に達した事が判明し、feof が真を返すようになる
>>76 -1 が返って来るのは、当然読み込んでるということ。
でも、その後にそれを表示してから、
その後にようやく feof をチェックしてるでしょ。
そっちのプログラムは。
で、そこでループが終了してる。
つまり、-1 が読み込まれた後に feof を実行すると
真を返すようになっている、ということだ。
fgetc()は、エラーとかファイルが終わってるとかで、読んだ文字がない時にEOFを返す。 「EOFを読み込んでいる」のではない。
「0 個のりんごがある」 と 「りんごが 1 個もない」 程度の話だよ、それは。
feofはファイルの末端に来ました fgetcは読んだ文字がないので-1を返しました feofは真を返しました って話?
ファイルポインタは初めてファイルの末端に来ました feofは偽を返しました fgetcはもう読み込める文字がないので-1を返しました feofは真を返しました こうだな。
初めて、は余計か。 ファイルポインタはファイルの末端に移動してきました feofは偽を返しました fgetcはもう読み込める文字がないので -1 を返しました feofは真を返しました こうか?
while(fgetc(fp) != EOF) の方がいいんじゃないの?
feof の挙動を調べたいみたいだよ。
1文字ずつ読んだ場合に加えて、いっぺんに読んだときどうなるかも調べてみては
>>84 それは趣旨が違うと思った
>feof()はファイルの終わりをどこで判定してるんでしょうか?
pthreadでデタッチスレッドを生成し、スレッドが終了した後に 仮想メモリが増えてしまいます。 #include <pthread.h> #define THREAD_COUNT 50 void *thread_func(void *arg); int main() { char command[128]; int i; pthread_t thread[THREAD_COUNT]; sprintf(command, "grep VmSize /proc/%d/status", getpid()); for (i = 0; i < 3; i++) { sleep(1); system(command); } for (i = 0; i < THREAD_COUNT; i++) { pthread_create(&thread[i], NULL, thread_func, &i); pthread_detach(thread[i]); } for (i = 0; i < 10; i++) { sleep(1); system(command); } return 0; }
89 :
88続き :2007/06/26(火) 15:06:07
void *thread_func(void *arg) { sleep(3); } が動かしたソースで、実行結果が↓こんな感じです。 VmSize: 1392 kB VmSize: 1392 kB VmSize: 1392 kB VmSize: 410996 kB VmSize: 410996 kB VmSize: 42356 kB VmSize: 42356 kB VmSize: 42356 kB VmSize: 42356 kB VmSize: 42356 kB VmSize: 42356 kB VmSize: 42356 kB VmSize: 42356 kB
90 :
88続き :2007/06/26(火) 15:10:54
色々調べたところ 410996kBは大体1392+8192kB×50(スレッド数) 42356kBは大体1392+8192kB×5 ぐらいになっているようでした。 8192kBはスタックサイズから来ているようで、スタックサイズを 変更してみたら仮想メモリサイズは変わりましたが、数式的には 上記と同じでした。 また、スレッド数を変えると410996kBのところがスレッド数に 応じた数に変わるのですが、最終的に落ち着く42356kBは 変わりませんでした。 増え続けることはないのでメモリリークとは違うと思うのですが 気にすることはないでしょうか。×5がどこから来ているのかとか どうも気になってしまって・・・ 何か分かりましたら教えてください。
91 :
88続き :2007/06/26(火) 15:11:47
すいません。ちなみに開発環境はRedHat 9.0、gcc 3.2.2です。
時間をずらして detach していった場合に 42356kB で止まるのだとしたら、 内部でいくつかの領域を確保したままにしてるのかも? 次にまた使うときのためにとか。 MacOSX 10.4.10 gcc 4.0.1 だと、 スレッド1つ分のサイズが残るみたいだ。
>>91 仮想メモリサイズの制限を越えたための拡張とかは?
94 :
88続き :2007/06/26(火) 15:49:52
>>92 色々観察してみると、同時に実行されるスレッド数が1つの場合、
1392kB+8192kB×1くらいになって、スレッドが終了しても
減りませんが、何度スレッドを起動してもこれ以上増えることは
ありません。
同時に実行されるスレッド数が5までの場合もこの傾向は同じ。
6を超えるとスレッド実行中の仮想メモリは増えるけど、スレッドが
終了すると5スレッド分の仮想メモリ量までは戻る、という
感じです。
5スレッド分は次回使いまわすために確保するようになってる
んでしょうかね。
>>93 ulimit -a で見たら、仮想メモリはunlimitedに設定されて
いました。
strcpyなんて使うなよ・・・
あっ、やっぱ問題があった、だから 使うなよ って後から言うのは卑怯。 さも知っていたかのようなことをいうやつに限って、そいつ自身が ありきたりのタブーをやらかしていることがある。
いやいやせめてstrncpy使うだろ 昔から問題は指摘されてたんだしさ
単に文字列の整形ならsprintf()の方がいいと思う
ブラックジャック先生なら整形に失敗しないYO!
おいっ、おまいら、はよ1進数について議論せいや?どんな推論が出るかにゃ〜〜 ♥
wktk
実質0しか表現できないっしょ 数え始めた瞬間に桁上がりの無限ループ
>>104 それ、問題提起した俺が最初に提唱したぞな。それじゃ詰まらないからぁ
ここであらぬ妄想をぶっこく香具師らに推論させたいのよ ♠
おまいの提唱なんぞ知らんがな
>>102 見てぱっと思ったから書いただけじゃ
Wikipediaに答があることをいつまでぐだぐだと……
それ以前にスレ違い。
気を使うのは外からの入力に対してであって 自分で作って自分で使うバッファは好きなの使えばいいと思う
>>98 >さも知っていたかのようなことをいう
知っててもおかしくはない…というより寧ろ、技術者としては知ってて当然。
君が無知だっただけ。
>>110 勿論。
>>111 > 君が無知だっただけ。
???
>>98 のどこをどう読んだら無知になるんだろうか?
>>98 なんて恥ずかしいセリフを言える時点で頭おかしい。
115 :
デフォルトの名無しさん :2007/06/27(水) 11:00:28
いや、恥ずかしいのは無知だとかありえない勘違いをしたこいつ↓
111 名前:デフォルトの名無しさん 投稿日:2007/06/27(水) 10:00:38
>>98 >さも知っていたかのようなことをいう
知っててもおかしくはない…というより寧ろ、技術者としては知ってて当然。
君が無知だっただけ。
知っててもおかしくはない…というより寧ろ、技術者としては知ってて当然。
君が無知だっただけ。
知っててもおかしくはない…というより寧ろ、技術者としては知ってて当然。
君が無知だっただけ。
知っててもおかしくはない…というより寧ろ、技術者としては知ってて当然。
君が無知だっただけ。
知っててもおかしくはない…というより寧ろ、技術者としては知ってて当然。
君が無知だっただけ。
知っててもおかしくはない…というより寧ろ、技術者としては知ってて当然。
君が無知だっただけ。
116 :
デフォルトの名無しさん :2007/06/27(水) 11:02:10
技術者としては知ってて当然。 技術者としては知ってて当然。 技術者としては知ってて当然。 技術者としては知ってて当然。 技術者としては知ってて当然。 技術者としては知ってて当然。 技術者としては知ってて当然。 技術者としては知ってて当然。 技術者としては知ってて当然。 strcpyの問題点を知っているだけで技術者気取りになれる新米プログラマに失笑です ><; ちなみに、そんなこと俺も当然知ってたけど、なんで俺が無知になるわけ?w Lhacaにそれが使われていたなんて、俺は知らなかったけど、strcpyくらい当然知ってましたよ ( ^ー^)b
キチガイはすぐ暴れるから困る。
111 名前:デフォルトの名無しさん 投稿日:2007/06/27(水) 10:00:38
>>110 勿論。
↑おいおい、すでに問題としてあげられたのに、何知ったかぶっこいて同意してんの?(苦笑)
>>111 ←こいつ最高に知ったかのアホだな。恥ずかしい。プログラマなんてやめた方が良いぞ?
人生の大半を無駄にして終わるぞ?
勘違い野郎こそ知ったかぶるから困る。何これ?痛すぎ、必死すぎ
>>97 =
>>99 =
>>111 < こういう奴が三流プログラマになって世にあらぬ
欠陥品を流通させちゃうんだよね。で、後でアップデートパッチでサポート。
サポートしてんだからちゃんと仕事してますよって間違ったアピールをして
ユーザが離れていって廃れるソフトウェア会社勤務乙。
URLエンコードってどうやるんですか?
C勉強したいと先輩に言ったらC♯勉強しろと言われたんですが、 CとC++とC#ってどんな違いがあるんでしょうか?
なんでその時に先輩に直接聞かなかったの?
>>121 仕様を聞いてるのかコーディングを聞いてるのか
コーディングです、入力した文字をGoogleで検索させたいのですが
エンコードの必要な文字コードかどうか判定して、 必要ならエンコードすればいい。
>>125 まずUTF-8に変換して、1バイトずつ見て非ASCIIを変換。
仕様はわかってるらしいから、そういう説明じゃ足りないんじゃないのかな 数値を16進文字列にするやりかたがわからないとかじゃないの?
unsigned char にキャストして sprintf で %%%02X すりゃいいと思うけど、 sprintf を使う場合はバッファオーバーフローに注意だな。 別にこの程度なら自前で変換してもいいんだけどね。
質問です。 C言語って色々命令作れる前に、最初からhファイルを読み込んで使える、 いわばインストール時に標準搭載されている命令ってあるじゃないですか。studio.hのprintfやmath.hのsqrtとか ああいう命令を分かりやすくどんな用法で使えばいいのかが全て網羅してある 本またはサイトはありますか?
ああ、「本または」って書いてあるね。すまんすまん。 じゃ、「作ってわか(ry
文字列の数字を消したいプログラム(例えばAB1C9をABC)をつくりたいんですけど 下のソースではうまく消えません。もしよければどのようにすればいいか指導お願いします。 #include <stdio.h> void kesi(char *str){ char c; while(*str!='\0') { c=*str; if(c<'0'||c>'9'){ //数字でないならば *str=c; } str++; } } int main(void){ char str[100]; scanf("%s",str); kesi(str); printf("%s",str); return 0; }
消した分だけ後ろの文字列を前に詰めないといけない。 void kesi(char *str) { char *to = str; while (*str != '\0') { char c =*str; if (!isdigit(c)) { *to = c; to++; } str++; } *to = '\0'; }
138さん返信ありがとうございます。 char *toとしてますが、 またポインタ宣言しなければ、ダメなんでしょうか?? あと初心者なのでisdigitとかまだよくわからないです…。もしよければアドバイスおねがいします
宣言しなきゃコンパイルできないし、isdigitはググれば山ほど出てくる
137のソースではただのchar c; としてポインタで宣言しないでも コンパイルは通ったんですけど…なぜポインタを使うのかよくわからなくて…。
138では、詰める前の文字を指すのにstrを使い、 詰めた後の文字を指すのにtoを使っている。
ポインタを使わないと、どこに文字をいれていいかわからないから
>>142 さん、わかりやすかったです!ポインタの理由が理解できました!
キューのプログラムで #define QUEUE 5 static int i = 0; i = (i+1)%QUEUE; で次の添字が得られる とか書いてあるんですが、よくわかりません。 常にiは0である気がするんですが、どこが間違っています?
(0+1) % 5 == 1 (1+1) % 5 == 2 (2+1) % 5 == 3 (3+1) % 5 == 4 (4+1) % 5 == 0 (0+1) % 5 == 1
148 :
デフォルトの名無しさん :2007/06/28(木) 00:16:59
初期化とキーボード入力以外で文字列を一回で代入する場合はstrcat()しかないですよね?
そんなことないよ
>>147 ありがとうございます。
ですがもう少し。
a%bってあったら「aをbで割った余り」ですよね?
だとすると、
(0+1)%5 = 1%5 = 0?
ではないのですか?
って書いたらわかりました。 スレ汚しごめんなさい。
1÷5 1は5で割り切れないので終了。余り 1
strcpyとか
>>151 strncat,strcpy,ctrncpy,sprintf,sscanf
ざっと思いつくのでこの程度。
あと、可変個引数使うときにある、printfのやつ。
あんま使ったこと無いから忘れたけど、vsprintfだっけ?
>>150 おぬしは間違いなくstaticについて理解していない。
なぜstaticが付いているのかを考えるのじゃ
質問です。 BASICのgotoみたいな命令はないのでしょうか?
159 :
デフォルトの名無しさん :2007/06/28(木) 01:02:33
Cで書いてコンパイルしたファイルを人に送ってもその人は実行できないんですか? というかできなかったのです。一瞬だけ実行されてすぐ消えてしまいます。 どうすればいいかわかりますか?
>>158 gotoというそのまんまの命令がある
loop:
printf("test");
goto loop;
みたいに使う
>>159 コマンドプロンプト経由で使えばおk
あ、ちなみにif文で条件を満たしていなかったらmainの一番上まで戻るというのがやりたいのですが・・・・
162 :
デフォルトの名無しさん :2007/06/28(木) 01:10:52
>>160 そのファイル名のみを相手のコマンドプロントでコマンドさせるってことですか?
構造体とポインタはどちらのほうが理解するのが難しい?
>>161 int main(void){
start:
〜いろいろな処理〜
if(条件を満たしていない) goto start;
多分普通の人であれば
int main(void){
do{
〜いろいろな処理〜
}while(条件を満たしていない);
おつむのレベルによる。
>>162 渡したファイルはexe?
コマンドプロントで、exeのあるディレクトリに移動して実行すればオケ。
>>163 一般的にはポインタが難しいと言われる。
>>162 1.コマンドプロンプトを起動してもらう
2.コマンドプロンプトにexeファイルをドラッグアンドドロップしてもらう
3.Enterキーを押してもらう
これが一番手軽だと思う
何に便利とか言い出すから一向に理解できないんだろ。
171 :
デフォルトの名無しさん :2007/06/28(木) 01:19:15
>>169 Nバイトの構造体配列をソートして並び替えることを考える。
このとき、Nバイトのコピーが頻繁に発生することになる。
構造体に対するポインタの配列として保存していた場合、ポインタのソートで済むことになる。
例えばポインタが4バイト、構造体が100バイト超とかで配列が1000超とかだとすれば
どちらが効率的かはわかるよね?
174 :
デフォルトの名無しさん :2007/06/28(木) 01:24:45
Cpad for Borland...ってやつで書いてるんですけどexeファイルがありません。 どうすればいいですか? 171と同一人物です
>>170 お前がその便利さを知らない、説明できないだけだろ?えせプログラマは
こんなところで質問者をたぶらかしてないで、へちょいプログラマで満足してろよ?
>>174 ファイルを保存している場所と同じ場所にexeファイルがあると思われ
178 :
デフォルトの名無しさん :2007/06/28(木) 01:34:22
>>176 あるにはあるのですが、ドラッグアンドドロップはできませんし、
そのディレクトリに移動して 〜.exe と打っても実行されません
>>178 コマンドプロンプトって何かわかってるか?
180 :
デフォルトの名無しさん :2007/06/28(木) 01:42:45
なんか全体的に黒いやつですよね? わかってるつもりです
>>180 「notepad」って打ってメモ帳が起動するか?
ドラッグアンドドロップでフルパスが表示されて、エンター押して実行できると思ったんだけどなぁ
183 :
デフォルトの名無しさん :2007/06/28(木) 01:48:14
>>182 メモ帳はでてきます。
でもファイルをドロップしようとすると○の中に×が入ってるようなのが出てきて
できません
もしかしてvistaか?
>>183 ちょっwwwwwww伏字エロいwwwwwwwww
ティ○ポの中にオ×コが入ってるようなので とか妄想しちゃうぞwwwww
>>183 xpとかだとドラッグアンドドロップできないようになってるのかな?
じゃぁあきらめてフルパス(c:\cpad\test.exeみたいなやつ)を打って実行するべし
入力面倒だけど。
187 :
デフォルトの名無しさん :2007/06/28(木) 01:54:18
>>186 Vistaですよ。
かなりめんどいってことですね〜〜…
ありがとうございました
VistaはD&Dできないのか・・・ ひとつ勉強になった。
セキュリティ云々でできなくなったそうだ
なぁ〜〜に、こうすりゃええがな。XPを仮想PCにインストール。仮想PCでプログラミング あっ武勇伝、武勇伝、武勇でんでんででんでんっ♪
ポインタが無かったらprintfすら・・・
ファイル操作も出来ないね
2つの文字列を指すポインタ(例えばs1はABC、s2はABを指してる)で 下のソースコードだと2つの文字列が改行にいくまで繰り返すって言う意味ですかね? while((*s1 != '\n') || (*s2 != '\n')) {〜〜 s1++; s2++}
(;^ω^)恐ろしいコード
すいません、ちょっと適当に書き込んだんで…。 ホワイルの中身の意味が知りたくて。
>>194 そのロジックだと、s1、s2の改行文字の位置が揃っていないと誤動作しそうだが。
#つーか、>194自身が挙げたサンプルで死亡確定だな。
198 :
デフォルトの名無しさん :2007/06/28(木) 07:57:55
>>194 s1にもs2にも改行コードないからプログラム起動して即吹っ飛ぶ。
s1がABC\n、s2がAB\nだったとしても一致しないのでやっぱり吹っ飛ぶ。
そのコードはs1とs2の改行コード位置が一致した場合にループ抜ける。
〜〜の中にきっとbreakが含まれてるんだ
C言語の精度って小数点以下いくつなんでしょうか??
言葉が足りなかった。 IEEE 方式のマシンが多い、と。 別にエクセス 64 のマシンでも C は使える。 C かどうかで決まるものではなく、 CPU が何かによって決まるもの。
うん、それで、小数点以下いくつなんでしょうか??
>>203 だから小数点以下いくつという形の精度じゃないと。
「浮動」小数点ってのは、そういう事だ。
有効桁数って、確か中学で習うよな…?
10進数だとIEEEの64ビット浮動小数点は小数点以下15桁ぐらいかな。 但しそれに掛ける10のn乗という指数が付くわけだが。
有効桁数15〜16桁あたりだな。 本当は2進数で考えないといけないんだけど。
209 :
207 :2007/06/28(木) 14:21:03
#include <stdio.h> #include <values.h> int main(void) { printf("%d, %Lg, %Lg\n", sizeof(long double), LDBL_MAX, LDBL_MIN); printf("%d, %g, %g\n", sizeof(double), DBL_MAX, DBL_MIN); printf("%d, %g, %g\n", sizeof(float), FLT_MAX, FLT_MIN); return 0; } gcc 4.1.1 (i386-redhat-linux) で上記のソースをコンパイルして 動かすと結果はこう出る。 12, 1.18973e+4932, 3.3621e-4932 8, 1.79769e+308, 2.22507e-308 4, 3.40282e+38, 1.17549e-38 e から後ろの部分が指数で「掛ける10のn乗」を表す。 3.3621e-4932 は 3.3621 掛ける10の -4932 乗だ。 但し上記の結果は環境依存で、同じ gcc でもコンパイルオプションに よっては変わってしまう。だから全てについてこうであるという保証は できない。(values.h も gcc 独自のヘッダかも知れない)。ただ大雑把に 言えることは float よりは double、また double よりは long double の方が多くの範囲をカバーできるかも知れないというだけだ。 (コンパイラによっては long double はないかも知れないが)。
ISO準拠の処理系ならlong doubleは必ずある。 209が使っている定数は<float.h>で提供されている。
long double は必ずある。 しかし、double と同じサイズのこともある。
212 :
デフォルトの名無しさん :2007/06/28(木) 17:10:52
putchar関数の意味がよくわかりません。 質問が抽象的すぎてごめんなさい
標準出力に文字(char)を一文字出力(put)する
214 :
デフォルトの名無しさん :2007/06/28(木) 17:42:10
…? putchar('\n') ってのはどういうことですか?
標準出力はわかるか? 通常は画面だと思っていい。 \n はわかるか? 改行コードをあらわすエスケープシーケンスだ つまり、画面上で改行する、ということ
216 :
デフォルトの名無しさん :2007/06/28(木) 17:50:19
それは printf("\n") とは違うんですか?
printf は文字列を扱う たまたまprintfで1文字出力するなら、putchar と同じ様になるな。 でも、printf の第一引数の文字列は % とか入ると違ってくるけどな。
"\n" は文字列 '\n' は文字
219 :
デフォルトの名無しさん :2007/06/28(木) 18:31:55
でもこの場合では意味することは同じなんですよね? というか、putcharでできることはprintfでもできるんですか?
できるけど、効率は悪い。
221 :
デフォルトの名無しさん :2007/06/28(木) 18:35:29
それは打つ文字数が多くなるとかいうレベルの話ですか? プログラムの内容には関係ないですよね?
あります。
printf は文字列を解析して % が出てきたらどうするかとかいう処理を行ってる。 ま、出力自体のコストに比べりゃ微々たる差だがね。
適材適所だ printfで全部まかなうのもいいし、使い分けるのもいい。 同じことができるなら、片方はまったく無駄だと思ってるなら それはキミが初心者だから。
最近のコンパイラは賢いから、
>>216 なんかはputchar('\n');に最適化されるけどな。
そこまでするのか! っていう最適化が 意外とされてるんだなあ。
gccは printf("%s\n", "hoge"); を puts にしてくれたりするよね。
>>227 こういうのってどうやって知るんですか?
○は□に最適化されるとか
逆アセンブルしてもいいし、 両方のパターンを書いてコンパイルして バイナリ比較して等しくなるかどうか確認したのでも。
すごい!
普通に gcc -S
特徴的なものは宣伝していたりマニュアルに書いてあったりもする。
スーパーハカーは自分で逆アセして知る。 一般人は掲示板で知る。
確かに。 普通のハッカーなら掲示板でヒントを読んで自分で試して知るだろうな。
235 :
ぴっころ :2007/06/28(木) 21:32:59
突然お邪魔致します。ぴっころです。 2進数で表した時、2の倍数は最下位ビットが0になる事が分かりました。 では3の倍数は何かこのような決まりはあるのでしょうか?
3進数で3の倍数は最下位ビットが0
237 :
ぴっころ :2007/06/28(木) 21:36:37
言葉足らずで申し訳ありません。 2進法で表した時です。
ぴっころって誰だよ。
>>235 ヒント1 : 2の倍数とは偶数のこと
ヒント2 : 3の倍数を並べてみよう
2 進法では別に 3 (11) の倍数に特徴はないなあ。 3 (11) で割ったら余りが 0 になるということくらいだな。
>>235 数学の問題だなあ。
3で割ると余り0
なんてのはあまり意味ないか・・・。
10進数で表した時に各桁を足して3の倍数ならそれは3の倍数
(123は1+2+3=6なので3の倍数)なんてのもあるが、関係ないね。
3の倍数を2進法で表したものは、正規表現/(0|1(00)*1)*/にマッチする。
243 :
ぴっころ :2007/06/28(木) 21:51:33
>>238 ドラゴンボールのぴっころから取らせて頂きました。
>>239 11
110
1101
1100
1111
10101
11000
11011
繰り返しもあるような無いような・・・。
ちょっと僕のキャパでは厳しいです・・・。
>>242 発想はいいがちょっと惜しいな。
1000000001の間に11を入れて1011000001も3の倍数だ。
>>243 うそだ!
NHKのじゃじゃまる、ぴっころ、ぽろりのぴっころだろ?
247 :
デフォルトの名無しさん :2007/06/28(木) 22:06:53
bccってのをXPで使ってたんですが、vistaに変えたんですが環境設定ソフトでPATHの設定が出来ませんってのが出るんですが・・・・ vista出使える環境設定ソフトかPATHの設定方法を教えてください。
248 :
ぴっころ :2007/06/28(木) 22:08:04
11 110 1101 1100 1111 10010 10101 11000 11011 11110 11→10→01→00 ・・・。 ちょっときついです。 教えてもらえると助かります。
1101のどこが3の倍数なんだよ。
1101 1100 数が減ってるな まぁ1001の書き間違いだろうからそれくらい勘弁してやれ
>>247 マイコンピュータのプロパティの中にない?
XP/2003まではそこにあるんだけど。
6bitでカルノー図書いてみたんだが一切簡単化できねーから周期性は無い臭い
253 :
デフォルトの名無しさん :2007/06/28(木) 22:30:16
>>251 システムのプロパティの中に環境変数でpathってのは見つけましたが違います?
マイコンピュータでプロパティやるとシステムのプロパティかCドライブのプロパティあたりしか出てきません。
3の倍数で偶数に該当するものをリストアップしてやんよ 6 000000110 12 000001100 18 000010010 24 000011000 30 000011110 36 000100100 42 000101010 48 000110000 54 000110110 60 000111100 66 001000010 72 001001000 78 001001110 84 001010100 90 001011010 96 001100000
256 :
デフォルトの名無しさん :2007/06/28(木) 22:35:43
257 :
デフォルトの名無しさん :2007/06/28(木) 22:39:43
すみません、学校の電卓プログラム問題で、わからない事があるので教えてください。 char *get_int(char *b, char *i) { int sign, num = 0; if(*b == '-') { sign = -1; b++; } else sign = 1; /*初期値*/ *i = 0; /*スペーススキップ*/ SKIP(b); /*十進数文字である間繰り返し*/ while (isdigit(*b)) { num++; /*これまでに得た整数の位取りアップ*/ *i *= 10; *i += (*b - '0'); b++; } /*十進数文字がなければエラーリターン*/ if (num == 0) b = NULL; return b; } 上記は自分がわかる範囲でマイナス演算子を付け加えたのですが、 これからどうしていいのかわからないので、 どなたか教えてください。よろしくお願いします。
> これからどうしていいのかわからない だったら、それはお前のわかる範囲ではない。
>>257 その一部じゃさっぱり。うpロダ使って全体をうpせい。それから実行結果の例も書いてくださいな
(*b == '-') かわいい ∧∧ 〜(*b == '-') <ニャー >> >>
>>248 全ての3の倍数は、その数を3で割っても最下位ビットは変わらない。
x = ( 'A'); やる気ねぇ〜顔
263 :
ぴっころ :2007/06/28(木) 22:47:09
>>254 なるほど。
6 00 00001 10
12 00 00011 00
18 00 00100 10
24 00 00110 00
30 00 00111 10
36 00 01001 00
42 00 01010 10
48 00 01100 00
54 00 01101 10
60 00 01111 00
66 00 10000 10
72 00 10010 00
78 00 10011 10
84 00 10101 00
90 00 10110 10
96 00 11000 00
下二桁 00→10の繰り返し、
下二桁より上 1ずつ増えているのは分かりました。
ですが、これで1000000001の間に11を入れて1011000001も3の倍数だ。
が何故言えるのでしょう?あと、3の倍数に偶数が入ってくる理由も・・・。
+= (*b - '0'); < 私を置いていくにゃ〜
>>263 それは3の倍数じゃなくて6の倍数でわ?
3の倍数 かつ 偶数 = 6の倍数ですよ
ファイルを指定した場所へ移動するにはどうしたらいいですか?
>>256 BCCをインストールしたディレクトリのBinディレクトリとかのフルパスをPATHとかに追記する(セミコロンでつなげる)
>>263 単にそれは、例えば10進法で、15の倍数を並べたら一の位に0と5が交互に現れる、
ってことを言ってるのと同じだよ
270 :
デフォルトの名無しさん :2007/06/28(木) 22:54:11
3の倍数、偶数抜き。何か法則がある? 3 000011 9 001001 15 001111 21 010101 27 011011 33 100001 39 100111
272 :
デフォルトの名無しさん :2007/06/28(木) 22:59:31
A(n) = A(n-1) + 6
273 :
デフォルトの名無しさん :2007/06/28(木) 23:13:28
>>235 3の倍数は、奇数ビット目の1の数と、偶数ビット目の1の数の差が、3の倍数になる。
ただし、差が3の倍数といっても数が小さいうちはずっと0。
例:39
100111、奇数ビット目=2、偶数ビット目=2、差=0
分からないなら、10進数で同じコトを考えてみればいいよ 10進数だと、10の倍数は1の位が0だということが分かりました。 では11の倍数は、何か特徴があるのですか? 11 22 33 … 1の位が1ずつ増えていくことが分かりました! …この結果で何か得られることはあると思うか?
275 :
デフォルトの名無しさん :2007/06/28(木) 23:49:23
unsigned char型の配列にbmpの画素の値を読みます。 これをソートするんですが、 ソートする関数の引数のところを void quicksort(char *array,int lower, int upper) とするとソートが正しくないことがあります。 void quicksort(unsigned char *array,int lower, int upper)にするとうまくいくようなきがするんですが、 あってますか?
とりあえず関数のシグネチャをプロトタイプにちゃんとあわせなさい
すいません。よくわからないです。 学校の課題なんですが、unsigned char型は問題ですでにつくられていて、 それを改造してるんです
それはきっとcharが符号付だからということなのだろう。
なるほど。 void quicksort(unsigned char *array,int lower, int upper)にすれば ソートはちゃんとうごいてますか? 一応実際の画像のソート状況を確認したら平気っぽかったですが
280 :
ぴっころ :2007/06/29(金) 00:40:39
ぴっころです。答えて下さった方々ありがとうございました。 失礼します。
3の倍数は1が常に偶数個
定数はdefine, const, enumのどれで指定するのが定跡でしょうか?
定数じゃないのばっかじゃん
?
て・・・定石なんてないのさ
テキストファイルをよみこんでたとえばファイルに cccchaa というのがかいてあったら下のような感じで画面に表示したいんですけど どんなソースコードですかね?アルゴリズムがピンとこないのでお願いします。 c→4 h→1 a→2 #include <stdio.h> int main(void){ FILE *fp,*fut; char sfn[80]; char yomi[256],mawasi[256]; int i; scanf("%s",sfn); if((fin=fopen(sfn,"r"))==NULL)return -1; fout=fopen("comp","w"); i=0; while((yomi[i]=fgetc(sfn))!='\0'){ i++; } fclose(fp); fclose(fut); return 0; }
・読んだ文字が前回と異なっていたら カウンタをリセット(0にする)。読んだ文字を覚えておき、カウンタをインクリメント ・読んだ文字が前回と同じならそのままカウンタをインクリメント
>>281 10101 (10進数で21)の時点で既に違うんだが。
一般的には、
>>273 が正解
もうこの話題終わってるけどね
構造体のint型の要素と、構造体外のchar型の変数とstrcmpで比較したいのですが int型の要素をどうchar型に変換するのかわかりません。 何か良い方法はありますか?変換は逆でも構いません。
atoi とか sprintf とか
先日C言語の勉強をしていたら以下のプログラムがありました。 なんで、プログラムを実行して、この結果が出てくるのか全く わかりません。プログラムの結果がなぜそうなるのか内容を出 来るだけ詳しく教えてください。初心者なのでなるべく丁寧に お願いします。もし、プログラムのタイプミスがあったらすい ません。 #include<stdio.h> #include<string.h> main(){ char c[3]; char s1[]="abcdefghijklmnopqrstuvwxyz" char s2 [100]; s2[0]='\0'; printf("s1 inital value:\"%s\"\n",s1) printf("s2 inital value:\"%s\"\n",s2) if cstrcmp(s1,s2)==0){ printf("s1==s2\n");} else{printf("s!=s2\n");} printf("Push ENTER to proceed."); fgets(c,2,stdin); strcpy(s2,s1); printf("s1 current value:\"%s\"\n",s1); printf("s2 current value:\"%s\"\n",s2); if(strcmp(s1,s2)==0) { printf("s1==s2\n");} else{prinf("s1!=s2\n");} }
この結果ってどの結果
「この」結果
sayonara
さよならbyebye〜元気でいてね 年に二回くらいのクソレスならキャッチするよ〜
2の倍数はある数を2倍したもの 2倍するとは、2進数だと左に1ビットシフトしたもの ゆえに、一番下のビットは必ず0になる。 3の倍数もこれに習ってやってみ。
291です なんでENTERを押すと次の実行結果が表示されるのな何でですか? ↑のも質問ですがこのような感じの内容を教えてください
>>297 s1 inital value:"abcdefghijklmnopqrstuvwxyz"
s2 inital value:""
s!=s2
Push ENTER to proceed.
s1 current value:"abcdefghijklmnopqrstuvwxyz"
s2 current value:"abcdefghijklmnopqrstuvwxyz"
s1==s2
これのどこがわからないの
>>291 stdio.h には、C標準ライブラリのコンソール出力関数のプロトタイプ宣言があり、
そこで宣言されているprintfを使っているから、結果が出力されるんです。
>>291 学生?俺もだけど
何の関数を使うためにstring.hをインクルードしているか?
strcmp(),strcpy関数はどういう関数か?
fgetsはどういう関数か?
を調べればたぶんわかると思うよ。
if構文とか'\0'とかprintf()とかエスケープ文字とか
文の終わりに;をつけるとか(付け忘れが多すぎたからあえて指摘)
くらいは知っているだろうし、人にきくほど難しいものではないとおもう。
>>291 >char c[3];
>fgets(c,2,stdin);
こんな阿呆なコード、誰が書いたんだ?
本質的じゃないトコにつっこむのもなんだかなー
だって、阿呆なんですもの
その程度のことを見つけてアホアホ得意気になる香具師は痛々しい。
まあ、fgets のサイズ指定は ヌルターミネータ込みのバッファサイズを指定することくらいは ちゃんと知っておいた方がいいとは思う。
しぜおf使おうぜ?
307 :
デフォルトの名無しさん :2007/06/29(金) 17:55:27
#include <stdio.h> int main(void) { int x,y,z,s; printf("何cmから:"); scanf("%d",&x); printf("何cmまで:"); scanf("%d",&y); printf("何cmごと:"); scanf("%d",&z); s = (x - 100)*0.9; x = x + z; for (; x <= y; s) printf("%dcm %.2fkg\n",x ,(double)s); return 0; } これだと x+5 についての場合のみ永久にブァーッと出てきます。 x〜yの範囲内にするにはどうしたらいいですか?
for (; x <= y; x += z) { double s = (x - 100) * 0.9; printf("%d cm %.2f kg\n", x, s); }
309 :
デフォルトの名無しさん :2007/06/29(金) 18:12:13
>>308 ありがとうございました。
この場合繰り返しが行われてる式は
x += z と double s =(x - 100)*0.9 と printf("%dcm %.2fkg\n",x,s)
の3つですよね?繰り返したい式が2つ以上あるときは
forの()の中に1つ書いて、()を閉じてから残りの繰り返したい式を書くということでいいんですか?
procedure a: Integer var int C; beigin a := 0; end; がうまくイカなんだがなんだろ
beigin → begin つーかこれPASCAL・・・
Pascal って人間は考える葦とかいっていた人か?
さつま芋とか水で洗って食う動物じゃね?
int* p; /*ポインタのデータ*/ int a = b/*p; /*b÷(pの先のデータ)→a*/; 割り算ができね
アライグマパスカル、うが
/ と * の間に空白開ければいいじゃん。
今でも、糞つまんないCPUのロジックは大方割り算なのは確かだw
今までで、プログラムって訳に起つよな(^^って思えたのは perlとrubyとMLとエクセルで使うVBAくらい。 C++とかJavaは嫌な思いしかさせてくれない。
で、Cはどこ?
here
Cは昔のアセンブラみたいなもん。 良いも悪いもない
>>322 そうだと思うけど、まずはやってみればいいんでね?
>>322 そのコーディング方法が分からないんで無ければ
画像処理スレかどっかで聞いた方がいいんでね?
最近ちょっとさわり始めたのですが、 memcpyのように引数にvoid*をとるとき、どうやってvoid*の中の物を 取り出すんですか?普通に配列のように[0]とかってやってもエラーになるし…
適当なポインタ型にキャストすればいい。
>>328 その場合、中身が構造体などの場合にはどうしたらいいんでしょうか?
char*などにキャストした後から戻せるのでしょうか?
構造体でキャストすればいいんじゃ
>>330 該当する構造体でキャストすればいいのはわかるのですが、
memcpyのようになんでもコピーできるようにするにはどうしたら
いいのかなと思ったのですが、これはあまりmemcpyを
使わない方がいいと言われるのと何か関係があるのでしょうか?
そんなもんchar*にキャストして1バイトずつ読み書きしているだけと思っていればいい。 実際には高速化するため複数バイトずつ読み書きするなど工夫しているいるけど。
>>332 参考になりました!
ありがとうございます。
まぁ、間違っても構造体のコピーにmemcpy()なんて使うなよ。
表示した画像を消すときはどんな関数を使いますか?
CLS 3
あ、Cで表示した画像を消すときはどんな関数を使いますか?
画像を表示するのにどんな関数使ってますか?
>>338 真っ白な画像を用意して、消したい画像の代わりに表示してはいかがでしょう。
もはやCのスレではなくなったな
exit(1);
教えてください。 main関数から、ある関数に引数を渡す場合は、次のような 感じで渡してもOKですか?ダメみたいなんすが、その理由が わからないです。 もちろん、実行する場合は引数を指定します。 a.out A.txt のように。 extern int p(char *filename) int main(int argc, char*argv[]) { p(argv[1]); }
&argv[1] argv
>>344 どうダメなの? それでいけると思うのだけど。
>>345 プロトタイプ宣言と型が合いません。
単にダメって言うんじゃなくて具体的にどんなエラーがでたとかさ・・・
パス指定なしのファイル名だけ書いていて、起動ディレクトリと違うところにあって見つからないとか。
申し訳ないです。 セグメンテンションフォルトです。
問題があるのはp()の方だろ
>>350 なるほど、呼び出す先のp関数がわるのかなぁ。
引数でわたってきたファイル名をfopen()を呼んでいるだけなんですが。
微妙に日本語がおかしいのが気になる
どうもあがとうございました。 呼び出す先のp関数が悪いみたいです。 if (f=fopen(filename,"f")) "f" -> "r" ですね。すいませんでした。 このようなif文で代入はOKなのかなぁ?
>>353 間違ってはいないがお勧めしない。
Cのエキスパートを自称するロートルは、しばしば「代入と比較を一行で書けるのがCらしさだ」とのたまうが、
バグの混入の原因になりかねないし、第一必ずしも読み易くない。
ifの中で代入すると大抵警告が表示されるしな。 if ((f = fopen()) != NULL)とするやつもいるが俺は好きになれない。
80カラムに収まるならついやっちゃうな・・・ f=NULL; f=fopen("ようじょ", "w"); if(f==NULL){ puts("ひゃぅん?"); } ここまでするとクドイ感じもするが・・・
fopenって失敗したらNULL返すんだからf=NULL;は要らなくね?
我が家ではこうしてますね・・・ 基本的に使う前と使った後はクドクドと初期化
よくこういうふうにやる FILE* fp = fopen(); if (f)
FILE* fp; FILE *fp; この二つの違いって何かあるの? 単なるコーディング流儀の違い?
流儀の違い
そう、流儀の違い。 構文上は、FILE*fp;もFILE * fp;も可能。
FILE * fp ; だっていいZE
>>360 前者はC++使いに多く、後者はC使いに多い。
両方使う私は、だからと言うわけではないがFILE * fp = fopen(...);と書く。
365 :
デフォルトの名無しさん :2007/06/30(土) 11:33:59
for文とwhile文の明確な違いって何ですか? たとえばfor文ではできるけどwhile文ではできないこととか・・・。
continue 時にも for(A;B;C) の C が実行されるってのが while だと実現が面倒。
367 :
デフォルトの名無しさん :2007/06/30(土) 11:41:46
バッファの割当の数とか数字を#defineしてしまうのは、なぜですか?マジックナンバーを使いたくないのはわかるのですが、 その都度malloc、もしくはreallocしてはいけないのですか? または、そのバッファの割当の数はどうやって決まるのですか? どうもCを書いていると全部mallocしたくなるのですが、C言語のハッカーさん教えてください。
for文の括弧内の式はどれも省略可能。 while文の括弧内の式は省略不可能。
forは式を省略できるがwhileは省略できない。 なので、無限ループはwhile (1) {...;}ではなくfor (;;) {...;}を使う。
もうしわけないです、コーディングは以下の理解でよいでしょうか。 だめ:× if (f=fopen(filename,"r")) よい:○ f=fopen(filename,"r"); if(f!=NULL)
>>367 malloc したら free しないとダメじゃん。
管理の手間が増えるからなるべくやりたくない。
必要な時はするがね。
ガベコレのある言語と一緒に考えない方がいいよ。
>>370 「だめ」ではなくて、「好ましくない」程度で。
他人が書いたものを読むときに、「だめ」と思わずに許容してあげましょう。
>>370 文法上の問題はないが推奨されない:△
if (f=fopen(filename,"r"))
よい:○
f=fopen(filename,"r");
if(f!=NULL)
374 :
デフォルトの名無しさん :2007/06/30(土) 11:50:26
whileでは無限ループはできないんですか?
375 :
367 :2007/06/30(土) 11:54:14
>371 どもです。なるほど。確かにガベコレある言語でしかマジメに開発したことがないので、納得できていませんでした。 別物ですね。別物。 でも、その際に使用するMAX_BUF_NUMとかは一般的に1024とか使用されているのですが、何ゆえその数字が決まるのですか? 質問ばかりですいません。
1KB程度でいいんじゃねって感じじゃね?
377 :
367 :2007/06/30(土) 12:15:56
> 376 サンクス しかし、1KBにするか4KBにするかといったことに悩むんですよね。 作りたいアプリの仕様が1KB程度だから、ここは1KBにするか、と考えるのは普通のような気もするのですが、 アプリを作りたいのではなくて、自分用の便利ライブラリを作成する際にどの数字を採用するか、 と考えるのが非常につらい。 つか、こんな考え方の俺ってガベコレ言語を使いすぎですか。
ライブラリならバッファの大きさなんてユーザから指定を受け付けるものに決まっているだろ。
C が嫌なら C++ で string とか vector とか使えばいいよ。
>>369 for(;;) は可読性が乏しいから while(1) の方が好きだな。
>>377 Cでライブラリ作るときは内部でバッファを抱えない。
(char *buf, size_t bufsize)
で受けるのがお約束。
高級にやりたいならmalloc, freeでやってバッファがあふれたらreallocで拡張。
手を抜きたいなら#defineで固定バッファであふれたらASSERTでとめるか放置してバッファオーバーフロー。
大体この三種類だな。重要度とパフォーマンスを秤にかけて好きにしとけ。
1kbと4kbのどっちが妥当かなんて答えようがない。
383 :
367 :2007/06/30(土) 12:45:56
>> 382, 379, 378 どうもありがとうございました。 後は、自分で考えることができそうです。 ついでにもう一つ聞いてもいいですか? 文字列の配列を作るときに、 ダブルポインタを採用するのがいいか、リンクリストを採用するのがいいか迷っています。 どちらがお勧めですか?
それは定数か? それとも実行中に作りたいのか?
>>383 使い方によるだろ
よくわからないならダブルポインタの方が扱いやすいかな?
リストなんて糞なもん使わずにchar**な配列作っとけ
387 :
367 :2007/06/30(土) 13:02:55
>>385 , 384
ありがとうございます。
構造体でどちらで定義しようかな、と考えていました。
typedef struct {
char *dstr;
int dlen;
} DATUM;
typedef struct {
DATUM *ptr;
int size;
} DATUMLIST;
とするか、
typedef struct _DATUMLIST {
char *dstr;
char dlen;
struct _DATUMLIST *next;
} DATUMLIST;
とするか迷っていたのです。まぁ、迷わずに実装してしまえば、どちらでもいいような気がしますが。
388 :
367 :2007/06/30(土) 13:06:07
>>386 それも考えました。
無駄に考えるのがよくないのですかね。
この際、char**な配列の方が楽のような気がしてきた。
int型を指すポインタ int* p; 一次元ポインタ配列 int** p; 二次元ポインタ配列 int*** p; 三次元ポインタ配列 int**** p; って風にスターを増やしていってもいいの?
#include <stdio.h> int multiple(int, int); main() { } int multiple(int x, int y) { if(y%x == 0) return 1; else return 0; } multiple関数を使って二つの整数を比較し 二つ目の整数が一つ目の整数なら1(真)、 それ以外なら2(偽)を返すというプログラムを作りたいのですが main関数をどうすればいいのかわかりません
>>389 int** p; は int* 型を指すポインタだ。
それが必要になれば使う。普通に使う。
>>390 main 関数で何がしたいのか分からないので
こちらにもどうすればいいのか分かりません。
普通にどちらも使う。 フォントによっては実際に星型なってることもあるし。
>>391 ありがとう
>>390 if(y%x == 0)
ってyに0が入ってきたらy%xは必ず0になって比較にならないんじゃね?
>>395 0 はあらゆる数の倍数(0 倍)だから動作的に問題ない。
xが0の時のほうがまずいよな。
まあ、どこまでエラー処理するかは状況次第だな。 assert するだけにしておくか、 それともエラー時に何か特別な処理をしてエラー復帰するか。
399 :
390 :2007/06/30(土) 15:24:33
main関数では、変数を二つスキャンして それをmultiple関数に渡し、multipleでの結果を main関数に返してプリント というふうにしたいです
そう書けばいいんじゃないかな。
401 :
390 :2007/06/30(土) 16:26:43
その書き方がわからなくて困ってます
そうですか。
エラー出てもいいからとりあえず書いてみれ。 それでも分からなければ、 自分でどうやってみたかをここにコピペしてみれ。
404 :
390 :2007/06/30(土) 17:12:58
どうしてこんなにお願いしているのに教えてくれないんですか。 もったいぶらないで今すぐに教えてください。
#include <stdio.h> int multiple(int, int); int main(void) { int x, y; scanf("%d %d",&x,&y); if(x == 0) return 1; printf("%d\n",multiple(x,y)); return 0; } int multiple(int x, int y) { return (y%x!=0)+1; } 二つ目の整数が一つ目の倍数なら1 と解釈してやってみた つかここ宿題スレだっけ?
うわ・・・
407 :
390 :2007/06/30(土) 17:21:03
#include <stdio.h> int multiple(int, int); main() { int a,b; scanf("%d%d\n", &a, &b); printf("%d\n", multiple(a,b)); return 0; } int multiple(int x, int y) { if(y%x == 0) return 1; else return 0; } このプログラムだと一応実行できるのですが 整数を二つ入力しても動かず、もう一つてきとうに整数を入れると 最初の二つの整数について判断します。 例えば 2 4←ここで4は2の倍数なので1が返ってくる はずなのですがそこでは処理がされず 5←さらに適当に整数を入力する 1←すると結果が返ってくる と、こんな感じです 整数を二つ入力した時点で処理結果を返したいのですが いいでしょうか?
>>404 >main関数をどうすればいいのかわかりません
>というふうにしたいです
>その書き方がわからなくて困ってます
一度もお願いなんかされてないんだが。
>>408 行間も読めないんですか? とか言われそうだなw
>>407 scanf()とprintf()のフォーマット文字列は互換性がないと思ったほうがいい。
あんたのコードは明らかにscanf()のフォーマット文字列が間違っているぞ。
411 :
409 :2007/06/30(土) 17:30:06
>>410 大丈夫、初めから読もうとしてないから。
これはひどい
413 :
390 :2007/06/30(土) 17:43:19
>>409 助言ありがとうございます
それと404は私ではないのであしからず
414 :
390 :2007/06/30(土) 17:57:37
main() { int a,b; printf("整数1:"); scanf("%d", &a); printf("整数2:"); scanf("%d", &b); printf("%d\n", multiple(a,b)); return 0; } 407のmain部分を上のようにしたら理想通りに実行されたのですが なぜ上手くいったのかがよくわかりません。 誰かその理由を説明してください。
416 :
390 :2007/06/30(土) 18:02:29
間違っていることはわかりましたが 407のscanf()はどういけないんですか?
\n
もし A、B、C、Dのいずれかを満たしたら、、、と出力 それ以外なら。。。と出力 とするにはどうやればいいですかね?
#include<stdio.h> #include<string.h> main(){ char c[3]; char s1[]="abcdefghijklmnopqrstuvwxyz" char s2 [100]; s2[0]='\0'; printf("s1 inital value:\"%s\"\n",s1) printf("s2 inital value:\"%s\"\n",s2) if cstrcmp(s1,s2)==0){ printf("s1==s2\n");} else{printf("s!=s2\n");} printf("Push ENTER to proceed."); fgets(c,2,stdin); strcpy(s2,s1); printf("s1 current value:\"%s\"\n",s1); printf("s2 current value:\"%s\"\n",s2); if(strcmp(s1,s2)==0) { printf("s1==s2\n");} else{prinf("s1!=s2\n");} } のプログラムのfgets(c,2,stdin); ってなんですか?なんの役割ですか?
>>421 どうでもいいけどそれ、そろそろtypo直そうな
× if cstrcmp(s1,s2)==0){
○ if (strcmp(s1,s2)==0){
fgets(c,2,stdin); がわかないんですよ タイプミスはすいません
流れも他スレも読まずに回答。
>>421 >のプログラムのfgets(c,2,stdin); ってなんですか?なんの役割ですか?
入力処理。改行を入力させるために使っているわけだ。
>>424 Push ENTER to proceed を表示したところで止まるだろう
エンターキーを押すと次に進む
ようはポーズさせているんだろう
>>428 なんでENTERを押すと次が表示されるんでしょうか?
>>428 自己レスかよ
fgets(c,2,stdin);
で標準入力からの入力待ちで止まっている
エンターキーで入力されたので次に進むだけ
cのデータ自体はいらないもの
わかりました。ありがとうございます
プログラムとか全くなんにもやった事ないんですけど、最初になにを用意したらいいものなんでしょう? ここのサイトをまず読めとか入門にいい本とかってありませんかね? 仕事では2D/3Dのデザイン系やってるんですけど、プログラムにもちょっと興味があるんで、 まずはCから勉強していこうと思っているんですが。
まず、コンパイラとリンカを用意します
最初に用意すべきものは、 何を用意すればいいかを自力で探せる能力だな とマジレス いや、マジでプログラマにとって最重要な能力は、情報収集力だよ
もうちょい広範囲に言うと「自己解決能力」
やる気。
やる気は大切だが、やる気だけの子も困ったり。
叩かれても泣かない。むしろ悦ぶ方向で。
四大欲求をフルに使いこなせる体力。
441 :
431 :2007/07/01(日) 01:16:58
そうっすねぇまずは色々情報探してみます。 入門出来たらまた相手にしてください。
442 :
デフォルトの名無しさん :2007/07/01(日) 01:56:16
#include <stdio.h> int main(void) { int min,max,x,y,i,j; puts("長方形を作りましょう"); printf("一辺(その1)"); scanf("%d",x); printf("一辺(その2)"); scanf("%d",y); min = x; if (y < x) min = y; max = y; if (y < x) max = x; for (i=1; i<=max; i++) { for (j=1; j<=min; j++) putchar('*'); putchar('\n'); } return 0; } 何がおかしいスかねぇ *が表示されないんですよねぇ
>>442 printf("一辺(その1)"); scanf("%d",&x); < & が抜けてるよ
printf("一辺(その2)"); scanf("%d",&y);
444 :
デフォルトの名無しさん :2007/07/01(日) 02:04:09
あ なんということ…ありがとうございます
445 :
デフォルトの名無しさん :2007/07/01(日) 02:08:54
ちなみにこのプログラムは順番的には for (i=1; i<=min; i++)→for (j=1; j<=max; j++)→putchar('*') →for (j=1; j<=max; j++)→putchar('*')→for (j=1; j<=max; j++)→putchar('*') …→putchar('\n')→for (i=1; i<=min; i++)→… みたいな感じで実行されてるのですか?
>>445 それであってるよ。実行して確認してみればいい。
447 :
デフォルトの名無しさん :2007/07/01(日) 13:00:50
四大欲求とは三大欲求に知的探究心を加えたものか
ノッてくれ〜Ha〜Ha〜♪
450 :
449 :2007/07/01(日) 14:45:40
素で誤爆しました すみません
Gnuplotを扱うC言語用のライブラリとか無いでしょうか? popen()関数を使って自分で作る事は出来るのですが もし優れたライブラリがあるならそっちを使いたいです C++では駄目でCでおながいします
例えば foo(cahr*p) { char *my_ptr = MyGetInnerParameter("内部パラメータを文字列で返す関数"); strcpy(p,my_ptr); } var() { char *ptr; foo(ptr); } こうすると、落ちるんだけど、どうして?
foo(char** p) にしないと
いやそれ以前のはなしか
どこ指してるかわからないpにstrcpyしちゃだめだろ
char* a[8]をlongに直すにはどうしたらいいでしょうか? >>で1つずつやっていくしかないですかね?
じゃあ foo(cahr*p) { char *my_ptr = MyGetInnerParameter("内部パラメータを文字列で返す関数"); strcpy(p,my_ptr); } var() { char ptr[8]; foo(ptr); } こうしてみたんだけど、やっぱりダメだった。 どうして?
cahr
コードを見る限り問題はなさそうな気がする。 MyGet(ryの戻り値がおかしいんじゃないのか。 戻り値になるバッファをスタックに取ってるとか。
コピーされる文字数が1024バイトだったとかってオチだろ。
デバッグとしてmy_ptr表示させてみたりとか、自分でしないの?
そもそも、呼ぶ側で領域確保が必要な関数の場合、 最初に用意する容量を問い合わせてから領域を確保して初めて呼び出せるんだろうに。 領域サイズの確認関数が無いなら、十分なサイズを用意してあげないとダメ。 そして、サイズに満たない領域にコピーしちゃダメ。
bregexp.dllのラッパーライブラリ内ですか?
465 :
デフォルトの名無しさん :2007/07/01(日) 22:45:56
サブ関数内でmalloc()でメモリ確保した領域ってメイン関数に帰るときに解放されないの?
>>465 free()かrealloc()で解放しない限り、されません。
>>465 解放されると困らないかい?
malloc() 〜 free() の作法としては、使う人が確保と解放の責任を持つって暗黙のルールなんだけど、サービス関数の中には、確保だけして解放は使う側でやってね。なんてローカルルールもあるしな。
解放されると思い込むくらいなら、仕様確認をした方がいいよ。
alloca なら開放されるな。 環境依存だが。
470 :
465 :2007/07/01(日) 23:22:00
あざーす
>>464 たいした手間じゃないから自分で書いたらいいよ
木構造の二分探索木において ルートの下にノードがあるとします。 その2つのノードからそれぞれ2本ずつ枝がでていて、 1本は別々のノードにつながっている。もう一本は同じノードにつながっている。 これをあらわすには数字の割り当て方はどうすべきですかね? 0 1 2 3 4 5 6 とあれば、2のleftが4をさすようにする。 5は捨てるって感じですかね?
よく意味が分からない。
データ数400の二次元配列でかつ小数点 それと木構造と組み合わせて計算とか地獄だな。。。
0 /\ 1 2 /\ /\ 3 4 5 みたいな感じにしたいのか?
>>475 はい、そうです。
各枝に確率をつけて、0のところを1.0と設定して
0から1、2への枝の確率をかけて1と2のノードにおいての確率をだす。
その次に1と2の下の3、4、5への枝に確率をつけて
3、4、5のノードにおいての確率を出す感じにしたいんですけど。
1つのノードに3つの確率がはいるようにしないといけないなーとは思ってます。
この計算を木でやるか配列でやるか迷ってます。
0 /\ 1 2 /\ /\ 3 4 5 /\ /\ /\ 6 7 8 9 となっていくんだったら、別に配列でもいい気がするな。 配列というか、三角行列?
478 :
デフォルトの名無しさん :2007/07/02(月) 01:14:04
#include <stdio.h> int main(void) { /*左上*/ int a,b,c; printf("何段ですか:"); scanf("%d",&a); for (b = 1; b <= a; b++) { for (c = a; c >= 1; c--) putchar('*'); putchar('\n'); } return 0; } 左上が直角になる三角形を作りたいのですが・・・何か四角形になります
>>478 for (c = a; c >= 1; c--)
↓
for (c = a; c >= b; c--)
480 :
デフォルトの名無しさん :2007/07/02(月) 01:25:48
>>456 8つのchar*が指し示している内容が分からないと何とも。
482 :
デフォルトの名無しさん :2007/07/02(月) 11:56:07
数人でCでプログラム開発しているのだけれど、 ソースコード中の各関数の前に、 // 関数名: // 作者: // 機能: // みたいな説明を付けたいのだけれど、どこかにカッチョいいサンプルないですか?
484 :
デフォルトの名無しさん :2007/07/02(月) 12:53:35
>483 ありがとうございます。でも、 そういう高度なのは使いこなせそいうにないので、 具体的なサンプルを探しています。よろしく。
485 :
デフォルトの名無しさん :2007/07/02(月) 12:58:04
#include <stdio.h> int main(void) { int a,b,c; printf("ピラミッドを作りましょう"); printf("何段ですか:"); scanf("%d",&a); for (b = 1; b <= a; b++) { for (c = a; c > 1; c--) putchar(' '); for (c = 1; c < 2b; c++) putchar('*'); putchar('\n'); } return 0; } 何が変なんですかね
使いこなさなくてもいいから、Doxygenスタイルで書いて置いたらいいんでね? もし>484がロートル、コボラの気に入りそうな「枠に填まった」コメントが好きならサンプル出してもいいけど。 #コメントを書くのに手間が掛かるのなんて論外だと思うんだがね。
488 :
2b :2007/07/02(月) 13:00:50
>>485 あんたの頭。コンパイルエラーが出たのなら、その内容くらい書くのが当然だ。
2b
ついでにピラミッドにするためには c > 1 じゃなくて c > b だと思われる
492 :
デフォルトの名無しさん :2007/07/02(月) 13:06:36
エラー E2378 4-18.cpp 10: For文に ; がない(関数 main() ) エラー E2379 4-18.cpp 10: ステートメントにセミコロン(;)がない(関数 main() )
493 :
デフォルトの名無しさん :2007/07/02(月) 13:11:00
488をスルーするとは酷い奴だ
495 :
488 :2007/07/02(月) 13:34:56
べ、べつに気づいてもらいたくて名前に仕込んだわけじゃないからね。 「意味のないレスするな」って言われないための予防策なんだから。
死ねよ
山岡来た
498 :
デフォルトの名無しさん :2007/07/02(月) 19:37:41
2から5までとか指定するのってどう書けばよかったっけ?
日本語を正しく書いてください
さすがにこれはエスパーじゃないと解読不能だな
for(i=2; i<=5; i++) printf("%d") switch(n) { case 2: case 3: case 4: case 5: printf("2..5"); } if(2 <= n && n <= 5) printf("2..5");
502 :
デフォルトの名無しさん :2007/07/02(月) 19:42:33
変数iにおいて iが2から5という条件 文書くときに if(???) の中身はどう書けばよいですか?
if (i >= 2 && i <= 5) ...
しかるべきところで職につけばお前も目にすることがあるかもしれないよ
関数ヘッダクラスヘッダはあったほうがソース見やすい。 どうせ引数説明とか入れるんだし。 もちろブロックコメントでな。ラインコメントをいくつも並べるのはカッコワル。
あと、関数ヘッダコメントに、その関数名をいちいち入れてるのってカコワルイ おまえ、それ何の意味があるんだと。
508 :
デフォルトの名無しさん :2007/07/02(月) 20:23:01
質問があるので宜しくお願い致します。 どうして、128バイトは1,024ビットになるのかわかりません どういう計算をすれば、そうなるのでしょうか?
511 :
デフォルトの名無しさん :2007/07/02(月) 20:46:27
>>509 ん〜考えても、どうして128バイトは1,024ビットになるのかわかりません
何の何階乗をすれbいいのでしょうか?
128 * 8 = 1024
8 * 128 = 1024
>>511 みなさんからいっぱいのレスだけども
も〜ちょっと分かりやすく書くと
128バイト×8ビット/バイト=1024ビット
1バイト=8ビット ってのを知らないだけなんじゃね
かけ算ができないだけだろ
容量換算の1(M)=2^10(K)=1024(K)とかとごっちゃになっているんじゃない?
いちいちゴミ撒かんと気が済まんのかこのスレは・・・
どっちがビットでどっちがバイトだっけ? そんな時期が私にもありました(AA略
そもそも1バイト=8ビットと決まってるわけじゃねーし。 厳密に8ビットというなら1オクテットと表現すべき。
じゃ1バイト=9bitなんていういかれた環境があるのかよ! と思っていた時期が私にもありました 本当にあったんだね
522 :
511 :2007/07/02(月) 21:21:02
サンクスです ですが、どうして128 * 8 して出すのかが 納得できません。。。
523 :
511 :2007/07/02(月) 21:21:52
なんとなくわかりました サンクスでした
なんとなくかよw じゃあ君が大好きなタコを例にして分かりやすく解説しよう。 「タコには足が8本あります。ここにタコが128匹います。全部で足は何本でしょう?」 タコ→バイト、足→ビット、に置き換えるとあら不思議。
128匹のタコ全部が足8本だとは限らないだろ
526 :
390 :2007/07/02(月) 22:45:49
#include <stdio.h> main() { int a; float b; for(a=0; a<=100; a++) printf("セ氏温度:%d カ氏温度:%.2f\n",a ,fahrenheit(a,b)); } int fahrenheit(int x,int y) { y = (float)(9/5)*x+32; return y; } セ氏温度0〜100℃に対してカ氏温度を出したいのですが 出力の際、カ氏温度が0.00になってしまします。 間違っているところの指摘をお願いします。
例の一匹の足の1本はすでに俺は食べた
>>526 fahrenheit()の第2引数はint型なのにfloat型のbを渡している
fahrenheit()の戻り値の型はint型なのに%.2fを指定している
もうひとつ。どっちにしろint型で返すことになってるが、 y = (float)(9/5)*x+32; は意図したのと違くなっていると思う
530 :
526 :2007/07/02(月) 23:04:50
>>fahrenheit()の戻り値の型はint型なのに この部分はどう直せばいいのですか?
戻り値をfloatに変えるとか、%dに変えるとか
struct abc{ char a; } main() { char b, c; c = ((struct abc)b).a; c = ((struct abc *)b)->a; } c = ((struct abc)b).a;がダメで c = ((struct abc *)b)->a;が良い理屈を教えて下さい。
>>532 それって良いのか?
コンパイルは通るだろうが、実行したら間違いなくSegmentFaultだぞ
((struct abc *)b)->a; は偶然うまく動くかもしれないが、よくない。
535 :
526 :2007/07/02(月) 23:23:06
エラーで「初期化されていないローカル変数"b"が使用されます」 と出るのですがこれが原因ですか?
>>533 aのoffsetが0ならうまく動くだろ。
>>532 (struct abc *)b はbで示される何らかの値をstruct abc のポインタに変換している
で b の値はポインタか?
どっちもよろしくない
538 :
536 :2007/07/02(月) 23:29:11
てっきり、&bかと思ってたわ・・・
>>535 a はfor文で値が入るが b には初期かも代入もされていない
b に値を入れろ
>>536 c = ((struct abc *)&b)->a;
なら、aのoffsetが0ならうまく動くかも知れん。
が、
>>532 はそうはなっていないので間違いなく保護違反
541 :
532 :2007/07/02(月) 23:58:38
ほんと、すいません。 c = ((struct abc *)&b)->a; でした。
542 :
535 :2007/07/02(月) 23:58:55
>>539 bに値を入れたら結果が変わりませんか?
543 :
532 :2007/07/03(火) 00:04:41
素人目にはc = ((struct abc)b).a;でも 問題ないように思えるのですが、 なにがダメなのでしょうか。
そう思えるから素人なんです。
すげえ正論だが質問の答えにはなってないな
>>543 何でって言われても、言語仕様でそのようなキャストは認められていないから、としか。
547 :
511 :2007/07/03(火) 00:56:08
タコ釣りか?
~ ってなんだよ
ティルデ
ニョロ
0 1ビット 01 2ビット 010 3ビット 0101 4ビット 01010 5ビット 010101 6ビット 0101010 7ビット 01010101 1バイト
553 :
デフォルトの名無しさん :2007/07/03(火) 01:08:27
>>547 例題がタコだからといって、演算子までタコにするのはやめような。
いつか 1byte != 1octet の時代は来るのだろうかー・・・
ヽ (゚o゚)∫ ノ川ル
>>554 1byte == 1octet の時代なんて一度も来た事がないんだが。
557 :
デフォルトの名無しさん :2007/07/03(火) 01:21:37
まだC言語とかやってたんだ。 懐かしいなー
今でも、36ビットワードマシンとかでは1バイト=9ビットだね UTF−9とかもあるし
UTF-9 はエイプリルフールのネタじゃなかったっけ?
scanfやfgetsで文字を入れて 文字列を比較する場合、どうすればいいんでしょうか? char* str; fgets(str,100,stdin); if(str=="start"){ なんとかかんとか; } これ、うまく動かないんですが
strcmp
>>560 1. str の指す領域を確保する
2. 文字列の比較には strcmp を使う
3. 比較する文字列を "start\n" にする
563 :
526 :2007/07/03(火) 08:27:43
#include <stdio.h> main() { int a; int b=0; for(a=0; a<=100; a++) printf("セ氏温度:%d カ氏温度:%d\n",a ,fahrenheit(a,b)); } int fahrenheit(int x, int y) { y = (9/5)*x+32; return y; } 誰かこのプログラムをカ氏温度が小数点まで 出力されるように改ざんしてください;
>>563 double型の変数でも使えばええやん・・・
#include <stdio.h> #include <stdlib.h> #include <string.h> struct list{ char *name; struct list* next; }; int main(void){ struct list *head,*ume; char *str; head=NULL; str=(char*)malloc(100*sizeof(char)); printf("名前を入力(endで終了)>"); fgets(str,100,stdin); while(strcmp(str,"end\n")!=0){ ume=(struct list*)malloc(sizeof(struct list)); ume->name=str; ume->next=head; head=ume; printf("名前を入力(endで終了)>"); fgets(str,100,stdin); } printf("%s%p\n",head->name,head); return 0; } リスト構造体のテストやってみたんですが これ実行して、taro、hanako、endと入力したら endが表示されるんだけどどこがおかしいんですかね? endと入力した時点でwhileから抜け出し、head->nameがendになると思えないんですが・・・
>>565 > head->nameがend
ume->next=head;
head=ume;
↑そりゃなるだろw
>>565 おかしいっていうのは、期待した動作と違うって事だろうけど
何をしたいのか分からんのに、答えられるわけ無いだろ
>>565 エスパー回答
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct list{
char *name;
struct list *next;
};
int main(void){
struct list *head, *ume;
char *str;
head = NULL;
str = (char *) malloc(100 * sizeof(char));
for(;;){
printf("名前を入力(endで終了)>");
fgets(str, 100, stdin);
if(strcmp(str, "end\n") == 0) break;
ume = (struct list *) malloc(sizeof(struct list));
ume->name = strdup(str);
ume->next = head;
head = ume;
}
ume=head;
while(ume!=NULL){
printf("%s", ume->name);
ume=ume->next;
}
return 0;
}
>565 ume->nameは常にstrを指していて、最後にendになってんだから当たり前だろ。
>>565 まあ大体察しはつくが・・・
「おかしい」って言う以前に、どういう動作を期待しているのかちゃんと書こうな
どのくらいの変数が必要なのかよくわからないときは とりあえず多めに変数宣言用意しておいてもいい? int i,j,k,l; double a,b,c,d,e; char f[1000],g[1000],e[1000]; とか・・・ 変数○○は使われていませんって警告がでるけど 多くしたら実行速度下がるとかエラーでるとかこまったことがおきるとかありますか?
struct list{ char *name; < いっ、いいんかい? struct list *next; };
573 :
デフォルトの名無しさん :2007/07/03(火) 09:59:25
571 困ったことが起こるよ new だといい
574 :
デフォルトの名無しさん :2007/07/03(火) 10:02:14
571 使ったことないけど std::vector, std::string がいいみたいだよ
C++とSTLの世界へご招待〜
C言語の入門者向け解説スレです。 ・C++言語はスレ違いです。
577 :
デフォルトの名無しさん :2007/07/03(火) 10:16:25
576 C言語専用の環境使っているやつがいるか?
そりゃいるでしょ
>>571 一応ありはありだが
・万一配列のサイズを超えたときにそれをはじくようなチェックを入れておく。
・スタックにあまり大きな配列を取らない(char *f, *g, *eにして領域をmallocする)。
あたりは注意しておいたほうがいい。
速度はメモリ浪費でスワップしない限りさほど落ちない。
580 :
デフォルトの名無しさん :2007/07/03(火) 10:30:04
今日はじめてSTLググってみたけど、これは使うべきだな 初心者こそ使うべきだな コーディングが楽になるな
charの配列の[0]から[3]の4バイトにデータがあります。 これを一つのintの変数に入れたいのですが、どうやればいいですか?
>>581 過去ログを読む気がないのなら、やりたいことを具体的に書け。
どんなデータをどう入れたいのか判らんことには答えようがない。
*(int*)配列名
585 :
デフォルトの名無しさん :2007/07/03(火) 11:55:18
c[0]+(c[1]<<8)+(c[2]<<16)+(c[3]<<24)
union使うとか
>584 配列の0から3でもバスエラーって発生するもんなの?
>>587 char配列がint安全な場所に作られる保証はない。
その点ではunionの方がまし。
しかし、unionには言語仕様的に実装依存の罠が。
そういう意味では>585でいいのだがエンディアンの問題が残る。
まぁ、最近のコンパイラならどれで書いても同じようなコードを吐くしね。
>>588 そういやこういう場合かもしれんしな。
#include <stdio.h>
#include <stddef.h>
int main() {
struct A {
char a;
char b[4];
};
printf("%ld\n", offsetof(struct A, b));
}
590 :
581 :2007/07/03(火) 12:30:43
>>583 一番簡潔なのですがかなり難解です。これから考えます。
>>585 一番分かり易いです。
unionの使い方に悩みましたがcharの配列と一つのintのメンバ変数を用意して
charの配列にデータを入れてintのメンバ変数でアクセスすればいいのですね。面白い。
GCC で試した所、
-O (最適化レベル1か、それ以上)
-funroll-loops (ループ展開最適化)
フラグを立てると
>>585 みたいなコードを吐いてくれるみたいだ。
int toInt(const char* ch) {
union {
char ch[sizeof (int)];
int i;
} endian;
int i;
int shift, dshift;
int n = 0;
endian.i = 0;
shift = *endian.ch ? 0 : (sizeof (int) - 1) * CHAR_BIT;
dshift = *endian.ch ? CHAR_BIT : -CHAR_BIT;
for(i = 0; i < sizeof (int); i++) {
n |= ch[i] << shift;
shift += dshift;
}
return n;
}
最近、関数のメモリの場所をポインタで取得できることを知ったのですが、 これを利用してデリゲートまがいなことってできませんかね?
qsort() とか使ったことない?
int a, b; があって両者の絶対値の大きさを比較したいとき 自乗した値を比較するのとabs()を使うのではどちらが速いのでしょう? 自乗してもintの範囲を超えないことは保証されているという前提で。 またこういったベンチマークテストはどうやって行うのでしょう?
数百万回〜数億回くらい実行して、速度を比較する。
>>594 こんなコードを書いてみる。
#include <stdio.h>
#include <stdlib.h>
int main()
{
volatile int a;
volatile int b;
for (int ic = 0; ic < 100 * 1000 * 1000; ++ic) {
#if 1
volatile int c = abs(a) > abs(b);
#else
volatile int c = a * a > b * b;
#endif
}
return 0;
}
こいつをこんな感じで実行してみる。
$ gcc foo.c -std=c99 -O3 ; time ./a
foo.c: In function `main':
foo.c:11: warning: unused variable `c'
real 0m0.734s
user 0m0.687s
sys 0m0.047s
意外にも、abs()の方が遅かった。
abs は条件判定が必要だからな。
あー、volatile宣言のお蔭で、参照回数の影響も出ちゃった。 よって一部訂正。 #if 0 int aa = a; int bb = b; volatile int c = abs(aa) > abs(bb); #else int aa = a; int bb = b; volatile int c = aa * aa > bb * bb; #endif 今回は大勢に影響はなかったけど。 で、ついでに-Sでアセンブリ出力を眺める。二乗版はこんだけ。 movl -4(%ebp), %eax movl -8(%ebp), %edx imull %eax, %eax imull %edx, %edx cmpl %edx, %eax setg %dl movb %dl, -9(%ebp) abs()版はどうしても条件分岐しないためにビット操作であれこれ捻り過ぎ。 movl -8(%ebp), %edx movl -12(%ebp), %eax movl %edx, %ecx sarl $31, %ecx xorl %ecx, %edx subl %ecx, %edx movl %eax, %ecx sarl $31, %ecx xorl %ecx, %eax subl %ecx, %eax cmpl %eax, %edx setg %dl movb %dl, -13(%ebp)
バイナリーサーチというものをやる場合 データが小さい順もしくは大きい順に並んでなかったらできない? つまりめちゃくちゃなデーターがあったら一旦それをバブルソートなどで整列させないとダメってことですか?
そう。
わざわざバブルソートを選択する理由も無いけどな
>>599 その通りです
バブルソートである必要はありませんが…
バブルソート突っ込まれ過ぎワロタ
>>599 揃っているからこそのバイナリサーチじゃないか。
って、仕組み見たら一目瞭然だと思うが・・・・・
で、バブルソートである意味はない。
でも、ふと思ったのは、必要なものをすべて見つける必要はなくて
一つ見つければいいというのであれば、動的に必要な部分だけ
ソートしながら利用するっていう使い方もあるのかな、と思った。
レイトバインディングのように、対象要素が大きくて
ソートの初期化コストが大きかったり頻繁に要素が追加されるという状況で使えないかな?
それともそういう場合はB-Treeとかを使っておくべき?(追加のコストによるのかな?)
#include いろいろ struct list{ int data; struct list *next; }; void showlist(); int main(void){ int indata,i,j; struct list *head,*test; head=NULL; while(1){ printf("数を入力(終了は0)>");scanf("%d",&indata); if(indata==0) break; test=(struct list*)malloc(sizeof(struct list)); test->data=indata; test->next=head; head=test; } showlist(); return 0; } void showlist(){ struct list *now; while (now!=NULL){ printf("%d ",now->data); now=now->next; } }; 構造ポインタで次々入力しshowlistで表示するというのを作ったんだけど これ実行したら、mainのreturn 0の上のshowlistがプロトタイプ宣言が無いと警告でるんですがどうしたらいいですか?
void showlist(void); ↑型を入れる
#include <stdio.h> void inputdata(int data[],int n); int main(void){ int x[10]; inputdata(x,10); return 0; } void inputdata(int data[],int n){//inputdata関数 int i; for(i=0;i<n;i++){ printf("Input data>"); scanf("%d",&data[i]); } for(i=0;i<n;i++){ printf("data[%d]=%d",i,*data[i]); } } C言語について質問です 配列x[0]〜x[9]のそれぞれに値を入れて表示するというinputdata関数を作ってみたいんですが これ動きません。どのように関数を直せばよいのでしょうか?
int *data[]
printf("data[%d]=%d",i,*data[i]); ↓ printf("data[%d]=%d",i,data[i]);
610 :
デフォルトの名無しさん :2007/07/03(火) 20:55:02
2^8は65,536でしょうか?
612 :
デフォルトの名無しさん :2007/07/03(火) 21:09:46
さんkyさう
つーかプログラミング勉強してる奴が電卓の使い方も(その存在も?)和歌ランとは・・・
小学生なんだろ。
2^8 = 16^2 = 0xFF
二次元配列で構造体を使って その中身の計算に 違う二次元配列の中身を用いないといけないんだけど すげーキレそう
ゆとりは相変わらずキレやすいな。
トイレに行くと血が・・・ orz
cdっていう配列があったとして &cd[0] と cd は全く同じ意味ですか?
ほぼ同じ意味
>>621 「2*2」と「1*4」は同じですか?
という質問と同じです。
値も型も同じですが、意図が違います
cdとブルーレイくらいしか変わらない
sizeofの引数にしてみそ
void型の関数でwhileやifの途中で関数を終わらせるにはどうしたらいいでしょうか? int型とかなら if(x==1) return 0; とかやれば関数から抜け出せるけど void型はどうやるんですか?
return;
だが、ループの途中からリターンするのはあんまり気持ちのいいもんじゃないよ。
そして、じゃあbreakはどうなんだ?というような宗教論争に
ネストされたループとか考えるとループ中のreturnはやむを得ない気がする。
10GBぐらいある巨大なテキストデータの中のある1行を 書き換えたいんだけどどうやればできますか。 普通にやると,また10GB書き出さないと出来ないような。
>>621 int cd[10]; として、
&cd[0] の型は int* で、
cd の型は int [10] だな。
全く同じではない。
634 :
デフォルトの名無しさん :2007/07/04(水) 01:18:05
>>631 ファイルでもメモリーでもどっちでもいいが、書き換えサイズが同じなら、読んで書いて閉じればそれで終わり。
挿入や削除ならそこでちょん切ってリスト構造で繋ぎ直す。
>>634 そのページのC編のほうのも参考にしてみたのですが、
できればグローバル変数を使わずに、
かつ、リスト操作関数の引数も、リストへのポインタだけにしたいのです。
逆に、関数内で作業用の変数が増えるのはあまりこだわりません。
もちろん、良識のある範囲で少ないほうがいいのですが。
Add系の関数の引数はデータもあるので、 増やす方は2コ(リストと要素)、減らす方は1コ、というのが正しいですね。
>>631 ファイルをリスト構造にする。
ところどころにダミーデータをいれておいて、そこをバッファに使う。
書き換えたい所を含んだクラスタを別のクラスタに繋ぎなおす。
別のファイルにパッチ情報として〜行目はこの内容に置き換わりました、のような情報を入れてセットで扱う。
直した所から後ろをそっくり書き直す
fgets(hoge, 64, stdin); みたいにしたとき、入力が64文字以上あるとどうなりますか? 63文字目までがhogeに入って後は無視されるんでしょうか?
63文字だけ stdin から読み込む、だけ。 後は次の読み込みがあれば、その時に読み込まれる。
641 :
639 :2007/07/04(水) 03:07:44
では、64文字目以降の改行までを無視することはできますか? fflush(stdin); してしまうと、リダイレクトされてきた時に 改行以降も全て捨てられてしまうのでは?
hoge[62] = 0; hoge[63] = 1; fgets(hoge, 64, stdin); if(hoge[63] == 0 && hoge[62] != '\n') { scanf("%*[^\n]s"); getchar(); }
int *p,a; p=&a; ってやったら *pはaと同じ(*p=a)になるんでしょ でも@=&aとやらず*p=aはなんでダメなの?
*p==a p==&a
int *p,a; p=&a; *p = 10; printf("%d\n",a); a = 20; printf("%d\n",*p);
pが未初期化だとどこさしてるかわからんのに その先に値を書き込もうとするか
647 :
デフォルトの名無しさん :2007/07/04(水) 12:10:01
STL勉強してるんだけど vector<string>とかできるの?
スレタイ読めないの?
試せば分かることをわざわざ聞きにくるやつに スレタイを正しく読むのは難しいだろ
試して出来ないから聞いてんじゃないの? 少しは予測しろよw
それは有り得ない話だ。
652 :
デフォルトの名無しさん :2007/07/04(水) 13:20:44
STL勉強してるんだけど vector<vector>とかできるの? vector<vector<int>>とか vector<vector<vector>> とかできるの?
これはひどい
スレタイくらい読め
STLはC言語では使えん vector<vector<int> > vector<vector<vector<int> > > で試せ
つ[名前空間] まあスレタイも読めないおばかさんは一生悩んでろ。
switch( uMsg ) case WM_CREATE: test1=1; test2=2; break; case WM_CREATE: { test1=1; test2=2; } break; case WM_CREATE: { test1=1; test2=2; } return; case WM_CREATE: { test1=1; test2=2; return; } どれ使ってもOK?
OK
{}で囲むのは途中で変数宣言したいとき。 breakとreturnは意味が違う。
別に変数宣言しなくても囲ってもいい
switch、caseに関わらず、別にスコープは好きなところで使って構わない。
関数内ならね。
>>641 fflushは入力バッファに対してどう作用するか定められていない
(出力バッファを吐き出すことだけが規定されている)ので、
このスレとしては知らないという答えになる。
{ }は見やすくするためにつけたけど、どこでも使ってOKなのね。 breakとreturnはよく考えるとぜんぜん意味が違う事に気づいた なぜreturnが入ってたんだろうw
関数と定義するとき、プロトタイプ宣言が必要って言われてますよね? プロトタイプ宣言って必要なんですか? なくても動くと思うのですが・・・
なくても動きますし、必須でもありません。 あなたがいらないと思うなら必要ではないでしょう・
なくても必ず正しく動くわけじゃないぞ。
668 :
デフォルトの名無しさん :2007/07/04(水) 19:20:45
自前の関数を関数内で使うときじょんじょが大事になる
例えばいつもおなじみのstdio.hという標準入出力ライブラリのヘッダファイルには printf関数やらfopen関数やらのプロトタイプ宣言がずらずらと並んでる stdio.hにはプロトタイプ宣言だけが書かれてて,printf関数やfopen関数の実装はstdio.cに記述されている ライブラリってのはヘッダファイルとソースファイルが対になっていて ヘッダファイルに「このライブラリはこんな機能を提供しますよ〜」っと目次みたいなもんを書いてるわけだ それがプロトタイプ宣言 なんでこんなことを分けるするかってのはソースを分割して機能別にライブラリ化するため 1個だけのソースファイルでプログラミングしてる時は必要無いけど普通はプロトタイプ宣言も書いておく main関数の前にずらずら別の関数の実装が並んでいると,どこがmainの始まりか探すのが大変なのもある
670 :
デフォルトの名無しさん :2007/07/04(水) 20:18:02
年と月を入力して 2007 7 sun mon tue wed thu fri sat 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 みたいな万年カレンダーを作りたいんですけど、アルゴリズムを詳しく教えてほしいです。 よろしくおねがいします。
あ、数字がずれてる…。 sunのnの下に1がきてmonのnのしたに2がくる感じです
ソース見た瞬間意識が朦朧としてきた
>672 文字列の終端は'\n'じゃない てめえの汚えケツ穴なんぞ誰がいるかってんだ
>>673 朦朧としてると、こっちから押し倒しちゃうze(はぁと
>>674 ありがちんこ☆
\0か!
あえて断言しよう
>>674 は絶好のチャンスを失った、と。
>>670 #include <unistd.h>
int main(int argc, char *argv[]){return execlp("cal", "cal", argv[2], argv[1], NULL);}
例えば、以下のような4つの要素からなる列が複数あるものに対して、 次のような処理: (1)1番目の要素が同一の場合、後から出現したものを採用する (2)3番目の要素でソートする を行いたいのですが、どのようなアルゴリズムになりますか? 例) 0010 ABC 60 70 0022 BCD 56 76 0010 EFG 85 34 0003 HIJ 70 98 ↓ 0010 EFG 85 34 0003 HIJ 70 98 0022 BCD 56 76
普通に配列につめてソートします。
680 :
678 :2007/07/04(水) 21:50:09
>>679 普通に配列からソートする場合、
どのように(1)の条件をクリアしますか?
そこで困っています。
同じものが出てきたら上書きする
1番目の要素が同一かどうか調べて、同一なら上書きすればいい(例だと、消去してる?)
>>680 0000番から9999番までの箱を用意してそれぞれの箱に入れていく。
で、既に入ってる場合は入ってるものを捨てて代わりを入れる。
全部入れ終わったらソート。
無駄だらけだけど分かりやすい考え方だとこんな感じ?
int i, j, k, n; for(i=n-1; i> 0; i--) { for(j=i-1; j>=0; j--) { if(a[j]==a[i]) { for(k=j; k<n-1; k++) a[k] = a[k+1]; n--; i--; } } } こんな感じで同じものを消去すりゃいいんじゃね?
ソートしてからの方が効率いいだろ・・・
>>685 ソートしちゃうとどれが先にでてきたか分からなくならない?
いや、マージソートとかならいいけど
>>686 そのための安定ソートだろ
入門篇ならバブルソートだろう
689 :
678 :2007/07/04(水) 22:45:58
>>683 それ考えたんですけど、
実際は0000000000番から9999999999番まで(10桁)あり、
番号も全部あるわけじゃないからやっぱり効率悪いですよね。
はやさも求められているんで・・・
ハッシュとか2分探索とか使うんですかね?
>688 一番目の要素で安定ソート 一番目の要素でのかぶりを削除 三番目の要素でソート ってことだろ。
インデックス情報を付加しといて qsort という手もある。
標準ライブラリに無いのが難点だけど 重複してるかどうか調べるのはハッシュ使うのがいいと思う
インデックス用の配列mallocしてqsortが一番楽だろ
695 :
デフォルトの名無しさん :2007/07/05(木) 15:50:14
CからつかえるフリーのXMLライブラリないですか?
696 :
デフォルトの名無しさん :2007/07/05(木) 15:53:13
何方か標準関数のプログラムの作り方教えてください
日本語でもう一度
698 :
デフォルトの名無しさん :2007/07/05(木) 15:55:33
>>672 見たらmain内で関数宣言してるけど、これはなに?
そういう手法があるの?関数の内容よりそっちに目がいった。
こんなことしたことないけど、どうなの?
そりゃキミが知らないだけだろ
プロトタイプ宣言くらい関数内でできる。
次のような関数を作りました。 Vertices isMaxNoVer(Vertices R[]){ Vertices max; int i, count=0; max.num = 0; max.deg = 0; max.no = 0; count = countVer(R); for(i=0; i<count-1; i++){ if(max.no < R[i].no){ max = R[i]; } } return max; } この関数を、次の再帰関数を使って二度目に呼び出した時、 動作がおかしくなり、以下のようなおかしな値が入ります。 test expand 1, 8 -1073747304 134516287 更にその後2度目のtest expand 3に入る前に セグメントエラーを起こして止まってしまいます。 これだけの情報でわかって頂けるかわかりませんが、 誰か助けてください。
702 :
701 :2007/07/05(木) 16:42:43
void expand(Vertices R[]){ Vertices p, buf[N], Rp[N]; while(countVer(R) != 0){ p = isMaxNoVer(R); printf("test expand 1, %d %d %d\n", p.num, p.deg, p.no); if((countVer(Q) + p.no) > countVer(Qmax)){ syokikaVer(buf); mataha(Q, p); printf("test expand 2\n"); syokikaVer(buf); ganma(buf, p.no, G); printf("test expand 3\n"); syokikaVer(Rp); katu(Rp, buf, R); printf("test expand 4\n");
703 :
701 :2007/07/05(木) 16:44:38
if(countVer(Rp) != 0){ numberSort(Rp); expand(Rp); } else if(countVer(Q) > countVer(Qmax)){ copyVer(Qmax, Q); } hiku(p, Q); } else return; hiku(p, R); } return; } QやQmax、Gはグローバル変数です。
>>701 それだけだと分からんなぁ〜
katu(Rp, buf, R);
numberSort(Rp);
このへんの関数に問題ありそうだけど
質問です。 今、以下のような関数と構造体を作ったのですが、 typedef struct { int Length, Maximam, ValueSize; void* Array; } ArrayList; char* GetValue(ArrayList* list, int index) { char* data = (char*)list->Array, item = malloc(list->ValueSize); int i = 0; unsigned int p = index * list->ValueSize; if(list->Length > index && item != NULL) { for(; i < list->ValueSize; i++) { item[i] = data[p + i]; } return item; } else { return NULL; } } 以下続く
item
707 :
705 :2007/07/05(木) 18:33:11
void AddRange(ArrayList* list, const void* values, int length) { char* data = (char*)list->Array, item = (char*)values; unsigned int i = 0, itemlength = length * list->Maximam, index = list->Length * list->ValueSize; if(list->Length + length >= list->Maximam) { list->Maximam += length * 2; list->Array = realloc(list->Array, list->ValueSize * list->Maximam); } for(; i < itemlength; i++) { data[index + i] = item[i]; } list->Length += length; } void main (void) { ArrayList list = { 0, 4, sizeof(int), malloc(sizeof(int) * 4) }; int i = 0; int s[10] = { 0, 1, 2, 3, 4, 5, 6 ,7 ,8 ,9 }; AddRange(&list, s, 10); AddRange(&list, s, 10); for(; i < list.Length; i++) { printf("%d\n", *((int*)GetValue(&list, i))); } } どうしてもGetValueのchar* itemの領域が確保できないんです。 他にも、listのArrayをいじってもヒープが壊れてますとか言われるのですが… なにかやってはいけないことでもやってしまっているのでしょうか? 行数圧縮しているため読みにくいとは思いますが、よろしくお願いします。
708 :
705 :2007/07/05(木) 18:34:36
ちなみに、元のソースではすべて int i = 0; int j = 0; のように宣言しています。
itemはchar型変数として宣言されてる *itemで宣言しなきゃダメだろ
>>709 元ソースでは
char*になってたんですが…
削りすぎた orz
711 :
705 :2007/07/05(木) 19:07:04
いろいろ試してみたのですが、 AddRange(&list, s, 10);を 連続でなくとも2回使用するとGetValueのitemの中がNULLに、 3回目からはAddRange(&list, s, 10);で行われるreallocで ヒープが壊れているというエラーが出てくるようです。 何が悪いんだろ orz
AddRangeの2回目でヒープ壊してる itemlengthとreallocのサイズが乖離してる
つーかGetValue()って範囲チェック除けば char *GetValue(ArrayList list, int index) { return (char*)list.Array + index * list.ValueSize; } これで十分じゃね?
itemlength = length * list->Maximam → itemlength = length * list->ValueSize でいけるかな?
>>712 itemlength = length * list->Maximam
のMaximamが原因でした。ValueSizeにするはずだったのに…
1回の使用だけだとエラーが出なかったので問題ないと思い込んで
気づかなかった orz
>>713 そんなやり方もあったんですか…
void*だとサイズわかんねぇよって怒られるのでchar*にして
コピーする方法しか知りませんでした。
>>714 全くその通りです。
まともにコードかけるようになるのは時間がかかりそうだ orz
ありがとうございました!
素直に型を限定すればいいのに
int型の数字を文字列に変換するのってどうやるん? 具体的に言うと int n = 34; char* nStr = intToStr( n ); /* nStr = "34" */ という風にしたいのだけれど。
char *buf; int n=34; buf=メモリ確保 ssprintf(buf,"%d",n);
>>718 サンキュ!
inline char* int2str( int n )
{
char *buffer;
buffer = malloc( sizeof( char ) );
sprintf( buffer, "%d", n );
return buffer != NULL ?
buffer:
"FAULT!!";
}
一応こういう感じで。
>>720 >buffer = malloc( sizeof( char ) );
1バイトしか確保できないよ
'\0'しか格納できない
もう少し多めに確保して
>return buffer != NULL ? buffer:"FAULT!!";
buffer の確保が失敗した場合 sprintf( buffer, "%d", n ); でエラーが出る
buffer = malloc( sizeof( char ) );
if(buffer){
sprintf( buffer, "%d", n );
return buffer;
}
else {
return "FAULT!!";
}
のほうがいい気がする
>>721 せっかくならmallocも直してやれよw
11桁くらい確保すれば十分の気がする
>>720 んじゃ buffer = malloc(sizeof( char ) *12);
または buffer = malloc(12);
>>722 符号付の場合、'\0'いれると12文字になる
724 :
デフォルトの名無しさん :2007/07/05(木) 23:40:25
最強の関数教えてください
VIPでやれ
どう考えても main だろ。
exit
buffer = (char*)malloc(sizeof( char ) *12); ↑これは?
bufferの型にあわせてあるんだろ。 C++じゃ必須の書き方だがCじゃいらん。
CとかC++の問題じゃねーだろ・・・知ったかの初心者がレスしてんのか、ここは? キャスト演算子とか知ってなさそうだな・・・平気で型の違う変数をキャスト演算子なしで 代入しちゃうようなヘボプログラマーかw
732 :
デフォルトの名無しさん :2007/07/06(金) 01:48:12
配列の添え字に変数を指定することは可能でしょうか?
コンパイラが自動的にやってくれるのを当てにして失敗するプログラマー(プ
>>730 (・∀・)ニヤニヤ
> bufferの型にあわせてあるんだろ。
> C++じゃ必須の書き方だがCじゃいらん。
735 :
732 :2007/07/06(金) 01:57:25
自己解決しました 可能っぽいですね
C だと void* から別のポインタ型への変換は暗黙にできるだろ・・・常識的に考えて。
void*が無かった頃のCならmallocはchar*を返したから キャストしないと警告もんだとか言い出してみる。
>>730 (・∀・)ニヤニヤ ヘボプログラマー必死だな
>>738 malloc で気を使っても、
どっかで void* 使ってたらそれだけでアウツだけどな。
その環境なら。
741 :
732 ◆L/nntMgEC6 :2007/07/06(金) 02:11:36
>>730 (・∀・)ニヤニヤ あるんだろ。Cじゃいらん。
>>738 (・∀・)ニヤニヤ
> void*が無かった頃のCなら
>>732 char a[10];
int i;
でa[i]ってことですか?
もちろん可能。
添え字は整数の値をとる式ならなんでもおkだぞ。
>>744 (・∀・)ニヤニヤ
> 添え字は整数の値をとる式ならなんでもおkだぞ。
(VIPPERのAA略)<常識的に考えて配列の要素番号の範囲内だろ
アホが常駐しとるな
747 :
744 :2007/07/06(金) 02:34:12
範囲外まで指定できちゃうのがエラーの温床になってるしな。
とりあえず (・∀・)ニヤニヤ を NG にした。
751 :
732 ◆L/nntMgEC6 :2007/07/06(金) 02:42:37
>>744 さん
回答有難う御座います。
int i;
char a[]="abc";
i=strlen(a);
char b[i];
のような感じで使いたいのですが、可能でしょうか?
>>747 (・∀・)ニヤニヤ 適切と不適切がわからないプログラマーワロスw
キャストは不要でつか〜〜〜?
746 名前:デフォルトの名無しさん 投稿日:2007/07/06(金) 02:33:49 アホが常駐しとるな (VIPPERのAA略) < 常識的に考えて知ったかぶって初心者にありもしないことを言う方がおかしいだろ どう考えて配列を適切に参照できる、要素番号の範囲内の値をとる式ならって話ならわかるけどw
とりあえず (VIPPERのAA略) を NG にした
>>744 (^∀^) ニタニタ
> 添え字は整数の値をとる式ならなんでもおkだぞ。
整数の値をとる式ならなんでも 整数の値をとる式ならなんでも
こやつは要素数と参照できる範囲外の値をとってもおkなんだぞぉーーー!
>>744 m9(^д^)9m プププ、(ダブル)プギャー
文体変えてAA使っても、いつものアホだってことはバレバレ
>>754 all right, I will use AA that's not for short.
>>757 > いつものアホ
アホとか言っちゃってるよぉ〜〜〜、お前がアホのくせして初心者に大嘘教えているくせにw
お前みたいな奴にアホ言われたくね〜〜なぁ。俺は間違ってねーし。お前は不適切。
VIPPER の AA 略 < 常識的に考えて、文法的におkってことを持ち出して 不十分な(というか間違っている)説明の言い訳をするかぁ? んじゃお前は a[10] の配列の10番目を参照するときは a[10] とでもやってろよ
>>751 それはダメ。
配列変数の宣言文には変数は使えない。
それをするなら
nt i;
char a[]="abc";
char *b;
i=strlen(a);
b=(char*)malloc(sizeof(char)*i);
>>751 int i;
char a[]="abc";
char *b;
i=strlen(a);
b = (char*)malloc(sizeof(char)*i);
free(b);
スレの流れからすればこんな感じ
bにaと同じ長さの文字列を入れるなら+1しないと駄目だけど。
763 :
732 ◆L/nntMgEC6 :2007/07/06(金) 02:58:25
>>761 さん
有難う御座います。おかげで疑問が解けました。
| ( ●)(●) いい加減な説明をしていることを指摘されて . | (__人__) 指摘した相手をアホとか言う方がアホだろ | ` ⌒´ノ 常識的に考えて・・・
回答者が書く補足としては、ありだとおもう。 突っ込みとしては、ちょっと弱い。
/ ノ ⌒ \ 文法的にも間違っていることを言う奴が | (●)(●) | 間違っていない奴にアホって言うアホだろ . | (__人__) | 常識的に考えて。ちゃんとキャストしろよ
常考常考うるせーよ 貶し合ってないで意味のある話をしろ
>>763 VBだとそれができるんだよね。
それはVBなどのインタープリター言語は実行時に変数宣言文も実行文もおなじように上から処理してゆくから。
Cのようなコンパイラ言語はコンパイル時に変数宣言文を処理してゆく。
だからコンパイル時に配列変数のサイズがわかっていないと処理ができない。
JavaもVBと同じだと思う。
ここは初心者が鼻息を荒くして入門書読みながらレスしてるのが多くて注意が必要
| ( ●)(●) お前みたいな奴は、たとえドラマの役者として . | (__人__) 起用されても、まともなキャスティングもされずに | ` ⌒´ノ 脇役かエキストラに決まってんじゃん>アホ言うたアホ
AA厨も早く寝ろ 今日はお開きだ
いまさらやらない夫のAA貼り付けて喜んでんのかよw
いまさら やらない か?っつか、いまさらキャストも適切に出来ない奴が 初心者相手にいい加減な説明、笑えねぇ〜〜〜〜〜。お前、指導者に向いてねーよ。
キャストすると型によってアドレスが変わるプロセッサの話をすると、へんなのを召喚しちゃいますか?
それがどうかしたのか? printf に渡すときの話とはわけが違うぞ?
1バイト文字と2バイト文字が混在してる文字列を ループ使って1バイトずつputchar()で画面に表示しても ちゃんとどちらも表示されるのは、シェルやプロンプトの方で 何バイト文字か確認して1バイト文字じゃない時は 一度バッファに溜める、とかしてるからですか?
ものによるとしか
782 :
780 :2007/07/06(金) 06:49:14
>>780 いいえ、シェルプログラムはそんなことはしません。
784 :
780 :2007/07/06(金) 07:52:43
>>783 あ、コンパイラがやってくれてるんですか?
>>784 いいえ、勿論コンパイラの知ったこっちゃありません。
もしかしたら、画面表示はシェルプログラムがやっていると思っているんですか?
例えば他のPCにリモートログインしたときには相手先のシェルプログラムが動くわけですが、
そのシェルプログラムが自分の使っているPCの画面を直接アクセスするなんて夢でも見ているんですか?
>>780 マルチバイト文字などに関係なく、標準入出力は
行単位バッファリングされていることが多い。
バッファリングなしにしても、まあ正しいマルチバイト文字列になった時点で
正しく表示されると仮定していいと思う。
787 :
780 :2007/07/06(金) 08:24:22
>>785 ということはOSの画面表示を担当するプログラムが
putchar()で2バイト文字の一部を出力しようとした時に
2バイト文字の一部だと判断し表示を一時中断して
次に送られてくるputcharの引数と組み合わせて
それに対応する2バイト文字を出力していているんでしょうか?
2バイト文字で、1バイト目単体で文字としてなりたっているようなのってなんかあったっけ?
>>788 iso-2022-jpの1バイト目はASCII文字と同じコード。
790 :
780 :2007/07/06(金) 08:30:47
>>786 行単位でバッファリングするんですね
それで予め2バイト文字があるかないか調べるわけですか、なるほど
>>789 Shift_JISしか考えてなかった。参考になった
ありがとう
文字コードの体系もしっかり管理しときゃ良い。
型で区別するんじゃない? char型ならその分のデータを受け取るまで待つ
ASCIIコード体系でなければ左へ受け流すぅ〜
1: 3.2 2.6 3.4 2.1 5.2 3.4 5.2 2.4 4.2 4.1 0.2 4.2 5.3 2: 3.2 2.4 3.4 2.2 5.2 3.4 5.2 2.4 4.2 4.3 0.2 4.2 5.3 3: 3.1 2.6 3.4 2.1 6.2 3.4 5.2 2.4 4.2 4.0 0.2 4.2 5.3 っていうデータがあるとして 10個目(つまり4.3 4.1 ,4.0)だけを抜き出すプログラムをつくれといわれると float型でやりますか?char型でやりますか?
「作れ」っつった本人に仕様を確認する。
とりあえず float は使わない。 使うなら double 。
つーか、計算もしないし区切りもはっきりしてるなら 文字列のままで通しちゃったほうがいいべ
>>793 それはない。そんなことしたら、ファイルにリダイレクトできない。
>>791 iso-2022-jpの場合、KanjiInが来た後は2バイト文字、そうでなければAsciiという分け方。
だから2バイト文字の後にKanjiOutが来ないと文字化けする。
>>790 バッファリングはするかもしれないが、出力の判断とは直接的には無縁。
でなければエスケープシーケンスでの制御ができない。
>>799 >KanjiInが来た後は
>KanjiOutが来ないと
そんなコード/シーケンスはありません。
801 :
デフォルトの名無しさん :2007/07/06(金) 18:09:25
Windows2000で作られたソフトはWindowsXPではうまく動作しないことが あるのですか。LSI C-86を使ってC言語を学ぶという趣旨の本を5年前に 買ったのを今になって勉強しようとしてインストールしたという次第です。 最初のコマンドプロンプトがC:\>になるはずのところ、C:Documents and Settings□□>となりエラーと表示されました。□□は、再起動時に アカウント指定を要求され、自分の名前を入れたものです。 別な場所へインストールすればよいのですか。よろしくお願いします。
>>801 LSI-C86は遺物なので、特殊性を理解できていないなら使ってはいけない。
MSのVisualStudioでもgccでも、無料で手に入るほかのコンパイラを使うことをお勧めする。
まあコマンドプロンプトをC:\>にしたいなら、cd \ でいいけどな。 本と同じになるだけで、役には立たないだろうけど。
804 :
デフォルトの名無しさん :2007/07/06(金) 18:26:59
>802 responseありがとうございます。早速入手しようと思います。
805 :
デフォルトの名無しさん :2007/07/06(金) 18:43:58
ソーカcd¥−enterで続けられるのか。
>>804 たぶん電子メールのレスと2ちゃんのレスは同じ意味を持ってると思うんだが、
だとしたら君が使ってるresponseはレスという意味とは違うぞ
nullponceというのを提案しまnce
810 :
723 :2007/07/06(金) 19:39:17
英語版ウィキペには Reply. Its abbreviation followed by colon (Re:) is prepended to e-mail subject lines when answering a received message って書いてるんだよな。 まあ、スレ違いだからどうでもいいが。
812 :
デフォルトの名無しさん :2007/07/06(金) 20:22:37
A)入力装置に関する記述のうち,適切なものはどれか。 1 ジョイスティックは,画面上に透明なセンサを取り付けたものであり,画面に指などを押し付けて座標を指示する。 2 タブレットは,ペンのような装置と板状の装置を組み合わせた入力機器であり,ペンのような装置を押し付けて座標を指示する。 3 ディジタイザは,人間のもつ静電気を利用して指の位置を検出するポインティングデバイスであり,操作面を指して座標を指示する。 4 トラックパッドは,球の一部分が装置の上面に出ているポインティングデバイスであり,球を指で直接回転させて,その変化量で座標を指示する。 すみません、質問なのですが今上の問題がハードウエアの組み込みの 参考書の問題がわかりませんので、教えてはいただけないでしょうか?
1はジョイスティックの説明ではない事は明らかだから× 2は正しいと思うから○ 3は知らんから知らん 4はトラックパッドじゃなくてトラックボールの説明だから×
815 :
デフォルトの名無しさん :2007/07/06(金) 20:29:48
ありがとうございました。 これで先に行けます。
816 :
デフォルトの名無しさん :2007/07/06(金) 20:32:06
制御系といえば、C言語だけど Cのすごい所って何?
体にぴったり張り付くスク水の用に、ハードウェアに貼り付ける所
3はタッチセンサとか、タッチスクリーンとか言われている物のうちの1種だね
821 :
デフォルトの名無しさん :2007/07/06(金) 20:42:36
C言語にできることは、C++にもできるって聞いたんだけど、 C++も体にぴったり張り付くスク水のように、 ハードウェアに貼りつけるの??
Cと同じようにできる。
823 :
デフォルトの名無しさん :2007/07/06(金) 20:44:46
C++もC言語と同じように最強ならば、 C++も制御系によく使われるの? それともC++はオープン系(WEB系も含む)?
824 :
デフォルトの名無しさん :2007/07/06(金) 20:47:10
質問です。年月日を入力してツェラーの公式を利用して曜日を表示するプログラム をつくりたいんですけど、BCCでコンパイルしたら公式のところでエラー 「浮動小数点の不正な使用」ってでるんですけど、どうしてだかわかりますかね? #include <stdio.h> int main(void){ int year,month,day; char youbi[7][10]={"Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"}; int i; printf("Year?"); scanf("%d",&year); printf("Month?"); scanf("%d",&month); printf("Day?"); scanf("%d",&day); i=(year + (year/4) - (year/100) + (year/400) + (2.6*month +1.6) + day)%7; printf("It's %s.",youbi[i]); return 0; }
>>821 C++の場合スク水フェチのオジサンが自分で着る用に作ったものもあるので注意
>>824 (2.6*month +1.6)を(int)(2.6*month +1.6)にしろ。
ここが整数でないから、%の左側全体が整数型でなくなっている。
剰余演算子は浮動小数点数を演算対象にできないので、件のエラーになる。
>>823 Cが制御系で使われるのは「最強」だからではなく「高級アセンブラ」だから。
C++も制御系で使われるよ。C++として使われるかはともかく。
つか、最強ってなんだよ。
>>824 剰余演算子%というオペランドは整数同士でないとダメ
演算してる行の型がごっちゃになってるから明示的にキャストしたり読みやすくすべき
基本的にコメント文とかで説明もなしに実数を整数に叩き込んだりしちゃだめ
なるほど。できました、ありがとうございます。
830 :
デフォルトの名無しさん :2007/07/06(金) 21:30:26
スレ違いかもだけど、ここの人達他のスレより頼りになりそうなので。。。 基本情報の午後問をCで受かりたいのですが、なんの本を読めばいいですか? 当方、C言語はよくわかりません。COBOLは少しできます。 ただCで受けたいのです。
C言語ってeclipceかbolandか、 それともvisual basic かどれでやればいいですか?
その質問おもしろい?
visual studioだっけ?
整数型配列は int iarray[10]; memset(iarray, 0, sizeof(array)); ですべて0で初期化できると知ったのですが、 実数型配列を double darray[10]; memset(darray, 0.0, sizeof(array)); のように初期化してもかまいませんか? つまり実数型配列の全ての要素を0.0にしたいのです
>>837 いいんじゃね?
DirectXとか、そういう方法で、実数やらポインタやらバリバリクリアしてたな。
移植性は無くなる。
> memset(darray, 0.0, sizeof(array)); あ、これは、警告かエラーになるな。 sizeof のところはミスだよね?
>>837 ANSI/ISO Cへの移植性を望むなら避けるべき。
浮動小数点数がIEEE 754に則っていることを仮定してよいなら構わない。
>>833 ほとんどにアルゴリズムの問題
ポケコンのCインタプリタでおk
>>839 すみません sizeof(darray) です
あとmanページでmenset関数を調べてみると
#include <string.h>
void *memset(void *buf, int ch, size_t n);
となっていたので
int ch に0.0と渡してもだめなんですね
ということは関数の仕様上は
memset(darray, 0, sizeof(darray));
と書くのが正しくて、
しかもCコンパイラの浮動小数点がIEEE754前提での使い方なので
結局は配列の要素数の分だけループで回して初期化するのが
一番いちゃもん言われにくいということでよろしいでしょうか?
ありがとうございました
エクセス64で 0 ってどうなるの?
>>843 double darray[10] = {0};という手もある。
>>845 漏れもそれでいいと思う
アセンブリみたら結局memset呼び出してるけど
質問です。 reallocを使ってて何度かlong*の領域をのばしてたんですが、 数百〜数千の間で必ずと言っていいほどヒープが壊れていますと 言われるのですが、値がばらばらでどこが原因だかわかりません。 こういうときはどのようにしてバグを見つければいいのでしょうか?
現象が再現する最低限のソースをアップすればいいんじゃね
849 :
847 :2007/07/06(金) 23:46:14
何回かデバッグしてたら全く手を入れてない所まで エラーが… もうやだ orz もう少しいじってからまた来ます。
>>847 デバッグする
最低限の機能だけにして実行してみる
ソースをじっくり眺める
最近c言語を習い始めた者ですが、初心者にお勧めなコンパイラって何がありますか?
VC++, gcc
VisualC++ 2005 Express Edition
エラーの元は何とかわかったのですが… 以下の関数 void Add(ArrayList* list, const void* value) { char* data = (char*)list->Array; char* item = (char*)value; int i = 0; unsigned int index = list->Length * list->ValueSize; if(list->Length >= list->Maximam) { list->Maximam *= 2; list->Array = realloc(list->Array, list->ValueSize * list->Maximam); } for(; i < list->ValueSize; i++) { data[index + i] = item[i]; } list->Length++; } でポインタの長さを2048以上にして次以降でポインタの長さをいじるか、 この関数でポインタの長さを4000以上にすると ヒープが壊れるみたいです。 //やっぱりCで.NETのArrayListもどきを作ろうとすること自体が間違ってるんだろうか…
すいません。訂正です。 長さを2048以上にして次以降 → × 長さを2000以上にして次以降 → ○
>>854 そこだけ見れば問題なさそうに見える。
> //やっぱりCで.NETのArrayListもどきを作ろうとすること自体が間違ってるんだろうか…
大いに間違っているといってやろうではないか。
軽くC++をやってみな。これくらい標準ライブラリの内だから。
>>854 reallocはメモリ確保できてるの?
mainの中身を
ArrayList list = { 0, 1000, sizeof(short), malloc(1000 * sizeof(short)) };
for(; i < 1001; i++)
{
Add(&list, &i);
}
for(i = 0; i < list.Length; i++)
{
printf("%d\n", *((short*)GetValue(list, i)));
}
free(list.Array);
getch();
としたら、ポインタの長さが4000バイト以上でfreeのところで、8000バイト以上だと
Addのところで止まるようになりました。
>>855 やっぱり間違ってますよね orz
C#から来てて、いい加減ネイティブでもかけるようになりたいなと思い
Cを始めたのですが、C++の方のがいいのかな…
>>857 上の例だと、4000バイトまでは確保できて、8000バイトからは確保できず、
エラーが出てしまいます。
realloc() した後で data(realloc 前の list->Array)の先に書きこんぢゃだめだろ。
>>858 突っ込みどころ満載だけど、一番の原因は>859だな。
>>859 ('A`)ヴァー
とんでもないところを間違っていることに今気づきました。
ありがとうございます。
>>860 まだ始めてから1ヶ月経ってないので、それは自覚していますが、
どこ、とまではわからず…
よろしければつっこんでいただけるとうれしいです。
(.NETの(ryが間違っていると言うこと以外で oz)
>>861 >860じゃないけど幾つか。
・realloc()の第一引数を戻り値で上書きしている
#realloc()の仕様に注意
・iの初期化と参照が泣き別れ
#折角forを使うのだから……
・indexの立場(名前と使い途)が微妙
#eralloc()した後で、オフセット計算してしまえば無くてもすむ
構造体のゼロクリアにmemsetではなく、{0}を使う実装を見たのですが、これはアリなの でしょうか? メンバに配列が居た時にきちんとゼロクリアされているかが疑問です。あ と、パディングされている部分もクリアされないような(これは大した問題じゃないかな)。
862 があげたとこ以外だと、 ・せっかく value を const にしていながら、const でない item に 無理やりキャストして代入し直している ・for ループで 1 バイトずつコピーするより、 memcpy() とか使うほうが効率良い ・main() 関数の i は int? short? int なのであれば、一旦 short 型の変数に代入して、short 型の変数の ポインタを Add() の引数として渡すべき ・Maximam -> Maximum
>>863 安心しろ、コンパイラはその辺を適当に最適化してくれる。
#つーか、パディングがクリアされることに依存したコードは論外だ。
つい先日もどこかのスレで{0}でもmemset()呼び出しのコードになったと言う報告があった。
iccではmemset()より高速な内部関数を呼ぶようだ。
>>858 listを作るときも、初期化子でやるのではなく、コンストラクタ相当の関数を作ろうよ。
そして終わりも直接freeするのではなく、やはりデストラクタ相当の関数を作る。
867 :
867 :2007/07/07(土) 13:17:40
質問です,Gauss-Jordan法を用いてxベクトルの値を調べるプログラムを作りたい のですが,いくらやっても手計算の結果と一致しません。Ax=bという行列とベクトルの 計算で, [1 4 3] A=[2 5 4] [1 -3 -2] [1] b=[4] [5] という数値で, [ 3] x=[-2] [ 2] という結果になるはずなんですが上手くいきません,どこが違うのでしょうか…? #include<stdio.h> #include<math.h> #define NMAX 3 main() { double a[NMAX][NMAX]={{1,4,3},{2,5,4},{1,-3,-2}}; /*数値は適当,課題はこの数値*/ double b[NMAX]={1,4,5},x[NMAX]; /*定数ベクトルの数値も適当*/ int i,j,k;
868 :
867 :2007/07/07(土) 13:28:22
for(k=0;k<NMAX;k++) { for(i=0;i<NMAX;i++) { if(i!=k) { for(j=0;j<NMAX;j++) { a[i][j]=a[i][j]-(a[i][k]/a[k][k])*a[k][j]; /*係数行列の対角化*/ b[i]=b[i]-(a[i][k]/a[k][k])*b[k]; } } } } for(i=0;i<NMAX;i++) { x[i]=b[i]/a[i][i]; } printf("The vector x(answer) is: \n"); printf("[%lf %lf %lf]",x[0],x[1],x[2]); }
>>868 素朴な疑問なんだが、「係数行列の対角化」の行は合ってる?
870 :
867 :2007/07/07(土) 14:43:45
あ、やっぱり。 対角化の処理の間に古い値と新しい値が混ざってしまうようだよ。 つまり、例えばこういうこと。 古いa[どっか]*古いa[よそ]→新しいa[どっか] 古いa[よそ]*新しいa[どっか]→間違ったa[よそ] 処理中は古い値を一時的に保存しておかないといけない。 つまり、例えばこういうこと。 古いa[どっか]→一時的なa[どっか] 古いa[よそ]→一時的なa[よそ] 一時的なa[どっか]*一時的なa[よそ]→新しいa[どっか] 一時的なa[よそ]*一時的なa[どっか]→新しいa[よそ]
872 :
867 :2007/07/07(土) 15:54:07
なるほど…、じゃあa1[NMAX][NMAX]を作って一時保存用の配列をつかってやってみます!
873 :
705 :2007/07/07(土) 16:03:00
いろいろ用事を片付けている間にたくさんありがとうございます。
>>862 >#realloc()の仕様に注意
後からわかったのですが、reallocでNULLが返ってきたときのことでしょうか?
一応代入前にNULLチェックをするようにします。
>・iの初期化と参照が泣き別れ
変数宣言と同時に初期化というのが体に染みついているので、
forの中で初期化するのがあまりしっくりこないもので…
>#realloc()した後で、オフセット計算してしまえば無くてもすむ
reallocした後に、data += list->Length * list->ValueSize;
という風にすると言うことでしょうか?
>>864 >無理やりキャストして代入し直している
確かにこれじゃconstした意味ないですよね orz
>memcpy() とか使うほうが効率良い
どこかで構造体のコピーにmemcpyは使うなと言うのを見たのですが、
この場合は大丈夫なのでしょうか?
>main() 関数の i は int? short?
ここに書いたのはただのテスト用なので問題ないのですが(一応short)、
実際に使うときには注意します。
>・Maximam -> Maximum
orz
>>866 ここには書きませんでしたが、コンストラクタ相当の関数ととデストラクタ
相当の関数は作ってあります。
いろいろなツッコミありがとうございました。
>変数宣言と同時に初期化というのが体に染みついているので、 コーディングガイドでは寧ろ、「参照直前に初期化(代入)」なんだけどね。 c99ならfor (int i = 0; ...ですむし、C++でも……って、C++ならSTL使うか。 どうしてもってことなら、c89でもブロックの先頭なら宣言できるのでこういう手は使える。 anyFunction(...) { ...; ...; { int i = 0; for (; i < list->ValueSize; ++i) { ...; } } }
int i = 0; ... for(i = 0; ...) { } って書けばいいじゃん。 どうせ最適化で最初の 0 初期化は消える。
Visual C++なら/TPを付ければfor (int i = 0;が使えるw。
それはそうと「w」の後に句点を付ける人初めて見た
VC++がいつまでたってもC99に対応しないのはCを潰そうとしているから。
文字列から全角空白文字を削除するにはどうすればいいでしょうか? 半角なら *p=='(半角スペース)' (pはchar *) で比較一致したら処理、で出来るんですが全角の場合どうすればいいのか分かりません お願いします
replace(char *buf, char *oldstr, char *newstr) という関数を作って replace(buf, " ", "") とかやっとけ
>>881 そのreplace関数の処理部分をどうすればいいのか悩んでいます
buf内にoldstrに一致するデータを探せばいいだけですかね?
文字列str に部分文字列findstrが含まれている場合1を返します
ただしstrに空白が含まれている場合はそれを除いた文字列と比較します
int sfind(char *str,char *findstr)
{
unsigned char *stmp,*fstmp;
while(*str!='\n'&&*str!='\0')
{
if(*str==*findstr)
{
stmp=str;
fstmp=findstr;
do{
stmp++,fstmp++;
if(*stmp==' ') { stmp++; continue; } //半角スペースを取り除く
// 全角スペースを取り除きたい.どうすれば?・・・B
if(*fstmp=='\0')return 1;
if(*stmp=='\n'||*stmp=='\0')return 0;
}while(*stmp==*fstmp);
}
str++;
}
return 0;
}
置換対象の文字列を検索するのにstrstrを使っては駄目なの?
>>883 そーですね
その方向でもう少し試行錯誤してきます
ありがとうございました
ポインタ変数pがあったとして p++; *p++; (*p)++; の違いを教えてください、よろしくお願いします。
*p++ = *(p++) ≠ (*p)++
>>885 実験してみりゃえっちゃないか
int i[ 3 ] = { 5, 10, 15 };
int *p = i;
printf( "*p:%d\n", *p );
p++;
printf( "*p:%d\n", *p );
*p++;
printf( "*p:%d\n", *p );
(*p)++;
printf( "*p:%d\n", *p );
>>887 さん、確かに実験してみたほうが早いですね。
とてもわかりやすかったです!ありがとうございます!
ポインタが理解できた気分になりました、気分ですけど。
イキナリで申し訳ありませんm(__)m 当方某学校にて「C言語入門」を勉強しているのですが、 宿題がわからないんです! 優しい方、お手数ですが教えていただけないでしょうか。 わからない、その1 「コンピュータが計算する、任意の数の型は何型ですか。」 わからない、その2 「関数yesno(char *msg)で、キーボードから a を入力したときの、戻り値は何か。」 もし、よろしければ答えてくださると助かります。 よろしくお願いいたします。
わからない、その3 「君が省略した部分」
891 :
デフォルトの名無しさん :2007/07/08(日) 02:41:53
>>889 お前の質問内容自体が、わからない。
エスパーよろしく
>>889 そんな貴方の授業依存な問題はさすがに無理。
その1はint型・・・か?ってか、コンピュータが何かもさっぱりだよな。
その2はさすがに関数の中身みねぇとわからん。エスパーで0と予想w
>>889 >「コンピュータが計算する、任意の数の型は何型ですか。」
特に理由が無ければintを使うって事かな?何この問題
>「関数yesno(char *msg)で、キーボードから a を入力したときの、戻り値は何か。」
関数の定義を見ないとわからないけど97か0か1か-1と予想。何この問題
おれの予想では 1、doubleで計算しとけばおkじゃね? 2、aを入力して戻るとしたらbool値もしくは対象の格納番地もしくは配列の添え字 かな・・。
「コンピュータが計算する、任意の数の型は何型ですか。」 なんのこっちゃ 1ワードの大きさと等しい型名のことか? それか1/0のブール型の論理演算でう!っていえばええんか?ええのんか〜
>>889 答が返ってくる質問ができるレベルにすら達してないよ
その1 バイナリー型 その2 YES_NO_DIALOG_KEY_OTHER とかどうよ?
当方
>>889 です。
ここのスレの方々、質問の幼稚さに顔が真っ赤になるばかりです。
実はもう一つ違うスレにマルチで
>>889 と同じ質問をしてしまいました。
欲がでたのです。本当に恥ずかしい限りですが、今回は宿題の期限が間近に迫っていまして、
この宿題の是非で学生としての楽しい楽しい夏休みが補講という ことに成り兼ねません(ノД`)
自分勝手なお願いなのですが、今パソコンをつかえる環境に無く(携帯からのカキコミ)、今日朝9時15分頃に
使えるんです。パソコンが、
上記も内容が同じような事をもう1つのスレにも書いたのですが、
その今日の朝に宿題UPしてもよろしいでしょうか。
よろしいでしょうか。というのは、先輩の方々にお答えしてもらいたいと、いうことです。
当方
>>889 です。
ありがとうございます(_ _(--;(_ _(--;
先輩方よろしくお願いします。
(ρ.-).。o○
このスレのエスパーズに海パン!
C言語使いにスク水嫌いはいない!
当方
>>889 です。
UPさせていただきます。
先輩方どうあよろしくお願いいたします。
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
/* 関数のプロトタイプ宣言 */
int random(int min, int max);
char yesno(char *msg);
/* メイン関数 */
void main(void)
{
int r;
char yn;
srand((unsigned)time(NULL));
yn = 'n';
while(yn == 'n')
{
r = random(5, 6);
printf("コンピュータが計算した数は %d です\n", r);
yn = yesno("終了しますか?(y/n)");
}
}
・・・・・・・続く・・・・・・・・・・・
/* ユーザ定義関数 */ int random(int min, int max) { int r; r=rand() % (max - min) + min; return r; } char yesno(char *msg) { char yn; printf("%s", msg); scanf("%c", &yn); if(yn == 'y' || yn == 'Y') { yn='y'; } else { yn='n'; } return yn; } 1.コンピュータが計算する任意の数の型は何型ですか。 2.コンピュータが計算する任意の数は、いくつからいくつの間の数ですか。 3.どのようにしたら、このプログラムを終了させることができますか。 4.関数 yesno(char *msg)で、キーボードから’a’を入力した時の、戻り値は何になりますか。 5.コンピュータに計算させる数を、3から8までにしたいときには、何行目のどこを書き換えればよいですか。 よろしくです。
まるで小学校のドリルかなんかのような設問だな。
この段階で落ちこぼれてたら、残りの授業は座ってるだけだな。 カワイソス。
そんな言い方はないと思うな。
当方
>>889 です。
1はint型
2は5〜6
3はy
4は不明
5r = random(5, 6);のところを5と6を書き換え
と予想しているのですが、まったく根拠なしなのですが、助言賜りたいですm(__)m
1. と 2. がよく分かりませぬ。 1. int 2. 5のみ 3. y か Y を入力 4. n 5. r = random(5, 6); を r = random(3, 9);
4. 'n'のがいいか
当方
>>889 です。
>>910 さん、レスありがとうございます。
1と2合ってる気がします(私見)。
1つ質問よろしいでしょうか。
なんで、4の戻り値がnになるのでしょうか。
もしよければ、レスお願いいたします。
日本語が下手ですが、こんな感じで char yesno(char *msg) { char yn; printf("%s", msg); scanf("%c", &yn); // yn に 'a' を入力 if(yn == 'y' || yn == 'Y') // yn が 'y' 、もしくは 'Y' かどうか yn='y'; // ifが真ではないので、実行されない else // ifが偽のため、以下を実行する yn='n'; // yn に 'n' を代入 return yn; // yn の値を返す }
いちいち yn に代入するのを省けばこんな感じ char yesno(char *msg) { char yn; printf("%s", msg); scanf("%c", &yn); if(yn == 'y' || yn == 'Y') return 'y'; else return 'n'; }
当方
>>889 です。
>>910 さん、わざわざありがとうございます。
よくわかんないですが、なんとなくわかった気がします。
宿題はまだあるので、がんばりたいと思います。
1からnまでの間で素数のみを取り出すエラトステネスのふるいをつくりたいんですけど ちょっとよくわからないので教えてほしいです。 n=20(入力 1 2 3 5 7 11 13 17 19(出力
>>916 どこが解かんないか解からんし
先ずは20を入力して配列なりリスト構造なりにデータを格納して出力する所から作ってみなよ
>>916 #include <stdio.h>
#include <stdlib.h>
#include <math.h>
int main(void) {
int *prime,LIMIT,i,j,c,n;
printf("Input n > "); scanf("%d",&n);
prime=(int*)malloc(n*sizeof(int));
for(i=1; i<=n; i+=2) prime[i]=1;
for(i=4; i<=n; i+=2) prime[i]=0;
LIMIT=(int)sqrt(n);
for(i=3; i<=LIMIT; i+=2) {
if(prime[i]==1) {
for(j=2*i; j<=n; j+=i)
prime[j]=0;
}
}
printf("%4d",2);
for(c=1,i=3; i<=n; i+=2) {
if(prime[i]==1) {
printf("%4d",i);
c++;
if(c==10) {
printf("\n");
c=0;
}
}
}
free(prime);
return 0;
}
そっすね
>898 すなおに補講を受けたほうがいいじゃね?
コメント文に /* Cスタイル */ // C++スタイル が有るんですがどっちかに統一したほうが良いですか? Cスタイルは目立ちやすいので見出しとかに使って C++スタイルはCスタイルに比べて目立ちにくいので文の注釈に適してるように思いますが・・・ なんか慣習とかあるんでしょうか?
上のはブロックコメントだから複数行書くときに使えばいい。そんだけ
複数行:/* */ 単行://
あーなるほどそんなシンプルな事でいいんですよね!
すみませんもう一つおねがいします 関数を実装する時に例えば戻り値の型がvoidで何も返さない場合,最後の文に return; を書くべきでしょうか? コンパイラは最適化してしまいオブジェクトコードには何の影響も無さそうですが. 関数はこの文で戻り値無しで終了するという事を明示的にするという意味で書くのは冗長すぎますかね? void Hoge(void){ puts("Hoge"); return; }
>>926 ↓このvoidは戻り値がないことを明示している。
void Hoge(void){
int error = foo();
if (error) {
return; ←エラーだったら処理やめる。中途リターンしないとインデントが深くなる
}
return; ← これはいると思うか?
}
長い関数の最後にreturnがなかったら、「そか、voidだもんな」と思うだけ。
長い関数の最後にreturn;があっても、「そか、voidだもんな」と思うだけ。
つけて防げるバグもなければつけて増えるバグもなし
return; /* この関数は戻り値を返さない */ としたらいいじゃん。
そんな事書かなくてもvoidでわかるやん
「voidを返す関数の場合はreturn;を書いてはならない」っていうコーディング規約 とかあったらイヤだな。
関数の途中で抜けたらだめなのか
>>934 そんなコーディング規約意味ないけどな。
どうしても末尾に書きたいなら
戻り値int にしてreturn 0にすりゃいいじゃん。
>>929 リターン値がintの関数で、ミスって、
return;
と書いても、エラーにならなかったような記憶が。
gccは-Wallオプションで警告が出るだけでコンパイル通る
>>938 Cとしてコンパイルしてる?
C++ならエラーだよ。
g++ だとエラー
お前らスレタイをだな
眠くて読んでなかった。少し反省してる。
945 :
ライ :2007/07/09(月) 12:45:29
固有値求めたいんだけどそのときに使うライブラリってなに?
そのくらい自分で書けばいいだろ。
947 :
ライ :2007/07/09(月) 13:16:16
4X4行列の固有値求めたいんだけどわからなくて
要するにあんた数学わかってないんじゃないの?
CLAPACK
自分で必死こいて高速化頑張ってもCLAPACKの足元にも及ばない悲しさ まあ車輪の再発明なんて馬鹿馬鹿しいよね
951 :
デフォルトの名無しさん :2007/07/09(月) 18:24:12
次の説明が正しい場合は1を、間違っている場合は2を( )に記入せよ。 @( )USBは多様な周辺機器と接続できるが,転送速度が遅いのでマウスやキーボードなどには適しているが,高速を要する外付け固定ディスクなどとの接続には不適切である。 A( )PCとキーボードやマウスはPS/2やUSBポートで接続する。 B( )PS/2やUSBにはホットプラグイン機能があるので、キーボードやマウスをこれらのポート差し込んだ時点で使用可能となる。 C( )マウスにはボール式、光学式、レーザ式などがあるが、光学式が最も精度が高い。 D( )CUIの代表的な入力装置はマウス、GUIの代表的な入力装置はキーボードである。 E( )キーボードのキー構造として、メンブレン方式とパンタグラフ方式があり、ノートPCではパンタグラフ方式の採用が多い。
宿題スレ池カス
そもそもこれだけでは板違い。
955 :
デフォルトの名無しさん :2007/07/09(月) 18:31:39
957 :
デフォルトの名無しさん :2007/07/09(月) 18:34:18
ソケットを使ってのネット通信について質問させてください。 UDPでの通信で、 サーバ側がソケットを作成→bindし、 クライアント側がソケットを作成→connectした場合、 サーバから文字列を送信する場合はどうすればいいのでしょうか。
ネトPスレ池カス
っつか、機種依存文字を多用するな・・・
マカ乙
機種依存文字なんて既に死語じゃね?
半角カナのごとくそういう時代になったのか・・・俺の知らぬ間に。 いや、もう10年近くインターネットを毎日利用しているが。
マカってほんとに「@」←これ見えないの?
「こんにちは、マックです。」 「こんにちは、パソコンです。それでは第(ピー)問」
大学の端末室はUNIXだからやっぱり丸付き文字は見られないな
lynxで見てるの?
携帯からも見えるが 検索しづらい文字使われるといらっとくるな
>>966 Firefox からだと「! 」に見える。
まあ、フォント次第なんだが、デフォだとそうなるね。
やっぱまだ標準的じゃないじゃん。誰だよ、マカーだの死後だの自分基準でものを言っている香具師は?
文字集合にUnicodeを使っていれば問題ない。そこにも丸付き数字は入っている。 近年はデスクトップもUnicodeの文字を表示できる環境が広まっているので、 確かに機種依存文字でなくなりつつあるというのはあながち間違いではない。 ここなら #9312;と書けばいいはず。①
int型のnを、15を越えない範囲内でインクリメントしたい場合、こ んな初心者丸出しのコードが思いつくのだけれど、もっと良い方法 は無いでしょうか? if (n <= 15) { n++; } else { ; } ビット演算する方法を考えてみたけど、とても良い方法とは思えな いので、教えてください。一応elseを明示しています。 if (!(0x10 & n)) { n++; } else { ; }
単純にこれでいいよ。Simple is best. if (n <= 15) { n++; } 後はコンパイラの最適化に期待しな。
>>973 同じことだよ。
やっぱ Mac からは「! 」に見える。
へぇ〜MacてUnicodeに対応してないんだ。
table[32] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 15, 15, ...}; としておいて table[ n & 0x1F ] というのはどうか
ダサッ
うるさいな 一生懸命考えたんだからガムぐらいくれよ
>>974 #include<stdio.h>
int main(void){
struct{unsigned value:4;}l={0};
int m=0,n=0;
int i;
for(i=0;i<20;i++){
printf(" %2d %2d %2d\n", l.value, m, n);
l.value+=1;
m=(m+1)&0xF;
n=(n+1)%16; // <- オススメ
}
return 0;
}
>>981 確かに 15を越えない範囲内でインクリメント はしているが、動作が変わってる
>>974 n+=(n<15)?1:0;
または
n=(n<15)?(n+1):15;
最速だし読んだ人も理解りやすいしifでいいじゃん if (n <= 15) { n++; }
もう終わってるネタだから
ということにしたいのですね:-)
今気づいたが 15を超えない範囲でインクリメントする場合の最大値は
15 になるのか 16 になるのかよく分からないな
(
>>974 に沿えば 16 が最大値だけど)
次スレそろそろたてる?
次スレを立てるにはスク水が必要じゃ
すいませんマージソートの非再帰的なプログラムってどうすればいいですか?
現在の幅を 1 から倍々で増やしていって、 幅が全長を越えるまで処理すればいいんじゃね?
993 :
デフォルトの名無しさん :2007/07/10(火) 02:21:41
-10を2進数に直すと、1111 0111で合っていますでしょうか? 自分の解釈では10なら、0000 1010なので-なら1から反転で 上のような回答になりました、違っていたらご指摘お願いします。
10 (10) = 0000 1010 (2) ↓ビット反転 1111 0101 (2) ↓+1 1111 0110 (2) = -10 (10)
-10 と 10 なら、足して 0 になれば正解だよ その2つを足して 0000 0000 になる?ならんな
1111 0110 やな。1010を反転させて0101 に 1 を加える それより上の桁は全部 1
997 :
993 :2007/07/10(火) 02:41:11
まず、ここまで10 (10) = 0000 1010 (2)は解ります 反転は0かrではなく、1からではなかったでしょうか?
998 :
993 :2007/07/10(火) 02:42:04
因みに、どうして 1111 0101 (2) ↓+1 1111 0110 (2) = -10 (10) で、+1をするのでしょうか?
っつか、どうしてって言われても、そういう仕組みがあるから。
1001 :
1001 :
Over 1000 Thread このスレッドは1000を超えました。 もう書けないので、新しいスレッドを立ててくださいです。。。