トップページ⇒tech
1001コメント252KB

C言語なら俺に聞け! Part 101

■ このスレッドは過去ログ倉庫に格納されています
0001v(^o^i)d05/01/31 08:37:54
まず問題を冷静に吟味してCの話か否かをはっきりさせてから質問しましょう。
質問する前には最低限検索を。

GUIなどの標準Cではできない事の質問は使用している開発環境のスレへGo! (←ここ注目)
ソース丸投げ、宿題、書籍 は専門の別スレがあるのでそこへさようなら。

エラー(警告含む)が起きたのならばエラーメッセージを書きましょう。

C FAQ 日本語訳
http://www.kouno.jp/home/c_faq/
Cプログラマ必読 ・プログラミング言語C(通称 K&R)
http://www.amazon.co.jp/exec/obidos/ASIN/4320026926/

各種リンク、関連スレは>>2-13あたり

C言語なら俺に聞け! Part 100
http://pc5.2ch.net/test/read.cgi/tech/1106403600/
他の過去ログはここに
http://nssearch.hp.infoseek.co.jp/clang/
0153デフォルトの名無しさん05/02/02 15:53:41
>>150>>152
助けるにしても情報が足りなさすぎです
0154デフォルトの名無しさん05/02/02 15:58:51
普通、OSは無言だが、隠さずに出せよ
0155デフォルトの名無しさん05/02/02 16:05:21
推薦書「OSは止まらない」
0156デフォルトの名無しさん05/02/02 16:09:20
でも、個別(カスタム)は知りません。だな
0157デフォルトの名無しさん05/02/02 16:12:16
>>150
似たことがあった。自分の場合、他のポインタで
メモリ破壊してるとこがあってそれを直すと解決した。
そんなことない?
0158デフォルトの名無しさん05/02/02 16:13:05
void fuc(){
FILE *fp;
char date[30];
strcpy(date,"a.txt");

fp=fopen(date,"r");

・・・

fclose(fp);

}

なんですが、、、
ファイルポインタを作りすぎると100個くらい?
エラーになるのですか?
0159デフォルトの名無しさん05/02/02 16:15:49
>>157
それは、既知だよ。ここに来るやつは。知ってるよw
016015705/02/02 16:20:20
>>159
これはすつれい。
0161デフォルトの名無しさん05/02/02 16:22:32
>>160
同じだ、何回メモリ暴走したことか、意味が無いな
0162デフォルトの名無しさん05/02/02 16:28:07
>>158
ファイルポインタを作りすぎるとって、一般的に100もファイルを開けるOSは少ないと思うのだけど。
ファイルポインタがエラーでNULLになるんでない?
0163デフォルトの名無しさん05/02/02 16:32:55
いや、どこまでOSを信用できるかだ、というか
OSに同化できるかだ
0164デフォルトの名無しさん05/02/02 16:36:14
>>162
100個くらいで大丈夫よ、安心して、
0165デフォルトの名無しさん05/02/02 16:41:30
ちなみにFOPEN_MAXなんて定数がある。
0166デフォルトの名無しさん05/02/02 16:53:59
難しい、結局、メモリ上限だな、FN_MAXが意味無いと同じだ、ウワーン
好きにやれよ
0167デフォルトの名無しさん05/02/02 18:01:00
念のためage
0168デフォルトの名無しさん05/02/02 18:01:11
構造体で次のようにやるとエラーがでるんですけど
struct A{
  int a;
  int b;
};
struct B{
A[10]; ←ここ
};
こういう使い方はできないんですか?
0169デフォルトの名無しさん05/02/02 18:04:34
>>168
struct B {
  struct A a[10];
};
「struct A」はあくまでも型名。
0170デフォルトの名無しさん05/02/02 19:02:38
struct A{
  int a;
  int b;
};
struct B{
A A[10]; ←ここ
};
コレなら作れる
0171デフォルトの名無しさん05/02/02 19:08:18
>>169-170
あ、そういえばそうだった・・・
なんか勘違いしてた・・・アリガトンゴザイマス
0172デフォルトの名無しさん05/02/02 20:31:21
>>170
ここのスレタイをよく読め。
0173デフォルトの名無しさん05/02/02 20:46:25
質問です。

C言語では配列の添え字を宣言する際に2のべき乗を使うと
内部演算がビットシフトで表現され、処理が高速になる。

と聞いたのですが、これを的確に実験する方法はあるでしょうか?
0174デフォルトの名無しさん05/02/02 20:48:50
こんなの実験も何もないだろうが。
アセンブラに落とせ。
017517305/02/02 20:58:31
アセンブラに落とす、とはどういった作業のことでしょうか?
申し訳ないです。
0176デフォルトの名無しさん05/02/02 21:01:27
>>175
gcc -S hoge.c
0177デフォルトの名無しさん05/02/02 21:19:44
それは「C言語では」というより、「何か特定のコンパイラでは」だな。
017817305/02/02 21:25:41
>>174=176(?)
お礼を忘れていました。すいません。有難うございます。

っと、>>176の作業によってアセンブラソースが生成されました。
が、これのどこを見ればいいのかさっぱりわかりません。
アセンブラのソースは少しだけ意味がわかる程度でして・・・。

私が考えるに、実行速度の向上はわずかで、
非常に大きなプログラムを書いたときに影響が出てくるのかということ。
で、ちょこっとのプログラムでは向上を確認できないのではないかと。

なに言ってるかわかんなくなってきました。頭冷やしてきます。
0179デフォルトの名無しさん05/02/02 21:38:01
影響が出るか出ないかは、プログラムの大きさじゃなくて、
何回その部分を実行するかで決まる。

で、興味を持ったから試してみたけど、
gccだと全部シフトと加減算にしてしまってるように見えるな。
乗算にした方が速いケースってないんだろうか。
0180デフォルトの名無しさん05/02/02 21:39:46
>>178
>>176は私ですー にゃんにゃん
つまり、別人^^;

あのですね、掛算をするときは最適化されちゃってあまり効果がないかもですが、
割算の時は効果がでるかもですー。

例えば、こういうコードをコンパイルするとどうなるでしょうか。
(やってみてくださいね)
test3とtest4では最適化されて同じ(アセンブリ)コードになってしまうかもしれませんが、
test1とtest2ではたぶんtest2の方が長いコードになってしまうとおもいますー
int test1(int a) {
return a>>1;
}
int test2(int a) {
return a/2;
}
int test3(int a) {
return a<<1;
}
int test4(int a) {
return a*2;
}
0181デフォルトの名無しさん05/02/02 21:51:02
#include <stdio.h>
#include <stddef.h>

main(){
struct station{
int bango;
char *p_name;
struct station *pm;
};

struct station m1 = {1001, "tokyo" , NULL};
struct station m2 = {1002, "shinbashi", NULL};
struct station m3 = {1003, "shinagawa", NULL};
struct station m4 = {1004, "kawasaki" , NULL};
struct station m5 = {1005, "yokohama" , NULL};

struct staion *p_m1;

m1.pm = &m2; //次のデータを指すようにポインタを設定する
m2.pm = &m3;
m3.pm = &m4;
m4.pm = &m5;

printf("bango namae\n");
for(p_m1 = &m1;p_m1 != NULL;p_m1 = p_m1->pm) //ポインタの更新
printf("%4d %s\n", p_m1->bango, p_m1->p_name);
}
018217305/02/02 21:51:29
やってみました。
たしかに、test2のみ長いコードになりました。
シフト演算はたしかに高速であるということですよね?

・・・で、問題は配列の添え字が
・2のべき乗
・そうでない場合
この実行速度の比較なんですが・・・どう繋がるんでしょう・・

私はあほなんでしょーか。
018318105/02/02 21:52:00
↑動かん
何で?
0184デフォルトの名無しさん05/02/02 21:53:37
>>181=183
コンパイルエラーがでるの?
実行時エラーが出るの?
実行時エラーは出るけどまともな結果がでないの?
0185デフォルトの名無しさん05/02/02 21:56:20
エラー E2451 未定義のシンボル pm(関数 main )
エラー E2451 未定義のシンボル bango(関数 main )
エラー E2451 未定義のシンボル p_name(関数 main )


参考書の通りにやってるんだけどなー
018618105/02/02 21:57:06
>>184コンパイルエラーでつ
0187デフォルトの名無しさん05/02/02 21:59:59
>>182
配列の添え字って
char* p;
int i;
p[16*i] = 0;
ってのは
p+(16*i)なわけだから
p+(i << 4)
と表現できるでしょ
0188デフォルトの名無しさん05/02/02 22:00:42
別のスレに池
0189デフォルトの名無しさん05/02/02 22:04:11
シフト演算が高速なのは工程数より
レジスタがどういう処理行うかって問題じゃないかぁ…
明らかに加算するよりbitシフトのが速そうな気がするじゃん
0190デフォルトの名無しさん05/02/02 22:08:35
配列の要素をアクセスするのにシフト使う?

char image[256*256];
みたいなんだったらシフト&マスクで高速化できる場面もありそうだけど。
0191デフォルトの名無しさん05/02/02 22:14:39
>struct staion *p_m1;
0192デフォルトの名無しさん05/02/02 22:56:49
このコードは移植性がありますか?

#include <stdio.h>          
void f(int a);              
void f(int a)              
{                          
  printf("a = %d\n", a);    
}                          
                           
int main(void)              
{                          
  void (*x)(int, int);      
  x = (void (*)(int, int))f;
  x(1, 2);                  
  return 0;                
}                          
0193デフォルトの名無しさん05/02/02 23:02:16
ない
0194デフォルトの名無しさん05/02/02 23:11:40
嘘臭えアル
019517305/02/02 23:13:12
例えば、二次元配列を一次元で表現するとして
int a[16][16];
これを
int a[256];
ってやるってことで、要素(6,8)にアクセスするときに
a[6][8]
ってやるところを
a[0x68]
ってやったりはしてます。
この辺とは関係ないんでしょうか・・・。
0196デフォルトの名無しさん05/02/02 23:14:02
移植性って言っても対象が解からないと意味なし。
0197デフォルトの名無しさん05/02/02 23:14:49
>>195
それは関係ありませんよー にゃんにゃん
019817305/02/02 23:15:32
>>181
えっと、

struct staion *p_m1;
     ~~~~~~~
これはstationじゃないですか?
019917305/02/02 23:17:59
>>195
うー。ということは配列の添え字に2のべき乗を使う意味は
無いということなんでしょうか・・・?
0200デフォルトの名無しさん05/02/02 23:20:30
>>199
特別な使い方をしない限り、ない。
020117305/02/02 23:25:46
>>質問に答えてくれたみなさま
有難うございました!勉強になりました。

実は明日までにレポートを書き上げる必要があって、
てんやわんやです。

がんばります!それでは。
0202デフォルトの名無しさん05/02/02 23:51:03
>>197
その口調、やめてくれないか?
すごく気持ち悪い
0203デフォルトの名無しさん05/02/02 23:55:20
>202
確かに。
目の前にいて、かつ、不細工や奴が言ってたら、条件反射で顔面殴りそうだ。
0204デフォルトの名無しさん05/02/02 23:57:48
うるさいぼけー にゃんにゃん
0205デフォルトの名無しさん05/02/02 23:58:48
はきゅーん
0206デフォルトの名無しさん05/02/03 00:01:37
>>202
ひどいよー にゃんにゃん
0207大原ゆき05/02/03 00:02:54
わかりました。
次回からはにゃんにゃん抜きで書きます。
0208デフォルトの名無しさん05/02/03 03:44:12
わかりました。
次回からはにゃんにゃん抜きで書きますにゃん
0209デフォルトの名無しさん05/02/03 03:45:17
-gついててもオプティマイズオプションは有効なままのほうが
便利なときって、どんなとき?
0210デフォルトの名無しさん05/02/03 05:02:06
>>209
デバッグが終わったことになっていて、実稼働を行なう時に、
core吐いて止まることが予想出来る場合、その時調べやすい
0211デフォルトの名無しさん05/02/03 06:30:34
1次元配列と2次元配列でたとえば
int a[6],b[2][3]を確保して
a[0]とb[0][0]、a[1]とb[0][1]、a[2]とb[0][2]、
a[3]とb[1][0]、a[4]とb[1][1]、a[5]とb[1][2]が
それぞれ同じアドレスを参照してa[0]を変えたらb[0][0]も一緒に中身が変わるようにしたいんだけど

#include <stdio.h>
void main(void)
{
int *a[2];
int b[6];

a[0]=&b[0];
a[1]=&b[3];
}

って書き方でいいかな?
なんか問題ある気がするんだけど他にいい方法ないかな?
あとポインタにするのは2次元配列のほうにしてほしいのよ
021218105/02/03 07:50:27
>>191>>198

えっとね・・・

・・・釣ってきますgj
0213デフォルトの名無しさん05/02/03 08:16:41
>>211
ポインタと配列の箱の絵でも書いて、じっくり考え直した方がよい。
0214デフォルトの名無しさん05/02/03 09:46:26
#include <stdio.h>

int main(void)
{
int a = 0;
switch (a) {
case 0:
printf("a is 0.\n");//この行をコメントにすると、コンパイルエラー
int b = 2;
printf("b is %d.\n", b);
break;
case 1:
printf("a is 1.\n");
}
return 0;
}
このソース(swtest.c)なんですが、
このままだと、問題なくコンパイル(gcc -Wall swtest.c)できるのに、
printf("a is 0.\n");
の行をコメントにしてからコンパイルしようとすると、
swtest.c: In function `main':
swtest.c:9: error: parse error before "int"
swtest.c:10: error: `b' undeclared (first use in this function)
swtest.c:10: error: (Each undeclared identifier is reported only once
swtest.c:10: error: for each function it appears in.)
となって、エラーとなってしまいます,,,。
どうしてなんでしょうか?(環境はMacOSX10.3+GCC3.3です。)
0215デフォルトの名無しさん05/02/03 09:54:50
どこでも宣言ってことはC99にしてるのかね。
case自体はラベルだから、gotoのラベルと一緒で
次に「文」が続く必要があるけど、宣言って、文じゃなかったかな。
覚えてないや。
0216デフォルトの名無しさん05/02/03 10:11:50
>>215
ありがとうございます。
同じswitchでもJavaとは微妙に違うんですね。
勉強になりました。
0217デフォルトの名無しさん05/02/03 12:54:22
かなり大きいソース公開サイトがあった気がするんですが、名前を思いだせません。
教えてください。
0218CodeGuru?05/02/03 12:58:53
>>217
スレ違い。
0219デフォルトの名無しさん05/02/03 13:01:11
>>217
sourceforge
koders
0220デフォルトの名無しさん05/02/03 13:10:05
>>218-219
そうやって教えると、>>217 はいつまで経っても莫迦のまま。
0221デフォルトの名無しさん05/02/03 13:12:52
>>220
お前が馬鹿だ。
0222デフォルトの名無しさん05/02/03 13:15:09
>>221
園児の脊髄反射乙。
0223デフォルトの名無しさん05/02/03 13:34:56
>>222
なんだとこの
0224デフォルトの名無しさん05/02/03 14:18:23
217がバカだと何か困ることがあるのか
0225デフォルトの名無しさん05/02/03 14:43:42
>>224
そりゃ困る。
馬鹿が伝染るからな。
0226デフォルトの名無しさん05/02/03 14:43:51
>>219
ありがとうございます。
後者の存在は初めて知りました。
022721805/02/03 15:06:54
漏れはありがたくなかったらしい。
0228デフォルトの名無しさん05/02/03 15:17:53
>>227
ほら、言わんこっちゃない…
0229デフォルトの名無しさん05/02/03 15:46:33
>>224
業界に入られた時に非常に困るだろ。
0230デフォルトの名無しさん05/02/03 15:53:11
>>217
http://www.codesampler.com/
0231デフォルトの名無しさん05/02/03 15:55:39
>>225
伝染すると誰がどう困るのか
0232デフォルトの名無しさん05/02/03 16:07:12
>>231
どんどん伝染を繰り返し、馬鹿が増える。
馬鹿が増えると文明を維持することが困難になる。
文明を維持することが困難になると人類の繁栄に影響がでる。
人類の繁栄は最優先事項なので、馬鹿が伝染すると困る。
0233デフォルトの名無しさん05/02/03 17:28:19
ある可変引数関数の引数を、他の可変引数関数の引数に指定する事はできます?

void pp(char *fmt, ...) {
printf(fmt);
}

とか。



0234デフォルトの名無しさん05/02/03 17:36:45
>>233
printfの場合はvprintfを使え。
自作の関数の場合は初めからprintf/vprintfの用にva_list版も作って置け。
023523305/02/03 18:17:53
>>234
わかりました。ありがとうございます。
0236デフォルトの名無しさん05/02/03 22:15:39
>>227
名前なんかいちいち見ないよ
0237デフォルトの名無しさん05/02/03 22:21:23
あなたが、3つのドアの1つを選んで賞品を獲得するゲーム番組に出ているとします。
ドアの1つには賞品の車があります。残りの2つのドアはハズレでヤギがいます。
あなたがドアの1つ、たとえば1番ドアを選びます。
司会者は、それらのドアに何があるかを知っており、ヤギのドアを1つ、例えば3番ドアを開けてみせます。
そこで司会者があなたに、「2番ドアに変更してもいいですよ」といいました。
2番ドアに変えたほうがいいのでしょうか。


↑の確率を試行回数1万回くらいで実験してみたいんですが
どんな風に書けばいいの?
0238デフォルトの名無しさん05/02/03 22:47:28
>>237
ごく単純なマルコフ過程。
0239デフォルトの名無しさん05/02/03 22:48:36
変えた時と変えない時?
変えた時は1/2で変えない時は1/3。以上
0240デフォルトの名無しさん05/02/03 22:50:42
>>239
はい?もう一度良く考えて。
0241デフォルトの名無しさん05/02/03 22:55:27
>>240
え”!!違うの?ずっとそうだと思ってた
0242デフォルトの名無しさん05/02/03 22:56:20
3人の囚人A、B、Cがいる。三人とも処刑されることになっていたが、
王子が結婚するというので王様が一人だけ恩赦にしてやることになった。
誰が恩赦になるのか決定されたが、まだ囚人たちには知らされていない。
結果を知っている看守に、囚人Aが『BとCのうち、どちらかは必ず処刑
されるのだから、処刑される一人の名前を教えてくれても、私に情報を
与えることにはならないだろう。一人を教えてくれないか。』と頼んだ。
看守は、その言い分に納得して『囚人Bは処刑されるよ』と教えてやった。
囚人Aは、「はじめ自分の助かる確率は1/3だった。いまや助かるのは
自分とCだけになったので、助かる確率は1/2になった」と喜んだ。
さて、看守の返事を聞いた後の囚人の助かる確率はどれだけか?
0243デフォルトの名無しさん05/02/03 22:58:15
スレ違い
Cの話にアレンジできない低脳は氏んで
0244デフォルトの名無しさん05/02/03 22:59:20
質問です。
文字列とポインタに関してです。

ポインタの文字列というものを勉強しているとき、
char *ptr = "123";
ptr = "456";
と途中で書き換えられる。
と書いてありました。
しかしもう少しよんでいくと、ポインタの文字列リテラルの中身を書き換えてはいけない
と書いてありました。
いったいどういうことでしょうか?

ポインタで文字列を扱った場合、書き換えてはいけないのですか?
0245デフォルトの名無しさん05/02/03 23:00:27
>>242
237と問題違うし
0246デフォルトの名無しさん05/02/03 23:00:30
Cスレイラネごみ
0247デフォルトの名無しさん05/02/03 23:00:56
>>243
アレンジできてないのはお前一人
0248デフォルトの名無しさん05/02/03 23:01:18
>>237
どう言う確立で司会者が変更して良いというのか。
0249デフォルトの名無しさん05/02/03 23:01:34
>>244
どこに書いてた?
0250デフォルトの名無しさん05/02/03 23:02:42
>>249
明解C言語という本です。
0251デフォルトの名無しさん05/02/03 23:02:48
>>242
1/3
0252デフォルトの名無しさん05/02/03 23:02:51
何を書き換えた?か。
■ このスレッドは過去ログ倉庫に格納されています