C言語なら俺に聞け(入門篇) Part 25

このエントリーをはてなブックマークに追加
1デフォルトの名無しさん
C言語の入門者向け解説スレです。
・C++言語はスレ違いです。
・分からない事をなるべく詳しく書いて下さい。
・ソースコードを晒すと答えやすくなるかもしれません。
・質問者は最初にその質問をした時のレス番号を名前欄に書いて下さい。

前スレ
C言語なら俺に聞け(入門篇) Part 24
http://pc11.2ch.net/test/read.cgi/tech/1201083176/

教えて欲しいのではなく丸投げしたいならこちらへ
C/C++の宿題を片付けます 104代目
http://pc11.2ch.net/test/read.cgi/tech/1202135539/
2デフォルトの名無しさん:2008/02/19(火) 00:09:53
3デフォルトの名無しさん:2008/02/19(火) 00:10:50
4デフォルトの名無しさん:2008/02/19(火) 00:12:55
5デフォルトの名無しさん:2008/02/19(火) 00:29:43
過去スレってなんか意味あるのか。
6デフォルトの名無しさん:2008/02/19(火) 00:46:32
なんだ初心者か。
7デフォルトの名無しさん:2008/02/19(火) 00:56:21
ほとんどdat落ちしてるし前スレのみでいいんじゃね?
●もちなんかレアだろうし
8デフォルトの名無しさん:2008/02/19(火) 01:01:15
●なくても見れるよ
9デフォルトの名無しさん:2008/02/19(火) 01:08:42
それ以前に、読むやついるのかって疑問も。
10デフォルトの名無しさん:2008/02/19(火) 01:52:43
読むことは無くても検索する事ならあるかもしれない
11デフォルトの名無しさん:2008/02/19(火) 03:29:29
たかだか2レス程度の過去スレリンクにけちつけるヤツってなんなの?
12デフォルトの名無しさん:2008/02/19(火) 11:02:18
そういう人に限って過去スレよめっていうんじゃない?
13デフォルトの名無しさん:2008/02/19(火) 15:51:40
C:\Program Files\Microsoft Visual Studio 8\VC\C>
test24.c
#include<stdio.h>
#include"myfunc.h"
{
......
}
myfunc.c
myfunc.h

環境 VC++ 2005 express edition

コマンドプロントでのリンクの方法おすえて。


14デフォルトの名無しさん:2008/02/19(火) 16:12:24
cl で拡張子まで指定すりゃリンクまでやってくれるよ。
15デフォルトの名無しさん:2008/02/19(火) 16:14:34
まあLINKでもいいけど。
オプションはGUIのほうでプロパティのリンカのコマンドラインみればわかるべ。
まああれ全部指定する必要も無いかもだが。
1613:2008/02/19(火) 17:19:51
cl teste.c myfunc.c
でけますた ありがとう あいしてる・
17デフォルトの名無しさん:2008/02/19(火) 21:16:35
>>12
反論できなくなると人格攻撃はじめるクセってみっともないから、直す努力したほうがいいよ。
まあ、そういう根性が染みついちゃってて、一生ゲスのまま終わっちゃうんだろうけどね。
18デフォルトの名無しさん:2008/02/19(火) 22:09:22
>>17
わざわざ同じレベルまで降りてやることもあるまいに。
19デフォルトの名無しさん:2008/02/20(水) 02:03:36
>>17

12だがなんのこっちゃ?

20デフォルトの名無しさん:2008/02/20(水) 02:50:57
>>11

>たかだか2レス程度の過去スレリンクにけちつけるヤツってなんなの?

?例えば、ですが…   2ch-browserの購入installを試みては…
r
21デフォルトの名無しさん:2008/02/20(水) 05:31:03
ポインタへの代入についての質問です。

const char**型の変数にchar **型の変数を代入するのは、
修飾型へのポインタに非修飾型へのポインタを代入することになるので
してはいけない(コンパイラが警告を出す)と本に出ていたので、

#include<stdio.h>

int foo(const char **p){
printf("ok\n");
return 0;
}

int main(int argc,char **argv){
foo(argv);
return 0;

}
上記のようにコーディングしてコンパイルしてみたのですが、
警告の類はでません(argcとpが参照されていないという
警告と標準ライブラリ関数のプロトタイプ宣言に関する
警告は出ます)。コンパイラはvisual studio2005に付属
しているもので/Wallオプションを付けてます。

なぜ警告がでないのでしょうか?

22デフォルトの名無しさん:2008/02/20(水) 08:32:15
>>21
国語の勉強してから、もう一度その本を読め。
23デフォルトの名無しさん:2008/02/20(水) 09:23:14
>>21
> const char**型の変数にchar **型の変数を代入するのは、
その代入をしていないから
24デフォルトの名無しさん:2008/02/20(水) 11:06:50
>const char**型の変数にchar **型の変数を代入するのは、
>修飾型へのポインタに非修飾型へのポインタを代入することになるので
>してはいけない(コンパイラが警告を出す)と本に出ていたので、
いいえ、そんな大嘘ありえません。
25デフォルトの名無しさん:2008/02/20(水) 13:55:21
いや、警告が出ないのは不思議。gccでも警告が出る。
VC++ならC++としてコンパイルすればエラーになるんだけど。

で、どういう問題があるんだったっけとググったら、ちょうどいい例が見付かった。
ttp://hpcgi1.nifty.com/MADIA/Vcbbs/wwwlng.cgi?print+200410/04100047.txt
int main() {
    const char c='c';
    char *x;
    const char **y=&x; // error
    // もしできたとしたら、以下の手順で c を変更できちゃう
    *y=&c;
    *x='b';
}
26デフォルトの名無しさん:2008/02/20(水) 15:02:40
>>25
質問の大元では関数の引数として const 修飾を使っている
27デフォルトの名無しさん:2008/02/20(水) 15:19:49
const char ** に char ** を代入することは、
「修飾型へのポインタヘのポインタ」に「非修飾型へのポインタへのポインタ」を代入することだから、
>21にあるような「修飾型へのポインタ」に「非修飾型へのポインタ」を代入することとはならないな。
28デフォルトの名無しさん:2008/02/20(水) 17:00:03
ぶっちゃけ動くならコードなんかどうでもいいですよね?
29デフォルトの名無しさん:2008/02/20(水) 17:02:13
メンテナンスを考えなくていいならな
30デフォルトの名無しさん:2008/02/20(水) 17:03:52
偶然動いてるのときちんと動いてるのと区別がちゃんとつくんならな。
31デフォルトの名無しさん:2008/02/20(水) 17:04:20
こういうのは自分だけで使うのか、他人に提供するのかでもかわってくるしな。
32デフォルトの名無しさん:2008/02/20(水) 21:10:12
>>26
x がグローバル変数なら似た事ができる。
3321:2008/02/20(水) 22:26:14
>>24
>>27
そうですね、
「修飾型へのポインタヘのポインタ」に「非修飾型へのポインタへのポインタ」を代入することでした。

>>25
確かににgccでコンパイルしてみたら警告がでました。
リンク先、参考になりました。ありがとうございます。

>>26
関数に引数を渡すのは、仮引数への代入として扱われるらしいので代入と書きました。わかりにくくて
すいません。

>>29
>>30
とりあえず、きちんとわかるまではエラーが出るような書き方は避けるようにしときます。
34デフォルトの名無しさん:2008/02/20(水) 22:28:31
関数に引数を渡すのは、仮引数への代入ではなく初期化。
3521:2008/02/20(水) 22:28:36
>>31
エラーじゃなくて警告でした。
3621:2008/02/20(水) 22:29:26
あ、そうですね。
代入だと、constつけたらできないですね。
37デフォルトの名無しさん:2008/02/21(木) 00:43:17
static関数はそのファイルでしか有効じゃないんですよね。
じゃあ、そのファイルでしか使用しない関数はstaticにしておけば、
関数名の衝突の心配が無くていいかと思うんです。

でも、そうしたらほとんどの関数がstaticになってなんか格好悪いんですけど。
そういうものですか?
38デフォルトの名無しさん:2008/02/21(木) 00:45:00
staticの何が格好悪いんだ
39デフォルトの名無しさん:2008/02/21(木) 00:46:37
>>38
いや、なんとなくです。
サンプルソースとか見ても、普通はそんなにstaticがついていない気がするし。
40デフォルトの名無しさん:2008/02/21(木) 00:47:11
普通そんなに関数名衝突しないだろ
41デフォルトの名無しさん:2008/02/21(木) 00:47:23
サンプルは適当に作ってるから書いてない事もある。
真面目に書く場合は公開しない関数には static を付けるのが普通。
42デフォルトの名無しさん:2008/02/21(木) 01:03:34
static付けたプロトタイプ宣言を書いといて、
定義は付けずに書けばどう?
43デフォルトの名無しさん:2008/02/21(木) 02:12:09
これに於いて


"スタック領域

戻り番地3
変数
戻り番地2
戻り番地1

       "

戻り番地とは、どういう意味なんでしょうか?

44デフォルトの名無しさん:2008/02/21(木) 02:15:07
retで戻る場所
45デフォルトの名無しさん:2008/02/21(木) 02:16:18
関数から帰ってきて再開する場所
void g() {...}
void f(){
 g() ;
r1:
 g() ;
r2:
}
上のgの中を実行中は

"スタック領域
r1

下のgの中を実行中は

"スタック領域
r2

f内の中を実行中はスタック領域=空
4643:2008/02/21(木) 02:16:50
>>44
ん???
4743:2008/02/21(木) 02:19:26
>>45
詳しく、ありがとうございます

ですが、どうしてこれが”戻る”っているのでしょうか?
48デフォルトの名無しさん:2008/02/21(木) 02:21:29
if(argc > 1) とは、argcが1より大きければ〜でしょうかね
49デフォルトの名無しさん:2008/02/21(木) 02:24:56
>>47
関数gにいってr1またはr2に戻ってくるから
50デフォルトの名無しさん:2008/02/21(木) 02:26:59
>>48
そのとおりだ、見ての通りだ
引数一個の時は、実行ファイル名と引数合わせて二個、argc==2だから注意しろ
51デフォルトの名無しさん:2008/02/21(木) 02:28:31
>>50
さんくすです
5243:2008/02/21(木) 02:33:49
>>49
ですが、これだと戻り番地が複数ありますよね???


"スタック領域

戻り番地3
変数
戻り番地2
戻り番地1

       "
53デフォルトの名無しさん:2008/02/21(木) 02:37:45
>>52
あなたが手を出すには、まだ早すぎるのかも知れません
どんなに説明していても、読まないみたいだし
54デフォルトの名無しさん:2008/02/21(木) 02:38:37
>>52
i()
{
今ここを実行中、ここが終わったら"戻り番地3"へ
}
h()
{
 i();
戻り番地3:
}
g()
{
 変数宣言 変数 ;
 h();
戻り番地2:
}

f()
{
 g();
戻り番地1:
}
55デフォルトの名無しさん:2008/02/21(木) 02:45:37
>>52
つまらないアドバイス
プログラムに関数がなく、gotoだけで何とかしたいと思ったらどうする?
実際CPUによってはマシン語にgotoしかないケースもある、その代り今、実行している位置を変数に記録できるとする。
戻り番地はある種の変数だ。goto label のとび先 label を格納することができる。
これで関数同様の処理の流れを作ってみよ
一日ゆっくり頭を悩ませるがよい
5643:2008/02/21(木) 03:58:14
>>53
確かに、まだレベルが達していませんでした。

>>54->>55
何とか何となくですが、理解できました。
gotoと参考書に載ってませんので、レベルを上げてから
深く考えてみます

ありがとうございました。。。
57デフォルトの名無しさん:2008/02/21(木) 05:16:32
UNIXはCで作られているのでしょうか?
58デフォルトの名無しさん:2008/02/21(木) 05:48:44
>>39
どのサンプルを見ているのか判らないけど、
汎用的なライブラリーとかソースみると間違いなく
ファイル内で完結する関数、変数にはstaticついてるよ

というかついてないと怖いと思う
5937:2008/02/21(木) 09:56:06
>>58
なるほど。
そういうものってことですね。
ありがとうございました。
60デフォルトの名無しさん:2008/02/21(木) 14:05:42
整数型の変数に最大値以上の数を入れようとした時、影響があるのはその変数だけでしょうか?
例えばunsigned intの最大値で111...111となってる所に1を足したら000...000となってしまうみたいですが、
この時となりのメモリーに1が繰り上がってしまうってことはあるんでしょうか?
61デフォルトの名無しさん:2008/02/21(木) 14:09:25
配列使って試してみたら?
62デフォルトの名無しさん:2008/02/21(木) 14:48:21
>>60
大丈夫、当該メンバ以外は影響受けません。
63デフォルトの名無しさん:2008/02/21(木) 14:59:57
>>61-62
ありがとうございます。
なるほど、配列だと隣のメモリにおかれるから確認に使えるんですね。
自分でも試して見ます。
64デフォルトの名無しさん:2008/02/21(木) 15:26:22
>>63
実践コードでは、良い悪いは抜きにして、それを前提にしたコードがかなりあるので確り覚えておくが吉。
二の補数でググッておけ
65ててて:2008/02/21(木) 18:24:29
memcmpについて質問です

char *han1;
char *han2;

char temp1[81];
char temp2[81];

han1 = fgets(temp1,81,Fp1);
han2 = fgets(temp2,81,Fp2);
となっていた場合に文字数81は

memcmp(han1,han2,81)と書いていいんでしょうか?
最後の文字のNULLを飛ばして80
memcmp(han1,han2,80)とどっちなのか悩んでいます
指摘お願いします
66デフォルトの名無しさん:2008/02/21(木) 19:20:53
むしろstrncmp
67ててて:2008/02/21(木) 19:24:24
strncmpをmemcmpに変えてっていう問題なんです
すみません
68デフォルトの名無しさん:2008/02/21(木) 19:31:29
試せば?
69デフォルトの名無しさん:2008/02/21(木) 19:45:48
まぁ、80でいいけど81だろうな。
70デフォルトの名無しさん:2008/02/21(木) 19:48:02
実は80も81も不正解、な気がする。
71ててて:2008/02/21(木) 19:50:46
ええ!?

ちなみに試せる環境がありません
72デフォルトの名無しさん:2008/02/21(木) 20:06:50
そりゃぁ、strcmp()じゃない時点で不正解だ。
73ててて:2008/02/21(木) 20:09:26
ううむ
まあとりあえず81って書いておきますw

情報ありがとうございましたw
74デフォルトの名無しさん:2008/02/21(木) 20:12:23
入力行が80文字未満だとtemp1 temp2にゴミが残るからねえ。
75ててて:2008/02/21(木) 20:18:34
とは思うんですが入力のほうは指定ないので少なく書いても幅が広がってしまうだけのようなきもするんですよね
76デフォルトの名無しさん:2008/02/21(木) 22:29:08
>>75
memcmp(han1,han2,strlen(han1))
77デフォルトの名無しさん:2008/02/21(木) 22:33:13
#include <stdio.h>
int main(void)
{
  char str[80];
  int i, spaces;
  char *p;
  printf("文字列を入力してください: ");
  gets(str);
  spaces = 0;
  p = str;
  while(*p){
      if(*p==' ') spaces++;
      p++;  /* このポインタのインクリメントは"*p++;"としても
               プログラムは正しく動作します。なぜですか?*/
  }
  printf("スペースの数: %d", spaces);
  return 0;
}

すいません。教えてください。
78デフォルトの名無しさん:2008/02/21(木) 22:38:43
* よりも ++ の方が演算の優先順位が上だから。
*p++ってのは*(p++)と等しい。
7977:2008/02/21(木) 22:40:33
>>78
すばやい回答、ありがとうございました。m(_ _)m
80ててて:2008/02/21(木) 22:41:18
>>76
なんという
そうかーなるほど・・・
うう、ひらめきって大事ですね
81デフォルトの名無しさん:2008/02/21(木) 22:45:01
char temp1[81] = {'\0'};
82デフォルトの名無しさん:2008/02/21(木) 22:46:58
>>81
temp1[81] == "abcde\0\0";
temp2[81] == "abcde\0f";
このとき文字列としては
83デフォルトの名無しさん:2008/02/21(木) 22:48:12
途中で送信してもうた...

>>82 のとき文字列としては等価と判定せねばなるまい
84デフォルトの名無しさん:2008/02/21(木) 23:40:51
memcmp(han1,han2,strlen(han1))の場合
han1が多い時とhan2が多いときで誤差でない?
8576:2008/02/21(木) 23:44:50
>>80
訂正
memcmp(han1,han2,strlen(han1)+1)
8684:2008/02/22(金) 00:27:26
han1が10文字
han2が20文字

han1が20文字
han2が10文字

の時にmemcmpだとゴミが入ってしまって無理じゃないかね?ってことね
87デフォルトの名無しさん:2008/02/22(金) 00:29:37
違いを検出するだけでいいなら、memcmp()でも問題ないね。
88ててて:2008/02/22(金) 09:57:29
han1 = fgets(temp1,81,Fp1);
han2 = fgets(temp2,81,Fp2);
と、なっているところでテキストファイル同士比べる時に、
han1 = [aaaaaaaaaa]
han2 = [aaaaaaaa]
などなっていても実際80文字分(1行分?)までの区切りなので初期化する必要ってありますか?
一応比較して結果が0なら比較内容同じ、-1か1なら違うとでるようにするだけなのでfgetの文字数と同じなら大丈夫な気がするような・・・
89デフォルトの名無しさん:2008/02/22(金) 10:00:40
短いほうが\0で終わってるわけだから
そこまでが同じならば短いほうが小さい、という結果になる
なのでどっちの長さを指定してもいいが、\0まで含めることが必要。
\0を超えての比較は意味が無いので、バッファのサイズで比較するのは間違い。
90ててて:2008/02/22(金) 10:52:10
なるほど〜

それじゃあ、そろそろ答え81って書いて提出します
みなさんのおかげでいろいろわかりました
どうもありがとうございました
91デフォルトの名無しさん:2008/02/22(金) 11:26:14
>>90
han1[]="abcd\0e";
han2[]="abcd\0f";
92ててて:2008/02/22(金) 12:21:24
>>91
の場の場合もあるにはありますよね
そこら辺の指定はまったくないんですよね

問題文
以下のプログラムは起動時に指定された2つのテキストファイルを比較し、
違う行があればその行番号を表示するプログラムです。
空白部分を埋めて、プログラムを完成させなさい。
という文章で自分で strcmp のバージョンは穴埋めはできたと思います

問題2
問題1のプログラムにおいてstrcmpを使用して読み込んだ2つのレコードが同じかどうか判断しています
これをmemcmpを利用したロジックに作り直しなさい

それで比較する部分のstrcmpをmemcmpに変えて書いたんですが読み込みするテキストファイルの指定は全くありません
それで文字列分指定すればいいかなーと思っていたんですが・・・

>>90のようにそこまで深く考えたほうがいいのでしょうか?
意地悪問題すぎる
93デフォルトの名無しさん:2008/02/22(金) 12:24:05
だから単に片方のをstrlen()+1すればいい
strlenも使用不可なのかな?でも自作するくらいならmemcmpも使わんしなw
94ててて:2008/02/22(金) 13:40:00
>>93
strlenは使えます

と言うか勘違いしてましたw
それで当たってますね

han1 = aaa\0
han2 = aaab\0
memcmp = (han1,han2,strlen(han+1))
だと返す変数0になりません?
と勘違い

文字数で違うなら\0の部分で0以外返しますし
文字が違うならやっぱり0以外返しますね

答えにそうかいて出します
ちゃんと理解して解決しました
本当にありがとうございます
95デフォルトの名無しさん:2008/02/23(土) 01:47:49
大きい二次元配列の初期化ってどうやればいいんですか?

char buf2[20][20];char buf[256];
double dat[10000];

とかだったら。
96デフォルトの名無しさん:2008/02/23(土) 02:06:36
>>95
ループで各要素に初期値を代入する。
2次元配列の場合は2重ループで初期値を代入する。

char buf[256];が文字列だったら、strcpy(buf, "");
97デフォルトの名無しさん:2008/02/23(土) 02:09:13
その前に、本当に初期化する必要があるかどうかチェックしてね。
無駄に初期化する人が多いから。
98デフォルトの名無しさん:2008/02/23(土) 02:15:11
>>96
それってstrcpy使う必要あるのか?
99デフォルトの名無しさん:2008/02/23(土) 02:22:59
初期化することって規約があることもあるんだぜ・・・。
100デフォルトの名無しさん:2008/02/23(土) 02:25:44
初期化する必要ない場合ってどういう場合?

LINUXでいいデバッガない?
101デフォルトの名無しさん:2008/02/23(土) 02:26:19
初期化する必要ない場合は初期化する必要ない場合
10296:2008/02/23(土) 02:26:53
>>98
ヌル文字での初期化の場合ね。
buf[0] = '\0'
でもいいんだが、好みの問題。
103デフォルトの名無しさん:2008/02/23(土) 02:29:08
double data[10000]={0}だと初期化できてないみたいなエラーでるけどこれは
範囲あるの?
104デフォルトの名無しさん:2008/02/23(土) 02:29:32
>>102
最適化すればオーバーヘッドなくなるのかな?
まぁもともと無視できるほどの差だろうけど
105デフォルトの名無しさん:2008/02/23(土) 02:30:57
>>103
規格では全て 0 で初期化されるはずだが。
警告出すコンパイラならあるけど。

ただ、コンパイラが糞だと知らん。
106デフォルトの名無しさん:2008/02/23(土) 02:34:47
セミコロンがないとかじゃないよな
107デフォルトの名無しさん:2008/02/23(土) 03:15:36
http://www.shinetworks.net/cgi-bin/img-up/src/1203703846656.jpg

この、12行目〜16行目までの解説をお願い致します。
特に解らないのが、12行目の" if(argc > 1) { "の部分です。
配列argcが1より大きければ、と言う言でしょうか?
108デフォルトの名無しさん:2008/02/23(土) 03:19:31
コボラーさんがC言語覚えるのは結構大変?
109デフォルトの名無しさん:2008/02/23(土) 03:19:36
文字列の長さも確認せずに strcpy はやばいだろ。
110デフォルトの名無しさん:2008/02/23(土) 03:20:38
大変? とか気にしてる時点で脈は無いわ。
111デフォルトの名無しさん:2008/02/23(土) 03:28:52
>>107
argcはコマンド引数の数+1。

コマンド行がhogeのときargcは1。
コマンド行がhoge arg1のときargcは2。

だからif(argc > 1)とはコマンド引数がひとつ以上あるということ。
112デフォルトの名無しさん:2008/02/23(土) 04:27:04
>>111
サンクスです
113デフォルトの名無しさん:2008/02/23(土) 04:28:35
>>111
>>だからif(argc > 1)とはコマンド引数がひとつ以上あるということ。
ないときは、あるんですかね?
114デフォルトの名無しさん:2008/02/23(土) 04:31:58
ないときはないよ。そんときは、argcが1になる。
115デフォルトの名無しさん:2008/02/23(土) 04:41:37
>だからif(argc > 1)とはコマンド引数がひとつ以上あるということ。
いや,2つ以上だろ.もしくは1つよりも多く.
116デフォルトの名無しさん:2008/02/23(土) 04:42:24
argc==2なら引数は1だろ。
117デフォルトの名無しさん:2008/02/23(土) 05:09:25
?                  ↓-此れは?
006: int main(int argc,char *argv[]


>>113
ああああああぁぁあぁ…   永遠に繋げていく事か"!

if( argc > 1, argv > 1, argc > 1) = argc[1]
118デフォルトの名無しさん:2008/02/23(土) 06:45:19
頭が混乱してきた…整理ついたら、出直してきます 
ありがとうございました
119デフォルトの名無しさん:2008/02/23(土) 09:48:04
コマンドラインとmain()の引き数の違いが理解できていない馬鹿がいる。

一般的に、コマンドプロンプトで command arg1 arg2 arg3 と入力すると、
command が実行されてそのmain()にはargv[0] = "command", argv[1] = "arg1",
argv[2] = "arg2", argv[3] = "arg3", argc = 4 と言う形で渡される。
120デフォルトの名無しさん:2008/02/23(土) 13:03:42
#define FREE(p) do{ free(p); (p) = NULL;}while(0)

というのを本で見たのですが、このdo-whileにはどういう意味があるんでしょうか?
一回だけで抜けるループ、というのは分かるのですが、単にカッコでくくるだけではいけないのでしょうか?
121デフォルトの名無しさん:2008/02/23(土) 13:05:33
>>120
if (・・・)
  FREE(・・・);
else
  ・・・

みたいな書き方に対応。
122デフォルトの名無しさん:2008/02/23(土) 13:05:45
>>120
セミコロンが必ず必要になる。
123デフォルトの名無しさん:2008/02/23(土) 13:08:20
if (〜) FREE(p); else 〜
のように使う場合、単なる { } だと
if (〜) { 〜 };
となって、ここで if 文が終わってしまい、elseを続けられない。do-whileを使えば大丈夫。
124デフォルトの名無しさん:2008/02/23(土) 13:14:29
あー、なるほど。

#define FREE(p) { free(p); (p) = NULL;}

だと、セミコロン無しの FREE(p) だけで文が完結してしまうんですね。
そこにセミコロン追加した FREE(p); だと意味合いが変わってしまう、
かといって if(...)FREE(p)else... なんてセミコロンを省略すると書き方が統一できずバグの温床になる、と。

どうもありがとうございました。
125デフォルトの名無しさん:2008/02/23(土) 13:14:36
それは(free(p),(p)=NULL)じゃだめなんでしょうか?
126デフォルトの名無しさん:2008/02/23(土) 13:31:54
別にだめなことはない
127デフォルトの名無しさん:2008/02/23(土) 13:34:32
変数が定義できるというメリットもある
128デフォルトの名無しさん:2008/02/23(土) 13:56:34
(free(p), (p) = NULL) だと、この式が余計な値を持ってしまうから
((void)(free(p), (p) = NULL)) の方が望ましい。
129デフォルトの名無しさん:2008/02/23(土) 16:37:54
そもそも
 #define FREE(p) do{ free(p); (p) = NULL;}while(0)
↑これ自体がだめなコードだと思う。
130デフォルトの名無しさん:2008/02/23(土) 16:40:08
なんで?
131デフォルトの名無しさん:2008/02/23(土) 16:44:29
>>129
free()したあとに、無条件でクリアするってのが?
まあ、あんまりいい手筋じゃないね。
132デフォルトの名無しさん:2008/02/23(土) 16:48:34
そのまま関数終わるときなら NULL クリア要らないってことか?
それならそのまま free 使えばいいじゃん。
133デフォルトの名無しさん:2008/02/23(土) 17:02:52
マクロじゃなくて関数でラップしたらだめなの?
134デフォルトの名無しさん:2008/02/23(土) 17:03:17
freeしたポインタ=もう使わないんだからわざわざ無駄なことして容量増やさなくてもいいじゃん
135デフォルトの名無しさん:2008/02/23(土) 17:04:18
>>134
その時は free 使えばいいじゃん。
実際にはまた使うことだってあるだろ。
そういう時には FREE が役に立つ。
136デフォルトの名無しさん:2008/02/23(土) 17:06:21
マタ使うってのは変数を使いまわすってだけで中身は別物入れるんじゃん。
137デフォルトの名無しさん:2008/02/23(土) 17:07:37
NULL 入れないと解放されてる状態かどうか判定できないだろ。
138デフォルトの名無しさん:2008/02/23(土) 17:12:21
>>136
dangling pointerでググれ。
139デフォルトの名無しさん:2008/02/23(土) 17:33:29
>>130
>>131
>>132

そういうことじゃなくて、マクロにすることで可読性を損ねるから。
標準関数をマクロでくるんじゃうのはいいこととは思えない。

>>133

そのほうがまだまし。
140デフォルトの名無しさん:2008/02/23(土) 17:43:39
関数でラップするとポインタのポインタを渡さないといけないから面倒だな。
141デフォルトの名無しさん:2008/02/23(土) 19:25:29
scanf()のマニュアルを読んでいて、型修飾子に'['が有ることを初
めて知りました。といっても説明文の意味が全く分からない。どう
やら、↓のように使うと、改行がヌル文字に変わるのでちょっと便
利かな、と思わなくもないのですが、これだ!という使い道は有り
ますか?

===========
sscanf("abc\ndef\n", "%[^\n] %[^\n]", str1, str2);
printf("%s\n", str1);
printf("%s\n", str2);
===========
142141:2008/02/23(土) 19:28:24
型修飾子ではなく変換指定子でした。
143デフォルトの名無しさん:2008/02/23(土) 20:13:02
>>142
fgets()の代わりに改行まで全て読んだり(或いは無視したり)、
数字と特定のアルファベットだけの文字列を抽出したり、
色々使い途はある。
144デフォルトの名無しさん:2008/02/23(土) 22:10:46
scanf("%*[^\n]%*c");
入力バッファをクリア
145デフォルトの名無しさん:2008/02/23(土) 22:42:52
wikipediaでも、scanf()でエラー時に改行まで読み飛ばして入力バッファクリアってサンプルコードが載ってるけど、
読み込みは行単位でないのに、エラー時のクリアを行単位でやるってのはどうかなって気がする。
146デフォルトの名無しさん:2008/02/24(日) 00:27:12
インタラクティブな入力なら、改行が伴うからいいんじゃね?
147デフォルトの名無しさん:2008/02/24(日) 00:35:35
結構大きいプログラムつくるようになったのだけど
バグの見つけ方がわかりません。
どうすればいいですか?

デバッガとかを使うべきなのでしょうか?
148デフォルトの名無しさん:2008/02/24(日) 00:40:09
バグが見つからないならデバッガ使っても意味無いような
149デフォルトの名無しさん:2008/02/24(日) 00:41:53
扱う数値が多すぎで
バグなのか計算がおかしいのかわからないんだよなー。
150デフォルトの名無しさん:2008/02/24(日) 00:42:36
計算がおかしいのはバグだろ
151デフォルトの名無しさん:2008/02/24(日) 00:44:12
>>147
バグのない期待通りの動作がどうあるべきかはもちろん解ってるな?
どの変数がいつどういう値であるべきか(あってほしいか)、
自分で組んでるんだから当然知ってるはず

あちこちにprintfを入れて色んな変数の値を表示させてみて、
それが期待通りの値を示してるかを確認するのが基本
バグがあるってことは、どこかで期待と異なる値が現れるはず
どこで食い違ってるのかを詳細に追っていけば、だいたい問題の箇所に辿り着く

デバッガはそういった作業を補助するツール
問題の箇所がある程度わかってるなら、そこで実行を止めて変数の値を調べたり
1行ずつ実行して変数の値の変化を調べたり、そういうもの
152デフォルトの名無しさん:2008/02/24(日) 00:53:46
てすとどりぶん汁!
153デフォルトの名無しさん:2008/02/24(日) 00:56:29
printfとかはやってます。
数値処理だからオーバーフローかなあとはおもってるけど
どこかはわからない。
154デフォルトの名無しさん:2008/02/24(日) 00:58:14
>>147
初心者ならば机上デバッグ。
プログラムを紙にプリントアウトして、なぜそういう結果になるかをトレースする。
つまり、自分が作ったプログラムの動きを把握できるようにすること。

デバッガーは補助のためのツールとして考えること。
155デフォルトの名無しさん:2008/02/24(日) 00:58:15
調べるしかないだろ
156デフォルトの名無しさん:2008/02/24(日) 01:02:30
>>153
どこかわからないってことはないだろう
・最初から間違った値を表示するか、
・途中まで合ってて途中から間違った値を表示するか、
・最後まで正しい値を表示するか、
このどれかしかないんだから
最初から間違ってるなら最初が原因
途中まで合ってて途中から間違ってたら、そこが原因
最後まで正しいってことは結果も正しい=バグはないってことだ
157デフォルトの名無しさん:2008/02/24(日) 01:06:00
論理的にかいてるのはいいけど
 途中経過があっているかどうかがわかるレベルの
プログラムなら悩んでないって
158デフォルトの名無しさん:2008/02/24(日) 01:08:22
わかるレベルまで崩すのがデバッグだ
ガンガレ
159デフォルトの名無しさん:2008/02/24(日) 01:10:18
>>157
大きいプログラムって何行くらいのプログラム?100行?500行?1000行以上?
関数の数は?
160デフォルトの名無しさん:2008/02/24(日) 01:13:00
プログラムをかいて徹底的に直してくれるような
教室ないのかな?

みなさんはどのように進歩していきました?
161デフォルトの名無しさん:2008/02/24(日) 01:13:41
>>160
人が直してくれたら、自分は進歩しないだろう
自分で直すんだよ、徹底的に
162デフォルトの名無しさん:2008/02/24(日) 01:16:14
>>160
10行くらいの小さなプログラムからラジコン、バイクまでがんばって修理してきました
今では1万行あってもそこそここなせます
163デフォルトの名無しさん:2008/02/24(日) 01:22:08
Ne_12275.tar.gz にうpしてみました
passはworkです

プログラムの説明はそのディレクトリのgaiyou.txtにかいています。
専門的なのでちょっとわかりにくいかと思いますが。
164デフォルトの名無しさん:2008/02/24(日) 01:23:32
http://www12.axfc.net/uploader/18/
サイトはここです
165デフォルトの名無しさん:2008/02/24(日) 01:27:12
>>154
机上デバッグって。
デバッガでステップ実行するほうがいいよ。
166デフォルトの名無しさん:2008/02/24(日) 01:28:56
>>165
求めたい結果が分かっていないのに?
167デフォルトの名無しさん:2008/02/24(日) 01:31:01
結果がわからないのに、それがバグだとわかるのか?
正しい結果を出してるかもしれないだろう?
168デフォルトの名無しさん:2008/02/24(日) 01:32:19
>>163
Ne_12775.gzだよな?
書き込みすら見直せないようだとバグの原因追求は難しいぞ
169デフォルトの名無しさん:2008/02/24(日) 01:34:38
12775でした
すいません。
170デフォルトの名無しさん:2008/02/24(日) 01:39:44
ていうかスレチじゃね?
入門をはるかに通り越してる
171デフォルトの名無しさん:2008/02/24(日) 01:45:12
ファイル処理とか音素のパスの行先とかはあってるとはおもうんだけど
正規分布の処理がおかしい気が自分でします。

http://www.htlab.ice.uec.ac.jp/~sekiguchi/Wed-seminar/document/20070711_04.pdf
ここの15枚目の式をつかってます。
172デフォルトの名無しさん:2008/02/24(日) 01:46:19
唐突にうpしても誰もデバッグはしてくれないと思うぞ

それだけだとかわいそうなんで一応アドバイスをしておくと
「あっているとおもう」こういう状態でデバッグするとはまる。
まずあっているとおもう場所を「確実にあっている」と確信できるまで調べるのがいいぞ
173デフォルトの名無しさん:2008/02/24(日) 01:48:48
char **foo = (char **)MALLOC(sizeof(char*) * 3);

みたいにした後、 foo から 3 を引っ張り出すにはどうすれば出来ますでしょうか?
174デフォルトの名無しさん:2008/02/24(日) 01:49:51
無理
別の変数に3を覚えておくしかない
175デフォルトの名無しさん:2008/02/24(日) 01:50:57
正規分布の関数のところまでは
入力平均分散重きがいっていて確認はできたけど
正規分布の計算したあとからわからないんだよね。。。
176デフォルトの名無しさん:2008/02/24(日) 01:53:54
177デフォルトの名無しさん:2008/02/24(日) 01:56:19
>>171
名前欄に数字でもいいから入れておいてくれ
>>171=>>175 なのかどうかも分からない
178163:2008/02/24(日) 02:01:16
171 175です
179デフォルトの名無しさん:2008/02/24(日) 02:12:57
>>163
仕様がわからないので、だれも答えられないと思う。

各計算プログラムのポイントとなるところで、入力データと計算結果のデータを
ファイルに書き込む

ファイルに書き込んだデータを検証する

この方法がよい思う。
180179:2008/02/24(日) 02:18:46
たとえば、こんな感じのデータをfprintfでファイルに出力する。

FUNCTION: hoge1
INPUT=XXX.XX.XXX.XXX <-hoge1関数の入力データ
OUTPUT=XXX        <-hoge2関数の出力データ

FUNCTION: hoge2
INPUT=XXX.XX.XXX.XXX
OUTPUT=XXX

181179:2008/02/24(日) 02:27:20
トレース用のfprintfのコードは以下のようにしておく

#ifdef TRACE_MODE
fprintf(・・・・
#endif

コンパイル時に-D TRACE_MODEをつければ、fprintfによるデータ出力が行われ、
-D TRACE_MODEをつけなけれデータ出力はされない。
こうすればコメントアウトをする手間が省ける。
当然だが、fprintfは追加モードで書きこむこと。
182デフォルトの名無しさん:2008/02/24(日) 02:29:42
>>181
このほうが楽じゃね?
#ifdef TRACE_MODE
#define trace_printf fprintf
#else
#define trace_printf
#endif
183デフォルトの名無しさん:2008/02/24(日) 09:53:50
>>139
こんなの既に定型句だから可読性なんて損ねないよ。
C++ や C99 ならインライン関数があるからいいけど、
C89 だとこの程度の処理だと
パフォーマンスも考えてマクロを選択するのは普通。
184デフォルトの名無しさん:2008/02/24(日) 11:40:51
>>183
組込みの人か?
それなら分かるけど、PC上のソフトで関数コールのオーバーヘッドが気になるほどの
パフォーマンス求められるってどんな分野のソフト?

関数でもマクロでも、どっちでも普通じゃねぇ?
185デフォルトの名無しさん:2008/02/24(日) 11:51:50
そもそも FREE の場合は C にテンプレートがない以上
汎用的な関数の実装は無理だろ。
void ** は厳密に規格に照らし合わせれば違法らしいし。
186デフォルトの名無しさん:2008/02/24(日) 13:16:38
>>184
15年前はそんなこと言ってられなかっただろ。
187デフォルトの名無しさん:2008/02/24(日) 14:06:16
関数にするとこうなるのか?
こんなことやってられないだろ。

void safe_free(void **p) {
 free(*p);
 *p = NULL;
}

/* p は int * で宣言されているとする */
void *vp = p;
safe_free(&vp)
p = (int*)vp;
188139:2008/02/24(日) 14:14:52
>>183
>>184

おれは組込み屋だが、パフォーマンス求めるなら素直に
free(p);
p = NULL;
と書けばいい。
神学論争になるから深入りしないけど、
三段マクロで地獄を見たので、マクロの使用は最小限にとどめるべきだと思う。
189139:2008/02/24(日) 14:17:37
>>187

↓これでいいと思う。

void* safe_free(void *p) {
 free(p);
 return NULL;
}

/* p は int * で宣言されているとする */
p = safe_free(p)


あまりいいコードとは思えないけど。
190デフォルトの名無しさん:2008/02/24(日) 14:27:23
そもそもポインタをクリアしても、safeにはならんだろ。
191デフォルトの名無しさん:2008/02/24(日) 14:28:52
freeしてないのに再利用ってのをふせぐためにやってるんじゃないのか?
192デフォルトの名無しさん:2008/02/24(日) 14:40:22
p がfree()されてないのに、また
p = malloc(・・・);
と、新しいメモリを確保してしまうことがあるから、

if (p) free(p);
p = malloc(・・・);

とチェックを入れてからmalloc()するってこと?
193デフォルトの名無しさん:2008/02/24(日) 14:42:38
if(p) でメモリが確保されているかどうかチェックできるし、
malloc の前にとりあえず free 書いとけばメモリリークは起こらないようになるね。
194デフォルトの名無しさん:2008/02/24(日) 14:56:50
ASSERT( p == NULL );
p = malloc(・・・);
こういうのはたまに書くけど、mallocの前にfreeしたことはないなぁ
195デフォルトの名無しさん:2008/02/24(日) 14:57:13
ポインタにnullを入れて、ポインタが使われているかどうかのフラグに使うってのは、
ロジック上そうすることがあるっていうのは分かるけど、つねにnullクリアして、常に
nullチェック入れるってのは、バグ隠しになる可能性が大。
196デフォルトの名無しさん:2008/02/24(日) 15:19:38
再利用する可能性のあるポインタはfreeした直後にNULLを入れておく。
これでいいじゃん。何を悩むことがあるのか。
197デフォルトの名無しさん:2008/02/24(日) 15:25:26
分割コンパイルをするときに
1つの関数を1つのファイルとしてコンパイルしたいんですけど
短い関数も1つのファイルにすべきなのですか?
結構関数おおいのですが
198デフォルトの名無しさん:2008/02/24(日) 15:30:48
>1つの関数を1つのファイルとしてコンパイルしたいんですけど

したいんなら、すべきだろう
199デフォルトの名無しさん:2008/02/24(日) 15:31:07
なんで1つの関数を1つのファイルとしてコンパイルするのかが分からない。
static 関数とか使わないのか?
1つの static 関数を複数の関数から呼ぶとなると
どうしても複数の関数を1つのファイルに置かざるをえないはずだが。
200デフォルトの名無しさん:2008/02/24(日) 15:32:11
extern
201デフォルトの名無しさん:2008/02/24(日) 16:05:16
>>200
阿呆でなければ馬鹿ですか?
202デフォルトの名無しさん:2008/02/24(日) 16:14:17
>>196
わざわざマクロとか関数を作ってるのは、無条件に全部クリアってつもりなんでしょ。
203デフォルトの名無しさん:2008/02/24(日) 16:34:42
>>192
>>193

メモリリークは起こらないかもしれないが、別のわかりにくいバグが出やしないか。
そのポインタはもう使われてない、ということは保証されないわけだし。
そういう意味ではポインタを使いまわすのは良くない。
スタックがどうしようもなく少ない場合は使いまわしたくなるかもしれないが、
そもそもそんな環境でmallocが使えるとは思えんし。
204デフォルトの名無しさん:2008/02/24(日) 16:44:31
そもそもmallocでスタックオーバーフローを出したことがない。
205デフォルトの名無しさん:2008/02/24(日) 16:52:41
ローカル変数を想定してそういう事言ってるのかもしれんが、
構造体メンバだとよくあることだぜ。
206デフォルトの名無しさん:2008/02/24(日) 17:31:05
なんかうまく言えないが、204が何かを勘違いしてる気がしてしょうがない。
207デフォルトの名無しさん:2008/02/24(日) 17:31:49
mallocでオーバーするのはヒープだろうな。
208デフォルトの名無しさん:2008/02/24(日) 18:20:45
C言語を勉強しようと思うのですが
はじめたばかりでもわかるC言語のサイトってないですか?
209sage:2008/02/24(日) 18:34:19
fseek関数について質問なんですが、第2引数のoffsetの書き方が
10
10L
sizeoff(int)*10
などさまざまな書き方があるのですが、どう違うのでしょうか?
210デフォルトの名無しさん:2008/02/24(日) 18:47:07
>>209
前2者は同じ。最後のそれは、int10個分という意味なので実際は20とか40になる。
ちなみに、ansi89以前のプロトタイプ宣言をしない場合には10ではなくて10Lと(longであることを明示的に)書く必要があった。
211209:2008/02/24(日) 19:09:31
>210
ありがとうございます。

10や10Lの型は何になるんでしょうか?
又、
typedef struct product{ 
char ○○;
 int △△;
float ××;
}product;
のような構造体でランダムアクセスを行った場合、fseek関数のoffsetは
sizeoff(product)
という書き方でいいんでしょうか?
212デフォルトの名無しさん:2008/02/24(日) 19:13:28
sizeof、だ。

typoじゃなかったのか・・・
213デフォルトの名無しさん:2008/02/24(日) 19:15:00
10 : int
10L : long
214209:2008/02/24(日) 19:15:37
あと、
typedef struct product{ 
      char ○○;
      int △△;
      float ××;
}product;
のような構造体で特定のメンバにランダムアクセスを行うには、fseek関数のoffsetは
sizeoff(product.○○)
という書き方でいいんでしょうか?
215209:2008/02/24(日) 19:18:45
>>212
ありがとうございます。
typoって何ですか?

>>213
ありがとうございます。
216デフォルトの名無しさん:2008/02/24(日) 19:22:25
typo : タイプミス
217デフォルトの名無しさん:2008/02/24(日) 19:23:18
×sizeoff
○sizeof
218209:2008/02/24(日) 19:24:29
>>216
わかりました。

>>217
すいません、以後気をつけます。
219デフォルトの名無しさん:2008/02/24(日) 19:27:30
>>214
offsetof を使う。
220209:2008/02/24(日) 19:57:59
>>219
ありがとうございます。

sizeofを使って、特定のメンバにアクセスすることはできませんか?
又、この構造体が複数あった場合、その中の一つの構造体の特定のメンバに
sizeofを使ってアクセスすることはできますか?
221デフォルトの名無しさん:2008/02/24(日) 19:58:56
>>220
offsetof を使うと言ってるんだから素直に offsetof 使え。
パディングがあると sizeof は破綻する。
222209:2008/02/24(日) 20:17:12
>>221
わかりました、そうします。

パディングというのはよくわからないのですが、構造体メンバの位置を調節
するため、sizeofでは正確に求められないということですか?
よかったら詳しく教えてください。
223デフォルトの名無しさん:2008/02/24(日) 20:34:30
なんでも構造体のメンバのアドレスを先頭から4バイト刻みでアクセスできるように隙間に詰め物することらしいよ
224デフォルトの名無しさん:2008/02/24(日) 21:05:26
>>222
>223でほぼ正しいが、4バイト刻みとは限らないので要注意。
225デフォルトの名無しさん:2008/02/24(日) 21:15:01
構造体で直接読み書きとか、お作法的にはよくないよ。
226デフォルトの名無しさん:2008/02/24(日) 21:17:47
構造体配列を使って四則演算を行うソースを作っています。
無限ループ内でiをインクリメントさせたいのですが、このソースでは1+1=とやっても1のままで結果が上手く出てきません。
無限ループ内でのインクリメントの仕方を教えて下さい。
int kind= /*数値…1、演算子…2、イコール…3に分類して、構造体配列に設定をするkindの宣言*/
double value= /*数値のみが格納されるvalueの宣言*/
char operand= /*演算子のみが格納されるoperandの宣言*/

double calculate(struct keisan *kei)
{
int i=1;

while(1)
{
if(kei[i].kind==3)
{
break;
}

if((kei[i].kind==2) && (kei[i].operand=='*'))
{
kei[i-1].value = kakeru(kei[i-1].value,kei[i+1].value);
}
if((kei[i].kind==2) && (kei[i].operand=='/'))
{
kei[i-1].value = waru(kei[i-1].value,kei[i+1].value);
break;
}
i++;
}

この後に足し算引き算を上のように無限ループで行う。
227デフォルトの名無しさん:2008/02/24(日) 21:26:01
>>226
ちゃんとiはインクリメントされると思うけどねぇ。
尤も、掛け算ではブレークしないのに割り算ではブレークするとか、変なところは色々あるけど。
228デフォルトの名無しさん:2008/02/24(日) 21:34:58
>>225
パディングをファイルに書き込んでる場合、
1メンバのデータサイズだけ読み出したら
ファイルポインタの位置がパディングの前で止まってる可能性があるな。
パディングを0にすることが許されない状況なら、
構造体を一括して読み書きするか、
常にメンバごとに読み書きしてパディングを書き込まないようにするか、どっちかだな。
229226:2008/02/24(日) 21:53:38
>>227
ちなみに足し算引き算のループはこれなんですが…
while(1)
{
if(kei[i].kind==3)
{
break;
}

if((kei[i].kind==2) && (kei[i].operand=='+'))
{
kei[i-1].value = tasu(kei[i-1].value,kei[i+1].value);
}
if((kei[i].kind==2) && (kei[i].operand=='-'))
{
kei[i-1].value = hiku(kei[i-1].value,kei[i+1].value);
break;
}
i++;
}
処理の手順は、
イコールかどうか(イコールならブレーク)→演算子かつ*かどうか(*なら掛け算、違うならスルー)
→演算子かつ/(/なら割り算)
となっているので、割り算でブレークという所がおかしいのでしょうか…
230デフォルトの名無しさん:2008/02/24(日) 21:59:55
kind は列挙体使うべきだな。
value と operand は共用体を使うのが常套手段か。
(kei[i].kind==2) && が並んでるのも気になる。
先に if(kei[i].kind==2) 書いてその中で演算子をチェックしようぜ。

まあそれはいいとして、
結果は i + 1 の方に入れないとダメなんじゃないのかな。
雰囲気的に。
231226:2008/02/24(日) 22:07:24
>>230
計算結果はi-1番目に入れろという指示が出ているんです…
それと、恥ずかしながら列挙体や共用体というのは使った事がありません。
コンパイルの結果はこんな感じです。

1/2=
[1][1.000000][]
[2][0.000000][/]
[1][2.000000][]
[3][0.000000][]
『2.000000』
答えは0.000000です
(無限ループの後にprintf("『%f』\n",kei[i-1].value);
return kei[0].value;
}を入れていて、メイン関数にkei[0].valueを返し、答えを表示しています。)
232まさかとは思うがw:2008/02/24(日) 22:39:55
素朴な疑問だが、1/2=ではなく2/1=だとどうなる?
233226:2008/02/24(日) 22:45:51
>>232
1/2=
[1][2.000000][]
[2][0.000000][/]
[1][1.000000][]
[3][0.000000][]
『1.000000』
答えは0.000000です

と出ます…
234209:2008/02/24(日) 23:29:59
遅くなってすいません。
>>223
>>224
>>225
>>228
ありがとうございました。
235デフォルトの名無しさん:2008/02/25(月) 12:15:57
>>223
掛け算を試しても0になるようなら、ソース丸ごとどこかにアップロードして味噌。
236226:2008/02/25(月) 13:00:22
すみません!解決しました…
戻り値を返してなかったりで駄目だったみたいです。
皆さん有難うございました。
237海苔:2008/02/27(水) 00:12:03
お初です。
少々お聞きしたいのですが、MSYSをインストールする際に、
heap領域が足りないというメッセージがでます。
heap領域を拡張するにはどうすればよいのでしょうか?
238デフォルトの名無しさん:2008/02/27(水) 00:16:03
メモリと OS を述べよ
239プログラムを作ってみた。:2008/02/27(水) 01:20:24
#include <stdio.h>
void main(void)
{
int a,b;
char c;

printf("Hello,World!\n");
printf("数字を入力して下さい。\n");
scanf("%d",&a);
printf("ループ回数を入力して下さい。\n");
scanf("%d",&b);
while(a<b)
{
a++;
printf("aの値は%d\n",a);
}
printf("ループ終了\n");
つづく
240プログラムを作ってみた。:2008/02/27(水) 01:21:36
前からの続き
printf("くじを引きますか?(Y/N)\n");
scanf("%c",&c);
if(c=Y)
{
printf("ガラガラガラ・・\n");
if(a<10)
{
printf("当たり");
}
else{
printf("はずれ");
  }
if(c=N)
  {
printf("プログラムを終了します\n");
}
else{
printf("入力エラー\n");
}
}
}
241プログラムを作ってみた。:2008/02/27(水) 01:23:25
エラー
cmd.exe /C LCC.EXE roop.c
*** コンパイル開始 ***
roop.c 22: 'Y' undefined
roop.c 31: illegal character
roop.c 31: illegal character
roop.c 32: 'N' undefined
roop.c 33: illegal character
*** コンパイル終了 ***

なぜYとNが認識されないのか・・?わからない
242プログラムを作ってみた。:2008/02/27(水) 01:24:08
使用機種はwindowsXP。
コンパイラはLSI試食版を使用。
243デフォルトの名無しさん:2008/02/27(水) 01:25:17
>>241
「認識されない」ではなくundefined=未定義
244デフォルトの名無しさん:2008/02/27(水) 01:25:31
if(c == 'Y')
245デフォルトの名無しさん:2008/02/27(水) 01:26:45
>>241

if(c=Y)

・文字だから、シングルクォーテーションでくくらないとだめ。
・条件式が代入になっている。

教科書があるならもう一度読み直せ。
246デフォルトの名無しさん:2008/02/27(水) 01:51:34
LSI試食版なんか使うな。
247デフォルトの名無しさん:2008/02/27(水) 16:59:02
16bit時代の遺産だろ?あれ
未だに使う人がいるのか…
248デフォルトの名無しさん:2008/02/27(水) 23:46:01
入門書に載ってた文字列からハッシュを取得するサンプルを打ち込んだら
ハッシュ(int)がオーバーフローしやがった思い出
さすが16bit
249デフォルトの名無しさん:2008/02/28(木) 11:39:24
マイコンでSW2を押すごとに、1、2、3、・・・・とつづくCのプログラム教えて
250デフォルトの名無しさん:2008/02/28(木) 12:05:23
>マイコンでSW2を押すごとに、1、2、3、・・・・とつづくCのプログラム教えて
突っ込みどころが多過ぎて話にならん。
あんたは初対面の相手にいきなりそんな質問するのか?
251デフォルトの名無しさん:2008/02/28(木) 12:15:42
2ちゃんで初対面とかw
252デフォルトの名無しさん:2008/02/28(木) 13:12:37
>>251
えーと、喩話というものを御存知ないのですか?
「あんたは…質問するのか? まさかそんな馬鹿なことはしないだろ?
だったら2chであろうとももう少しましな質問の仕方をしたらどうだ?」
と、ここまで書かないと理解できませんか?
253デフォルトの名無しさん:2008/02/28(木) 13:34:37
>>249
電気・電子板いけ
254デフォルトの名無しさん:2008/02/28(木) 14:02:09
すみません、質問させてください
rand()関数だけで 1, 2, 4, 8, 16 ... のように
自分で決めた値だけで乱数を生成するようにできるんでしょうか?

それとも上のようにしたい場合は
取り合えず一度値を生成してからswitch()するのが普通なんでしょうか?
255デフォルトの名無しさん:2008/02/28(木) 14:06:38
1<<(rand()%16);

とか。
規則性のある数列ならrand()%整数で必要な個数の整数値を出して、
一般項の形に計算してしまえばいい。
256デフォルトの名無しさん:2008/02/28(木) 14:08:25
普通はテーブル使うんじゃね?
よっぽど数が少くて、計算でも置換できないならswitchでもいいけど。
257デフォルトの名無しさん:2008/02/28(木) 14:17:13
int a[10] = {2,5,10,21,33,45,100,1001,2222,3232};

a[rand()%10];

とかね。
258デフォルトの名無しさん:2008/02/28(木) 14:17:27
数が少なくてもテーブルのがわかりやすいと思う
259デフォルトの名無しさん:2008/02/28(木) 14:24:57
なるほどー、テーブルが分かりやすいかな
規則性計算も勉強になりました

レスくれたみなさんありがとうございました
260デフォルトの名無しさん:2008/02/28(木) 14:46:04
キーボードから正の数値を入力させたいときに、

int a;
char buf[32];
do{
fgets(buf,32,stdin);
a=atoi(buf);
}while(a<=0);

とやって、文字列や負の数が入力されたらループする!
正の数が入力されたらループを抜ける!すげー!カッコイイ!
というのを見たんですけど、
0や負の数も含めて入力させたいときにはどうしたらいいんでしょう。
ループの中身ってfgetsで文字列入れてしまってもa=0になりますよね?
261デフォルトの名無しさん:2008/02/28(木) 14:56:34
>>260
・strtol(buf, & endp, 0)で得られた、変換終了点にある文字がナル文字でなければ変換失敗。
・sscanf(buf, "%d", & a)の戻り値が1でなければ変換失敗。
262デフォルトの名無しさん:2008/02/28(木) 14:58:10
>>261
ありがとうございます、調べてみます!
263デフォルトの名無しさん:2008/02/28(木) 14:58:14
>・sscanf(buf, "%d", & a)の戻り値が1でなければ変換失敗。
但し、入力が100giga の様な場合は変換に成功してgiga は単純に捨てられることに注意。
264デフォルトの名無しさん:2008/02/28(木) 15:22:06
#include <stdio.h>
#include <stdlib.h>

int main(void)
{
int a;
char buf[32];
char *end;
do{
fgets(buf, 32, stdin);
a = strtol(buf, &end, 0);
}while(*end != '\n');
printf("正常終了 a=%d",a);
return 0;
}

こんな感じでできました、ありがとうございました。
変換終了点がヌル文字でなければ〜とありましたが、
fgetsで読み込んだので改行文字との比較でいいんですよね?
265261=263:2008/02/28(木) 16:00:20
あーそうか、改行文字を取り除いてないからその通りだね。
266デフォルトの名無しさん:2008/02/28(木) 19:05:41
C言語でグラフを出力するプログラムって作れますか?
267デフォルトの名無しさん:2008/02/28(木) 19:21:07
>>266

作れる。


けど、どういうグラフだよ。
268デフォルトの名無しさん:2008/02/28(木) 19:30:01
普通のジグザグ波です
フーリエで求めたジグザグ波をグラフにしたいんです。
269デフォルトの名無しさん:2008/02/28(木) 23:26:58
>>268
X Y
を, ひたすら書いたファイル("fft.dat"でもなんでもいい)に吐き出せ!!!
そのあとで
sprintf(buff, "system %s", "fft.dat");
って, やるんだ!!!
270デフォルトの名無しさん:2008/02/28(木) 23:29:07
やります!!!
271デフォルトの名無しさん:2008/02/28(木) 23:29:19
orz
> sprintf(buff, "system %s", "fft.dat");
× "system ...
〇 "gnuplot ...
272デフォルトの名無しさん:2008/02/28(木) 23:40:58
今さっきturboをインストールしたばかりの初心者です。
手元の入門書にしたがってコンパイル・実行したのですが、メッセージペイン上に表示させられません(ごたぶんにもれずHello Worldのプログラムです
表示させるための設定を教えてください
273デフォルトの名無しさん:2008/02/28(木) 23:50:34
>>272
メッセージペインってなに?
どういう環境で動かそうとしているの?
274デフォルトの名無しさん:2008/02/28(木) 23:57:36
message pane ---プログラムをコンパイルしたときに発生したerror,warningを表示する画面でプログラムを
を実行したメッセージも表示する画面
らしい(手元の本はc++builderXで説明してるけど俺のはturboだから、ちょっと違うみたい)
275デフォルトの名無しさん:2008/02/29(金) 00:17:20
getch()をreturnの前に置けばよかったみたいです
自己解決したので忘れてください
276デフォルトの名無しさん:2008/02/29(金) 00:27:26
すんません

Cってなんですか?
ゲーム開発する事?
277デフォルトの名無しさん:2008/02/29(金) 00:28:21
プログラミングをするにあたっての使用する言語。
ホームページを作るにはHTML言語ってのが必要。
そういうこと
278デフォルトの名無しさん:2008/02/29(金) 00:48:01
>>276
ゲームを作るために必要な言葉の1つ
279デフォルトの名無しさん:2008/02/29(金) 05:36:00
C言語に慣れるためにいろいろなプログラムを入力してみているんですが、
分からないことがあったので質問させていただきます。

#define N 5
#define start 1
int main(void){
int i, k;
float rate[N][l], max = 0.0;

for( i=0; i<N; i++ ){
printf("%d番目のデータ >> ", start+i);
scanf("%f", &rate[i] );
if( rate[i] > max ){
max = rate[i];
k = start + i;
}
}
printf("最高値は%d年の%.0fパーセントです\n",k, max*100 );
return 0;
}

とあるサイトの参考プログラムです。
これは、小数点で確率を入力し、最高値を求めるというものですが、
これを改変して、最小値を求めるプログラムにするにはどうすればいいのでしょうか?
280デフォルトの名無しさん:2008/02/29(金) 06:25:13
>>279
そもそもそのプログラムだと、maxの初期値である0.0未満の値のみを入力すると
最大値が0.0になってしまうから正しく動作しているとはいえない。
だから例えば
if( rate[i] > max ){
のところを
if( rate[i] > max || i == 0 ){
のようにするべき。そしてその場合はmaxを初期化する必要はない。
同様に最小値を求めたい場合は…どうすればいいかわかるよね?
281デフォルトの名無しさん:2008/02/29(金) 06:51:14
>>280
上手く動作しました!
なるほど、maxを初期化しなくても良くなる方法があったのですね。とてもためになりました
ありがとうございました
282デフォルトの名無しさん:2008/02/29(金) 08:04:29
確率なんだから-は考えてないだけじゃね?
if(rate[i] > max || i==0) は無駄な判定回数増えるし。
283デフォルトの名無しさん:2008/02/29(金) 09:15:27




/* 待っちに待った、4年にいっち度のっ、日っが来っましたよっ と */
int is_leap_year(int y)
{
int rc = 0;

if (y % 4 == 0 && y % 100 != 0 || y % 400 == 0) {
rc = 1;
}

return rc;
}



284デフォルトの名無しさん:2008/02/29(金) 17:06:08
多重ループから完全に抜け出す場合にはgoto文使うのはアリですか?
それともフラグを立てての制御のほうがいいんでしょうか?
285デフォルトの名無しさん:2008/02/29(金) 17:42:10
状況による
286デフォルトの名無しさん:2008/02/29(金) 17:45:16
俺は自分しか読まないなら可読性重視
287デフォルトの名無しさん:2008/02/29(金) 17:57:28
>>285
>>286
返答ありがとうです。
この場合にはgoto文もやむなしという解釈でいいんですね。
これからは状況によって使い分けてみます。
ありがとうございました。
288デフォルトの名無しさん:2008/02/29(金) 18:15:28
>>287
多重ループから抜け出したらそこは関数の外だったって言う状況なら、迷わずreturnだけどねぇ。
289デフォルトの名無しさん:2008/02/29(金) 18:45:45
すみません、くだらない質問なのですが
while(fgets(buffer, sizeof(buffer), fp) != NULL){
p = strtok(buffer, ",");
while(p != NULL){
int num = atoi(p);
printf("%d ",num);
p = strtok(NULL, ",");
}
printf("\b\n");
}
CSVを読み込むのに、このような処理を行う、とあったのですが
いまいちstrtokがわかりません
bufferに1行読み込んで、それをカンマ区切りで分割するのであれば
strtokが1個でいいのではないかと考えてしまいます

どのような流れで動いているのかいまいちイメージしにくくて
わかりやすく説明していただけませんか
290デフォルトの名無しさん:2008/02/29(金) 19:10:40
>>289
敢えて呼び出しを一回しか書かないとしたら、
whileの判定部内でstrtok()を呼ぶことになって収まりが悪い。
しかも、初回だけbufferを渡さないといけないから尚更ややこしくなる。
291デフォルトの名無しさん:2008/02/29(金) 19:15:08
>>290
たとえば 12,34,56,78,
という列があったときに
1回目のpにはナニが入ってくるのか

2回目のwhileはpに1列入ってくるとイメージできるのですが
その中でのstrtokの1番目がNULLなのがわからずで

結局ナニをやってるのかわからないのです
292デフォルトの名無しさん:2008/02/29(金) 19:20:23
>>291
2回目以降のstrtok()の呼び出しでは、第1引き数をNULLにすることで
前回の呼び出し時の「続き」の処理を行なうことを要求している。
つまり、1回目のstrtok()は'2'の後の','を'\0'に換えて'1'へのポインタを返す。
2回目の(ループ内の最初の)strtok()は'4'の後の','を'\0\に換えて'3'へのポインタを返す。
以降順次、'7'へのポインタを返した次の呼び出しで、NULLを返すことで文字列を使い切ったことを伝えている。
293デフォルトの名無しさん:2008/02/29(金) 19:23:45
まあできればstrtok使わないで自力でやったほうがいいと思うが。
strtokの動作を知っておくのはあっといたほうがいいが
294デフォルトの名無しさん:2008/02/29(金) 19:26:22
こういう図解がわかりやすいか?
ttp://www9.plala.or.jp/sgwr-t/lib/strtok.html
295デフォルトの名無しさん:2008/02/29(金) 19:29:44
>>291
これを試してみ
#include <stdio.h>
#include <string.h>
int main()
{
char buffer[] = "foo,bar,hoge";
printf("%s\n", strtok(buffer, ","));
printf("%s\n", strtok(NULL, ","));
printf("%s\n", strtok(NULL, ","));
printf("%s\n", strtok(NULL, ","));
}
296デフォルトの名無しさん:2008/02/29(金) 19:36:03
まぁ、どの道strtok()は仕事では使い物にならないケースが多いけどね。
# strtok()でできることは大抵sscanf()で%[]や%nを駆使すればできてしまう。
297デフォルトの名無しさん:2008/02/29(金) 19:55:10
初心者なのですが質問です
getch()のカーソル点滅が邪魔なんですが、これを消す(隠す)ことは可能ですか?
298デフォルトの名無しさん:2008/02/29(金) 19:58:42
>>292-296
ありがとうございます。
もう少し落ち着いて読んでみます。

>>296
今までfscanfで分割して読み込みをよくやっていたので
はじめはsscanfやfscanfでやろうとしていたのですが
読み込むデータが
x,y,z,
x y z
x,y,z,a,
x y z a b
のようにカンマ区切りやスペース、3〜5の不定であるので
strtokを使うことになりました。

まだ学生なのですが、仕事で使えないと聞いて少し悲しくなりました
299デフォルトの名無しさん:2008/02/29(金) 20:16:23
>>284
読みやすさを考えて選べばいいと思う。
俺は、breakやgotoはループ内には1個までと決めてる。それ以上はフラグを併用するかな。
300デフォルトの名無しさん:2008/02/29(金) 20:23:38
>>298
char * tmpStr = "12,34,56,78,";
char buf[10];
sscanf(tmpStr, "%[^,]", tmp);
を試して見給え。
301デフォルトの名無しさん:2008/02/29(金) 21:05:55
298ですがご教授いただいたことで何とか理解できました。
問題は3〜5の不定の数をどうやって配列にするか……
もう少し粘ってみます。

>>300
ありがとうございます。
sscanfでも出来ました。
数がわかっている場合はこっちのほうがやりやすいです。
不定のときはどうしたらいいのか…

>>297
ttp://www.play21.jp/board/formz.cgi?action=quote&resno=12700&id=dixq&quo=12706&lognum=39&from=tree
こちらに、非表示にさせる方法が載っていました。
302デフォルトの名無しさん:2008/02/29(金) 21:34:48
とてつもなくアバウトな質問で申し訳ないんですが、
みなさんはソースを読むとき、どういう順番で目をつけて読んでますか?
私は今までFortranで書かれた一つのコードしかないプログラムしか
読んだことが無かったのですが、今、Cの複数のソースコードで構成された
プログラムを読む羽目になってます。Fortranのときは、call文を検索して
流れをざっと把握出来たんですが、Cは読みづらくて仕方ありません。
(ちなみにフローチャートとかはありません…)
読み方のコツのようなものがあれば教えていただけませんか?
303デフォルトの名無しさん:2008/02/29(金) 22:09:41
>>302
てきとーに思いついたのをいくつか
・ヘッダファイルを見て構造体や関数の一覧を眺める
・main関数を探してそこから順に辿っていく
・doxygenなどを使って見やすくする
304デフォルトの名無しさん:2008/02/29(金) 22:20:44
初心者です
教養程度の数学の実験ができるようになるまでにどのくらいの時間が掛かると思いますか?
305デフォルトの名無しさん:2008/02/29(金) 22:24:18
算数で6年数学で10年プログラミングで1年
計17年くらい
306デフォルトの名無しさん:2008/02/29(金) 23:30:38
>>302
誰もgetoptなど頭から挙動全部を読み取れなんて言ってないんだったら、
そのプログラムの中核をなす部分の検討をつけて、そこはじっくり読む事に専念する。
他の雑多処理関数などは後回し。  そんな事しないと何日も日が暮れる。
あと、なるべく存在する変数などは極力頭に入れて理解しておくと流れが良くなる。
分かりにくい表現は、自分で書き直したり、コメントを入れるといいかも。
307デフォルトの名無しさん:2008/02/29(金) 23:40:08
>>305
小学校からかよw
10年というと、大学までか
308デフォルトの名無しさん:2008/03/01(土) 00:03:31
>>301
んじゃ、更にこれを。
char * tmpStr = "12,34,56,78,";
char buf[10];
int read;
sscanf(tmpStr, "%[^,]%n", tmp, & read);
309デフォルトの名無しさん:2008/03/01(土) 01:18:26
外部ファイルの内容を終端から逆順で別ファイルにコピーする簡単なプログラムですが
スマートなプログラムが作れません。
教えていただけませんか??
今のソースは↓↓

fp_src = fopen(argv[1], "r");
fp_src = fopen(argv[2], "w");
fseek (fp_src, -2L, SEEK_END);
while (ftell(fp_src) != 0) { ←条件にEOFを使うのはNG
c = fgetc(fp_src);
fputc(c, fp_desc);
fseek (fp_src, -2L, SEEK_CUR);
}
c = fgetc(fp_src);
fputc(c, fp_desc);
}
310デフォルトの名無しさん:2008/03/01(土) 01:21:13
↑上の者ですが間違いだらけでした訂正します。

fp_src = fopen(argv[1], "r");
fp_dest = fopen(argv[2], "w");
fseek (fp_src, -2L, SEEK_END);
while (ftell(fp_src) != 0) { ←条件にEOFを使うのはNG
c = fgetc(fp_src);
fputc(c, fp_dest);
fseek (fp_src, -2L, SEEK_CUR);
}
c = fgetc(fp_src);
fputc(c, fp_dest);
}
311デフォルトの名無しさん:2008/03/01(土) 01:31:48
うしろから1kBとかまとめて読んで、
前後を入れ替えてから書き出していけばいいんじゃねえの。

そのやり方はあまりにも時間掛かるぞ。
312デフォルトの名無しさん:2008/03/01(土) 01:44:24
>>309
ファイルが巨大でないなら、
メモリ確保して全部読み出して、メモリ上でひっくり返すのが楽チンだと思う。
313デフォルトの名無しさん:2008/03/01(土) 02:03:28
>>311 312

それが出来れば簡単なんですが
fseek fputc fgetc 関数を使えという課題なんですよ・・・
314デフォルトの名無しさん:2008/03/01(土) 02:05:46
じゃあ、それでいいんじゃね。
変な条件つけられたら、変なコードしかかけないのは当然だ。
315デフォルトの名無しさん:2008/03/01(土) 10:28:29
Cの入門書やってるのですが
サンプルを打ち込むのは意味があるのでしょうか?
説明を読んで理解して章の最後の問題をやるだけでプログラミング上達するのでしょうか?(基本情報を取れるレベルという意味で
何回かやったんですがいつも途中の難しくなる所で(ポインタ、ファイル操作
挫折してしまいます。どうすればいいでしょうか?
316デフォルトの名無しさん:2008/03/01(土) 10:37:12
>315
小学校の国語でもまずは文字の書き取りからだろ?作文はその後だ。
プログラミングが上達うんぬんは作文できるようになってからであってそれ以前の段階。
317デフォルトの名無しさん:2008/03/01(土) 12:21:44
getch以外でキーボードの方向キー入力を認識する方法はありますか?
318317:2008/03/01(土) 13:00:15
すみません、質問を変えます
getch以外に処理を中断させる方法はありますか?
319デフォルトの名無しさん:2008/03/01(土) 13:13:19
>>318
つ[abort()]
320デフォルトの名無しさん:2008/03/01(土) 15:20:43
>>315
サンプルを見てただ打ち込むのはタイピングなので、プログラミング能力は上達しない。サンプルの意味を考えたり、サンプルを少し変えて、動きの変化を見るようになれば、プログラミングの上達につながるかもしれない。

挫折する場合は、その手前の基礎知識が不足しているか、その入門書が基礎の説明を端折っているかだ。
321デフォルトの名無しさん:2008/03/01(土) 17:36:13
TRUE, true, FALSE, falseなどを使いたいのですが、定義されていないとエラーになりました。
これらは自分でdefineするものなのでしょうか?
322デフォルトの名無しさん:2008/03/01(土) 17:37:28
enum bool {false, true}
323デフォルトの名無しさん:2008/03/01(土) 17:42:06
「真の場合0以外を返す」という関数が多いですが、それで100%正しい判断ができますか?
324デフォルトの名無しさん:2008/03/01(土) 17:43:09
はい。
325デフォルトの名無しさん:2008/03/01(土) 17:45:59
ありがとうございました。
326デフォルトの名無しさん:2008/03/01(土) 17:46:47
>>323
その戻り値はenum boolとは違うものなので、enum boolと比較してはいけない。
327デフォルトの名無しさん:2008/03/01(土) 17:47:30
Cはtrueとかfalseとか定義しないで、生の数字を使った方がいいよ。
328デフォルトの名無しさん:2008/03/01(土) 17:49:07
あら・・・
if(modotiri != 0) こんな感じで真と判断するのが良いということですか?
329デフォルトの名無しさん:2008/03/01(土) 17:50:50
if(modortiri)
まあ意味的には同じだ。
330デフォルトの名無しさん:2008/03/01(土) 17:53:00
皆さんありがとうございました。
331デフォルトの名無しさん:2008/03/01(土) 18:42:53
まぁ、普通はstdbool.hをインクルードしてfalse, trueを使うのだが、
trueと比較するのはナンセンスだ。
332デフォルトの名無しさん:2008/03/01(土) 19:18:39
そんなC99のヘッダ持ち出されても
333デフォルトの名無しさん:2008/03/01(土) 19:25:05
C言語スレなのに仲間外れなC99涙目
334317:2008/03/01(土) 19:37:09
>>319
ごめんなさい、中断ではなく一時停止でした
「↓」を表示後、キー入力があるまで処理を一時停止させ、
キー入力があればそれに対応した動きをさせたいのですが・・
335デフォルトの名無しさん:2008/03/01(土) 20:34:02
>>334
環境依存。
336デフォルトの名無しさん:2008/03/01(土) 20:43:13
getch()がそもそも環境依存だし、こっちに行ったほうがいいかも。
http://pc11.2ch.net/test/read.cgi/tech/1204124499/
337デフォルトの名無しさん:2008/03/01(土) 20:46:58
値が不定( -1000〜0 かもしれないし 0〜1000 -1000〜1000 かもしれない)
のデータから
max と min を出そうというとき
データを一時的にtempに入れて評価しようと思っているのですが

tempとmax minを比較するときに
max/minをどのように初期化したらいいのかわかりません。

たとえば0で初期化したとき、データが
-1000〜-10 の値だった場合、maxが初期化した0になってしまい、データとの整合性が
おかしくなってしまいます。

このような場合どうしたらよいのでしょうか
338デフォルトの名無しさん:2008/03/01(土) 20:48:42
tempと比較する前に一旦値を全部しらべる
339デフォルトの名無しさん:2008/03/01(土) 20:53:56
>>337
・一番目のデータで初期化し、2番目のデータ以降を比較する。
・値域を越える、意味のある最大(最小)値で初期化する。
340デフォルトの名無しさん:2008/03/01(土) 20:54:44
>338はありえないな。
341デフォルトの名無しさん:2008/03/01(土) 20:56:50
>>337
・データーの、並べ替えを、行う
342デフォルトの名無しさん:2008/03/01(土) 21:00:36
レスありがとうございます

>・一番目のデータで初期化し、2番目のデータ以降を比較する。
これはflgなどを設定してやるのですよね。
どうもフラグの扱いが下手で前に失敗して敬遠していました。

>・値域を越える、意味のある最大(最小)値で初期化する。
maxを-9999 minを9999で初期化するようなことですよね。
何がブチこめられるか検討がつかない場合、ちょっと怖くて…
343デフォルトの名無しさん:2008/03/01(土) 21:05:17
>>342
・フラグは、いりません、垂れ流しプログラムで、おk
・データーの、型の、最大値、最小値で、初期化すれば、おk
344デフォルトの名無しさん:2008/03/01(土) 21:12:17
>>342
// 前者の例
int getMaxValue(int * array, unsigned dataLen)
{ // dataLen が0のときには何らかの対策が必要
int maxValue = array[0];
for (unsigned ic = 1; ic < dataLen; ++ic) {
if (maxValue < array[ic]) maxValue = array[ic];
}
return maxValue;
}
// 後者の例
int getMinValue(int * array, unsigned dataLen)
{
int minValue = INT_MAX;
for (unsigned ic = 0; ic < dataLen; ++ic) {
if (minValue < array[ic]) minValue = array[ic];
}
return minValue;
}
345デフォルトの名無しさん:2008/03/01(土) 21:13:30
>>343
すみません…頭が悪くていまいち理解ができなくて。
型の最大値・最小値というのはどういうことなのでしょうか


ちゃんと書いてなかったのですが、データは
while(fscanf(fp,"%f\n",&temp) !=EOF){

}
という感じで読み込んでいます
346デフォルトの名無しさん:2008/03/01(土) 21:15:05
>>344
更新する前に書き込んでしまいました、すみません。
ちゃんと読んで理解して試してみます
347デフォルトの名無しさん:2008/03/01(土) 21:17:33
>>343
データ(data)はコンピュータ(computer)などの例と違い、
最後は延ばさないのが一般的です。

・延ばさないのが一般的
データ(data)
・延ばすのが一般的
キー(key)、カー(car)
・どちらも使われる
コンピュータ(コンピューター)(computer)
348デフォルトの名無しさん:2008/03/01(土) 21:20:25
>>344
>if (minValue < array[ic]) minValue = array[ic];
処理がgetMaxValue()と同じになってるw > だな。
349デフォルトの名無しさん:2008/03/01(土) 21:22:41
>>345
例えばunsigned charなら最大を0、最小を255で初期化するってこと。
350デフォルトの名無しさん:2008/03/01(土) 21:23:31
>>345
fscanf(fp,"%f\n",&temp) !=EOF

これはいけない。

fscanf(fp,"%f\n",&temp) ==1

としよう。
351デフォルトの名無しさん:2008/03/01(土) 21:30:20
>>347
老婆心、ありがとうございます、そういう、理由だったんですか
IMEが「データ」「ー」としてしか、受け付けて、くれず、意味が、わかりません、でした
352デフォルトの名無しさん:2008/03/01(土) 21:33:54
読点多すぎw
353デフォルトの名無しさん:2008/03/01(土) 22:00:09
>>347
一般的かどうかで言えばそうだね。

技術用語としては、基本的に

・ 3文字以下の単語は末尾の長音記号は省略しない
・ 3文字以上の単語は末尾の長音記号は省略する

で、一部慣用的な例外があるって感じ。
354デフォルトの名無しさん:2008/03/01(土) 22:00:58
ミスった。

× 3文字以上
○ 4文字以上
355デフォルトの名無しさん:2008/03/01(土) 22:42:25
スレ違いだが論拠になるのはこの辺だな。

JISZ8301:2005 規格票の様式及び作成方法(より適当に抜粋)
附属書G(規定) 文章の書き方,用字,用語,記述符号及び数字
G6.2 外来語の表記
c) 長音符号は,通常,次によって用いる。
2) 規格の用語及び学術用語にない用語の語尾につける長音符号は,表 G3 による。

表 G.3―外来語の表記に語尾の長音符号を省く場合の原則
a) その言葉が 3 音以上の場合には,語尾に長音符号を付けない。
b) その言葉が 2 音以下の場合には,語尾に長音符号を付ける。
c) 複合の語は,それぞれの成分語について,上記 a) 又は b) を適用する。
d) 上記 a)〜c) による場合で,長音符号を書き表す音,はねる音,及びつまる音は,それぞれ 1 音と認め,拗音は 1 音と認めない。

ttp://www.jisc.go.jp/app/pager?id=23428
356デフォルトの名無しさん:2008/03/02(日) 00:07:24
数値処理で注意すべきところはなんですか?
357デフォルトの名無しさん:2008/03/02(日) 00:11:46
358デフォルトの名無しさん:2008/03/02(日) 00:14:38
数値を対数で計算するときに注意するところは?
359デフォルトの名無しさん:2008/03/02(日) 00:55:30
底を、まちがえない
360デフォルトの名無しさん:2008/03/02(日) 00:59:03
使えるライブラリーを探す
361デフォルトの名無しさん:2008/03/02(日) 01:22:28
ライブラリーってどうやってつかうの?
行列計算のライブラリーとかはとってこないといけないらしいが
362デフォルトの名無しさん:2008/03/02(日) 01:23:00
どう使うってヘッダーとして入れればいいだろ
363デフォルトの名無しさん:2008/03/02(日) 01:24:08
微妙に意味不明
364デフォルトの名無しさん:2008/03/02(日) 01:26:11
具体的には?
365デフォルトの名無しさん:2008/03/02(日) 01:27:49
>>361
そのライブラリの配布物かサイトのどこかに使い方の説明書きが付いてると思うが
366デフォルトの名無しさん:2008/03/02(日) 01:28:00
ライブラリってライブラリ関数のこといってるの?
だとしたら
#include <string.h>とか
#include <stdio.h>とかやってると思うけど、
そのヘッダーファイルを自分の使いたいライブラリに書き換えて使えばいいんじゃ?
367デフォルトの名無しさん:2008/03/02(日) 01:29:25
おまえら大抵の標準外のライブラリはリンクが必要な事を教えてやれよ
368デフォルトの名無しさん:2008/03/02(日) 01:30:24
>>361
普通は、
1.ヘッダーファイルとオブジェクトライブラリとマニュアルを入手する。
2.使用するライブラリ関数を呼んでいるソースファイルで、必要なヘッダーファイルをインクルードする。
3.コンパイル時にオブジェクトライブラリを指定する。
369デフォルトの名無しさん:2008/03/02(日) 01:39:27
>>367
標準のライブラリもリンクは必要ですが。
370デフォルトの名無しさん:2008/03/02(日) 02:39:24
カーニハンさんの本を買った、それ見ながら
なにか作りたいけど、どうせ作るなら日常で多少の役に立つものを作りたい。
しかしそれが思いつかない。
なんかヒント下せぇ。
371デフォルトの名無しさん:2008/03/02(日) 02:46:57
金の管理
372デフォルトの名無しさん:2008/03/02(日) 02:48:33
嫁の管理
373デフォルトの名無しさん:2008/03/02(日) 03:34:37
管理する嫁が無い

ありがとうございました
また困ったら質問させていただきまふ
374デフォルトの名無しさん:2008/03/02(日) 03:59:02
自分でUNIXの基本的なコマンドつくってみるとか
catとか
375デフォルトの名無しさん:2008/03/02(日) 11:46:25
>>370
その本だけじゃムリ。
376デフォルトの名無しさん:2008/03/02(日) 11:57:49
>>370
単純な話、パソコン使ってて不便だなと思った時に
それを解決するプログラムを作ればいい。
377デフォルトの名無しさん:2008/03/02(日) 13:03:01
マルチですみません

main()ってどれが正しいのですか?
実効環境によってちがうのですか?
この手のドキュメントは何になるでしょうか?

void main(void);
int main(void);
int main(int argc, char *argv[]);
int main(int argc, char **argv);
378デフォルトの名無しさん:2008/03/02(日) 13:12:33
下3つは全ての環境で常に正しい。
下2つは文法的に同等。
一番上は環境依存。

最も確実なドキュメントは規格。
JIS X3010 を嫁。
379デフォルトの名無しさん:2008/03/02(日) 13:16:39
>>375 おれはその本と Unix のソースコードで C を覚えたが...
380デフォルトの名無しさん:2008/03/02(日) 13:19:43
>>378 適切な回答ありがとう
>>379 おれはポインタ本に頼ってしまった…隠してあるけど
GNUのソース見るとすごいなと思う
381デフォルトの名無しさん:2008/03/02(日) 14:09:12
現在でもUinixのソースコードを見るのが一般的なのでしょうか?
382デフォルトの名無しさん:2008/03/02(日) 14:13:52
そもそも一般的だった時代があるのか?
383デフォルトの名無しさん:2008/03/02(日) 16:53:30
>>381

一般的だった時代があるかどうかはともかく、
ごちゃごちゃしたコードもあるので、勉強にはあまり勧めない。
384デフォルトの名無しさん:2008/03/02(日) 17:17:05
一度は読んだほうがいい、ソースコード
http://pc11.2ch.net/test/read.cgi/tech/1201966827/
こういうスレもある
まともに機能してないけど
385デフォルトの名無しさん:2008/03/03(月) 00:24:53
>>374-376
おお、さらにレスが
ありがとうございます
いつかはソース眺めてフムフム、と言ってみたい
386デフォルトの名無しさん:2008/03/03(月) 00:30:23
ソーっスね〜
387デフォルトの名無しさん:2008/03/03(月) 09:41:24
>>381
以前、catコマンドだとかlsコマンドのソースコードを見たことがあったけど
えらい汚いコードだった。

初期のUnixのコードはいろいろな開発者が手を加えているので
統一性が取れていなくて見苦しい。

ちゃんとした製品として作られたものでオープンソースのものがあるから
それをダウンロードして見るのもいい。
388デフォルトの名無しさん:2008/03/03(月) 16:35:15
素数を求めるC言語プログラミングを教えてください
条件が有りまして
for文のネストもしくはwhile文のネストを使ってなおかつgoto文を使って下さい
よろしくお願いします。
389デフォルトの名無しさん:2008/03/03(月) 16:36:27
>>388
C/C++の宿題を片付けます 104代目
http://pc11.2ch.net/test/read.cgi/tech/1202135539/l50
390デフォルトの名無しさん:2008/03/03(月) 16:38:16
>>389
ありがとうございます
391デフォルトの名無しさん:2008/03/03(月) 17:37:28
gotoを使ってくださいって、やな課題だな
392デフォルトの名無しさん:2008/03/03(月) 17:42:02
void use_goto()
{
goto hoge;
hoge:
return;
}

これかましてたらいいんでね
393デフォルトの名無しさん:2008/03/03(月) 17:45:30
よし、俺に任せろ。
#include <stdio.h>
int main()
{
while (1) while (1) goto next;
next:
puts("2");
return 0;
}
394デフォルトの名無しさん:2008/03/03(月) 17:48:44
これで問題なかろ?
#include<stdio.h>

#define NUM_MAX 100

int main(void){
int i, j;

for(i=2;i<=NUM_MAX;i++){
for(j=2;i/j>=j;j++){
if(i%j==0) goto as_break;
}
as_break:
if(i/j<j) printf(" %d", i);
}
return 0;
}
395デフォルトの名無しさん:2008/03/03(月) 23:05:00
gotoである意味なくね?
breakでいいじゃん。
396デフォルトの名無しさん:2008/03/03(月) 23:08:10
>>395
いや、命題がgoto使えってことだから
397デフォルトの名無しさん:2008/03/04(火) 08:02:52
単純にbreakを置き換えるんじゃなくて、gotoを使う意味があるようなのにしたらってことじゃね?
398デフォルトの名無しさん:2008/03/04(火) 08:06:49
質問者は既に移動したんだからスレ違い自粛しる。
399デフォルトの名無しさん:2008/03/04(火) 08:13:10
goto使うんなら
for(i=2;i<=NUM_MAX;i++){
for(j=2;i/j>=j;j++){
if(i%j==0) goto as_break;
}
printf(" %d", i);
as_break:
}
だな。
400デフォルトの名無しさん:2008/03/04(火) 08:53:11
ファイルの行数を
一度読み込みをしないで調べる方法ありますか

9
0
78


みたいなのを
今まで一度最後まで読み込んで、行カウントして
その分の配列を確保して、先頭から読み直してたのですが
1億行とかになると時間が掛かりすぎて。
401デフォルトの名無しさん:2008/03/04(火) 08:58:56
>>399
そうするならラベルの名前は変えたほうがいい
402デフォルトの名無しさん:2008/03/04(火) 09:01:20
>>401
いい加減にしなさい。

>>400
動的確保すればいいんじゃない?
要は、1万行分確保しておいて、溢れるようなら更に1万ってな調子で。
C++ならvectorで簡単にできるけど、Cならrealloc()使ってちと面倒だけど。
403デフォルトの名無しさん:2008/03/04(火) 09:14:50
gotoは絶対禁止って頭から覚えこまされるヤツがおおいせいで、まともな使い方できないのが多いね。
404デフォルトの名無しさん:2008/03/04(火) 10:57:06
禁止じゃなくても、あんまり使う機会無いからな
405デフォルトの名無しさん:2008/03/04(火) 15:24:54
Cはラベル付きbreakとか例外とか使えないからgotoの価値があるけど、
それ以外になんか有効な使い方ってある?
406デフォルトの名無しさん:2008/03/04(火) 17:21:39
うちの会社だといちおうコーディング規則で使うなとなっていまふ goto
あんまり便利な用途も思いつかない(エラーで飛ぶぐらい?)
407デフォルトの名無しさん:2008/03/04(火) 19:17:46
質問です。
定数の配列って出来ますか?

#define HOGE {123,456,789}

こういうのがしたいんですが、

constでグローバル変数にするしかないですか?
408デフォルトの名無しさん:2008/03/04(火) 19:19:42
>>407
それをどう使うつもりなのか知らんが、グローバル変数では困るわけは?
409デフォルトの名無しさん:2008/03/04(火) 19:25:28
>>408
constで困りませんが、
他に方法があるのかな?と思い質問しました。
410デフォルトの名無しさん:2008/03/04(火) 20:08:49
>>409
C99に対応したコンパイラなら

(int[]){123, 456, 789}

こんな書き方ができるらしい
411デフォルトの名無しさん:2008/03/04(火) 20:52:49
>>410
もうCじゃないな
412デフォルトの名無しさん:2008/03/04(火) 21:22:09
定数でいいならenumという手もある。そうでないならconstだな。
413デフォルトの名無しさん:2008/03/04(火) 23:11:42
すいません。教えてください。℃素人です。
"return"と"exit"ってどのような違いがあるのでしょうか?
414デフォルトの名無しさん:2008/03/04(火) 23:14:55
return は値を返す
exitはその場で終了
415デフォルトの名無しさん:2008/03/04(火) 23:15:38
勉強を進めていけば分かるよ
説明しても今は理解出来ないと思う
416デフォルトの名無しさん:2008/03/04(火) 23:18:27
ごめんもうちょっと詳しく書くわ。
勉強最中に 関数 ってのを習うと思うんだけど、今は int main( void ) ってのでしょ?
これはメインとなるプログラム本体だと思ってOK。 そして 1つのプログラム だと思ってもOK。
でも通常プログラムってのは、色々なプログラムを集合させて1つのプログラムにするんだ。
何気なく使ってる printf もプログラム。 printfは、文字を渡すと文字を表示させるっていうプログラムだけど、
たとえば数字を二つ渡すと 計算をしてくれるってプログラムがあって、それを main のなかで使いたいとすると、
二つの数字の結果がほしいわけでしょ?その結果を返すために return なんちゃら ってのが必要なのです。
417413:2008/03/04(火) 23:18:50
>>414さん
レスありがとうございます。
"return"はmain関数に値を返すのは
わかっているのですが、例えば"exit(1)"と
いった場合の"1"という値は何処へ行くのですか?
度々ですみません。
418デフォルトの名無しさん:2008/03/04(火) 23:19:39
プログラムの呼び出し元。
419デフォルトの名無しさん:2008/03/04(火) 23:20:06
>>417
どこって、exit関数内に行くんですよ。
420デフォルトの名無しさん:2008/03/04(火) 23:22:17
exitの引数で指定した値はOSに返る
421デフォルトの名無しさん:2008/03/04(火) 23:23:01
>>420
プログラムの呼び出し元は OS だけとは限らんぜ。
422デフォルトの名無しさん:2008/03/04(火) 23:23:35
main関数内でのreturnとexitってことでしょ?
それならreturn 1もexit(1)も同じ
423デフォルトの名無しさん:2008/03/04(火) 23:26:09
横レスでスマソ。
main関数内で終了させる場合はreturn 0;。
main関数以外の関数で終了させる場合はexit(1);。
ちなみにmain関数内でexit(1);で終了させることも可。

こういう解釈でいいのかい?
424デフォルトの名無しさん:2008/03/04(火) 23:27:00
>>416
滅茶苦茶だな。

>>417
main()関数は一般的にOSからの入り口と出口になる。
入り口は当然関数の先頭であり、出口はreturn。
この出口に直行するショートカットがexit()になる。
これは、main()からに限らず他の関数からいきなり
OSへの出口に直行するためにも使えると言うわけ。
まぁ、何かと不都合が生じる原因にもなるから
「対処不能な障害による」緊急脱出でもなければexit()はお勧めしない。

>>423
そういうこと。
425413:2008/03/04(火) 23:27:05
みなさん、ありがとうございます。

>>422さん
なるほど、同じなのですね。理解できました。
ありがとうございます。
426デフォルトの名無しさん:2008/03/04(火) 23:27:09
すげー18分しかかかってねえ!不思議!
427デフォルトの名無しさん:2008/03/04(火) 23:27:10
EXIT_SUCCESSかEXIT_FAILURE使った方がいいけど
428デフォルトの名無しさん:2008/03/04(火) 23:28:35
>>421
OSが介在しない特殊な環境を除けば、コマンドライン以外の例えば
何がしかのアプリから直接起動しているように見えても実はOSを経由している。
だから、一般的にはOSとのI/Fと考えて問題はないと思うが。
429デフォルトの名無しさん:2008/03/04(火) 23:29:16
>>423
呼び出し元へ返す値は一般的には
0 正常終了
0以外 異常終了
だよ

(もちろん正常終了しても意図して 0 以外を返す場合もあるよ)
430デフォルトの名無しさん:2008/03/04(火) 23:29:18
>>416は滅茶苦茶なの?間違ってはいないと思うんだが・・・まだまだ俺が未熟なせいか?
431デフォルトの名無しさん:2008/03/04(火) 23:30:07
内部的には大体こんな感じになってる。
これは概念的な物で、実際にはもうちょっと複雑だろうけど。

void __startup() { // これが C で作られたプログラムの全体
 int status;
 __initialize(); // main より前に行う必要のある初期化
 status = main(); // main を呼ぶ(場合によってはコマンドライン引数を渡す)
 exit(status); // main の戻り値を使って exit を呼んで、プログラムを終了する
}

void exit(int status)
{
 __atexit(); // atexit で登録した後処理を行う
 __finalize(); // 後始末を行う(ファイルのフラッシュとか)
 __quit(status); // プログラムの呼び出し元に値を返してプログラムを終了する
}

まあ、必ずしもプログラムの呼び出し元に値を返さないといけないわけじゃないだろうけど、
プログラムの呼び出し元に終了状態を示すのに「使う事ができる」と規定されてたと思う。
432デフォルトの名無しさん:2008/03/04(火) 23:32:14
>>429
ということは、
main関数以外の関数で終了させる場合、
正常終了ならexit(0);
異常終了ならexit(1);
ということなんですね。
433デフォルトの名無しさん:2008/03/04(火) 23:34:06
>>432
ちがう。異常終了は非0
-1かもしれないし100かもしれない
434デフォルトの名無しさん:2008/03/04(火) 23:34:55
呼び出し元に返される値は必ずしも exit の引数(main の戻り値)と同じとは限らない。
ただ、とにかく exit の引数(main の戻り値)が 0 の時は
呼び出し元に正常終了を表す値が返り、
1 の時は呼び出し元に異常終了を表す値が返る。

>>433
0, 1 以外の値の場合にどうなるかは環境依存。
435デフォルトの名無しさん:2008/03/04(火) 23:36:43
>>432
異常終了は非0か。
ある意味こういうところがCの難しいところな気がしてきた。
436デフォルトの名無しさん:2008/03/04(火) 23:39:05
0返そうが非0返そうが何か起こるわけじゃないから気にしなくて良いよ
そんなんにこだわってるから難しいんじゃないの?
>>427でいいじゃない
437デフォルトの名無しさん:2008/03/04(火) 23:39:54
>>432
Yes.
ただ、できるだけ main に戻った方が個人的にはいいと思う。
途中で行った処理に色んな後始末が必要な場合もあるだろうから、
main にまで戻る間にその後始末を行うと良い。
できるだけグローバル変数を使わないプログラムの場合、
後始末を全部 atexit に任せるのは結構辛いものがあると思うしね。
438デフォルトの名無しさん:2008/03/04(火) 23:40:45
>>435
異常終了は 1 。
規格ではそれ以外で異常終了になる事を保証してはいない。
使っている処理系で保証していれば話は別だが。
439デフォルトの名無しさん:2008/03/04(火) 23:43:41
規格ではEXIT_SUCCESSは0だと定められている。(EXIT_FAILUREは忘れた)
よってmain関数はとりあえずreturn 0;で問題ない。別にEXIT_SUCCESSでも一向に構わない。
440デフォルトの名無しさん:2008/03/04(火) 23:46:53
ちなみに、main()から-1を返したりexit()に-1を渡す例をしばしば見かけるが、
大抵のOSでは負値を受け取るようにはできていないので要注意。
255と解釈されるかもしれないし、65535と解釈されるかもしれないし、
巡り巡って-1と解釈されるかもしれないわけだ。
441デフォルトの名無しさん:2008/03/04(火) 23:48:01
関数に引数でポインタを渡して関数内で引数のアドレスを変更しても
呼び出し側の引数のポインタのアドレスが変更されないのはなぜでしょうか?

void foo(char *c)
{
c++;
return;
}

void main()
{
char c[256];
char *p = c;

foo(p);

}

442デフォルトの名無しさん:2008/03/04(火) 23:49:59
>>441
関数にポインタのポインタを渡して、そのポイント先を変更するようにすればOK。
443デフォルトの名無しさん:2008/03/04(火) 23:50:56
例えば gcc 4.0.1 / Mac 10.4.11 で実行してみると、
呼び出し元には exit の引数(main の戻り値)を 256 で割った余りが返る。
昔 Turbo C++ / MS-DOS でチェックしたときも同じだった気がする。
こういう環境だと、非 0 だろうが、256 の倍数を返せば正常終了になる。

どんな環境でも異常終了を示すことが保証されているのは 1 だけ。
0, 1 以外を返した時にどうなるかその環境のドキュメントを読むべし。
444デフォルトの名無しさん:2008/03/04(火) 23:51:00
>>441
仮引数はすべてコピーでしかない
コピーをいくら弄ろうとオリジナルに影響は無い
445デフォルトの名無しさん:2008/03/04(火) 23:51:41
>>441
引数で渡した値を変更しても、呼び出し元には反映されない。
ポインタが指してる先なら変更できる。
ポインタを変更したいならポインタのポインタで渡す。
446デフォルトの名無しさん:2008/03/04(火) 23:52:15
>>441
変数だろうとポインタだろうと渡された値は関数内でコピーされたローカル変数。
それ自体を変化させても呼び出し元の値が影響を受けることはない。
呼び出し元の値を変えたければ「変えたい値のポインタ」を渡して、
関数内で「そのポインタが指し示す変数」をいじる必要がある。
だからポインタの値を関数内でいじりたければ「ポインタのポインタ」を渡さないといけない。
447デフォルトの名無しさん:2008/03/04(火) 23:53:35
>>441
関数に引数で変数を渡して関数内で引数の値を変更しても
呼び出し側の引数の変数の値が変更されないのと同じ理屈。
void foo(int i)
{
  i++;
}

int x = 5;
foo(x);
そのために、変数へのポインタを使う。
void foo(int *i)
{
  (*i)++;
}

int x = 5;
foo(x);
ここではint型だったが、ほかの型でも同じこと。例えば、char *型でも。
void foo(char **c)
{
  (*c)++;
}
int main()
{
  char c[256];
  char *p = c;

  foo(&p);

  return 0;
}
448441:2008/03/04(火) 23:53:56
>>442,444,445,446
ありがとうございます。
449デフォルトの名無しさん:2008/03/04(火) 23:54:47
>>441
当時中学生だった俺は当日に買いに走った
運良く数冊残っていてそれを持ってレジに行ったんだ
レジのおばちゃんが俺をみてこう言ったんだ
「あんた未成年でしょ。未成年には売らないよ。」
その日は諦めて次の日に遠出して他の本屋に行ったんだが全て売り切れだった
あの日ほど絶望感を感じたときはない
450デフォルトの名無しさん:2008/03/04(火) 23:54:51
441 大人気だなw
451デフォルトの名無しさん:2008/03/04(火) 23:55:02
>>441の人気に嫉妬wこの手の質問はFAQだからなぁ
452デフォルトの名無しさん:2008/03/04(火) 23:57:54
goto goto goto goto goto goto goto goto
ゴートゥーだけで組んだらどうなるかな
453デフォルトの名無しさん:2008/03/05(水) 00:00:22
goto が嫌いになる
454デフォルトの名無しさん:2008/03/05(水) 00:00:48
すばらしい回答だな
455デフォルトの名無しさん:2008/03/05(水) 00:00:49
>>452
飲んでるコーヒー吹いた
456デフォルトの名無しさん:2008/03/05(水) 00:00:58
goho とか混じっていても気がつかない
457デフォルトの名無しさん:2008/03/05(水) 00:02:21
#define g int
#define o main
#define to () {
#define go return
#define tog 0;
#define oto }

g o to go tog oto
458デフォルトの名無しさん:2008/03/05(水) 00:03:10
なんというすばらしいmain関数
459デフォルトの名無しさん:2008/03/05(水) 00:04:16
gohome yankee;
460デフォルトの名無しさん:2008/03/05(水) 00:46:40
#include <stdio.h>
#include <malloc.h>
main(togo,toog)
int togo;
char *toog[];
{char *ogto, tgoo[80];FILE *ogot; int oogt=0, ootg, otog=79,
ottg=1;if ( togo== ottg) goto gogo; goto goog; ggot:
if ( fgets( tgoo, otog, ogot)) goto gtgo; goto gott;
gtot: exit(); ogtg: ++oogt; goto ogoo; togg: if ( ootg > 0)
goto oggt; goto ggot; ogog: if ( !ogot) goto gogo;
goto ggto; gtto: printf( "%d goto \'s\n", oogt); goto
gtot; oggt: if ( !memcmp( ogto, "goto", 4)) goto otgg;
goto gooo; gogo: exit( ottg); tggo: ootg= strlen(tgoo);
goto tgog; oogo: --ootg; goto togg; gooo: ++ogto; goto
oogo; gott: fclose( ogot); goto gtto; otgg: ogto= ogto +3;
goto ogtg; tgog: ootg-=4;goto togg; gtgo: ogto= tgoo;
goto tggo; ogoo: ootg-=3;goto gooo; goog: ogot= fopen(
toog[ ottg], "r"); goto ogog; ggto: ogto= tgoo; goto
ggot;}
461デフォルトの名無しさん:2008/03/05(水) 01:14:00
なんか記号使わないperlとかいう奴思い出した
462デフォルトの名無しさん:2008/03/05(水) 01:18:03
K&Rの演習解答本「Cプログラミング言語アンサー・ブック」を読んでいて、
わからないところがありました。

演習7−4のアンサーで、scanf関数に実引数を渡さないケースがあったのです
が、この場合、具体的には何が行われるのでしょうか。

%で始まる変換仕様でない部分なので、読み飛ばされるような気がするのですが……。

よろしくお願いします。
463デフォルトの名無しさん:2008/03/05(水) 01:27:59
なぜその部分のソースを晒さない。
464デフォルトの名無しさん:2008/03/05(水) 02:19:14
>>461
ppencodeか
465デフォルトの名無しさん:2008/03/05(水) 06:23:54
ファイルのサイズにはEOFは含まれるものなのでしょうか?
466デフォルトの名無しさん:2008/03/05(水) 07:08:52
>>460
出てくると思ったw
467デフォルトの名無しさん:2008/03/05(水) 07:09:34
>>465
含まれない
468デフォルトの名無しさん:2008/03/05(水) 08:56:06
なにー、そうなんですか。
でもファイルの一部なんですよね?

EOFのコードが埋め込まれていて、それがファイルの一部なのに入らないんですか。
EOFのコードって処理系によっても違うんではないでしたっけ?
テキストファイルの後ろに必ずあるものでもないって聞いたことあったから
含まれてるものだと思った。

ところでlsとかで表示されるファイルのサイズっていつ調べるんだろうね。
469デフォルトの名無しさん:2008/03/05(水) 09:19:39
>>468
ファイルによってデータの終わりをサイズ情報によって管理するものと、終端のしるしである
EOFによって管理するものがある。
前者が一般的で後者はまれ。
昔の磁気テープはEOFを書き込んでいたと記憶する。

> ところでlsとかで表示されるファイルのサイズっていつ調べるんだろうね。
ディレクトリーファイルを読み込んだとき。
470デフォルトの名無しさん:2008/03/05(水) 09:21:55
>>468
ファイルシステムとOS依存だが、埋め込まれているなら含まれる。
今時のOSとファイルシステムなら、特に埋め込まれないから含まれない。
また、ファイルサイズはファイルシステムが管理しているので、書いたときの
サイズが保持されているだけ。

つーか、鼬害だがね。
471デフォルトの名無しさん:2008/03/05(水) 11:05:14
その昔CP/Mというのがあってな…
472デフォルトの名無しさん:2008/03/05(水) 11:58:52
^Z
473デフォルトの名無しさん:2008/03/05(水) 12:08:15
sscanfで何かしらのデータを読み込んだ時、文字列から何バイト読み込みに使ったか
知る術はありますか?
int i;
sscanf("100,100","%d",&i);
ここから読み込んだ文字は"100"の3バイトだから、何とかして3を取得したい。
474デフォルトの名無しさん:2008/03/05(水) 12:41:30
>>473
%n
475デフォルトの名無しさん:2008/03/05(水) 13:44:53 BE:185783832-2BP(50)
int main(void){
.
.
.
return 0;
}
のreturn 0; の意味がいまいち分かりません。これは0じゃなきゃ駄目なんでしょうか?
1とか2とかだとどうなんですか?
476デフォルトの名無しさん:2008/03/05(水) 13:54:22
この値はプログラムの呼び出し元(OSとか)に送られる数字で、
一般に0は正常終了、1は異常終了。
何らかのエラーで終了する時にはreturn 1;と書いたりする。
477475:2008/03/05(水) 13:55:50
>>476 ありがとうございました。
478デフォルトの名無しさん:2008/03/05(水) 15:06:51
>>474すいません、もう少しヒントいただけますか?
479デフォルトの名無しさん:2008/03/05(水) 15:08:26
scanf()の書式の説明に書いてあるだろう。
その場で実際にいろいろ試してみないと今後苦労するぞ。
480デフォルトの名無しさん:2008/03/05(水) 15:13:28
>>474やっぱいいです。ありがとうございました
481デフォルトの名無しさん:2008/03/05(水) 15:14:03
>>479とおもったら・・・
すいません。すぐに出てきたんでやりました。
482302:2008/03/06(木) 00:41:02
>>303
>>306
遅くなりましたがありがとうございます。
doxygenというのは知らなかったので参考にします。
483462:2008/03/06(木) 01:10:43
>>463

どうもすみません。初心者なので、どうお伝えすればよいのかよくわからなかったのです。

ソースが結構長く、どう抜粋すればよいのかもわからないため、言葉で説明したいと思います。


scanfは、「int scanf(char *format, ...)」のように引数を取りますが、
このうち可変引数リスト「...」がない状態で使用していたソースを見つけました。「scanf(format);」のような形になっているのです。
こうした場合、どういう挙動を取るのでしょうか?

ソースはscanfが可変引数をどのように処理するかを示すための関数で、次のように宣言されるものです。

int minscanf(char *fmt, ...)

関数では、まず、fmtを読み取り、%とそれに続くアルファベット1文字まで、charの配列localfmtに代入します。
次に、%に続くアルファベット1文字でswitch文を分岐させ、アルファベットが対応する変換仕様の文字が表す型で、可変引数リストの引数を読み込み、scanf関数に引き渡します。

例えば、アルファベットが「d」や「i」なら、次のようになります。

scanf(localfmt, ival);

ivalはint型のポインタです。

問題は、アルファベットが変換仕様の文字に対応していなかった場合です。
その場合は、switch文のdefaultとして、次のように処理されます。

scanf(localfmt);

このscanfの呼び出しに、可変引数部分がないため、挙動が予測できないのです。

もし、お分かりの方がいらっしゃいましたら、ご教示いただけますよう、何卒、お願い申し上げます。
484デフォルトの名無しさん:2008/03/06(木) 02:35:40
第1引数の文字列を大文字にして第2引数にコピーする関数をつくったのですが
うまく動きません
何故か文字列によっては正しくコピーされます
どなたか原因をご教授ください

#include <stdio.h>
#include <ctype.h>

void string_up(char *source, char *result);

int main(void)
{
   char *str;
   string_up("lsdk",str);
   printf("%s",str);
   return 1;
}

void string_up(char *source, char *result)
{
   while(*source)
      *result++ = toupper(*source++);
   *result = '\0';
}
485デフォルトの名無しさん:2008/03/06(木) 02:47:33
>>484
結果を入れるべきstrに、結果が入るアドレス設定されていないから。
char配列なりmallocで動的になり結果が入るだけのメモリを準備して、
それをstrに設定してやる。
486デフォルトの名無しさん:2008/03/06(木) 02:57:17
>>485
なるほど!
分かりました
ありがとうございました
487デフォルトの名無しさん:2008/03/06(木) 03:00:37
>>484
strは宣言されただけで初期化されていないのでstring_upで大文字化した文字が代入される場所は不定になる
何が起きても不思議ではない状態になっている
string_up("lsdk",str);を呼び出すのならstrはchar *str;でなくchar str[5];とかで場所を確保しておかないといけない
つまり元の文字列と同じかそれ以上のサイズのメモリー領域を確保する
488デフォルトの名無しさん:2008/03/06(木) 03:21:22
質問です
引数で渡した文字列の中から一部分を抜き出し、
そのアドレスを返す以下の様な関数を作ろうとしているのですが、
constでない変数をconstをつけて返すのは許されるのでしょうか?
駄目な場合戻り値で返すアドレスの中を書き換えられたく無い場合はどうすれば良いのでしょうか

const char* funcA( const char* input_data)
{
 static char data_area[32];
 memset( data_area, 0x00, sizeof(data_area) );
 strncpy( data_area, input_data+15, 30);
 data_area[31] = '\0';
 return (const char*)data_area;
}

489デフォルトの名無しさん:2008/03/06(木) 03:21:57
>>483
minscanfで処理できる変換指定ではないが、scanfで処理可能な変換指定をlocalfmtが含むときは、
変換指定の数が後続のポインタ引数の数より多いのでscanfの動作結果は未定義になる。
localfmtに変換指定が含まれない場合は、入力がlocalfmtの各文字に一致していなければならない。
490デフォルトの名無しさん:2008/03/06(木) 07:38:50
>>488
許される。
しかも、constが追加される方向の型変換は、キャストを書かなくても行える。
491デフォルトの名無しさん:2008/03/06(木) 16:00:32
プログラム始めたばかりなのですが

if(a==0)
if(b==0)



if(a==0)
else if(b==0)

の違いってあるんでしょうか?
492デフォルトの名無しさん:2008/03/06(木) 16:02:07
>>491
あります
ぜんぜん違う
493デフォルトの名無しさん:2008/03/06(木) 16:03:17
どう違うんでしょうか?
494デフォルトの名無しさん:2008/03/06(木) 16:04:34
else の意味はわかってるのか?
495デフォルトの名無しさん:2008/03/06(木) 16:07:26
elseの意味は大体なら。

if(a==0)
printf("%d", a);
else
printf("not a \n");

のような使い方は出来ると。

if
if
if
が並んだものと

if
else if
else if

となったとき、何が違うのか混乱してしまって
496デフォルトの名無しさん:2008/03/06(木) 16:13:36
if(a==0)
else if(b==0)

は、
if(a==0)
if((a!=0) && (b ==0))

497デフォルトの名無しさん:2008/03/06(木) 16:22:42
ということは

if(a==0)
if(b==0)のbで行われるのは

a!=0でもa==0のときでも行われる、ということでおkですか?
498デフォルトの名無しさん:2008/03/06(木) 16:37:55
おk

if(a==0)
// この時点で前のifに関する処理は全て終わって以降の処理とは無関係になってる
if(b==0)
499デフォルトの名無しさん:2008/03/06(木) 16:47:41
ありがとうございます
納得できました!
500mahhi:2008/03/06(木) 22:25:40
はじめまして。
少々お聞きしたい事があるのですが、Cの環境構成の事で質問が
あります。
現在、CDTでGDB Debuggerを使用してデバッグを行っているのですが、
Socket関数を使う際に、
kernel32!IsBadWritePtr();
という表示がでて、デバッガが飛んでしまいます。
言語とは少し話がそれてしまうかもしれませんが、
何かアドバイスがあればどうかお願いいたします。
501デフォルトの名無しさん:2008/03/06(木) 22:35:32
Eclipseは使ったことないなあ
502488:2008/03/06(木) 23:08:05
>>490
ありがとうございます。
Cのconst修飾子に関する資料が中々見つからなかったので助かりました。
503デフォルトの名無しさん:2008/03/06(木) 23:27:13
まだはじめたばかりだで計算のプログラム書ける程度の雑魚だけどおもすれぇ
次はifを使うらしい、楽しくなってきた!
504デフォルトの名無しさん:2008/03/06(木) 23:34:27
今日はじめたばかりの素人です。
本を買ってほんのとおりに進めたのですが、コマンドプロンプトでコンバイルするときに、
一番最初のプログラム
#include <stdio.h>

main()
{
printf("Hello World\n");
}
がインクルードファイルstdio.hをオープンできないとエラーがでました。
何処にミスがあったのでしょうか?・・・
多分しょうもない事なのでしょうが、三時間考えてます・・・誰かお助けを・・・
505デフォルトの名無しさん:2008/03/06(木) 23:35:40
コンパイルね。
コンパイラのアドレスとかきちんと設定した?
インクルードするためのファイルきちんとある?
506462:2008/03/06(木) 23:42:43
>>489
どうもありがとうございました。
厚く御礼を申し上げます。
507デフォルトの名無しさん:2008/03/07(金) 00:15:03
Cプリプロセッサで条件コンパイルする場合
1. #if defined(評価式)
2. #if 評価式
のどちらでもかけてしまいますが正しい使い分けはあるのでしょうか?
ご存知の方ご教授願います
508デフォルトの名無しさん:2008/03/07(金) 00:16:37
#if defined(〜) はマクロが定義されているかいないかを判定する
#if 〜 は値が0か0以外かを判定する
509デフォルトの名無しさん:2008/03/07(金) 00:30:30
#ifdefの話かと思ったら違うのか
510デフォルトの名無しさん:2008/03/07(金) 00:32:59
#if defined と #ifdef は同じかと
511デフォルトの名無しさん:2008/03/07(金) 00:35:17
>>505
ありがとうございます!!
かさねてすみませんがコンパイラのアドレスと言うのは、システム変数の編集とかってやつですか?
その辺は設定しました。
インクルードするためのファイルってのはさっぱり分からないので多分ない気がします。
どうすれば良いのでしょうか?・・・
512デフォルトの名無しさん:2008/03/07(金) 00:42:21
>>510
一緒じゃないぞ。defined(〜)なら他の式と組み合わせられる
単体で使うことが多いからifdefの方が便利だけど
513507:2008/03/07(金) 01:04:51
皆様素早いレスありがとうございます。
大変参考になりました。
514デフォルトの名無しさん:2008/03/07(金) 01:24:53
コマンドプロンプトを立ち上げると
C:\Documents and Settings\<ユーザネーム> >
と出るのですが、このパスを変更するにはどうしたらいいですか?
515デフォルトの名無しさん:2008/03/07(金) 01:28:46
コマンドプロンプトへのショートカットのプロパティ
516デフォルトの名無しさん:2008/03/07(金) 01:30:37
>>514
スレ違い。

>>515
私は寧ろ、cdコマンドさえ知らないのかと思ったのだが、その可能性もあったね。
517デフォルトの名無しさん:2008/03/07(金) 02:22:13
初心者です
if〜elseとif〜else〜ifの違いはなんですか?
518デフォルトの名無しさん:2008/03/07(金) 02:33:41
>>515
ありがと
>>516
コマンドプロンプトに慣れていないのは事実だけど馬鹿ではないよw
519デフォルトの名無しさん:2008/03/07(金) 03:41:27
>>518
バカじゃないのに、コマンドプロンプトの質問がスレ違いかどうかも判らなかったの?
それとも、スレ違いと承知の上で質問した阿呆?
520デフォルトの名無しさん:2008/03/07(金) 07:14:11
>>517
if〜else〜if って何だ?
521デフォルトの名無しさん:2008/03/07(金) 11:18:09
if ()
{}
else if ()
{}
else
{}
のelse if か?
522デフォルトの名無しさん:2008/03/07(金) 15:14:52
enumの意味は大体分かるのですが、何のためにあるのかがいまいち分かりません。
どういう時にenumを使えば便利なのでしょうか?
523デフォルトの名無しさん:2008/03/07(金) 15:44:40
#define SUNDAY 0
#define MONDAY 1
#define TUESDAY 2
・・・
という時に
enum dayofweek_t { SUNDAY, MONDAY, TUESDAY, ..... };
と書けば短くて便利
524デフォルトの名無しさん:2008/03/07(金) 15:58:50
enum {baka, aho, manuke};
switch (getchar() - '0') {
case baka:
break;
case aho:
break;
case manuke:
break;
default:
break;
}
525TKN:2008/03/07(金) 16:03:45
SCC1010 "認識できない識別子 %n0 が発見されました"
そういうエラーを出るプログラムを教えていただけませんか。
526デフォルトの名無しさん:2008/03/07(金) 16:38:14
>>525
コンパイラでしょ。
527522:2008/03/07(金) 16:42:41
>>523 #define… が省略できるだけということですか?
528デフォルトの名無しさん:2008/03/07(金) 16:49:55
>>527
void func(enum dayofweek_t);
のように関数プロトタイプを書けば、1とか2といった無意味なint値ではなく
SUNDAY, MONDAY, .... のいずれかを渡すべきであることが明確になる
529522:2008/03/07(金) 16:54:33
>>528 わかりました!ありがとうございました。
530デフォルトの名無しさん:2008/03/07(金) 19:33:43
getchar()関数を用いてswitch文を実行したいのですが、まるで反応なしです、switch文。
文法上に誤りがあるのでしょうか?

while(1){
c = getchar();
if( c == EOF ){
break;
}

printf("文字\n");

switch(c){
case 'A':
case 'a':
printf("文字\n");
break;
case 'Z':
case 'z':
printf("文字\n");
break;
case 'X':
case 'x':
printf("文字\n");
break;
default:
printf("-------------------\n");
break;
}

if( mhp == 0 ){
printf("文字\n");
}
531530:2008/03/07(金) 19:35:45

”}”追加です。
532デフォルトの名無しさん:2008/03/07(金) 19:52:40
まるで反応無しの意味がわかりません。
533530:2008/03/07(金) 20:02:52
ごめんなさい。
入力待ちの状態になるのですが、エンターを押すと一番目のprintfの文字が実行されて(エンターを押す限り)、
switch文の処理にいきません。
534530:2008/03/07(金) 20:10:15
ただzを押すと、switch文の処理に移行するのですが、

============
文字@
Zの、文字B
文字@
============

↑が永遠に繰り返されます。
535530:2008/03/07(金) 20:11:39
#include <stdio.h>

int main(){

int i;
printf("文字\n");
printf("文字\n");
scanf("%d" , &i);
if( i == 1 ){
printf("文字\n");
536530:2008/03/07(金) 20:12:25
int hp,atk,mhp,c;

hp = 10;
atk = 1;

mhp = 20;

while(1){

c = getchar();
if( c == EOF ){
break;
}

printf("文字@\n");
537530:2008/03/07(金) 20:13:26
switch(c){
case 'A':
case 'a':
printf("文字A" , atk);
mhp -= atk;
break;
case 'Z':
case 'z':
printf("文字B\n");
break;
case 'X':
case 'x':
printf("文字C\n");
break;
default:
printf("-------------------\n");
break;
}

if( mhp == 0 ){
printf("文字D\n");
}
}


}else {
printf("文字E\n");
}
return 0;
}
538デフォルトの名無しさん:2008/03/08(土) 00:13:03
>>527
途中に値を追加したい場合、
#define だと番号ふり直す必要があるけど、
enum だと勝手に番号ふってくれるので便利。
539デフォルトの名無しさん:2008/03/08(土) 00:21:37
小心者です
ネット上にあるファイル(index.htmみたいな)を
ローカルに保存するプログラムを教えて頂けないでしょうか
540デフォルトの名無しさん:2008/03/08(土) 00:25:51
>>539
・ソケットを作成する
・サーバに接続する
・HTTPリクエストを送信する
・HTTPレスポンスを受信する
・データを受信する
・ローカルに保存する
・終了
541デフォルトの名無しさん:2008/03/08(土) 00:30:28
>>539
勉強用にCで書きたいとかなら、ソケットやらプロトコルやら勉強して>>540みたいに書かなくちゃならないけど、
そうでないなら、スクリプト系の言語を勧める。
C#やらJavaとかでも一発だけど。
542デフォルトの名無しさん:2008/03/08(土) 00:38:25
>>540
>>541
ありがとうございます
大変参考になりました
543デフォルトの名無しさん:2008/03/08(土) 03:08:54
#define SIZE 1024
のかわりに
enum { SIZE = 1024 };
とタグなしで書いているのを読みましたが、何かメリット/デメリットはあるのでしょうか?
544デフォルトの名無しさん:2008/03/08(土) 03:21:52
名前空間の汚染の度合いが抑えられる
545デフォルトの名無しさん:2008/03/08(土) 03:26:21
デバッグ時にシンボルが埋め込まれる
546デフォルトの名無しさん:2008/03/08(土) 05:00:58
#ifdef で定義チェックできない
547デフォルトの名無しさん:2008/03/08(土) 11:18:24
今独習Cをやってるんですけど解答に

// ファイル2をファイル1にコピー
while (!feof(f2)) {
ch = fgetc(f2);
if (!feof(f2))
   fputc(ch, f1);
}

と言うコードが含まれているのですが、なぜfeofが2回必要なのでしょうか?
while文の条件がf2がファイルの終わりではない
と言う条件なのになぜ、while文のなかでもう一度feofが必要なのでしょうか?
それとfgetcは、(ファイルから1文字読み込みその際、ファイル位置指示子を進めます。)
と説明に書いてあるんですが
ch = fgetc(f2); のところで、f2がファイルの終わりなったらf1に書き込まれないのでは?
548デフォルトの名無しさん:2008/03/08(土) 11:27:33
feof()なんて使ってるコード初めて見た
549デフォルトの名無しさん:2008/03/08(土) 11:48:30
feof()が妥当かどうかはこの際置いておくとして、
fgetc()してみないとfeof()かどうかは判らないのでfgetc()した後にもチェックは必要。
但し、普通はfgetc()の戻り値を使って判定するからわざわざfeof()を呼ぶようなコードを書く香具師は少ない。
そもそもそのサンプルの目的だけなら、これで事が足りる。
int ch; // 前提として敢えて明記
while ((ch = fgetc(f2)) != EOF) fputc(ch, f1);
550547:2008/03/08(土) 13:05:36
>>549
答えてくださりありがどうございます。
>fgetc()してみないとfeof()かどうかは判らないので

もしf2のファイル位置指示子が、最後の1文字を指していて
ch = fgetc(f2);でファイル位置指示子を進めたら、次のif()はfeof()が
ファイルの終わりになるので、if()文は、実行されない、と思っていたのですが
実行されているようなので、なぜ実行されるのでしょうか?
551デフォルトの名無しさん:2008/03/08(土) 13:20:18
だからぁ、feof()はファイルを調べることをしないで直前に行なった
(この場合はfgetc()の)結果を参照するだけなんだってばさ。
だから、余程の神経症で「fgetc()の結果を使ってEOFを判断するのは間違っている。
本来の意味的にfeof()を使うのが正しい」なんて思い込みのある人以外は使わないんだって。
552547:2008/03/08(土) 13:47:45
>>551
ありがとうございます。

>feof()はファイルを調べることをしないで直前に行なった
>この場合はfgetc()の)結果を参照するだけなんだってばさ。

これで理解できました。
553デフォルトの名無しさん:2008/03/08(土) 14:38:09
>>551
バイナリや非ASCIIテキストなどを扱わなければEOFでの判断でもいいけれど、
汎用性を考えればfeof()を使うべきでしょ。
554デフォルトの名無しさん:2008/03/08(土) 15:13:57
>>553
EOFは、何か負の値とされている。
一方、fgetcはEOFでなかったときに返す値は、
0から255 (正確にはUCHAR_MAX)。

だからバイナリファイルでも何でもEOF判定で絶対に問題ない。
そのためにfgetcはint型を返すのだから。
555デフォルトの名無しさん:2008/03/08(土) 15:57:54
何でchar型じゃなくてint型なんだろうと思ってたらそういう事だったのね
556デフォルトの名無しさん:2008/03/08(土) 16:06:56
独習Cの俺評価が急落した。読んだこと無いけど・・・
557デフォルトの名無しさん:2008/03/08(土) 16:37:13
そうか、feof()を使ううちの新人は独習Cで独習してたのか……
558デフォルトの名無しさん:2008/03/08(土) 17:34:46
manですらtest for end of file
とか書いてるんだし独習Cが悪いわけじゃないよ多分
ANSI Cが時代遅れのロートル言語って事なんだよ
559デフォルトの名無しさん:2008/03/08(土) 18:10:31
fgetc()はエラーでもファイル終わりでもEOFを返すけど、feof()は本当に終わりの時しか真を返さないから、
それだけでループの終了判定をしてると、エラーのときに無限ループになる。
560デフォルトの名無しさん:2008/03/09(日) 02:44:30
CUI=コンソールアプリケーション。
GUI=Windowsアプリケーション。

なんですか?
561デフォルトの名無しさん:2008/03/09(日) 02:45:57
いいえ。
562デフォルトの名無しさん:2008/03/09(日) 03:15:21
記号が「=」→「∈」なら、「はい。」ともいえなくもない。
563560:2008/03/09(日) 03:36:53
CUIでWindows.hをインクルードした場合、それはwindowsアプリではないんですか。
もうよくわかんね('д`)
564デフォルトの名無しさん:2008/03/09(日) 03:39:14
GUI=グラフィックユーザーインターフェース
CUI=キャラクターユーザーインターフェース
名前のまんまだ。
アプリ云々は二の次の話
565560:2008/03/09(日) 03:45:32
ありがとうございます。
助かりましたm(_ _)m
566デフォルトの名無しさん:2008/03/09(日) 09:20:34
>>563
CUIのウィンドウズアプリケーションだって存在しうる。
ウィンドウズでしか動作しないCUIアプリケーションがそういう存在。
567デフォルトの名無しさん:2008/03/09(日) 11:55:18
int max_of(const int vc[])
{
.................
}
const修飾子って配列の中身をいじくる動作がないときでも付けたほうがいいんですか???
568デフォルトの名無しさん:2008/03/09(日) 11:56:32
>>567
追加なんですが
constをつけたらコンパイラから警告がでるんですが
gccです
569デフォルトの名無しさん:2008/03/09(日) 12:06:20
>>567
これでどんな警告がでるの?
570デフォルトの名無しさん:2008/03/09(日) 16:17:07
constは「この関数内で値をいじらない」という意味でつける、紳士協定のようなもの。
実際にはいじれる。

モジュールを作る人=設計者
モジュールを使う人=プログラマ
と考えると分かる。

以下エスパー
... discards qualifiers from pointer target type
const付きの引数をほかのconstなしの引数を持つ関数に渡した場合出る。

void func2( int *a )
{
return;
}

void func( const int *a )
{
func2( a );

return;
}
571通りすがりのホゲホゲEX:2008/03/09(日) 16:47:30
572デフォルトの名無しさん:2008/03/09(日) 17:23:51
すみません、質問させてください
char *p="abあかさcたな";と宣言したポインタpを使って
pが今指している1文字がワイド文字かそうでないかを判定し
最後の文字まで同様に判定したいのですがこういうのはできるんでしょうか?
573572:2008/03/09(日) 18:11:12
質問した後に解決できました、ごめんなさい
574デフォルトの名無しさん:2008/03/09(日) 20:18:25
>>570
それってCだと警告ですむんだっけ?
エラーかと思ってた。
575デフォルトの名無しさん:2008/03/09(日) 21:53:51
すみません。
VC++2008を使用しているのですが、コンソールAPIを記述し実行するにはどうしたら良いでしょうか?
576デフォルトの名無しさん:2008/03/09(日) 22:02:40
>>575
コンソール系のAPIってAllocConsole()とかあのあたりの?
使ったことないけど、ほかのAPIが使える状態なら、コンソール系のAPIも普通に使えそうだけど。
577デフォルトの名無しさん:2008/03/09(日) 22:26:19
578デフォルトの名無しさん:2008/03/09(日) 22:32:51
初心者な質問ですみません。
ヘッダを作成する際に、変数ではなく、関数を呼び出しする時にexternをつける理由を教えてください。

extern AtoI()などです。

変数の時につける理由はわかるんですが、関数につける理由がいまいちわかりません…。
579デフォルトの名無しさん:2008/03/09(日) 22:42:05
変数と同じ理由だよ

「どこかにある(定義されている)関数を使いますよ」
という宣言
580デフォルトの名無しさん:2008/03/09(日) 22:42:57
ちなみに関数はdefaultでexternなので付ける必要はない
581デフォルトの名無しさん:2008/03/09(日) 22:49:47
>>579
ありがとうございます。やっと謎が解けました。
582デフォルトの名無しさん:2008/03/10(月) 01:24:32
数学の知識はどの程度必要なんでしょうか?
(C言語プログラミング)
583デフォルトの名無しさん:2008/03/10(月) 01:28:46
繰り上がりのある足し算くらいは出来たほうがいい。
584デフォルトの名無しさん:2008/03/10(月) 01:33:23
>>582
分数の、加減乗除、約分、方程式の、移項、多角形の、内角の、和、九九、あげたら、きりが、ありません
585デフォルトの名無しさん:2008/03/10(月) 01:35:32
何がやりたいかによるとしか
586デフォルトの名無しさん:2008/03/10(月) 02:07:48
上がっているほとんどが算数である事実。
587デフォルトの名無しさん:2008/03/10(月) 04:01:41
>>582
「日本語を学ぶのに、漢字の知識は度の程度必要か」以上に意味がない質問になっている。
Cで数学の諸問題を解くならば高等数学の知識が必要になるが、
事務処理的なプログラムを作るだけなら算数程度の知識で充分。

まぁ、必要なら都度学べばいいしね。
588582:2008/03/10(月) 15:35:55
ありがとうございます。
必要に応じて勉強します。
すみません。
589デフォルトの名無しさん:2008/03/10(月) 18:46:53
MS-DOS上で Lattice C ver 3.2を使いプログラミングしたいのですが分からない事があります。

.cのファイルをコンパイルし .objのファイルを作る所まではできました。

次に、リンカを使い実行ファイルを作る所なのですが、リンカをどう使っていいのか分かりません。

よろしくお願いします。
590デフォルトの名無しさん:2008/03/10(月) 19:04:12
link -? で出ないか?
普通は環境変数ちゃんとしてたら、objファイル名並べるだけでいけそうだが。
591デフォルトの名無しさん:2008/03/10(月) 20:15:17
>>590
でないんです><

objファイル名書いただけでは、実行ファイルは作成されますが、実行してもエラーになります。
592デフォルトの名無しさん:2008/03/10(月) 20:26:34
それはプログラムがバグっているか、環境が合っていないかじゃないのか?
593デフォルトの名無しさん:2008/03/10(月) 21:23:23
何かライブラリが必要なのかな?
594デフォルトの名無しさん:2008/03/10(月) 21:26:21
とりあえず Hello プログラムが動けばプログラムの問題。
あるいは、その程度では顕在化しないようなバグがコンパイラかリンカに存在するか・・・だな。
595デフォルトの名無しさん:2008/03/10(月) 23:55:36
英小文字をgetsで標準入力より配列テーブルへ入力する。
入力されたデータの個数と共に配列の先頭アドレスを関数英大文字変換に渡す
英大文字に変換されたデータをprintfで標準出力に出力する。
ただし、入力するデータの戸数は最大10個までとする。

入力の時の表示はstr=とする
出力の時の表示はSTR=XXX......Xとする


これどう書けばいいのでしょうか?参考書を読んでも全然わからないです
596デフォルトの名無しさん:2008/03/11(火) 00:10:05
>>595
宿題は宿題スレへ。
そうでないなら真面目に勉強しましょう。
597デフォルトの名無しさん:2008/03/11(火) 09:11:07
Libxml2(2.6.31)のxmlNewTextReaderFilenameで、URLの指定で失敗します。
対処方法の判る方いますでしょうか?

やりたい事は、C言語で、外部のXMLファイルを読み込んで、タグの要素(title等)を取り出したいだけです。
phpの「file_get_contents」のような、サーバーのファイルを取得するような関数はありますでしょうか?


1:成功
 http://*****/search_api?kw=APPLE&type=all
2:失敗(リンゴをUTF8でエンコード)
 http://*****/search_api?kw=%E3%83%AA%E3%83%B3%E3%82%B4&type=all

reader = xmlNewTextReaderFilename(uri);
で、uriが半角英数字で成功し、文字列で失敗(NULL)が返ってきます。

ブラウザのURL欄に打ち込んだ場合は、どちらも表示されます。
598デフォルトの名無しさん:2008/03/11(火) 09:48:46
>>597
どう見ても、入門向けの質問ではないしlibxml2とやらの仕様に関わる問題なので
xml関連のスレへどうぞ。
つーか、単にそのライブラリが所謂%エスケープ文字列に対応してないんでないの?
ブラウザみたいになんでもありなものと較べちゃかわいそうだよ。
599598:2008/03/11(火) 10:04:24
先週からCをやる羽目になりまして、初心者です。
libxml2は下記を参考にしてみたんですが,,
ttp://opentechpress.jp/desktop/03/10/07/1427238.shtml

引き続き (o*。_。)oペコッ
600デフォルトの名無しさん:2008/03/11(火) 13:47:54
質問させてください

ある関数の引数としてprintf()と同じ書式指定付き文字列と複数の変数を取って
その関数内部のprintf()に引数をそのまま渡してprintf()と同じ出力にしたいのですが
こういう場合の引数の指定法やprintf()への渡し方はどうすればいいのでしょうか?
601デフォルトの名無しさん:2008/03/11(火) 13:51:16
>>600
va_start
vprintf
602デフォルトの名無しさん:2008/03/11(火) 13:58:31
>>601
ありがとう、助かりました
603デフォルトの名無しさん:2008/03/11(火) 21:01:13
>>599
やる羽目になった張本人に聞けばいいんじゃないの?
少なくとも、>598を読んで対処方法が何も思いつかないなら聞くだけ無駄かと。
604デフォルトの名無しさん:2008/03/11(火) 21:14:01
動的確保をやらないでファイルが以下のような感じであって。

例えば2次元配列なら
x y
1 2
3 4
5 6

num[x][y]として確保するにはどうすればいいでしょうか。
プログラムの関係で、動的配列は使えなくて
一度読み込みを行うと時間が掛かってしまいます。
x yはファイルによって様々です。

605デフォルトの名無しさん:2008/03/11(火) 21:15:30
>>604の場合ですが
上の3行の場合だと
num[6][7]が領域として必要となります。

num[2][3]のようにファイルに書かれていない領域は0で初期化して
メモリ上に存在するということで。
606デフォルトの名無しさん:2008/03/11(火) 21:20:07
>>604
「動的確保しないで、動的に確保するにはどうしたらいいですか」と聞かれても困ります。
607デフォルトの名無しさん:2008/03/11(火) 21:24:38
>プログラムの関係で、動的配列は使えなくて
どんな関係だ?授業上の制限とかか?
608デフォルトの名無しさん:2008/03/11(火) 21:34:56
vectorで確保していたのですが
num[2][3]のような空の値をちゃんと空としてくれなかったので
使う関数の関係で空のところを指定しないと破綻してしまうのです
これまでは

ファイル一時読み込み
値の最大値分を確保
ファイルポインタを先頭へ
確保した領域に順次代入

という手順を踏んでいたのですが
これだと行数が莫大になったときに、読み込みだけで時間がひどく掛かってしまい。
609デフォルトの名無しさん:2008/03/11(火) 21:42:07
>>608
どうしたって2スキャン掛かるものは掛かるからねぇ。
処で、「空」と言うのはどういう状態を指しているの?
そのnumとやらの宣言がどうなっているのか知りたいのだが。
# つーか、>606-607は無視かYO!
610デフォルトの名無しさん:2008/03/11(火) 21:47:24
2スキャンを、スキャンしないようにするのはキツイですか。
2スキャンであれば簡単なので問題ないのですが……

すんません、無視したわけではないのですが。

授業とは違います。

空の状態は0初期化がベストですが、intのゴミが入っていても構いません

numはint型で、ファイルの値に準じて幅が変わる配列です。
現状はvector(int)のような一次元配列で確保していってます。
611デフォルトの名無しさん:2008/03/11(火) 21:51:02
vector<vector<int>>でいいんじゃね?
読み取ってsize調べて小さければreserveして・・・
二次元になっててややこしいけどできなくはないよ。
612デフォルトの名無しさん:2008/03/11(火) 21:55:08
× vector<vector<int>>
○ vector<vector<int> >

なんだが、次期規格では >> が許容されて、
さらに gcc がこの前 >> に対応したみたいだな。
613デフォルトの名無しさん:2008/03/11(火) 22:03:06
一次元でもアクセスするときはnum[][]で大丈夫だと思っていたのですが


if( (int)num.size() < temp[0] + temp[1]*maxValue[0]){
num.resize( temp[0] + temp[1]*maxValue[0]);
num[ temp[0] + temp[1]*maxValue[0] -1 ] = POINT;
}
else
num[ temp[0] + temp[1]*maxValue[0] - 1 ] = POINT;

値を入れる個所はこのようになっています。POINTはとりあえず値が入っている状態です。

temp[0] temp[1] に読み込んだ値が入っていて
numは二次元配列を一次元配列として扱ってアクセスするようにしています。
これだと0のときにエラーが出たり、よくわからないところでvectorが値を確保しなかったり
関数に送ると望まない結果がでてしまっています。
614デフォルトの名無しさん:2008/03/11(火) 22:03:46
すみません、1行目は何か変なこと書いてました。
615デフォルトの名無しさん:2008/03/11(火) 22:08:07
temp[0] + temp[1]*maxValue[0] ばっかで目が痛い。
一時変数にでもいれとこうぜ。
616デフォルトの名無しさん:2008/03/11(火) 22:31:25
xの最大値が決まらない内にvectorにアクセスしたいなら、
offset = (x + y) * (x + y + 1) / 2 + yでアクセスすればOK。
つーか、vectorのreserveにもこのoffsetが使える。
617デフォルトの名無しさん:2008/03/11(火) 22:32:15
ちょっと待て、ここはCスレじゃないのか?w
618デフォルトの名無しさん:2008/03/11(火) 22:38:26
たしかにw>>608でいきなりvectorが出てきてからおかしくなったなw
619デフォルトの名無しさん:2008/03/11(火) 22:39:13
>>616
その使い方だとどうなるか教えていただけませんか?
offsetを使ったソースを描いたことが無くて

>>617
確かにそのとおりでした。ほんとすみません
620デフォルトの名無しさん:2008/03/11(火) 23:04:42
>>619
そもそもこちらの解釈があっているか判らんので確認。
--
ファイルにはxとyが各行に記録されていて、(0, 0) から(xMax, yMax)までを収容できる配列が欲しい。
Cでは可変長の多次元配列を扱えないから、
・一次元配列の、ポインタ配列(vector<vector<int> >に相当)
・仮想的に一次元の配列(vecotr<int>に相当)
のどちらかで扱うことになる。

前者は、順次必要なだけ確保することはそれほど難しくないし、アクセスは容易。
但し、長さの異なる配列へのポインタ配列と言う構造から長さの等しい配列へのポインタ配列への変換コストが掛かる。
# でないと、ファイル内に書かれていない座標に相当する空間が得られない恐れが出てくる。
これを避けるには、事前にxMaxが確定している必要がある。

後者は、xMaxが確定していれば確保することは容易だが、アクセスにはオフセット計算が必要。
勿論、ファイルを全部読むことなしにxMaxを確定することはできない。
--
ここで、xMax, yMaxを確定するには一旦ファイルを全部読むことになるから避けたいと言う要求が発生。
どうすればいいか、と言うのが問題。

先程の方針では、どちらも都合がよくない。そこで、xMax, yMaxに拠らないアクセス方法と確保手段があればいい。
その為には、後者のオフセット計算においてxMaxに依存しない形でオフセットを計算できればいいということになる。
上記のオフセット計算は、次のように番号を振ることに相当する。
y座標↓x座標→0  1  2  3  4
0          0  1  2  3  4
1          5  6  7  8  9
2         10 11 12 13 14
3         15 16 17 18 19
4         20 21 22 23 24
これを次のように振ることにすればいい。
……
おっと、余白がないので詳細は割愛。
621デフォルトの名無しさん:2008/03/11(火) 23:16:10
三角行列はサイズによらないインデクシングが行える。
行列全体を上三角行列と下三角行列の2つに分けて扱えば
行列全体もサイズによらないインデクシングが行える。
これを使えば1パスで読み込めるし、
インデクシングもそれほど大変じゃなく行えるよ。
622デフォルトの名無しさん:2008/03/11(火) 23:23:37
例えば下三角行列で考えるとする。
んで、こういう風にインデクシングする。

* 0 1 2 3 : j
0 0
1 1 2
2 3 4 5
3 6 7 8 9
i

この時、インデックスは i と j から次のようにして求められる。

(インデックス) = i * (i + 1) / 2 + j

j が 0 の時、そのインデックスはその上にある要素の数に等しい。
これは高校で習う簡単な和の公式(Σのやつ)で i (i + 1) / 2 と求まる。
あとはそれに j を足すだけ。
さて、>620の続き。
xMaxに依存しない番号の振り方はこう。
y座標↓x座標→ 0 . 1 . 2 . 3 . 4
0         . 0 . 1 . 3 . 6 10
1         . 2 . 4 . 7 11 16
2         . 5 . 8 12 17 23
3         . 9 13 18 24 31
4         14 19 25 32 40
この方式だと、番号即ちオフセットの計算式は先程書いたように(x + y) * (x + y + 1) + yになる。
これならば、各行を読み込んでxとyが確定した時点でそのときのxMax, yMaxと比較、
更新する必要があれば更新してメモリを再確保すればいい。
つまり、どの行を読み込んだ時点でもそのときの(0, 0)-(xMax, yMax)の空間は確保されていると言うこと。
# 勿論、xMax * yMax程度の無駄な空間が発生することにも要注意。
624デフォルトの名無しさん:2008/03/11(火) 23:29:58
>>623
インデックスの振り方が違う。
それだと 15, 20〜22, 26〜30 とかのインデックスが宙に浮く。
>>621-622 だとそういう宙に浮くインデックスが発生しない。
625デフォルトの名無しさん:2008/03/11(火) 23:36:15
具体的にコードを書くとこんな感じ。

#define SIZE 100
static int num1[SIZE * (SIZE + 1) / 2];
static int num2[SIZE * (SIZE - 1) / 2];

int get_value(size_t x, size_t y) {
 assert(x < SIZE && y < SIZE);
 if(x >= y) {
  return num1[x * (x + 1) / 2 + y];
 } else {
  return num2[y * (y - 1) / 2 + x];
 }
}

void set_value(size_t x, size_t y, int value) {
 assert(x < SIZE && y < SIZE);
 if(x >= y) {
  num1[x * (x + 1) / 2 + y] = value;
 } else {
  num2[y * (y - 1) / 2 + x] = value;
 }
}
626デフォルトの名無しさん:2008/03/11(火) 23:43:25
実装はこっちのが見通しいいかね。
アドレス欲しい事もあるだろうし。

int* get_address(size_t x, size_t y) {
 assert(x < SIZE && y < SIZE);
 if(x >= y) {
  return &num1[x * (x + 1) / 2 + y];
 } else {
  return &num2[y * (y - 1) / 2 + x];
 }
}

int get_value(size_t x, size_t y) {
 return *get_address(x, y);
}

void set_value(size_t x, size_t y, int value) {
 *get_address(x, y) = value;
}

/* 速度が気になる人用 */
/* C++ ならインライン関数でいいと思うが。 */
#define GET_VALUE(x, y) (*get_adderess((x), (y)))
#define SET_VALUE(x, y, value) (*get_adderess((x), (y)) = (value))
627デフォルトの名無しさん:2008/03/11(火) 23:47:03
そこでC99ですよ
628デフォルトの名無しさん:2008/03/11(火) 23:50:38
動的に確保しないとなると、
スタックサイズをよほど大きくするのでなければ、
巨大配列は静的変数にしなくてはいけないだろうな。
629デフォルトの名無しさん:2008/03/11(火) 23:52:53
set_value の戻り値の型が void だから SET_VALUE も void にした方がいいし、
GET_VALUE の値も右辺値にした方がいいな。

#define GET_VALUE(x, y) ((int)(*get_adderess((x), (y))))
#define SET_VALUE(x, y, value) ((void)(*get_adderess((x), (y)) = (value)))
630C言語初心者:2008/03/12(水) 10:57:10
void main(void)
{
JIKAN a, b, c;
printf("時1?");
scanf("%d", &a.ji);
printf("分1?");
scanf("%d", &a.fun);
printf("秒1?");
scanf("%d", &a.byo);
printf("\n");
printf("時2?");
scanf("%d", &b.ji);
printf("分2?");
scanf("%d", &b.fun);
printf("秒2?");
scanf("%d", &b.byo);
c = t_add(a,b);
printf("%d時%d分%d秒 + ", a.ji, a.fun,a.byo);
printf("%d時%d分%d秒 = ", b.ji, b.fun,b.byo);
 *2 「計算結果の表示の仕方」
}
JIKAN t_add(JIKAN x, JIKAN y)
{
JIKAN a;
a.byo = x.byo + y.byo;
*3 「時、分、秒の加算処理の仕方」
*4 「計算結果の返し方」
}
のプログラム構成の時、*1〜4のところに何と打てばいいかを教えてもらえませんか?


631デフォルトの名無しさん:2008/03/12(水) 12:56:02
>>630
>何と打てばいいか
//
632デフォルトの名無しさん:2008/03/12(水) 13:13:10
アクションゲームみたいなものをつくってみたいのですが、今までCでは計算系のこと
しかしてないので、絵の描き方・動かし方などどこから手をつけていいのか分かりません。
自分で描いたものを画面上で動かすには具体的にどうすればいいのでしょうか?
633デフォルトの名無しさん:2008/03/12(水) 13:28:27
>>632
具体的には、環境に依存するAPIを使ったり使わなかったり。
WindowsならWin32 APIとか、UNIXならXlibやSDLとか。
634デフォルトの名無しさん:2008/03/12(水) 14:31:44
現在main側で
CreateFile
GetFileSize
calloc(ファイル読み込み用バッファ)
ReadFile
という処理を行っているのですが
この処理を自作関数にして
main側から自作関数内のバッファにアクセスしたいのですが
どうすればできますか?
635デフォルトの名無しさん:2008/03/12(水) 14:35:11
>>634
自作関数からバッファへのポインタを返す

main:

char* buffer = myfunc();
...
free(buffer); /*不要になったら消す */

myfunc():
...
char* buffer = calloc(...)
...

return buffer

636デフォルトの名無しさん:2008/03/12(水) 15:29:03
>>635
ありがとうございます。
637デフォルトの名無しさん:2008/03/12(水) 15:30:11
>>632
単にゲーム作りたいだけならD言語とかでやってみたら?
バイナリ吐けるし、GCあるし、言語機能とか段違い。ついでに文法もCに似てる。
638デフォルトの名無しさん:2008/03/12(水) 15:33:35
char * buffer = calloc(...)
639デフォルトの名無しさん:2008/03/12(水) 16:13:20
>>637
いくら似ているとは言え、別の言語なんだから、
ライブラリのこととD言語のことを同時に学ぶことになり、
大変だと思うんだけど。
640デフォルトの名無しさん:2008/03/12(水) 16:18:39
まあ、DはCの標準ライブラリ全部つかえるけどな
641デフォルトの名無しさん:2008/03/12(水) 16:50:22
>>639
そりゃまあそうだけどゲーム作るんならDでやっておいた方が後々楽だろうと思ってな
Cだとプログラムでかくなればなるほどしんどくなるだろ
642デフォルトの名無しさん:2008/03/12(水) 16:55:05
無難にC++でいいよ。
最新バージョンのDMDでコンパイル通るまともなライブラリがない。
643デフォルトの名無しさん:2008/03/12(水) 17:08:08
Visual C++ 2005を使っていて気づいたんですが
*str="aiueo";

str[]="aiueo";
では、
str[]のほうは文字列をいじれるのに対して、
*strだと文字列いじれないんですね。
以前はいじれた気がしたんですが・・・。
644デフォルトの名無しさん:2008/03/12(水) 17:11:43
環境によってはいじれることもあるけど、危険なのでいじらない方がいい。
645デフォルトの名無しさん:2008/03/12(水) 17:13:31
ということはVC++2005では*strで文字列扱うのはもう推奨していないというかダメということですね?
646デフォルトの名無しさん:2008/03/12(水) 17:16:02
デバッグのときに混合表示で見てみるとわかる
647デフォルトの名無しさん:2008/03/12(水) 17:16:43
連投すみません。
C/C++ではそういう操作が出来るのがいいところだったのに
ガチガチに縛られ始めてなんか悲しい。
648デフォルトの名無しさん:2008/03/12(水) 17:18:12
全然ダメじゃないんだが、

>*str="aiueo";
>と
>str[]="aiueo";

の違いはちゃんと理解してるか?
前者はメモリ上のどこかに"aiueo"という文字列を置いて、strにそのポインタを代入する。
後者は"aiueo"で初期化された配列を確保する。
649デフォルトの名無しさん:2008/03/12(水) 17:18:27
>>643
*str="aiueo";
"aiueo"という文字列定数へのポインタがstrに入っている。
"aiueo"という文字列定数がどこに置かれるかはコンパイラ次第
コード領域で書き込み不可のところにあるかもしれないし、組み込みだとROMかもしれない

str[]="aiueo";
strという配列をスタック(staticならスタック以外のデータ領域)に作製し、"aiueo"という要素で初期化。
スタックまたはデータ領域なので書き換え可能。
650デフォルトの名無しさん:2008/03/12(水) 17:26:47
>>648>>649
*str="aiueo";とstr[]="aiueo";の違いは分かっているつもりなのですが、
以前は出来たものが出来なくなって不便を感じたんです。
でも安全面のことを考えたら使えないほうがよさそうなので
これからはstr[]="aiueo";を使っていこうと思います。
ありがとうございました。
651デフォルトの名無しさん:2008/03/12(水) 17:27:46
以前は出来たってなんだよ。
出来ないことを無理やりやって偶然うまく動いてただけだろ。
652デフォルトの名無しさん:2008/03/12(水) 17:30:41
>*str="aiueo";とstr[]="aiueo";の違いは分かっているつもりなのですが、
分かってるつもりで分かってない。

>以前は出来たものが出来なくなって不便を感じたんです。
分かってたらこの台詞はでてこない。

ポインタと配列は初心者のうちはどうしても混同する。
恥ずかしいことじゃないからもう一度入門書読んでおいで。
653デフォルトの名無しさん:2008/03/12(水) 17:31:10
>>650
常にstr[]を使う必要はないんだぞ。文字列を書き換えたいときだけ
str[]にすればいい。
10年以上Cを書いてるけど、配列を文字列定数で初期化する機会はほとん
どなかった。
654デフォルトの名無しさん:2008/03/12(水) 17:41:12
C言語なつかしす
655デフォルトの名無しさん:2008/03/12(水) 18:02:54
>>650
わかっているなら文字列「定数」を書き換えようと思わないはずだ。
656デフォルトの名無しさん:2008/03/12(水) 18:07:49
>>647
規格としてはC89のときから駄目になっている。

あと、これには/GFオプション(同一文字列を1つにまとめる)のような
最適化が可能という利点もある。
657デフォルトの名無しさん:2008/03/12(水) 21:04:54
マ板から来ました。
>OOスレ8 なぜオブジェクト指向は普及しないのか
>ttp://pc11.2ch.net/test/read.cgi/prog/1201610928/
にとても変な自称LinuxのCマスター(笑)のコテハンがいます。
よければ見て笑ってやってください。

できれば、引き取ってください。
658デフォルトの名無しさん:2008/03/12(水) 21:06:47
>>630
JIKAN t_add(JIKAN x, JIKAN y)
{
JIKAN a;
//*3 「時、分、秒の加算処理の仕方」
a.byo = x.byo + y.byo;
a.fun = x.fun + y.fun;
a.ji = x.ji + y.ji;
a.fun += a.byo / 60;
a.byo %= 60;
a.ji += a.fun / 60;
a.fun %= 60;
a.ji %= 24;

//*4 「計算結果の返し方」a.byo = x.byo + y.byo;
return a;
}

// *2 「計算結果の表示の仕方」
printf("%d時%d分%d秒\n", c.ji, c.fun, c.byo);
659デフォルトの名無しさん:2008/03/12(水) 23:27:25
すんまそん・・・下の図形ってコマンドプロンプトでどうやって表示させるんでしょうか・・・?
for文を使って書く問題で、入力した数字で深さを決定するんですが・・・

入力:4
出力:        
             *
            * *
           *   *
          *******

今は入力4なので、縦の長さが*4つ分になってます。マジでわからん・・俺はアホでした・・・
底の*は入力数をnとすると、2n-1になるから一番最後に表示すればいいかなと思ったんですが・・ここまでで思考停止してます・・・
660デフォルトの名無しさん:2008/03/12(水) 23:28:23
>>659
Cじゃなくて算数の質問ならスレ違いですよw
661デフォルトの名無しさん:2008/03/12(水) 23:28:56
おもいっきりズレてますすんません・・・ちゃんと表示されない・・・
*
* *
* *
******* こうかな・・・?
662デフォルトの名無しさん:2008/03/12(水) 23:29:27
すげー下らん質問ですが、
定期的に呼び出されるタイマー関数内で計算中の変数を保管しておいて、ゲームループで再び呼び出されたとき、
その続きから開始したいです。どうすればできますか?
お願いします。
663デフォルトの名無しさん:2008/03/12(水) 23:36:16
>>662
グローバル変数とかstaticにするとか。
664デフォルトの名無しさん:2008/03/12(水) 23:36:42
>>662
ファイバー
665デフォルトの名無しさん:2008/03/12(水) 23:54:22
>>661
空白を入れたいなら&nbsp;で入力したほうが
666デフォルトの名無しさん:2008/03/12(水) 23:55:21
662ですが、ありがとうございます。
667デフォルトの名無しさん:2008/03/13(木) 00:15:43
>>665
こんな機能が・・・どうもです
    *
  *  *
 *   *
********
668667:2008/03/13(木) 00:19:36
また間違った・・・・
http://www.u-gakugei.ac.jp/~miyadera/LECTURE/ElecBook2/ptech04.htm
ここの4-6なんですが・・・もう書き込みませんので、どうかやり方を教えてください・・・ウッウッ
669デフォルトの名無しさん:2008/03/13(木) 00:37:07
>>667
高さが4のとき、最下段は8個なのか?
面倒だから7個だと仮定して。
・最下行
*が7個
・その上の行
空白1個、*1個、空白3個、*1個
・その上の行
空白2個*1個空白1個
・最上行
空白3個、*1個

最上行をm=0として、以下順にインクリメントして最下行をm=n-1とする。
・m=0のとき、空白(n-1)個、*1個
・m>0且つm<n-1のとき、空白(n-m-1)個、*1個、空白2m-1個、*1個
・m=n-1のとき、*(2n-1)個

要は、こうなる。
for (int m = 0; m < n; ++m) {
for (int i = 0; i < n - m - 1; ++i) putchar(' ');
if (m == 0) {
putchar('*');
} else if (m < n - 1) {
putchar('*');
for (int i = 0; i < 2 * m - 1; ++i) putchar(' ');
putchar('*');
} else {
for (int i = 0; i < 2 * n - 1; ++i) putchar('*');
}
putchar('\n');
}
670デフォルトの名無しさん:2008/03/13(木) 00:41:19
かなり汚いけど・・・
int size = 7;// 自分で入力。
for ( int i = 0; i < size - 1; i++ ) {
for ( int j = 0; j < size - i - 1; j++ ) printf( " " );
printf( "*" );
for ( int j = 0; j < i* 2 - 1; j++ ) printf( " " );
if ( i > 0 ) printf( "*" );// 1行目は*1個なので出力させないためのif
printf( "\n" );
}
// 最後の行
for ( int i = 0; i < size * 2 - 1; i++ ) printf( "*" );
671デフォルトの名無しさん:2008/03/13(木) 00:56:25
シンプルに行こう。
-- // 変数名などは>669に準じた。
for (int m = 0; m < n - 1; ++m) {
printf("%*c", n - m, '*');
if (m > 0) {
printf("%*c", 2 * m, '*');
}
putchar('\n');
}
for (int i = 0; i < 2 * n - 1; ++i) putchar('*');
672デフォルトの名無しさん:2008/03/13(木) 01:09:21
現在やさしいCのP263でファイルの分割をやっているのですが
#include <stdio.h>
#include "myfunc.h"

int main(void)
{
int num1, num2, ans;

printf("1番目の整数を入力してください。\n");
scanf("%d", &num1);

printf("2番目の整数を入力してください。\n");
scanf("%d", &num2);

ans = max(num1, num2);

printf("最大値は%dです。\n", ans);

return 0;
}

を実行してもインクルードファイルmyfunc.hをオープンできないとエラーがでます。
以下myfunc.hファイルの内容

/* max関数の宣言 */
int max(int x, int y);

関数を定義したmyfunc.cファイルもあるのですがエラーいまいちよくわからず

まずオープンできないというエラーを解決したいのですが
なにがおかしいのでしょうか?
コンパイラはBorland C++ Compiler と CPadを使っています。
673デフォルトの名無しさん:2008/03/13(木) 01:14:19
ヘッダーに関数の中身も書けばいいよ
674デフォルトの名無しさん:2008/03/13(木) 01:18:12
>>671
printfとか長く使ってないとそういう仕様をド忘れしちゃうんだよね・・・
%の数と引数の数が合わない時点で?が出てしまったorz

>>672
パス関係の問題だと思う。
675デフォルトの名無しさん:2008/03/13(木) 01:19:46
なんで一つのループに最初と最後も入れたがるのかね。
676デフォルトの名無しさん:2008/03/13(木) 01:23:12
>>673
まだよくわからないのですが
この後にその関数を定義したファイルのオブジェクトファイルと
上のmain関数が含まれているファイルのオブジェクトファイルをリンクして
1つのプログラムにするらしいので・・・

>>674
パス関係とはつまりどういうことなのでしょうか
677667:2008/03/13(木) 01:25:32
すげええええええええええええええ

なるほど!!!みなさんマジでありがとうございました!!
アホには思いもつきませんでした・・・・さっき自分でやってたら、変数がいっぱいになってわけわかんなくなりました(((´・Д・)))

内側の空白がn-m-1コとか、式がぜんぜん思いつきませんです・・・。やっぱセンスですか。。。

678672:2008/03/13(木) 01:26:35
すいません、自己解決しました。
ファイル名だと思っていた.hというのが拡張子だったことに気づきました・・・
ヘッダファイル==.hのファイルということですね
まぬけな落ちですいません。
こたえてくれた方ありがとうございました
679デフォルトの名無しさん:2008/03/13(木) 01:31:25
>>678
includeするファイルは別に.hに限らない。.tbl/.data/.txtなんでもかまわない。
バイナリは無理な気がするがテキストならまず問題ない。
単純にincludeはその位置にファイルを展開する(コピペしたのと同じ)と思っていい。

規格まで確認したわけじゃないし、.h以外のincludeを認めないコンパイラもあるとは思う。
680672:2008/03/13(木) 01:47:23
>>679
なるほど、自分は.h.cとかいうマヌケなことをしてました。

2つのオブジェクトファイルをリンクするので詰まってしまいました。
Borlandとかでぐぐってるけどイマイチわからない
素直に本のとうりにVC++2005しとくべきだったか\(^o^)/
681デフォルトの名無しさん:2008/03/13(木) 01:55:13
リンカとかに慣れておくのはいいことだと思うよ。
borland持ってないけどこことか参考にならないかな?もう見てたら失礼。
http://www.ics.kagoshima-u.ac.jp/edu/proen1c/memo/bcc32.html
682デフォルトの名無しさん:2008/03/13(木) 01:57:40
main.c と 〜.h を同じフォルダに置いてincludeするだけでできるとおもうが
683672:2008/03/13(木) 02:11:49
>>681
目を通したことならあります、ありがとうございます。

>>682
mainのファイルの#includeにヘッダファイルの他に
関数を定義したファイルの.cを追加したらできました。
なんとなくわかってきた・・・かも
アホな質問ばっかですいません、ありがとうございました。
684デフォルトの名無しさん:2008/03/13(木) 02:19:19
>>677
いや、申し訳ないがセンスの問題じゃない。
センスがなくても>669の前半のように実際に調べてそれに当て嵌めるだけ。
ちなみに、n-m-1は左側の空白の個数だ。
これも、最上段(m=0)のときにn-1必要であることが判れば難しくないだろう。

尤も、>677で間違えるようなそういうミスを排除する注意力をセンスと言うかは別の問題だが。
685667:2008/03/13(木) 03:09:27
グホッ間違ってました・・・すみまそん
これから頑張ります。今日は寝ないです
686デフォルトの名無しさん:2008/03/13(木) 09:39:15
つまり、>>660ってこったな。
687デフォルトの名無しさん:2008/03/13(木) 09:45:58
>>677
思いつくんじゃない、計算するんだ。
100円と200円の商品買って税込みいくらになるか、って聞かれたら思いつきじゃなく計算するだろ?
688デフォルトの名無しさん:2008/03/13(木) 17:20:58
char a[]="(2+3)*3";

aの文字列を自動計算させてint型にしたいのですが、
どういう関数を使えばできますか?
689デフォルトの名無しさん:2008/03/13(木) 17:22:14
自分でそういうことする関数を作れ。
690デフォルトの名無しさん:2008/03/13(木) 17:24:20
一文字づつ解析するしかないんじゃね?
691デフォルトの名無しさん:2008/03/13(木) 17:28:27
回答ありがとうございます
作る方向でやってみます
692デフォルトの名無しさん:2008/03/13(木) 17:31:05
int calcString(const char * str)
{
char buf[strlen(str) + 25];
sprintf(buf, "awk 'BEGIN{print %s;}'", str);
FILE * fp = popen(buf, "r");
fgets(buf, sizeof(buf), fp);
fclose(fp);
return atoi(buf);
}
693デフォルトの名無しさん:2008/03/13(木) 18:39:17
694デフォルトの名無しさん:2008/03/14(金) 00:28:12
//アルキメデスの円周近似

#include<stdio.h>
#include<math.h>

int main(void)
{
int i;
long double a[100],b[100];
a[0]=4.0*sqrt(3.0);
b[0]=6.0;

for(i=0;i<99;i++)
{
a[i+1]=2*a[i]*b[i]/(a[i]+b[i]);
b[i+1]=sqrt(b[i]*a[i+1]);

printf("6X2^%d角形を用いた近似値:%Lf~%Lf\n",
i,b[i+1]/2,a[i+1]/2);
}
return 0;

}
桁数が足りなくなるのですがどう修正すればいいですか?
695デフォルトの名無しさん:2008/03/14(金) 00:52:04
%.20fとかにする。とはいっても結局すこし進めば結果は同じだけど
俺の環境じゃ「6X2^24角形を用いた近似値」あたり以降は同じ結果になった。
696デフォルトの名無しさん:2008/03/14(金) 02:53:16
C言語ならって一年くらいになるものです
少し大きめのプログラムを作っていて、いくつか線形リストを作ることになったのですが
構造体ごとに線形リストの関数を作るのはどうも綺麗じゃないので
線形リストを作る関数一つで各構造体の線形リストを作成したいと思っているのですが
そういったことは可能なのでしょうか?
697デフォルトの名無しさん:2008/03/14(金) 02:55:33
void*を使って、ユーザ側で適当にキャストさせるとか、
マクロでジェネリックプログラミングするとか。
698デフォルトの名無しさん:2008/03/14(金) 03:01:47
要素はvoid*にして、リストを管理する関数を共通にする。
リストの要素に関する関数を外出しにする。
(生成、廃棄、参照など)
699デフォルトの名無しさん:2008/03/14(金) 03:10:10
>>694
Windows/VC++だとlong doubleとdoubleの精度は同じ
15,6桁が上限

それ以上を望むならdoubleを使わないで、自前で整数の配列を用意して
それで計算する。

ちょっと面倒。
700デフォルトの名無しさん:2008/03/14(金) 03:18:11
>>696
C言語だとそれぞれの構造体ごとに関数作るしかないね
C++なら話は別
701デフォルトの名無しさん:2008/03/14(金) 03:22:20
>>700
いや、>>697さんのいう「void *」でおk

struct list {
struct list *next;
void* data; <-ここにぶら下げる
};
702デフォルトの名無しさん:2008/03/14(金) 04:42:41
>>694
これでn=30まで出るが。
--
int main()
{
const long double eps = 3e-19;
long double p = 2 * sqrtl(3);
long double q = 3;
for (int n = 1; p - q > eps; ++n) {
printf("n = %2d: %22.20Lf, %22.20Lf, %22.20Lf\n", n, p, q, (p + q) / 2);
long double r = 1 / p + 1 / q;
p = 2 / r;
q = sqrtl(p * q);
}
printf("%.20Lf\n", p);
return 0;
}
--
sqrtl()のない環境なら、sqrt()の結果を初期値にニュートン法でsqrtl()を実装すればいい。
要は、long doubleで計算するなら平方根も同じ精度が必要と言うことと、
n=100まで求めたいのならそれなりの他倍長演算を実装する必要があるということ。
703デフォルトの名無しさん:2008/03/14(金) 07:18:22
>>701
可変長構造体でもいいかな。
二重にメモリ確保しなくていいし。
704デフォルトの名無しさん:2008/03/14(金) 08:20:26
>>701>>703
PC上だろ?
unionじゃダメなん?
705デフォルトの名無しさん:2008/03/14(金) 08:46:08
>>704

それだと汎用的に作れない。
用途が特定だったらいいけど。
>>701 のやり方が一般的だと思う。
706デフォルトの名無しさん:2008/03/14(金) 14:42:34
また質問しにきました・・・・
http://www.u-gakugei.ac.jp/~miyadera/LECTURE/ElecBook2/ptech06.htm
ここの4−11で、
/* 34 */ for (i = 0; i < n; i = i + 1)
/* 35 */ {
/* 36 */ k = i;
/* 37 */ for (j = i+1; j < n; j = j + 1)
/* 38 */ if(s[j] < s[k])
/* 39 */ k = j;
/* 40 */ dummy = s[i];
/* 41 */ s[i] = s[k];
/* 42 */ s[k] = dummy;
/* 43 */ }
ってあるんですが、理解できないです・・・

@まずi=0番目のときに、そこの配列に格納された値とj=i+1からj++としていって、そのj番目の配列で最小値を見つけたら入れ替えると思うんですが、
 if(s[j] < s[k])←ここで判断してるんでしょうか?これは最小値ではなく、大小しかわからないと思うのです(おいらが間違ってるんでしょうけど・・・)

Ak=i として、さらに k=jとしてますが、このくだりがまったく理解でしましぇん・・・
 このkは何の役割なんでしょうか?kを消して、iとjに書き換えて実行したら変な結果になるんで、これもおいらが間違ってるんでしょうけど・・
 /* 38 */ if(s[j] < s[i])
/* 40 */ dummy = s[i];
/* 41 */ s[i] = s[j];
/* 42 */ s[j] = dummy;
/* 43 */ }

詰まってます・・・どなたか教えてクダシャイ・・・・




707デフォルトの名無しさん:2008/03/14(金) 14:46:25
変数名が最悪だなw
708デフォルトの名無しさん:2008/03/14(金) 14:48:09
/* 37 */ for (j = i+1; j < n; j = j + 1)
/* 38 */ if(s[j] < s[k])
/* 39 */ k = j;

これでforループワンセット。
{}でくくれば分かりやすいのに、不親切なコードだね。

for (j = i+1; j < n; j = j + 1)
{
   if(s[j] < s[k])
   {
      k = j;
   }
}

つまりこういうこと。
jをi+1からn-1まで動かして、s[k]より小さいのが見つかったらそれを新たなs[k]にする。
ループを抜けたときはs[i+1]からs[n-1]の中で最小のものがs[k]になってる。
709デフォルトの名無しさん:2008/03/14(金) 15:00:41
kっていうのはiからn-1までの中で最も小さい数が入ってる番目。

まず仮にi番目を最小と仮定する。
k=i

次に一つずつ大きさを比較して、より小さいものがあればkにその番目を入れる。
for(j=i+1; j<n; j++) if(s[j]<s[k]) k = j;

n-1まで比べ終わったら、i番目と最小の位置を入れ替える。
dummy = s[i];
s[i] = s[k];
s[k] = dummy;

これを繰り返すことで配列が小さい順に並ぶ。
710デフォルトの名無しさん:2008/03/14(金) 15:03:16
読みやすさよりサイズ優先の人ってたまにいるよね
711デフォルトの名無しさん:2008/03/14(金) 15:42:46
ぬおおおおおおおおおお!!!なるほど!!!理解できました!!
みなさんどうもです!!!
712サッカー:2008/03/14(金) 16:29:40
助けてください。
c言語の文字列ソートで
char * month[]={"january" ,"february", "march","april","may","june","july"}
をアルファベット順に大文字に変えてソートするやり方
がわかりません。教えてください。今日までなので時間がありません。
お願いします。
713デフォルトの名無しさん:2008/03/14(金) 16:33:45
宿題は宿題スレへ
714サッカー:2008/03/14(金) 16:44:09
教えてください。
本当にわからない。
お願いします。
715デフォルトの名無しさん:2008/03/14(金) 16:46:23
>>714
スレの探し方もわからんのかよ

C/C++の宿題を片付けます 104代目
http://pc11.2ch.net/test/read.cgi/tech/1202135539/l50
716 ◆nUWYoBn0RQ :2008/03/14(金) 16:53:02
今日はじめてやったから・・・。
ありがとうございます。
717デフォルトの名無しさん:2008/03/14(金) 17:32:04
今日はじめてでトリップ付けてるってどういうことだよw
718サッカー:2008/03/14(金) 17:42:21
トリップって#のこと?
宿題スレに書いてあったから付けてみた〜。
あと宿題スレ返事来ないよ
どーしよー。
719696:2008/03/14(金) 19:45:16
皆さんどうもありがとう、まだ少し理解してない部分もありますが参考書片手にがんばってみます。
ありがとうございましたorz
720デフォルトの名無しさん:2008/03/15(土) 00:50:59
>>702
>n=100まで求めたいのならそれなりの他倍長演算を実装する必要があるということ。
今はスキル不足で無理なのでいつかリトライしてみます
721デフォルトの名無しさん:2008/03/15(土) 01:11:43
>>720
速度を求めないならニュートン法とかFFTとか使わない単純な多倍長演算でも可能
最近のPCなら1000桁くらいならあっというま。
722デフォルトの名無しさん:2008/03/15(土) 02:05:32
作りもしないで言うだけなら簡単だよな。
平方根関数をニュートン法使わないで実装する方が面倒だっての。
723デフォルトの名無しさん:2008/03/16(日) 07:55:07
すごく初心者な質問なんですけど
たとえば5秒間何もしないで待つと「a」、その間に何かキーを押すと「b」を出力するのってどうやるんでしょうか?
724デフォルトの名無しさん:2008/03/16(日) 08:12:24
>>723
環境依存の方法に頼るしかないんじゃないかな。
たとえばUNIXならselectやpollを使う。
725デフォルトの名無しさん:2008/03/16(日) 09:00:38
>>723
環境による。
非同期型のイベント駆動型のプログラムにするか、ループでキー入力を監視する同期型のにするかでも違う。

ループでキー入力を監視する方式でkbhit関数が使える環境ならばこんな感じ。

time_t start_time, current_time;
int anykey_pressed = 0;

time(&start_time);
current_time = start_time;
while (difftime(current_time, start_time) < 5) {
  if (kbhit()) {
    getch();
    anykey_pressed = 1;
    break;
  }
  time(¤t_time);
} }
printf("%s\n", anykey_pressed? "b": "a");
726デフォルトの名無しさん:2008/03/16(日) 12:00:18
>>724,>>725
ありがとうございましたm(_ _)m
727デフォルトの名無しさん:2008/03/16(日) 15:05:17
Cのソースが10個 → 1つのDLL

にするにはどうしたらいいのですか?バッチファイル使うので
すか?
makefileですか? WDKをつかって buildでしょうか?
お願いします。DLLが作れません。
728デフォルトの名無しさん:2008/03/16(日) 15:07:56
>>727
一個のファイルならDLL作れるのか?
729デフォルトの名無しさん:2008/03/16(日) 15:10:21
catでくっつけてコンパイルする
730デフォルトの名無しさん:2008/03/16(日) 15:17:21
まずコンパイラのマニュアルを読みましょう
731デフォルトの名無しさん:2008/03/16(日) 15:20:00
aを底とするxの対数を求めたいんですが、log()とlog10()しか見つかりませんでした。
aを自由に決めれる関数はないのでしょうか?
もしくは、log()やlog10()をつかって簡単にだせるんでしょうか?
教えてください。
732デフォルトの名無しさん:2008/03/16(日) 15:22:06
自作すればおk
733デフォルトの名無しさん:2008/03/16(日) 15:24:44
>>731
log(x)/log(a)
734デフォルトの名無しさん:2008/03/16(日) 15:25:42
>>731
中卒?
735デフォルトの名無しさん:2008/03/16(日) 15:28:59
>>733
ありがとうございます。
>>734
超底辺大学卒です。
736デフォルトの名無しさん:2008/03/16(日) 15:32:53
対数の底の変換公式は高校数学必修ではなかったのか…
737デフォルトの名無しさん:2008/03/16(日) 15:39:22
そういやそんな公式あったな 普段 底はEだからあまりつかわないけど
738デフォルトの名無しさん:2008/03/16(日) 16:32:33
スクリーンセーバーを自作してみたいのですが、
その手助けになりそうなWebサイトとかないでしょうか?
739デフォルトの名無しさん:2008/03/16(日) 16:40:36
スクリーンセイバー C言語 でぐぐっとけ
740デフォルトの名無しさん:2008/03/16(日) 17:26:25
*so = calloc(ry
while((*so++ = *ptr++) != '?');
printf("%s",so)
動的に確保した領域に文字をコピーしたいのですが、
どうしたらできますか?
741デフォルトの名無しさん:2008/03/16(日) 17:28:37
最初の3行は何だ?
742デフォルトの名無しさん:2008/03/16(日) 17:49:50
calloc()の略してる部分が分からないってことかね。
743デフォルトの名無しさん:2008/03/16(日) 17:57:47
whileのところでコピー出来なくて、
原因がわかりません。
744デフォルトの名無しさん:2008/03/16(日) 18:04:43
わからないなら略さないで晒せよ
745デフォルトの名無しさん:2008/03/16(日) 18:19:38
>>743
'?' のところは、文字化けじゃなくて、ソースのまんまなの?
746デフォルトの名無しさん:2008/03/16(日) 18:31:18
まんまです。
747デフォルトの名無しさん:2008/03/16(日) 18:33:27
'?' は'\0'だね。

strdup() (もしくは _strdup())を使えば、一発で処理できるよ。 
748デフォルトの名無しさん:2008/03/16(日) 21:18:23
ん?文字列中の?までを確保した領域にコピるんじゃないの?
749デフォルトの名無しさん:2008/03/16(日) 21:24:01
cgi のパスを保存したいのかな?
750デフォルトの名無しさん:2008/03/16(日) 21:26:05
それならそれでsoの最後に\0を追加する必要があるんでない?
751デフォルトの名無しさん:2008/03/16(日) 21:40:51
const char* get_hoge(const char* str) {
 const char* end_str;
 size_t len;
 char* res;

 end_str = strchr(str, '?');
 if (end_str == NULL) {
  return NULL;
 }

 len = end_str - str;
 res = (char*)malloc(sizeof (char) * (len + 1));
 if (res == NULL) {
  return NULL;
 }

 memcpy(res, str, len);
 res[len] = '\0';
 return res;
}
752デフォルトの名無しさん:2008/03/16(日) 21:46:35
>>750
calloc()つかってるのは、それ省くためなんじゃないの?
753デフォルトの名無しさん:2008/03/16(日) 21:51:03
>>740
? 以降の長さを無視してよいならこれでもおk
so=strdup(ptr);
p=strchr(so, '?');
if(p!=NULL) *p='\0';
754デフォルトの名無しさん:2008/03/16(日) 22:06:55
ptr が書き換え可能な領域に存在するなら
一旦 '?' を '\0' に書き換えてから strdup して
後で元に戻すという手もあるが
あまりオススメしない。
755デフォルトの名無しさん:2008/03/16(日) 23:15:29
標準入力からオーバーフローを起こす危険性無しに文字列を
読み取る方法を考えているのですが、

for(i = 0; i <= sizeof(str)-2; i++){
cc = getchar();
if(cc == '\n'){
str[i] = '\0';
break;
}else{
str[i] = (char)cc;
}}
if(i == sizeof(str)-1){
str[i] = '\0';
}

↑と

fgets(str, sizeof(str), stdin);
p = strchr(str, '\n');
if(p == NULL){
str[sizeof(str)-1] = '\0';
}else if{
*p = '\0';
}

↑では、どちらの方が実行速度が速くなるのでしょうか?
756デフォルトの名無しさん:2008/03/16(日) 23:23:09
速度は実測が基本。でも下が速くなりそうだな・・・
757デフォルトの名無しさん:2008/03/16(日) 23:27:51
>>755
下のは、 p == NULL のときは、'\0'を入れる処理はいらないんじゃね?
758デフォルトの名無しさん:2008/03/16(日) 23:28:51
>>755

コンパイラが最適化を掛けるから、結局は実測しないとわからない。
環境によって違うこともあるだろう。
この場合は下が速そうな気がするけど。
759755:2008/03/16(日) 23:35:47
回答ありがとうございます。
みなさんがおっしゃってくれたように実測してみることにします。

>>757
そうでした。ありがとうございます。
760デフォルトの名無しさん:2008/03/17(月) 03:41:27
入力された文字列をMallocで確保した部分にコピーしたいと思っていますがうまく出来ません。
どうしたらいいでのでしょうか?

char line[100],*linep,*word;
int x;

linep=line;
gets(line);
while (*linep != '\0'){
x=x+1;
linep=linep+1;
};
printf("%d",x);
linep=line;
word=(char *)malloc(x+2);
do{
*word = *linep;
word=word+1;
linep=linep+1;
}while(*linep != '\0');
printf("%s",word);
最初はlineのサイズをSizeofで取って、mallocで空間を作ってstrcpyでコピーしていましたが、
それだと配列の最大サイズを使ってしまうので、なんとかして入力された文字列ちょうどのサイズで
入力内容を受け取りたいです。どうかご教授願います。
761デフォルトの名無しさん:2008/03/17(月) 03:45:41
>>760
x初期化してないってことは・・ないよねぇ・・やっぱ
762デフォルトの名無しさん:2008/03/17(月) 04:02:02
>>760
あ、すいません。書いてませんでしたが初期化はしてあります。
763デフォルトの名無しさん:2008/03/17(月) 04:13:53
>>760
printfで使う時のwordって
末尾指してないか?
764デフォルトの名無しさん:2008/03/17(月) 04:16:19
gets(line);
x=strlen(line);
word=(char*)malloc(x+1);
strcpy(word,line);
みたいな流れじゃないの?
765デフォルトの名無しさん:2008/03/17(月) 04:29:58
>>763
仰るとおり、末尾を指してました・・・
通りでprintfで(null)って表示されるわけだ・・・

>>764
お書きいただいた方法でやってみたら、アッサリ出来ちゃいました


お二方ともありがとうございました!
766デフォルトの名無しさん:2008/03/17(月) 05:36:57
C言語ソフトのインストールについての質問いいですか?


ただいま、無料のC言語のダウンロードに挑戦中なのですが、コマンドプロンプトの起動はどうしたらよろしいでしょうか?

cygwinをインストール中です。

C言語の開発の勉強をしようと思ってるのですがまだ入り口にも入れず。

現在状況
1.C言語って何ぞや?
2.初心者用の本数冊購入。
3.C言語開発にインストールしなければいけないソフトがあると判明。
4.インターネットよりcygwinをダウンロード
5. システムの環境変数を変更。
6.ウィンドウズパスの設定。
7.動作確認。コマンドプロンプトの起動←???の状態

あと、そのソフトがCドライブに入っているかどうかも心配。


767デフォルトの名無しさん:2008/03/17(月) 05:42:53
>>766
スタートメニューにcygwinのアイコンできてない?それをクリックしろ
768766:2008/03/17(月) 05:47:11
できていません。

ちなみに、使用環境は、ウィンドウズXPです。
769デフォルトの名無しさん:2008/03/17(月) 05:48:43
>>768
スタートメニューのアクセサリにあるかと
770766:2008/03/17(月) 06:06:13
766
ありましたありがとうございます。

すいません、続いてですが、参考書にCドライブのしたにcprogというフォルダを作成しそこを今回のプログラムを割く整数rのに使うこととします。
Cドライブのすぐ下にcprogというフォルダを作成してください。
とでたのですがどうすればよろしいでしょうか?
右クリックで新規作成のフォルダを作ろうと試みたのですが表示できませんでした。
771デフォルトの名無しさん:2008/03/17(月) 07:11:24
>>770
まず、この板で聞くのではなくwindowsの使い方そのものを勉強しろ
プログラミングの勉強は3年先だ
772デフォルトの名無しさん:2008/03/17(月) 07:28:38
>>765
というか誰か gets を使ってることに突っ込もうぜ!
773デフォルトの名無しさん:2008/03/17(月) 09:09:15
板違いだったらスマソ
C C# C++  この3つの中で一番良い言語はどれ?
774デフォルトの名無しさん:2008/03/17(月) 09:30:28
C
775デフォルトの名無しさん:2008/03/17(月) 09:31:19
>>773
「良い」の定義をだな
776デフォルトの名無しさん:2008/03/17(月) 10:16:53
>>773
鼬害ではないが、スレ違い。この板のスレ一覧をよく見たまえ。
777デフォルトの名無しさん:2008/03/17(月) 11:58:16
できました。
あともう少しで開発できると思うんですけどまだ分からないとこがあります。

現在状況
1.C言語って何ぞや?
2.初心者用の本数冊購入。
3.C言語開発にインストールしなければいけないソフトがあると判明。
4.インターネットよりcygwinをダウンロード
5. システムの環境変数を変更。
6.ウィンドウズパスの設定。
7.動作確認。コマンドプロンプトの起動←???の状態 解決 ありがとうございます。
8.C:¥ドライブにフォルダを作成する。意味が分からなかったんですけどC:の中にフォルダを作るということだったみたいです。
9.ソースファイルの作成。
10.メモ帳出現。
11.gccのコマンド入力中。←???

入力が正しいのか分かりませんが、出た文字がno input files
です。

フォルダできてないのかな?
C:直下にcppogのフォルダを作るというのをC:をクリック後新規で作りました。
でも一応フォルダの中にコマンドプロで出現したメモ帳はあるみたいです。

追伸ここで聞くことでなければどこで聞くべきか教えてください。

一応C言語をはじめるということでこの初心者の掲示板で聞いています。


778デフォルトの名無しさん:2008/03/17(月) 12:01:27
追記

参考書では、exeの実行ファイルができているとなっているのですが、私のは、.c
のままです、
779デフォルトの名無しさん:2008/03/17(月) 12:02:57
>>777
カレントディレクトリがあってるかな?

コマンドプロンプトでlsって入力して実行して作ったテキストがあるかどうか教えてくれ
780777:2008/03/17(月) 12:19:05
質問事項
C言語を始めるためにウィンドウズに開発言語用ソフトのインストールの方法。

ソフト名
cygwin

作業状況
4.インターネットよりcygwinをダウンロード
5. システムの環境変数を変更。
6.ウィンドウズパスの設定。
7.動作確認。コマンドプロンプトの起動←???の状態 解決 ありがとうございます。
8.C:¥ドライブにフォルダを作成する。意味が分からなかったんですけどC:の中にフォルダを作るということだったみたいです。
9.ソースファイルの作成。
10.メモ帳出現。

コマンドカレントでの入力

c:
cd \cprog
notepad p01-04-1.c  ←メモ帳出現
dir         ←ソースファイル.c確認参考書ではここまで一緒。
gcc-ansi-pedanic p01-04-1.c -o p01-01-1

入力後のメッセージgcc-ansi-pedanicは、内部コマンド、または外部コマンド、
操作可能なプログラム又バッチファイルとして認識されていません。
というメッセージです。

やり直して再度打ち込んだ後こなりました。
もしかして、最初のダウンロードからして失敗?
781デフォルトの名無しさん:2008/03/17(月) 12:21:08
>>780
gcc p01-04-1.c
とだけ打って
a.exe
ができればおk
782デフォルトの名無しさん:2008/03/17(月) 12:21:58
>>780
which gccと入力して実行した場合の結果はどうですか?

gcc -o p01-04-1.c p01-04-1
じゃないか?
783780:2008/03/17(月) 12:27:06
>>781
usr/lib/gcc/1686-pc-cygin/3.4.4./../../../と続きました。

>>782

/usrbic/gcc
です。
784デフォルトの名無しさん:2008/03/17(月) 12:41:01
>>783
gccは、エラーがなければだんまりなので、何か出たらそれはエラーだ
エラーメッセージは自分で打ったり略したりせずなるべくコピペしる (あまり多い場合は最初の数行くらい)
コマンドプロンプトを右クリックするとメニューが出るから範囲指定を選んで、左ボタンでびろーっと範囲を選択して、Enterキーを押す
で、ここに貼り付け
785783:2008/03/17(月) 12:46:09
貼り付けるのはエラーメッセージだけでいいですか?
全部貼り付けて何か問題ないですか?
ネットにどこまで公開しても大丈夫か分かりません。
一応シリアル等分からない範囲で貼り付けます。
シリアルのみ削除しました。
Microsoft Windows XP [Version 5.1.2600]
(C) Copyright 1985-2001 Microsoft Corp.

C:\Documents and Settings\NEC-PCuser>c:

C:\Documents and Settings\NEC-PCuser>cd \cprog

C:\cprog>notepad p01-04-1.c

C:\cprog>dir
ドライブ C のボリューム ラベルは Windows XP です
ボリューム シリアル番号は です

C:\cprog のディレクトリ

2008/03/17 12:16 <DIR> .
2008/03/17 12:16 <DIR> ..
2008/03/17 12:16 0 p01-04-1.c
1 個のファイル 0 バイト
2 個のディレクトリ 2,310,393,856 バイトの空き領域

786デフォルトの名無しさん:2008/03/17(月) 12:46:53
>gcc-ansi-pedanic
あなたには空白が足らないわ。
787783:2008/03/17(月) 12:48:14
続き
C:\cprog>which gcc
/usr/bin/gcc

C:\cprog>dir
ドライブ C のボリューム ラベルは Windows XP です
ボリューム シリアル番号は です

C:\cprog のディレクトリ

2008/03/17 12:23 <DIR> .
2008/03/17 12:23 <DIR> ..
2008/03/17 12:16 0 p01-04-1.c
1 個のファイル 0 バイト
2 個のディレクトリ 2,309,021,696 バイトの空き領域

C:\cprog>gcc p01-04-1.c
/usr/lib/gcc/i686-pc-cygwin/3.4.4/../../../libcygwin.a(libcmain.o):(.text+0xab)
undefined reference to `_WinMain@16'
collect2: ld returned 1 exit status

C:\cprog>gcc-ansi-pedanic p01-04-1.c -o p01-01-1
'gcc-ansi-pedanic' は、内部コマンドまたは外部コマンド、
操作可能なプログラムまたはバッチ ファイルとして認識されていません。
788783:2008/03/17(月) 12:54:36
Microsoft Windows XP [Version 5.1.2600]
(C) Copyright 1985-2001 Microsoft Corp.

C:\Documents and Settings\NEC-PCuser>c:

C:\Documents and Settings\NEC-PCuser>cd \cprog

C:\cprog>notepad p01-04-1.c

C:\cprog>gcc -ansi -pedanic p01-04-1.c -o p01-01-1
gcc: unrecognized option `-pedanic'
/usr/lib/gcc/i686-pc-cygwin/3.4.4/../../../libcygwin.a(libcmain.o):(.text+0xab):
undefined reference to `_WinMain@16'
collect2: ld returned 1 exit status

C:\cprog>




789デフォルトの名無しさん:2008/03/17(月) 12:57:14
で、なんでcygwinの使い方も判らない香具師のスレ違いの質問に付き合っているんだ?
790デフォルトの名無しさん:2008/03/17(月) 12:58:51
>>787
俺は cygwin じゃなくて mingw を使ってるんだが
wmain を使うと同じようなエラーが出る(まだ解決していない)

d:/usr/mingw/bin/../lib/gcc/mingw32/3.4.2/../../../libmingw32.a(main.o)(.text+0x
104): In function `main':
d:/src/mingw/build/runtime/../../runtime/main.c:73: undefined reference to `WinM
ain@16'
collect2: ld returned 1 exit status

** error 1 ** deleting a.exe

とりあえず wmain または _tmain を main にしてみてはどうだろう
791783:2008/03/17(月) 12:58:58
dir抜けてますけど788の入力で行き詰っています。
792デフォルトの名無しさん:2008/03/17(月) 12:59:53
入門編てのはC言語に関してであって、
cygwinやコンパイラの使い方のわからん奴のスレじゃないぞ
793デフォルトの名無しさん:2008/03/17(月) 13:03:42
>>787
>2008/03/17 12:16 0 p01-04-1.c
>1 個のファイル 0 バイト

0バイト?
書いたプログラムの中身は?
794デフォルトの名無しさん:2008/03/17(月) 13:20:42
cygwinやコンパイラどころかメモ帳の使い方も分かってない板違いじゃないか
なんで熱心に付き合ってるんだ?
795デフォルトの名無しさん:2008/03/17(月) 13:25:29
保存してないというオチか…
よくあることだったのに、気づかなかったな

>>791
type p01-04-1.c
796デフォルトの名無しさん:2008/03/17(月) 15:24:09
C言語を習得するために
Visual Studio Professional Edition
買ったんですが最初は何をすればいいんでしょうか?
797デフォルトの名無しさん:2008/03/17(月) 15:26:44
わかりやすそうな本を買うもしくは借りる。
798デフォルトの名無しさん:2008/03/17(月) 15:54:55
>>796
ExpressEditionがあることを知り、無駄な買い物をした事に気付いて臍を噛む。
799デフォルトの名無しさん:2008/03/17(月) 17:04:16
よくわからないままC++/CLIで.NETアプリを作ってしまってスレに再び質問に来る
800デフォルトの名無しさん:2008/03/17(月) 17:10:39
800
801デフォルトの名無しさん:2008/03/17(月) 20:07:01
変数の型を調べる関数ってないですか?
802デフォルトの名無しさん:2008/03/17(月) 20:14:15
標準には無い
803801:2008/03/17(月) 20:25:14
ありがとうございます
他の方法考えてみます
804デフォルトの名無しさん:2008/03/17(月) 20:26:16
用途による。
宣言に使うとかならtypeof(非標準)
同型か比べるとかならtypeid(標準)
805デフォルトの名無しさん:2008/03/17(月) 20:26:52
>>804
typeidはC++
806デフォルトの名無しさん:2008/03/17(月) 21:50:24
Hello World!のC言語プログラムあってます?


#include<stdio.h>

main()
{
printf("hello\nword!\n");
}
807デフォルトの名無しさん:2008/03/17(月) 21:53:33
>>806
合ってるかどうかは実行してみれば分かる
808デフォルトの名無しさん:2008/03/17(月) 21:53:40
>>806
スペルミスがあるのとその main 関数の型は推奨できない
809デフォルトの名無しさん:2008/03/17(月) 22:22:07
>>806
hello word! のプログラムとしてなら、及第点です。
それはさておき、こう書きましょう。
--
#include <stdio.h>

int main()
{
printf("Hello world!\n");
return 0;
}
810デフォルトの名無しさん:2008/03/17(月) 22:27:59
>>808
K&Rもプログラミング言語C++も、Hello worldのmain()はその書き方。
811デフォルトの名無しさん:2008/03/17(月) 22:32:47
>>810
だから何?
812デフォルトの名無しさん:2008/03/17(月) 22:36:19
>>811
「それ、どうでもいいっていうか、むしろいらんツッコミだね」って意味。
813デフォルトの名無しさん:2008/03/17(月) 22:46:46
戻り値の型省略すると警告するコンパイラもあるから
省略しない方が鬱陶しくなくていい。
814デフォルトの名無しさん:2008/03/17(月) 22:56:19
C99だとエラーになった気がするし、
うっかりC++としてコンパイルすると絶対にエラーだし、
俺もあったほうがいいと思っている。
815デフォルトの名無しさん:2008/03/17(月) 22:59:29
逆だろ
816デフォルトの名無しさん:2008/03/17(月) 23:01:28
逆?
817デフォルトの名無しさん:2008/03/17(月) 23:14:15
K&Rにしたがっておけば間違いないよ。
818デフォルトの名無しさん:2008/03/17(月) 23:17:17
>>817
10年前ならね。しかし、最早その台詞は旧仮名遣いに固執するかの如く無意味だ。
819デフォルトの名無しさん:2008/03/17(月) 23:51:05
乱数の初期化にはどういう役割があるのですか?
820デフォルトの名無しさん:2008/03/17(月) 23:55:29
自分の思ったとおりの乱数を発生させたり、
自分の思ったとおりの乱数を発生させないようにしたりする役割がある。

いつも同じ値で初期化すれば、
(randの実装が同じなら)その後のrandが返す値はいつも同じ経過を辿る。
同じ結果を再現させることが可能になる。

time(0)の値を使うなどして、いつも異なる値で初期化すれば、
その後のrandの経過は毎回異なるものになる。
同じ経過ではランダムっぽくなくてつまんないときに役に立つ。
821デフォルトの名無しさん:2008/03/17(月) 23:56:45
>>819
発生させる乱数を初期化値によって変える。
822デフォルトの名無しさん:2008/03/18(火) 00:00:42
初期化を明示的に行わなかった場合、
毎回同じ値で初期化される。
そうなると毎回同じ乱数列しか出てこない。
それが嫌な時に初期化を行う。
823819:2008/03/18(火) 00:07:11
ありがとうございました。よく分かりました。
824806:2008/03/18(火) 00:14:59
C:\cprog のディレクトリ

2008/03/18 00:10 <DIR> .
2008/03/18 00:10 <DIR> ..
2008/03/18 00:10 12,941 p01-01-1.exe
2008/03/17 21:59 63 p01-04-1.c
2008/03/17 22:22 8,873 p01-04-1.exe
3 個のファイル 21,877 バイト
2 個のディレクトリ 2,216,493,056 バイトの空き領域

C:\cprog>p01-04-1
hello
word!

コマンドプロントでこう表示されたんですけどこれでOKですか?


825デフォルトの名無しさん:2008/03/18(火) 00:40:43
wordでええのやったら。
826デフォルトの名無しさん:2008/03/18(火) 00:44:44
OKかどうかは他人が判断できることじゃないだろう・・・
827デフォルトの名無しさん:2008/03/18(火) 05:35:11
符号なし掛け算のプログラムをしているのですが
unsigned int x,y;
unsigned long long z;
z = x * y;
で2^32-1までの値同士の計算が2^64-1まで扱えるはずの
zに正確に収まるのを期待したのですが。
たとえばx=28938y=2930866のときz=3209021684というように
違う値が返ってきます。どうしてでしょうか?
828デフォルトの名無しさん:2008/03/18(火) 05:38:53
出力は
printf("x=%u y=%u z=%llu"x,y,z);
としています。
829デフォルトの名無しさん:2008/03/18(火) 06:31:45
C言語(C++も可)で、ファイルをソートする方法はありますか?
メモリに載せてからソートするしかないですか?
たとえばサイズが1Gだとメモリを節約したい所です
830デフォルトの名無しさん:2008/03/18(火) 06:40:25
求めているのは外部ソートなんだろうけど、
そーゆーのはDBに放り込んで知らんぷりするのが正しい気もする
831デフォルトの名無しさん:2008/03/18(火) 06:53:27
>>827
unsigned int * unsigned int -> unsigned int
つまりすでにunsigned intで表現できる範囲を超えて
オーバーフローした値をunsigned long longに代入しても
時すでに遅しということ。期待通りの動作を得たいのなら
z = (unsigned long long)x * y;
とする。
832デフォルトの名無しさん:2008/03/18(火) 07:33:34
>>829

ソート、って何のソートだ?
833デフォルトの名無しさん:2008/03/18(火) 07:34:16
そのように突っ込まずに、そぉ〜っとしておいてやることさ、ふっ。
834デフォルトの名無しさん:2008/03/18(火) 07:44:52
>>833
おまいさんもそーとーな悪だな。
835デフォルトの名無しさん:2008/03/18(火) 07:48:12
初心者にオススメの参考書ってありますか?
836デフォルトの名無しさん:2008/03/18(火) 09:18:44
>>835
高橋麻奈の「やさしいC」
837デフォルトの名無しさん:2008/03/18(火) 09:45:38
>>836
(;´Д`)ハァハァ
838デフォルトの名無しさん:2008/03/18(火) 09:52:50
ttp://homepage3.nifty.com/~mana/index.html
ttp://homepage3.nifty.com/~mana/yasaci.html
何勘違いしてんだよ・・・って、俺もあっちを想像してたけど、検索して
本当に真面目なもので拍子抜けしたw
839デフォルトの名無しさん:2008/03/18(火) 10:17:58
>>829です
ソートは改行区切りの文字列をソートしたいです
vector<string>に読み込んでsortという手はファイルが大きいと難しいです
840デフォルトの名無しさん:2008/03/18(火) 10:22:09
>>839
multiset といいたいが C言語だから文字列の先頭アドレスの配列を qsort
841デフォルトの名無しさん:2008/03/18(火) 10:27:12
1ギガとか5ギガとか巨大ファイルでメモリは200mしか無い場合はどうすればいいですか?
あと別質問ですが、DOS時代に作成されたソートのEXEとASMファイルをみつけました。
ASMはどのようにコンパイルできますか?
842デフォルトの名無しさん:2008/03/18(火) 10:30:19
ASMはコンパイルするもんじゃないよ
843デフォルトの名無しさん:2008/03/18(火) 10:33:07
>>841
適当な大きさ(100MBとか)に区切って取り出しソートしたものを一時ファイルに書き出す。
それを繰り返していくつかの一時ファイル(ファイル名は連番にすると良い)を作り出す。
あとは↓と同じ方法でひとつのファイルにマージする。遅いがしかたない。
http://www.wdic.org/w/SCI/%E3%83%9E%E3%83%BC%E3%82%B8%E3%82%BD%E3%83%BC%E3%83%88
844デフォルトの名無しさん:2008/03/18(火) 10:36:41
出来たら、一度に巨大ファイルをソートしてくれるライブラリがあったら良いのですが・・ありませんか?
あと、C、C++ → ASM → EXE と変換されるはずですよね? だからASMのコンパイラも内蔵されていますよね? visual studioだとなんという名前ですか?
intel やBCCも教えてください
845デフォルトの名無しさん:2008/03/18(火) 10:41:58
マージソートのコツ教えてください。 データ数Nだとすると、各小分割は√Nにしたら速いですか?
半分くらいが良いですか? マージの手数を増やすか、各ソートの行程を増やすかですが
846デフォルトの名無しさん:2008/03/18(火) 11:03:42
自己解決しました  ml.exeでした 
847デフォルトの名無しさん:2008/03/18(火) 12:02:41
移動平均をCで書いたんだけどあってる?
static char digitalNum = 16; /* 移動平均回数 */
static unsigned long digitalBuf[16]; /* 移動平均用のバッファ */
long digitalFilter(unsigned long ad)
{
int i;
static char ct = 0;
static unsigned long tmp;

tmp = 0;
digitalBuf[ct++] = ad;
if(ct >= digitalNum){
ct = 0;
}
for(i = 0; i < digitalNum; i++){
tmp += digitalBuf[i] / digitalNum;
}
return tmp;
}




848デフォルトの名無しさん:2008/03/18(火) 18:09:10
>>847
合ってる

一要素に対しての移動平均しか求められないくてよければこれでもおk
#define BUFSIZE 16
long simple_moving_average(long value)
{
static long buf[BUFSIZE], sum;
static int bufindex;

sum-=buf[bufindex];
sum+=(buf[bufindex]=value);
bufindex=(bufindex+1)%BUFSIZE;

return sum/BUFSIZE;
}

下記のような構造体を作って関数に構造体のアドレスを渡してやるほうが後々楽かも
struct hoge
{
long *buf;
int bufsize, bufindex;
long sum;
};
849デフォルトの名無しさん:2008/03/18(火) 21:35:31
>>835

>>836の言っていた 高橋麻奈の「やさしいC」をやり終えたら

アラン・R. フューアー (著)の「Cパズルブック」をやってみてください
20年くらい前に出版された方でも、最近出版された方でもいいんで・・・・・
850デフォルトの名無しさん:2008/03/18(火) 22:07:09
メイクできないんですがこれはどこがおかしいでしょうか?

#include <stdio.h>

int main(void){
int a = 5;

if(a<10){
printf("under");
}
}
851デフォルトの名無しさん:2008/03/18(火) 22:11:44
>>850
ソースコードが無い
コンパイラがない
path の設定をしていない
make がない
makefile がない
makefile の書式が間違っている
makefile 内のファイル名が間違っている
unicode で保存した
その他
852デフォルトの名無しさん:2008/03/18(火) 22:12:06
>>850
>メイクできない
これ以上無いほど詳しく
853デフォルトの名無しさん:2008/03/18(火) 22:19:31
勉強の前に、プログラミングを学ぶ上での姿勢を教えていただけますか?
854デフォルトの名無しさん:2008/03/18(火) 22:19:53
>>853
背筋を伸ばす
855デフォルトの名無しさん:2008/03/18(火) 22:21:05
猫背がいけなかったんですね
856デフォルトの名無しさん:2008/03/18(火) 22:25:41
>>847
16個の合計がunsigned longの最大値を超えないなら、
割り算は合計を出してから最後に1回だけ行うべき。
処理速度と計算誤差の両面で損してるぞ。
857デフォルトの名無しさん:2008/03/18(火) 22:28:18
>>851-852

ごめんなさい最初から書き直したら出来ました
何が問題だったかはわかりません
ありがとうございました
858デフォルトの名無しさん:2008/03/19(水) 01:24:17
>>847
・移動平均回数は未だいいとして、なんでバッファまで公開しているの?
・移動平均回数をcharに制限する理由は? 只の整数定数ならint(或いはunsigned int)にするべき。
・adはunsigned longなのに戻り値はlongなのは何故?
・既出だけど、割り算は最後に行なうべき。
・tmpを静的にする理由は? 特に理由がないなら静的にしない方がいい。
859デフォルトの名無しさん:2008/03/19(水) 12:32:38
>>858
>>・既出だけど、割り算は最後に行なうべき。
これはオーバーフローがありえるのでこうしてます。

そのほかはまったくご指摘のとおりです。
860デフォルトの名無しさん:2008/03/19(水) 12:42:44
double で足して最後に割る
861デフォルトの名無しさん:2008/03/19(水) 14:06:32
グローバル変数で質問です
グローバル変数は初期化をしないと0で初期化される
この0って言うのは

int i;
char str1;
char str2[10][10];
int *p;

って言うグローバル変数を宣言した場合

i = 0;
str1 = '\0';
str2 = 全部 '\0';
p = NULL;

で初期化されるって言うことですか?
それともintとかdoubleなどの数値を扱う型しか0で初期化されない?
862デフォルトの名無しさん:2008/03/19(水) 14:14:13
>>861
>で初期化されるって言うことですか?

そーです
863861:2008/03/19(水) 14:56:34
>>862
ありがとうございます
スッキリしました
864デフォルトの名無しさん:2008/03/19(水) 19:04:35
p = NULL; ってところは意外に重要で、
ヌルポインタのビット表現が 0 じゃない状況でも
ちゃんと p はヌルポインタで初期化される。
浮動小数点数の 0 についても同様。

特殊な環境か状況じゃないとまず関係ない話かもしれないけどね。
865デフォルトの名無しさん:2008/03/19(水) 21:54:39
int *p = 0;
全然問題無い。

まぁ言いたいことはそう話じゃないのは分かってるケド。
866デフォルトの名無しさん:2008/03/19(水) 22:17:09
>>859
unsigned long longを使ってもdoubleを使ってでもまとめて割った方がいい。
極端な話、adが15ばかり16回連続して来たら15になるべき戻り値が0になってしまう。
867デフォルトの名無しさん:2008/03/19(水) 23:57:34
>>864
int *p = 0;
と書けば、コンパイラは賢いから
「ヌルポインタのビット表現が 0 じゃない状況でもちゃんと p はヌルポインタで初期化される。」
C++ では私はよくみかけるのですが。
868デフォルトの名無しさん:2008/03/20(木) 00:04:13
>>867
それで正しい
コンパイラが賢いというか、規定でもそうなってる
869デフォルトの名無しさん:2008/03/20(木) 00:04:33
>>867
>>864 は、グローバル変数が0クリアされるってのが、ポインタの場合はどうなるかって説明だろ。
870デフォルトの名無しさん:2008/03/20(木) 00:07:24
質問者はその違いをちゃんと理解してて>>861-863のやり取りですべてが終わってるように見えるんだけど。
871デフォルトの名無しさん:2008/03/20(木) 10:20:50
つまり理解してない人が勝手に盛り上がってると。
872デフォルトの名無しさん:2008/03/20(木) 12:04:47
質問です。

あるプログラムのヘッダーファイルを読んでいるのですが初めて見る書式なので、
その書式がどういう意味なのか理解できず、苦しんでいます。

ググってもそれらしいものが出てこなかったのでご教授頂ければ幸いです。


--- sample.h ---

struct smaple {
char hoge;
int fuga;
void *what;
}

#define sample_call(var1,var2,var3) \
struct sample sample1 = { \
var1, \
var2, \
(var3) \
} \

このようなマクロと構造体があったとして
var3を()で括るとどのように扱われるのでしょうか。

よろしくお願いいたします。
873デフォルトの名無しさん:2008/03/20(木) 12:28:42
この場合特に影響は無いと思うけど、
マクロの引数は基本的には
とりあえず括弧で囲んでおいた方がいいとは思う。
874872:2008/03/20(木) 12:37:09
>>873

ありがとうございます。
影響がある場合もあるということですね。
ありがとうございました。
875デフォルトの名無しさん:2008/03/20(木) 14:12:12
質問です。列挙定数を使用して文字に色をつけたいのです
printf("\033[0m\033[01;31mHellow\033[0m\n");
これでHellowが赤くなる、という手本があったので仮に組んでみました。

#include <stdio.h>
int main(void)
{
printf("\033[0m\033[01;31mHellow\033[0m\n");

return(0);
}

これをgcc cygdriverでコンパイルしたところ、
●[0m●[01;31mHellow●[0m   ●=エンターキーのような記号
と表示され、実際に色はつきませんでした。
ググってもみましたが、解説が見当たらなかったので書き込みました。
正しい記述を教えてください。
876デフォルトの名無しさん:2008/03/20(木) 14:43:36
ttp://www.kumei.ne.jp/c_lang/intro/no_58.htm
ウィンドウズ使ってるならprintfじゃ色つかないよ
877875:2008/03/20(木) 14:55:45
>>876
ありがとうございます。

補足ですが
cygでコンパイルをし、Hellowの色を変更できるようにせよ、とのことでした。
ですからcygのコンパイル画面だったら色が変わるはず・・・なんです。
878デフォルトの名無しさん:2008/03/20(木) 14:57:47
conio.hは?
879デフォルトの名無しさん:2008/03/20(木) 14:59:24
875のエスケープシーケンスはDOS由来のもので、
Win32のコンソールアプリケーションの場合、
9xのDOS窓なら(Cygwinでも)使えるが、NTでは使えない。
880875:2008/03/20(木) 15:09:39
>>878
ありがとうございます。
これは、<stdio.h>を<conio.h>にしろ、ということでしょうか?
一応今試してみましたが、結果は変わりませんでしたorz
881デフォルトの名無しさん:2008/03/20(木) 15:27:43
>>880
違うぞ、conio.hでぐぐってこい。色変えたりできる。環境依存だけど。
882デフォルトの名無しさん:2008/03/20(木) 15:46:22
telnetサーバたてて、teratermとかputtyとかでXPに
入る手はあるけど。cmd.exeが超絶使いにくい。
 poderosaには、cygwinコンソールを開くオプションが
あったはずだから使ってみるのも手
883デフォルトの名無しさん:2008/03/20(木) 16:15:49
本題とは全然関係ないけどHellowってHelloじゃないのか。
884デフォルトの名無しさん:2008/03/20(木) 16:17:06
ハローw
885デフォルトの名無しさん:2008/03/20(木) 18:12:29
ループ処理を、かなり長い時間(数十秒とか)待たせてから行いたいんですけど
なんかいい関数ないですか?
usleepで引数に10000000を与えるくらいしかないですか?
886デフォルトの名無しさん:2008/03/20(木) 18:13:36
sleepを複数回呼び出せばいいんじゃまいか?
887デフォルトの名無しさん:2008/03/20(木) 18:15:06
usleepでは困るという理由を挙げてくれないと代替案も出せない
888デフォルトの名無しさん:2008/03/20(木) 18:17:30
>>887
いや、大きい数字を使うのが何となく気持ち悪いんで
もっと適した関数が用意されてたりするのかなぁと思いまして

>>886
sleep自身をループさせる、と?
889デフォルトの名無しさん:2008/03/20(木) 18:18:20
というか数十秒ならsleep使えばいいんじゃナインか?
890デフォルトの名無しさん:2008/03/20(木) 18:21:55
つか、環境依存だろ。
891デフォルトの名無しさん:2008/03/20(木) 18:23:41
>>888
sleepの引数の単位はmsか?なら秒のラッパー関数でも作れば?
void mySleep( int second ) {
for( int i = 0; i < second; i++ ) {
sleep( 1000 );
}
}
892デフォルトの名無しさん:2008/03/20(木) 18:24:02
>>889
んぁあっ
usleepしか知らなかったっ sleepだと1秒単位なのか
ありがとうございます

ついでに本命のほうを聞きたいのですが、
基本的には無限ループさせておいて、
任意のタイミングのキーボード入力でループを抜けさせるって出来ますか?
893デフォルトの名無しさん:2008/03/20(木) 18:25:30
無限ループってなにか計算をさせるってことか?
スレッド使えば?
894デフォルトの名無しさん:2008/03/20(木) 18:25:39
環境によってはできる。
標準Cだけではできない。
895デフォルトの名無しさん:2008/03/20(木) 18:34:49
スレッド……?
ちょっと調べてみましたが難しそうだ……
ありがとうございました
896デフォルトの名無しさん:2008/03/20(木) 18:39:15
>>892
sleepはミリ秒単位だぞ。
897デフォルトの名無しさん:2008/03/20(木) 18:51:25
>>896
おいw
898デフォルトの名無しさん:2008/03/20(木) 18:53:35
ミリ秒単位はSleep()のほう、と言ってみるテスト。
899デフォルトの名無しさん:2008/03/20(木) 19:02:15
891にだまされるとこだった。
900デフォルトの名無しさん:2008/03/20(木) 20:14:24
C勉強中の僕に教えてください
キャストを勉強しているのですが、パーセントを求めるプログラムを作ってます。
DWORD Ad、DWORD Size、double parcent です。

parcent = (double)((Ad / Size)*100);

これだとAd、Sizeがどんな値だろうと、parcent に0.0しか表示されません。
この問題を解決するにはどうすればいいでしょうか?
ご教示お願いします
901デフォルトの名無しさん:2008/03/20(木) 20:17:15
それだとまず (Ad / Size)*100 がDWORD型で計算されて、最後にdouble型にキャストされる。
Ad / Size は端数切捨てで0だろうから、結果は0.0。

parcent = ((double)Ad / Size)*100);

これでおk。
902デフォルトの名無しさん:2008/03/20(木) 20:17:38
percent = (double)Ad / Size * 100;

とか

percent = Ad * 100.0 / Size;

とか色々。

Ad / Size が整数同士の割り算になってるのがいけない。
903デフォルトの名無しさん:2008/03/20(木) 20:23:56
>>901-902
素早いお返事ありがとうございます。
括弧をつける位置で結果が大きく変わるんですね。。
動作まで詳しく教えてくださり、本当にありがとうございました。勉強になりました。
904デフォルトの名無しさん:2008/03/20(木) 20:31:32
×parcent
○percent
905デフォルトの名無しさん:2008/03/20(木) 20:47:59
>>904
おっと・・ご指摘ありがとうございます
これは恥ずかしいです。直しておきます。^^;
906デフォルトの名無しさん:2008/03/21(金) 22:27:37
構造体で使う
->と.の違いはなんですか?
907デフォルトの名無しさん:2008/03/21(金) 22:32:23
>>906
struct table1 {
  int a;
  int b;
};
struct table1 *pl
strucy table1 tab

/* tabのaを参照する */
tab.a;

/* p1にtabのアドレスを代入して、tabのaを参照する */
p1 = &tab;
tab->a;
908907:2008/03/21(金) 22:34:44
まちがえた!

struct table1 {
  int a;
  int b;
};
struct table1 *p;
struct table1 tab;

/* tabのaを参照する */
tab.a;

/* pにtabのアドレスを代入して、tabのaを参照する */
p = &tab;
p->a;
909デフォルトの名無しさん:2008/03/21(金) 22:39:51
A->B = (*A).B
910デフォルトの名無しさん:2008/03/21(金) 22:41:30
struct ABCD {
int def;
}

struct ABCD abc;
struct ABCD* p_abc = &abc;

abc.def と p_abc->def と (*p_abc).defは同じ
911デフォルトの名無しさん:2008/03/21(金) 22:54:45
なんか入門書でも買った方がはやくね?
912デフォルトの名無しさん:2008/03/21(金) 23:05:10
なるほど、ありがとうございます。
続けて質問したいのですが、
struct mem{
char data[64];
}

dataの中に"abcdef"という文字列を入れる場合
.か->、どちらを使ったほうがいいですか?
913デフォルトの名無しさん:2008/03/21(金) 23:09:04
同じって上でいってるじゃん・・・
struct mem foo;
struct mem * bar = foo;
strcpy( foo.data, "abcdef" );
strcpy( bar->data, "abcdef" );
914デフォルトの名無しさん:2008/03/21(金) 23:09:06
>>912
説明がまったくわからなかっということですかw
915デフォルトの名無しさん:2008/03/21(金) 23:12:30
for文を使って一文字ずつ追加していく場合です。
916デフォルトの名無しさん:2008/03/21(金) 23:13:37
>>915
strcpyの時と変わらないよ
917デフォルトの名無しさん:2008/03/21(金) 23:17:04
そのものずばりのソースが書き込まれるまで頑張るつもりなんじゃね?
だれか書いてあげてよ。
918デフォルトの名無しさん:2008/03/21(金) 23:17:25
だからどっちでもいいと何度いったら・・・
struct mem foo;
struct mem * bar = foo;
const char hoge[] = "abcdef";
int i;
for( i = 0; i < strlen( hoge ); i++ ) {
foo.data[ i ] = hoge[ i ];
//上と同じ、同じって言ってるんだから同じ!
// bar->data[ i ] = hoge[ i ];
}
// ケツに\0ちゃんと入れるように
919デフォルトの名無しさん:2008/03/21(金) 23:33:55
代入の際、->と.
どちらの方が見やすいですか?
920デフォルトの名無しさん:2008/03/21(金) 23:37:21
>>919
質問!きみはどっちが見やすい?
921デフォルトの名無しさん:2008/03/21(金) 23:40:40
www
922デフォルトの名無しさん:2008/03/21(金) 23:41:27
bar->data[i] と (*bar).data[i] 、どっちが見やすいか、という質問か
せっかくだから俺は右を選ぶぜ!
923デフォルトの名無しさん:2008/03/21(金) 23:44:47
俺も右の方が見やすいとおもうから->のことは忘れた方がいいよ
924デフォルトの名無しさん:2008/03/21(金) 23:51:14
->なんて使わなくてもいいよ!
925デフォルトの名無しさん:2008/03/21(金) 23:53:12
キャストと見間違えそうだなw
926デフォルトの名無しさん:2008/03/21(金) 23:57:26
五重ポインタから参照するとき、
(****pp)->data[i] と (*****pp).data[i] では後者がわかりやすいよな!
927デフォルトの名無しさん:2008/03/22(土) 00:09:44
(*****ppppp).data[i]だろ
928デフォルトの名無しさん:2008/03/22(土) 00:26:24
これコンパイルすると終了しちゃうのはなぜでしょうか?

#include <stdio.h>
int main(void)
{
int pr, sum;
sum = pr = 0 ;
printf("買いたい商品の値段を入力してきださい\n");
scanf_s("%d",pr);
while ( pr != 0)
sum = sum + pr ;
printf("小計;",sum);
printf("税込み:%d", (int)(1.05*sum));
printf("次の商品の値段を入力してください\n");
scanf_s("%d", pr);
return 0;
}
929デフォルトの名無しさん:2008/03/22(土) 00:28:33
>>928
while ( pr != 0)
sum = sum + pr ;
930デフォルトの名無しさん:2008/03/22(土) 00:37:15
×scanf_s("%d",pr);
○scanf_s("%d", &pr);
931930:2008/03/22(土) 00:38:09
ごめん・・
932デフォルトの名無しさん:2008/03/22(土) 00:43:42
printf("買いたい商品の値段を入力してきださい\n");

printf("小計;",sum);
933デフォルトの名無しさん:2008/03/22(土) 00:44:32
どうせなら配列の参照も
a[i]→*(a+i)変換を…
934デフォルトの名無しさん:2008/03/22(土) 01:26:19
wikiからコピってきた再帰なんですが

int fact(int n) {
if (n==0)
return 1; /* 脱出条件。0!は1である */
else
return fact(n-1)*n; /* n!は(n-1)!にnを乗じたもの。再帰呼び出し */
}

elseのとき、なんで return fact(--n)*n; じゃダメなの?
935デフォルトの名無しさん:2008/03/22(土) 01:29:46
fact(--n)*(n+1)ならいけそうな気がするけどどういう順序で計算するのかわかんね
936デフォルトの名無しさん:2008/03/22(土) 01:34:02
>>934
その記法は未定義動作だからやっちゃだめなの
937デフォルトの名無しさん:2008/03/22(土) 01:35:59
938デフォルトの名無しさん:2008/03/22(土) 01:38:01
>>934
定義されていないからかな

a=3;
printf("%d %d\n", --a, a);
未定義!
939デフォルトの名無しさん:2008/03/22(土) 02:21:02
>>935-938
難しいけどありがとうございました!
940デフォルトの名無しさん:2008/03/22(土) 05:44:14
そもそもnの値を変更することに意味ないだろ
941デフォルトの名無しさん:2008/03/22(土) 09:32:11
ちょっと気になっただけなんだけど、
>fact(--n)*n
>printf("%d %d\n", --a, a);
不定じゃないっけ?
なんで未定義なのか教えて貰えると助かる。
未定義なら俺の理解が間違えてるので。
942デフォルトの名無しさん:2008/03/22(土) 09:49:49
>>941
規格で決まってないから未定義、それ以外に理由は無い

決まって無いから動作は不定
943デフォルトの名無しさん:2008/03/22(土) 10:02:57
不定という言葉が悪かったかな。

941で書いた式は未規定だと思うんだけどどう?
944デフォルトの名無しさん:2008/03/22(土) 10:20:40
副作用の完了前に参照することが未定義じゃなかったか?
945デフォルトの名無しさん:2008/03/22(土) 11:06:03
あー、なるほど。
追って調べてみたらその通りだった。
ありがとう。
946デフォルトの名無しさん:2008/03/22(土) 13:04:29
http://www.kouno.jp/home/c_faq/c11.html#33
>簡潔に説明する。実装により定義された動作とは、どう振る舞うかを 実装が選択して、その振る舞いを文書にすることを意味する。
>不定の 動作とは、どう振る舞うかを実装が選択しなければならないが文書に する必要はないことを意味する。
>未定義とは、本当にどんなことがお こっても不思議ではないことを意味する。

規格が「未定義」であるとしている例。
http://www.kouno.jp/home/c_faq/c3.html#0
947デフォルトの名無しさん:2008/03/22(土) 13:44:43
func(long *l){
*l = 10;

short s;
func((long *)&s);

エンディアン等の環境によらず、Cの規格でsは10になることは保証されますか?
最適化は行われない前提で。
よろしくお願いします。
948デフォルトの名無しさん:2008/03/22(土) 13:57:49
>947
なるわけがないというか、C の規格では未定義動作で何が起こっても OK。つまりやっちゃいけないコードだ。
が、仮に short と long が反対だったとして、その結果が変わってしまうことがエンディアンの違いってやつなのだが。
949デフォルトの名無しさん:2008/03/22(土) 13:59:07
short*からlong*へのキャストは定義されていないからUB
950947:2008/03/22(土) 14:14:21
すみません。間違いです。
longとshort逆でした。

この場合、リトルエンディアンな環境だと10になることが保証されている、
でよろしいでしょうか?
951デフォルトの名無しさん:2008/03/22(土) 14:22:52
>>950
メモリアドレスのアライメントの関係で、環境によってはアクセス違反が発生する。
よって規格の保証はないな。

> 最適化は行われない前提で。
そもそもこう書いているのは、実装依存上等ってことだろw
952950:2008/03/22(土) 14:33:59
あー、longとshortが逆ってことは、アライメントの件はクリアか。
前半は無視してね。
あとは、longの上位ワードも初期化してやればいけそうだが、規格上はどうだろ?
953デフォルトの名無しさん:2008/03/22(土) 14:40:15
>>952==951
すこし落ち着け。
954デフォルトの名無しさん:2008/03/22(土) 14:47:07
>>952
Cの規格では、あるポインタを他のポインタ型にキャストした場合の動作は定義されていない。
long*は汎用ポインタにしかキャストできない。
955デフォルトの名無しさん:2008/03/22(土) 14:49:57
mallocを否定するとは。とか言ってみる。
956デフォルトの名無しさん:2008/03/22(土) 14:50:27
汎用ポインタは除いてね。
957デフォルトの名無しさん:2008/03/22(土) 15:17:41
別ポインタへのキャストは未定義じゃなくて処理系定義なんじゃないの?
958デフォルトの名無しさん:2008/03/22(土) 15:58:48
#include<stdio.h>

int main(void)
{
int a=5;

printf("%d\n",-a);
return 0;
}
で-5が出力されるわけですがprintf("%d\n",-a);のaの前の-はaに-1をかけてるってことでいいんですよね?
959デフォルトの名無しさん:2008/03/22(土) 16:00:47
「a の符号を反転した値を取得する」 ということしか言っていない。
それを実際にかけ算で行っているか別の方法で行っているかは環境次第。
960デフォルトの名無しさん:2008/03/22(土) 16:04:48
>>959
わかりました
ありがとうございました
961デフォルトの名無しさん:2008/03/22(土) 16:14:08
Intel 系なら NEG って命令があってそれで符号反転できる。
962デフォルトの名無しさん:2008/03/22(土) 16:21:15
>>954
いや、定義されてるだろ。
オブジェクト型のポインタから他のオブジェクト型へのポインタへのキャストは出来る。
ただし正しく境界調整されていない場合の動作は未定義。
963デフォルトの名無しさん:2008/03/22(土) 22:32:58
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
FILE *fp1, *fp2;
double d;
int i;
if((fp1 = fopen("values", "wb"))==NULL) {
printf("ファイルを開くことができません\n");
exit(1);
}
if((fp2 = fopen("count", "wb"))==NULL) {
printf("ファイルを開くことができません\n");
exit(1);
}
d = 1.0;
for(i=0; d!=0.0 && i<32766; i++) {
printf("数字を入力してください(終了するには0を入力してください): ");
scanf("%lf", &d);
fwrite(&d, sizeof d, 1, fp1);
}
fwrite(&i, sizeof i, 1, fp2);
fclose(fp1);
fclose(fp2);
return 0;
}

数字を入力するたびにファイルに書き込むプログラムを作成ということなんですが、何故上書きされないのでしょうか?。入力した数字すべてがファイルに書き込まれる仕組みがわかりません。


964デフォルトの名無しさん:2008/03/22(土) 22:39:21
質問の意味が分からない
965デフォルトの名無しさん:2008/03/22(土) 22:43:12
fwrite()はそういう仕様です。
966デフォルトの名無しさん:2008/03/22(土) 22:43:41
ファイルポインタでググれ。
967デフォルトの名無しさん:2008/03/22(土) 22:47:19
>>964

初めに1.0と入力したとして次に2.0と入力したら前の1.0の値の上から書き込まないということなんでしょうか?。
質問の意味がわからなかったらすいません。

どう書いたらいいのだろう…。
968デフォルトの名無しさん:2008/03/22(土) 22:48:19
>>963
更新モードでオープンしていないから。
969デフォルトの名無しさん:2008/03/22(土) 22:51:57
>>967
ファイルポインタは書き込みをした分だけ自動的に先に進む
同じ場所に書き込みをするにはファイルポインタを移動する

ex.
fseek(fp, -4L, SEEK_CUR);
970デフォルトの名無しさん:2008/03/22(土) 22:52:13
>>965
ありがとうございます。
fwrite()を理解できて無いようです。

>>963
ポインタ難しい><。ポインタが理解できて無いようです。
971デフォルトの名無しさん:2008/03/22(土) 22:52:25
>>967
fseek()で、ファイルポインタを先頭にもどす。
972デフォルトの名無しさん:2008/03/22(土) 22:56:12
ファイルポインタとポインタは別物だぞ。
973デフォルトの名無しさん:2008/03/22(土) 23:00:16
たくさんの回答ありがとうございます。

>>968
更新モード知らないかもです。

>>969
そうなんですか。ファイルポインタを理解しないといけないみたいですね。

>>971
fseek()なんてあるんですか〜。

>>972
違うのですか〜。勉強になります
974デフォルトの名無しさん:2008/03/22(土) 23:37:05
次スレ立てました
C言語なら俺に聞け(入門篇) Part 26
http://pc11.2ch.net/test/read.cgi/tech/1206196600/
975デフォルトの名無しさん:2008/03/22(土) 23:41:58
一つ質問させてください

多次元配列についてなんですが
要素ごとに違う数の要素を持たせることって可能ですか?
たとえば、

A[0]には
A[0][0],
A[0][1]
があって

A[1]には
A[1][0],
A[1][1],
A[1][2]
があるみたいなです

分かりにくくてスマソ
976デフォルトの名無しさん:2008/03/22(土) 23:44:16
>>975
無理
977デフォルトの名無しさん:2008/03/22(土) 23:44:42
色々方法はあると思うが、動的に確保するのが一番分かりやすい実装法。
もちろん、1つの配列をそういう区間に切り分けて扱うこともできるけどね。
978デフォルトの名無しさん
>>976
>>977
レスどもです
参考にします