C言語なら、ぬるぽに聞け! Part 〈53〉
■ このスレッドは過去ログ倉庫に格納されています
0001ぬるぽ
NGNG質問する前には最低限Googleで検索を。
GUIなどの標準Cではできない事の質問は使用している開発環境のスレへGo!
ソース丸投げ、宿題、書籍 は専門の別スレがあるのでそこへさようなら。
コンパイラを探しているなら >>2-13 を。
上記を逸した場合の結果は激しく未定義だゴルァ!!
∧_∧
( ´∀`)< ぬるぽ
C FAQ 日本語訳
http://www.catnet.ne.jp/kouno/c_faq/c_faq.html
Cプログラマ必読 ・プログラミング言語C(通称 K&R)
http://www.amazon.co.jp/exec/obidos/ASIN/4320026926/
0159デフォルトの名無しさん
NGNG新しい型を定義したんだからint等と全く同じように使える。
0160151
NGNGvoid func(Foo *f);
という関数宣言がでてきても、Cコンパイラから
未知の型:Foo
とかおこられないで、大丈夫なの?
C++なら
struct Foo;
void func(Foo *f);
とFooについて宣言する必要があるけど…
0161デフォルトの名無しさん
NGNGlog()とか使って計算するしかないのでは?
0162デフォルトの名無しさん
NGNGsprintfでも使ってeの後だけ切り出す手もあるねぇ
0163デフォルトの名無しさん
NGNG試せばいいだろ!(怒)
0164制御屋さん見習中
NGNGありがとう!
それは思いつきませんでした。
0165デフォルトの名無しさん
NGNGなんでその宣言の前にtypedefを書こうと思わないわけ?
0167デフォルトの名無しさん
NGNGtypedef struct{
int a;
char *b;
} Foo;
void func(Foo *);
こうだよこう。
0168151
NGNGこれだと、Fooについての実体をかいてますよね?
つまり、Fooの実体を変えるた場合、コンパイルを
やり直す必要がある(コンパイル依存が生じる)。
必要なのは「(構造体への)ポインタ」だけなのに…
ポインタであることさえわかれば、構造体の実体が
どうなっていても、ポインタのサイズは一定値なので
不要なコンパイル依存性を除去できるのですが…
0169デフォルトの名無しさん
NGNGを誰か説明してください。お願いします。わけわからんです。
0170デフォルトの名無しさん
NGNGとりあえずやってみろよ。
話はそれからだ。
0171デフォルトの名無しさん
NGNGlog()じゃなくてlog10()使えよ。
>>162
それだったらecvt()の方がよくないか?
0172151
NGNGC++だとヘッダファイルは以下ですむ
#ifndef FOO_FUNC_H
#define FOO_FUNC_H
struct Foo;
void func(Foo *f);
#endif
Fooの実体については何も書いていないので
コンパイラ依存がない。
つまり、Fooが定義されているfoo.hが変更されても
foo_func.hは関与しない
0173デフォルトの名無しさん
NGNGヘッダーファイルに関数の宣言を書くということは、他のファイルからもその関数を呼び出すんだろ?
0174デフォルトの名無しさん
NGNGポインタのサイズは一定でも、「なにの」ポインタかはコンパイラが意識する必要があると思え。
0175デフォルトの名無しさん
NGNG0176デフォルトの名無しさん
NGNG順番に型宣言でもして分解すればわかるだろう?
>int (*fns[])(struct gmstat*) = {gmmain, gmrank, gment, };
intを返す、struct gmstat*を唯一の引き数とする、関数へのポインタの配列fns、
それをgmmain, gmrank, gmentの3つの要素で初期化する。
つまり、
struct gmstat foo;
int rtn = fns[0](&foo);
と
int rtn = gmmain(&foo);
が等価なわけだな。
で、どうせなら
static int (*const fns[])(struct gmstat*) = {gmmain, gmrank, gment, };
にしておけ。
0177151
NGNGそれは、実際に必要な時まで、コンパイラが意識するタイミングを
送らせる(プログラマが調整させる)ことができますよね?
「Effective C++」の34項
「コンパイルするファイル間の依存性はできるだけ減らそう」
の話をしているつもりです…
これのC版のsttructはどうするのかなぁ、と。
やっぱりタグ名を使って冗長(?)に
extern struct Foo_tag;
void func(struct Foo_tag *f);
とでもするのでしょうか?
0178デフォルトの名無しさん
NGNG0179151
NGNGそれはそうなのですが…(^^;
Cでやるにはどうするのかな、と。
すみません、マルチポストっぽくって申し訳ないのですが
これからC++のスレでも質問させてもらいます…
0180デフォルトの名無しさん
NGNG要するに、構造体のメンバを隠蔽したいということか?
だったら、構造体を不完全型として宣言すればいい。
構造体へのポインタ「だけ」が必要な関数には、
typedef struct foo foo;
という宣言だけを見せて、メンバへのアクセスが必要な関数には、
struct foo { ... };
という宣言を見せればいい。
0181デフォルトの名無しさん
NGNGそれはそれで構造体の構造を変更しても、関数を使う側のファイルはコンパイルし直さなくても良いような気がする。
0182デフォルトの名無しさん
NGNG> これからC++のスレでも質問させてもらいます…
C++での方法を知っているのになぜ質問する。
0183デフォルトの名無しさん
NGNG冷やかしに来たのなら失せろ
0184デフォルトの名無しさん
NGNG>>180の言うようにCでもできるがダブルスタンダードになって
保守性が落ちるだけのような気がして気持ち悪い。
「C++でできることがCではどうなるか」疑問に思うのはいいが、
違う言語なのだから必ずしも同じように使わなくてもいいと思うのだが。
#名前空間の所為で、Cだとtypedef struct foo {int foo;} foo;なんてできるのだし。
0185sage
NGNG0186151
NGNG実際にCでかいていまして…
0187デフォルトの名無しさん
NGNGという質問が次は来るに 2,000ヌルポ
0188デフォルトの名無しさん
NGNG0189デフォルトの名無しさん
NGNGコンパイル時間がもったいないとか?
0190189
NGNG0191デフォルトの名無しさん
NGNG0192151
NGNGやってみたいと思っているんだけど…
しいていうならC++厨です
C++スレで質問したのですが、CならCの流儀にしたがえ
とアドバイスをうけました。
ですので、タグ名をつかってみることにします
(typedefをせずに)
荒らす気はなかったのですが、みなさんに迷惑を
かけてしまいました。
どうもすみませんでした。
0193デフォルトの名無しさん
NGNGがんがれ
0194デフォルトの名無しさん
NGNGもしくは説明されてるサイト教えてください
0195デフォルトの名無しさん
NGNG0196デフォルトの名無しさん
NGNG林の本でもいいから初心者本買えよ
http://www.google.com/search?num=50&hl=ja&lr=lang_ja&q=C%8c%be%8c%ea%82%cc%8c%5e+%8aT%94O
0197151
NGNGそれで、CスレでもC++スレでも、質問を終わります
C++スレでの終わりの意見はここです
http://pc2.2ch.net/test/read.cgi/tech/1047560042/623
たくさんアドバイスをしてくださって
どうもありがとうございました
0198タマちゃん
NGNGmain()
{
func1();
}
func1()
{
printf("a");
}
をコンパイルしようとすると、
5: Warning: function 'func1' undefine -- assumed to be int
って返ってきてしまいます。
どこが間違ってると思います?
0199デフォルトの名無しさん
NGNG解1)
#include "stdio.h"
func1()
{
printf("a");
}
main()
{
func1();
}
解2)
#include "stdio.h"
void func();
main()
{
func1();
}
void func1()
{
printf("a");
}
0200タマちゃん
NGNG神よ
ありがとう
0201199
NGNGmainの中でfunc1が出てきたときにはコンパイラはfunc1のプロトタイプは知らない。
知らないから、ファイルを読み進んでその先にあるかもしれないfunc1の
プロトタイプを知ろうとはしない。これが前方参照をしないの意味だ。
で、プロトタイプがわからない関数にぶち当たったときコンパイラは
intを返す関数だと仮定して処理を進める。これはCの規約でもある。
コンパイラがだしてるwarningはそのことを言ってる。
そのwarningを意訳すると、
「funcなんてしらねえよボケ、intを返すと見なすからそのつもりでいろや」
と言ってる。
んで、解1の方は前もってfuncの定義をしておくもので、
解2はコンパイラにfuncのプロトタイプを与えるというものだ。
0202デフォルトの名無しさん
NGNG0203デフォルトの名無しさん
NGNGintは処理系にとってもっとも自然な整数型。
同じサイズの処理系もあるし、違うサイズの処理系があってもよい。
たぶんおまいのさわれるコンパイラはサイズが同じなので違いはない
0204デフォルトの名無しさん
NGNG実引数にも影響を及ぼすことができるサンプルプログラミングですが
本に書いてあるとおりにやって何度も確認してるのですが
どこが間違えてるか分かりません。おしえてください。
#include <stdio.h>
void swap(int *pX,int *pY);
int main(void)
{int num1=5;
int num2=10;
printf("変数num1の値は%dです。\n",num1);
printf("変数num2の値は%dです。\n",num2);
printf("変数num1とnum2の値を交換します。\n");
swap(num1,num2);
printf("変数num1の値は%dです。\n",num1);
printf("変数num2の値は%dです。\n",num2);
return 0;
}
void swap(int *pX,int *pY)
{int tmp;
tmp=*pX;
*pX=*pY;
*pY=tmp;}
0205デフォルトの名無しさん
NGNG>swap(num1,num2);
swap(&num1,&num2);
&がない。よく本見てみ
0206デフォルトの名無しさん
NGNG0207デフォルトの名無しさん
NGNGありがとうございます!!正常な数値がでました。
ところで何故こうなるのでしょうか??
void swap(int *px,int *py);で宣言するときに
*pxおよび*pyは数値ですよね?
で、呼び出すときは swap(&num1,&num2);
と &num1および&num2はアドレスですよね?
つまり、&num(アドレス)を*px(数値)に代入することなんてできるんでしょうか?
0208デフォルトの名無しさん
NGNGint *ap;
ap=&a;
これをやってるのと同じ。
0209デフォルトの名無しさん
NGNGstruct name {
int namelen;
char namestr[1];
};
ってのが,C FAQ に載っていますが,
この使用に関して危険性は無いのでしょうか?
素人目には,かなり恐い感じがするのですが.
namestr[xx] のアドレスが危険な領域である可能性は無いのでしょうか?
0210デフォルトの名無しさん
NGNG関数内でint *px; を宣言して
引数のアドレスがコピーされるようなもの。
0211デフォルトの名無しさん
NGNG超ある。
ってかnamelenを何に使うのか説明してくれ。
0212デフォルトの名無しさん
NGNGていうか
mallocとかであらかじめメモリーを確保するから大丈夫
0213デフォルトの名無しさん
NGNGpname=malloc( sizeof(struct name) +9 );
としたら
pname->namestr[9] まで問題ない。しかしそれ以降は危険。
0214デフォルトの名無しさん
NGNGすごく初心者の友達がプログラムを覚えたいらしく、教えてあげることになり
ました。(僕もそんなに知識はありませんが)。使える言語が少ないのでC言語を
教えることにしました。ただ、友達はただがいいらしいのでそれを探したところ、
Borland等があるみたいですね。教えるために僕もBorland等をインストール
しようと思っているのですが、VC++が有るパソコンにそれを入れるとどうなりますか。
ぶつかって動作がおかしくなったりしませんか。教えてください。長文ですいません。
0215デフォルトの名無しさん
NGNGもうまんたい
0216デフォルトの名無しさん
NGNG0217209
NGNGこの場合 namelen はプログラマが陽に管理することになるんですね?
pname=malloc( sizeof(struct name) +9 ); のとき
pname->namestr[9] までOKなので,例えば
pname->namelen = 10; と設定してやるとか.
struct name {
int namelen;
char * namestr;
};
とすれば
struct neme namae; のとき
namae.namestr = xx;
namae->namestr = (char*)malloc(xx);
と出来ますよね?こっちのほうがいいような.freeしにくいのか?
この構造体のメリットは配列長情報を格納できることなのでしょうか?
いまいちピンとこないのですが,有効な利用法などはあるのですか?
0218デフォルトの名無しさん
NGNG0219デフォルトの名無しさん
NGNG209はCFAQでもダメだって書いてる。
どうやって
"配列namestrが複数の要素を持つように振る舞わせる"んだろ
char namestr[1];みたいな場合
namestr=ポインタ;
みたいな表現は許されないような気がした
217の方の使い方はいろいろあります。
最初にxxの大きさで割り当てた後
もっと大きいサイズが途中で必要になったりしたときとか長さが無いと困るし
そういうことをする関数を作った場合引数がごちゃごちゃしないとかかなあ
0220デフォルトの名無しさん
NGNG>公式な解釈によると上の技巧は Cの 規格に厳密には準拠していないと考えられる。
>(この技法が正しいか どうかを取り巻く議論を尽くすことは、このFAQの守備範囲を越えて いる。)
>しかし世の中に知られている全てのコンパイラの実装で、こ の方法は移植性が高いようである
>(配列の境界を注意深くチェックす るコンパイラは警告を出すかもしれない)。
>別のやり方としては、可変長の要素の大きさを、小さく取るより、非 常に大きく取ることが考えられる。上の例でいえば、
>char namestr[MAXSIZE];
>ここでMAXSIZEは配列namestrに保存されうるどんな名前よりも大きい。 しかしながらこの技法も、規格の厳密な解釈によると許されないよう だ。
駄目とは書いてないような・・
0222デフォルトの名無しさん
NGNGファイルフォーマットに可変長データ部分がある場合
ヘッダを一気に読んでこういう構造体にあてはめると効率が良いよ。
コンパイラの特性に依存してるから、移植性はほとんどないけど。
0223デフォルトの名無しさん
NGNGしかし、C99 では認められている気配。
0224デフォルトの名無しさん
NGNG0225デフォルトの名無しさん
NGNG0226デフォルトの名無しさん
NGNGそういえば、>>9のコンパイラ一覧にLSI-Cの試食版は入ってないな。
俺も昔はお世話になったが、やはりintが2byteはもう過去の遺物だろう。
0227デフォルトの名無しさん
NGNG俺がC始めたときは環境変数とか全然分からなかったから、
自動でパス通してくれるのは本当にありがたかったよ。
0228デフォルトの名無しさん
NGNG#include "stdio.h"
ビクビクガタガタ
ところで、純粋にC言語の勉強をするだけなら、gcc(cygwin)がお勧め。
ネットにさえ繋がればインストールは難しくないし、無料。
ただし、グラフィック関連は難しいので、あくまでも「C言語だけ」の世界だが。
0229デフォルトの名無しさん
NGNG0230デフォルトの名無しさん
NGNG0231デフォルトの名無しさん
NGNG0232デフォルトの名無しさん
NGNG0233デフォルトの名無しさん
NGNGc=n;とすれば良い所を可読性を良くする為、あえて
c=(char)n;としても遅くなったりしませんか(ループ内とかで)?
内部的な動作は良く知らないので教えてください。
0234デフォルトの名無しさん
NGNGとてつもなく遅くなる。禁じ手。
0235デフォルトの名無しさん
NGNGうほっ、そりゃまずいっす。 情報サンクス!
0236デフォルトの名無しさん
NGNG信じるな。
0237デフォルトの名無しさん
NGNGよく知らないけど
ハンガリアン表記すりゃあ、そんな必要無くなる罠。
0238デフォルトの名無しさん
NGNG> cがchar nがint型として
> c=n;とすれば良い所を可読性を良くする為、あえて
> c=(char)n;としても遅くなったりしませんか
処理系依存なのでアセンブラに落として同じコードになるか確かめろ。
0239デフォルトの名無しさん
NGNG0240デフォルトの名無しさん
NGNG0241デフォルトの名無しさん
NGNGc=(char)(a+b);
c=(char)a+(char)b;
みたいなのだと、結果は同じでも速度は変わる。
0242モナ王
NGNG以下のようなプログラムを実行します。
int main()
{
int i, j, n_1, n_2;
double K[M][N];
n_1 = 4;
n_2 = 2;
printf(" n_1 =%d\n", n_1);
printf(" n_2 =%d\n", n_2);
func( A, B, P, G, n_1,n_2,K);
printf(" n_1 =%d\n", n_1);
printf(" n_2 =%d\n", n_2);
return EXIT_SUCCESS;
}
すると、n_1とn_2の値が、func()の後で どちらも0になります。
func()内部で、n_1、n_2は値を参照しているだけです。
(for文のループに使用)
何故変わるのか理解できません。
宜しくお願いします。
0243デフォルトの名無しさん
NGNGこれだけの情報で分かったら神
引数を値を代入するような用途に使うのはいかがなものかと
0244デフォルトの名無しさん
NGNGfuncがスタック内容を壊してるから
0245デフォルトの名無しさん
NGNG正規の方法では、ポインタを使わない限り、それは意図しようが無い。
唯一 K がポインタ渡しになっていると思われるので、その扱いを間違えた func() の
バグだろう。
0246モナ王
NGNG>funcがスタック内容を壊してるから
これってどう言う意味ですか?
0247245
NGNG0248デフォルトの名無しさん
NGNG0249モナ王
NGNG長いのですが、、、
int func( double a[N][N], double b[N][M], double p[L][N], double g[M][N],
int Ncol,int Nrow,double K[M][N])
{
int i,j,k;
double InvF[N][N],s,tmp[10][10];
for (Pole_Count = 0; Pole_Count < Ncol; Pole_Count ++){
if(p[1][Pole_Count] == 0){
if(Pole_RealCal( a, b, p, g, Ncol) == 0){
/* エラー処理 */
return 0;
}
}else{
if(Pole_ImgCal( a, b, p, g, Ncol) == 0){
/* エラー処理 */
return 0;
}
}
}
for (i = 0; i < N; i++)
for (j = 0; j < M; j++) K[i][j] = 0.0;
return 1;
}
0250モナ王
NGNG>>249 自己レスです。
バグが分かりました。
K[][]の初期化を誤っていました。
(NとMが逆)
for (i = 0; i < N; i++)
for (j = 0; j < M; j++) K[i][j] = 0.0;
大変失礼しました。
当方win98 +Cygwin +gcc -Wall でコンパイルしています。
この様なバグは、見つけるのが難しいと思います。
皆さんはどのようにして、発見しているのですか?
0251デフォルトの名無しさん
NGNG0252デフォルトの名無しさん
NGNG>>244の予想どうりでワロタ
0253デフォルトの名無しさん
NGNG・ループ制御変数であっても一文字は避ける。
・ループの中身が一文だけであってもブロック化する。
・変数名を大文字で始めない。
・配列全体の初期化はmemset()を使う。
0254モナ王
NGNGありがとうです。
行列を扱いたいので、2次元配列を使いたいです。
・ループ制御変数であっても一文字は避ける。
これは、どういう意味ですか? i、jはやめろということですか?
・ループの中身が一文だけであってもブロック化する。
{}を付けろということですね。
・変数名を大文字で始めない。
了解です。
・配列全体の初期化はmemset()を使う。
これは知りませんでした。情報ありがとうございます。
0255デフォルトの名無しさん
NGNG私ならば、こうすると言う話だが。
Cの二次元配列は一次元目を固定サイズにしないといけないので使い難いと思わないか?
だから二次元配列の代わりに一次元配列で済ませるのが習慣になっている。
例えば配列全体の平均値を返す関数にするならこんな感じだ。
double CalcAverage(double const *pArray, size_t width, size_t height)
{
double sum = 0;
int iy;
for (iy = 0; iy < height; iy++) {
int ix;
for (ix = 0; ix < width; ix++) {
sum += pArray[ix + iy * width];
}
}
return sum / (width * height);
}
もしix + iy * widthが鬱陶しいなら、
#define pos(x, y, w) ((x) + (y) * (w))
とでもすればいい。そうすればpArray[pos(ix, iy, width)]と書ける。
0256デフォルトの名無しさん
NGNG0257デフォルトの名無しさん
NGNGコピペしたもんだからそういうことに。
指摘THX>>256
0258デフォルトの名無しさん
NGNG#include <stdio.h>
int main(int c, char **v)
{
c--;
if(c<0)return 0;
printf("%s ", v[c]);
return main(c, v);
}
■ このスレッドは過去ログ倉庫に格納されています