C言語なら俺に聞け! Part 101
■ このスレッドは過去ログ倉庫に格納されています
0001v(^o^i)d
05/01/31 08:37:54質問する前には最低限検索を。
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/
0002デフォルトの名無しさん
05/01/31 08:38:47gcc
http://gcc.gnu.org/
【Win32用の開発環境のみ。】
gcc-cygwin
http://www.redhat.com/software/tools/cygwin/
gcc-mingw
http://www.mingw.org
Digital Mars C++
http://www.digitalmars.com/
Open Watcom
http://www.openwatcom.com/
Borland C++ Compiler 5.5.1
http://www.borland.co.jp/cppbuilder/freecompiler/
Visual C++ Developer Center: Microsoft Visual C++ Toolkit 2003
http://msdn.microsoft.com/visualc/vctoolkit2003/
【ライセンスや機能などに問題あり】
Microsoft C/C++ 13.0.9466(VC.NET)
http://www.microsoft.com/japan/msdn/netframework/downloads/
LCC-Win32
http://www.cs.virginia.edu/〜lcc-win32/
CINT
http://root.cern.ch/root/Cint.html
めじろ++98
http://www.vector.co.jp/soft/win95/prog/se075910.html
Intel C++ Compiler for Linux
http://developer.intel.com/software/products/compilers/clin/noncom.htm
0003デフォルトの名無しさん
05/01/31 08:39:350004デフォルトの名無しさん
05/01/31 08:45:080005デフォルトの名無しさん
05/01/31 08:46:500006デフォルトの名無しさん
05/01/31 09:16:13出力したときに結果がすべて0になってしまいます。何も代入されないってのはおかしいので質問させていただきます。
以下はその探索に使用するプログラムを抜き出したものです。再帰を使ってます。
m番目にまだめぐってない点を見つけて、次に(m+1)番目に巡ってない無い点を・・・と探して行ってます。
具体的にはN*Nのます目に0(FALSE)を入れたあとで縦に点の番号、横に巡回の順番をとって、
点 n が m 番目に巡回したときに n行m列のます目に1(TURE)を入れていき、最後にその順番に従って距離計算、比較を行っています。
変数の説明ですが、s1、s2、d1、d2は大域で宣言し、 tは縦、yは横、s1は横(点側)から見たとき巡回が重複か否かを見ていて、s2はすでに回った点の番号を入れ、
d1は各点間の距離でこれはすでに計算されています。よろしくお願いします。
void search(int t){
int y,i,j;
for(y = 0; y < N; y++){
if(s1[y] == FALSE){
s1[y] = TURE; s2[t] = y;
if(t < N-1) search(t+1);
else{
for(i = 1; i < N; i++)
d2 += d1[s2[i-1]][s2[i]];
d2 += d1[s2[0]][s2[N-1]];
if(d2 < mini_d){
mini_d = d2;
for(j = 0; j < N; j++)
mini_s2[j] = s2[j]; d2 = 0;
}
}
s1[y] = FALSE;
}
}
}
0007デフォルトの名無しさん
05/01/31 09:20:37mainの最後にprintfでこの2つを出力しています。
0008デフォルトの名無しさん
05/01/31 10:17:310009デフォルトの名無しさん
05/01/31 10:22:02でもdefineでもそう定義してありました・・・
ここは直します
0010デフォルトの名無しさん
05/01/31 10:23:13まさか、mini_dが初期化されてなくて0のままって落ちじゃないよな?
ぱっと見よく判らんから、私なら極力グローバル変数を無くすように書き換えて、
各変数の生存期間を制限した上でそれぞれの挙動を確かめるだろうな。
#私ゃグローバル変数の挙動を追えるほど頭良くないんでね。
0011デフォルトの名無しさん
05/01/31 10:36:32mini_dは最初は0で初期化しましたけど、それじゃ比較できないよなってことで
適当に大きい数を最初に入れてます
それと自分で実験してみたんですが、大域でとった場合は関数の引数に入れなくても、
またreturnしなくても数値代入ができるようなのでそうしました。
/**/で説明入れてみます。
void search(int t){
int y,i,j;
for(y = 0; y < N; y++){
/*t番目に巡回したときにまだ回ってない点があるならそこにチェック(TRUE)を入れる*/
if(s1[y] == FALSE){
s1[y] = TURE; s2[t] = y;
/*まだ回りきってないなら次に行く点を探す*/
if(t < N-1) search(t+1);
/*回りきっていたら距離計算、比較*/
else{
for(i = 1; i < N; i++) d2 += d1[s2[i-1]][s2[i]];
d2 += d1[s2[0]][s2[N-1]];
if(d2 < mini_d){
mini_d = d2;
for(j = 0; j < N; j++) mini_s2[j] = s2[j]; d2 = 0;
}
}
/*バックトラックのために一個前に回った点の履歴を削除*/
s1[y] = FALSE;
}
}
}
001210
05/01/31 10:41:01大丈夫、そのコメントくらいは理解できたから。
それが正しいかどうか、グローバル変数も含めて挙動を推測するだけの頭はないがね。
で、私なりの方針を提示したわけだが、それを否定されたら私にできるアドバイスはもうないよ。
0013デフォルトの名無しさん
05/01/31 10:44:56わかりました
大域変数減らしてみます、ありがとうございました
まずはd2を。
0014デフォルトの名無しさん
05/01/31 13:59:14else{
d2 = 0; /* d2 はここで初期化しないとダメ。*/
for(i = 1; i < N; i++)
d2 += d1[s2[i-1]][s2[i]];
0015GANMEN ◆6JRRRjFXoU
05/01/31 14:12:400016デフォルトの名無しさん
05/01/31 14:16:40氏ねば?
0017デフォルトの名無しさん
05/01/31 14:58:55Web制作
http://pc5.2ch.net/hp/
0018デフォルトの名無しさん
05/01/31 16:09:53で、反対語は? > 大域
0019デフォルトの名無しさん
05/01/31 17:07:01局所変数
0020デフォルトの名無しさん
05/01/31 17:37:26質問お願いします。
文字をある長さまで指定した文字で充填することは可能でしょうか?
イメージ的にはoracle SQLのRPAD関数のような事がやりたいのですが…。
よろしくお願いします。
0021デフォルトの名無しさん
05/01/31 17:41:36memset()
0022デフォルトの名無しさん
05/01/31 17:42:04別に御仕着せの関数を使わないと、Cじゃなんもできないってわけじゃないんだから。
002320
05/01/31 17:47:28>21様
ご回答ありがとうございます。
21様の方法で試してみます。
>22様 もしうまくいかなければ自分で作ってみます。
どうもありがとうございました。
0024デフォルトの名無しさん
05/01/31 21:28:24関数の定義で記憶クラスを省略した場合は extern 扱いになりますが、
プロトタイプ宣言の場合も省略時は extern と考えていいですか?
ネットを回ってると、プロトタイプ宣言では関数の定義が外部にある場合は
extern、内部の場合は記憶クラスなしと言う記述があって混乱しています。
また、関数定義では extern、そのソース内のプロトタイプ宣言は static と
指定すると外部からは static 扱いになってるのはそのように決まってるのでしょうか。
早く出た順なのかな、と extern static と同じ関数をプロトタイプ宣言させて、
関数の宣言では extern としても static 扱いだったので…。
VCとBCCのコンパイラで試しました。
0025デフォルトの名無しさん
05/01/31 21:32:56staticは使うけど
0026デフォルトの名無しさん
05/01/31 22:07:41じゃなかったっけ
0027デフォルトの名無しさん
05/01/31 23:09:58扱いはしてない
0028デフォルトの名無しさん
05/01/31 23:15:27領域先頭アドレスさえ間違えなければ
サイズとか分からなくてもきちんとfreeできるものですか
char* p = NULL;
/* 4〜5層下の関数がpにmallocする */
test_func(p);
/* 大きさとか知らんけど解放 */
free(p);
0029デフォルトの名無しさん
05/01/31 23:16:260030デフォルトの名無しさん
05/01/31 23:18:05test_func(&p);
か
p=test_func();
003128
05/01/31 23:28:21mallocした領域の終端には
ボクには見えない機械様用のマーキングかなんかがきっと
あるのですね。
0032デフォルトの名無しさん
05/01/31 23:30:37http://www.kouno.jp/home/c_faq/c7.html
の7.26
0033デフォルトの名無しさん
05/01/31 23:35:57>>25
自分も普段は関数に extern は使ってないです。
プロトタイプ宣言で static を使ってる例ってネットじゃあまりみないですね。
>>26
それだと道理があいますね。なるほど。。。
>>27
リンク時に外部参照が未解決になるので static 扱いされて参照できない
のかと思ったのですが、もっと別の理由ということでしょうか。
0034デフォルトの名無しさん
05/01/31 23:44:57> プロトタイプ宣言で static を使ってる例
staticを付けると翻訳単位内でしか呼び出せなくなるのでどうせヘッダに宣言する意味がないから。
0035デフォルトの名無しさん
05/01/31 23:53:41unko.c
static void unko() { /*...*/ }
manko.c
mein() { unko(); }
manko.c では unko は暗黙に extern 宣言される
だからこそリンクでずっこける
^^^^^^^^^
0036デフォルトの名無しさん
05/02/01 00:10:02ヘッダに宣言しても確かに意味ないですね。
やったら各ソースで見つからないと怒られるのかな。。。後でやってみます。
関数が定義されているソース内のプロトタイプ宣言でも static は結構書いてないのが
多そうな気がするのですが、気のせいでしょうか。
>>35
記憶クラスを省略した場合は extern というのは一応分かってるつもりです。
プロトタイプ宣言の場合は、違う説明をしているサイトがあって混乱してますが。。。
自分が特に疑問に思ったのは下記のような場合です。(関数名はかえました。)
testA.c
static void testA(void); /* プロトタイプ宣言は static */
extern void testA(void) { /*...*/ } /* 関数宣言は extern */
testB.c
int main(void) { testA(); } /* 外部参照の未解決が発生。static が優先されてしまう。。。? */
003736
05/02/01 00:11:53は関数宣言ではなくて、関数定義の間違いでした。
0038デフォルトの名無しさん
05/02/01 00:19:350039デフォルトの名無しさん
05/02/01 01:08:46なりません
0040デフォルトの名無しさん
05/02/01 08:16:56ill-formedtって未定義って解釈でいいでしょうか。
プロトタイプ宣言と関数定義で記憶クラスが違うというのは普通しないですもんね。
>>39
関数で使用できる記憶クラスは extern と static だけですよね。
省略時に extern でないとすると static ってことでしょうか。さすがにそれは。。。
0041デフォルトの名無しさん
05/02/01 08:40:45全然ちがいます。
> 関数で使用できる記憶クラスは extern と static だけですよね。
いいえ
0042デフォルトの名無しさん
05/02/01 08:44:540043デフォルトの名無しさん
05/02/01 09:30:240044デフォルトの名無しさん
05/02/01 09:34:29教えて欲しい
0045デフォルトの名無しさん
05/02/01 09:35:450046デフォルトの名無しさん
05/02/01 11:45:54なにかソフトがいるのですか?
0047デフォルトの名無しさん
05/02/01 11:48:390048デフォルトの名無しさん
05/02/01 12:18:26非可逆です。
0049デフォルトの名無しさん
05/02/01 12:19:350050デフォルトの名無しさん
05/02/01 12:36:09>testB.c
> int main(void) { testA(); } /* 外部参照の未解決が発生。static が優先されてしまう。。。? */
プロトタイプを省略すると、
int を返す関数と解釈される。
つまり、「testB.c」では「int testA();」がないと言われるのは当然。
0051デフォルトの名無しさん
05/02/01 16:20:08#include <stdlib.h>
int main(void)
{
int i, r, j, c=0, n[6];
do {
r=rand()%42+1;
for(j=0;j<c;j++) {
if(c==0) break;
if(r==n[j]) break;
}
if(j==c) {
n[c]=r;
c++;
}
} while(c<6);
printf("%d %d %d %d %d %d", n[0], n[1], n[2], n[3], n[4], n[5]);
return 0;
}
ロト6の数字をランダムに作り出すプログラムを作ろうと思ってます。
何度やっても同じ数字しか出ないのですが、プログラム的な問題なんでしょうか?
0052デフォルトの名無しさん
05/02/01 16:34:550053デフォルトの名無しさん
05/02/01 16:36:19randの実装を100回くらい読んでみろ。
0054デフォルトの名無しさん
05/02/01 17:24:49malloc や calloc で cast 無しでメモリ領域を確保するとき、warning が出ないようにするには
どうすればよろしいのでしょうか?
コンパイラは gcc, g++ です。
0055デフォルトの名無しさん
05/02/01 17:27:25は?神でいいよ。
005654
05/02/01 17:34:19すみません、意味が分からないのですが・・・
コンパイル時に Warning が出て、正常にコンパイルできないのですが・・・
0057デフォルトの名無しさん
05/02/01 17:37:30どっちだよ
つか C++ じゃmalloc, calloc なんて使わねーしな
0058デフォルトの名無しさん
05/02/01 17:40:48mallocの返り値はvoid*型だよね。
で、君が確保したメモリ領域は何型で使うの?
例えば、int*型だったとしたら、そこにvoid*型を代入するのはおかしいよね。
いい?代入というのは左辺値も右辺値も同じ型でないといけないの。
mallocは確保したメモリ領域の先頭アドレスを返してくれるわけだけど、void*型を
int*型にキャストしてから代入しないといけないの。
warningとは、君がそういうことをしていないから警告しているわけ。
errorとは別物だよ。
0059デフォルトの名無しさん
05/02/01 17:42:48君が使わなくても使う人はいるけどネ。
0060デフォルトの名無しさん
05/02/01 17:45:49006154
05/02/01 17:50:55すみません、人(先生)が書いたプログラムなので。
基本的に C のプログラムなのですが、コメントに // を使ったり、
関数の途中で変数宣言したりするので、結局 g++ でコンパイルするしかないのです。
>>58
それは分かるのですが、double 型に int 型の変数を代入したときに自動的に型変換されるように、
malloc や calloc でも自動的に型変換してくれないものかと思ったのですが・・・
0062デフォルトの名無しさん
05/02/01 17:57:070063デフォルトの名無しさん
05/02/01 18:01:00いちいちキャストすんな ぼけ。
0064デフォルトの名無しさん
05/02/01 18:01:15うpろだ紹介しる。
誰か出してくれるだろ。
明日までに他の誰もうpしなかったら俺がやる。
0065デフォルトの名無しさん
05/02/01 18:08:08> それは分かるのですが、double 型に int 型の変数を代入したときに自動的に型変換されるように、
> malloc や calloc でも自動的に型変換してくれないものかと思ったのですが・・・
暗黙の型変換は、すべきでないところで暗黙の変換が行われることがあるため、
型を意識してプログラミングしなければならない。
しばしばバグの元になる。
暗黙の型変換はCの汚点の一つ。
0066デフォルトの名無しさん
05/02/01 18:11:44gccって一行コメントに未対応だったか?
俺が動かした環境だと、なぜか、Windowsからエミュレートしたら動かなかったけど
Warning出て欲しくなければ、コンパイラオプション(-?かな)をチェック。たぶん出来る。
0067デフォルトの名無しさん
05/02/01 18:18:33よろしこ。
ttp://up.isp.2ch.net/upload/c=03okari/index.cgi
0068デフォルトの名無しさん
05/02/01 18:26:21規格ではvoid *と任意のポインタとの相互の変換は暗黙のうちにやって良いことになっているけどね。
0069デフォルトの名無しさん
05/02/01 18:27:18>>65
0070デフォルトの名無しさん
05/02/01 18:32:10違った。日本語のコメントがあったから動かなかっただけだったと思う。
0071デフォルトの名無しさん
05/02/01 19:36:04嘘をつくな
warning はコンパイルを妨げないぞ
ある処理系では warning でもコンパイルを中止しろというオプションがあったりするが
それを自分で指定しておいて寝言ほざいてんじゃねえだろな
0072デフォルトの名無しさん
05/02/01 19:47:40「正常に」ってのが、警告無しにって意味じゃない?
まぁ、ソース変えずに警告だけ無くしたいなら、警告消えても消えなくても同じだけど
(∩ ゚д゚)アーアー警告しらなーい
って感じだし。
0073デフォルトの名無しさん
05/02/01 20:05:47忘れてるとか
0074デフォルトの名無しさん
05/02/01 20:27:33PerlやRubyなんか最悪。
Javaはキャストだらけでださい。
Cの方がよっぽどまし。
0075デフォルトの名無しさん
05/02/01 20:36:42int hoge;
int hoge_hoge()
{
int geho;
hoge=1;
geho=1;
}
int main(void)
{
hoge_hoge();
printf("%d", hoge);
}
とすれば、全ての関数の中でhogeが使えますが
関数内で定義したgehoはmainの中では使えませんよね?
関数内で作った変数を他の関数からも使えるようにすることはできないのでしょうか?
0076デフォルトの名無しさん
05/02/01 20:40:50いいえ。
0077デフォルトの名無しさん
05/02/01 20:41:120078デフォルトの名無しさん
05/02/01 20:43:12ありえねーッ
本読んでもわかんねーッ
0079デフォルトの名無しさん
05/02/01 20:44:31だれも答える必要ねーッ
0080デフォルトの名無しさん
05/02/01 20:55:16何のためにint hoge_hogeにしたの?
そういう気分だったから?
0081デフォルトの名無しさん
05/02/01 21:16:48>>41
ill-formedtって翻訳かけたら不適格って出てきました。全然違いますね。すみません。
関数で使用できる記憶クラスのくだりはスコープに関連した…が抜けてました。
自信がないですが、extern, static, と関数に使用できるのはあとtypedef・・・?
typedef では関数のポインタに対してで、関数に使用できるとなると違和感があります。
すみません、自分なにかすごい勘違いしてそうです。
>>44
googleで検索かけたら、上のほうに不明瞭と出てきてたので、未定義のことなのかなと
思ってしまいました。infoseek翻訳で調べたら不適格ですね。
となると、本来はコンパイルエラーにならないといけない・・・?
>>50
36の testB.c で記述抜けがありました。試したときは extern void testA(void);
という testA.c の関数定義にそったプロトタイプ宣言を入れてました。
家と会社にある本、解説サイトもこの辺あんまり書いてませんで、
42でも言われてますけど、本当に知りたいなら規格書を読むべきですよね。うーむ。
0082デフォルトの名無しさん
05/02/01 21:17:21C99も読んでねーのかよ。
0083デフォルトの名無しさん
05/02/01 21:52:32nについては、1〜20くらいを考えています。
0084デフォルトの名無しさん
05/02/01 21:55:12再帰すれば?
0085デフォルトの名無しさん
05/02/01 21:57:35roop()
{
int i;
for( i = 0; i < n; i++ )
{
}
0086デフォルトの名無しさん
05/02/01 22:03:190087デフォルトの名無しさん
05/02/01 22:05:40{
int i;
for( i = 0; i < n; i++ )
{
roop();
}
それで、変数ひとつ用意して、if文で規定値になるまで再帰する、みたいな条件を書いたんですが、
なにか変なことしてますか??
0088デフォルトの名無しさん
05/02/01 22:25:38面倒くさいのなら、ソース生成プログラム作れば?
0089デフォルトの名無しさん
05/02/01 22:27:33そんなことせんでもマクロで十分。
0090デフォルトの名無しさん
05/02/01 23:03:41帰ってきたら結論出てるかと思ったのにまだのようなので調べてみたよ。ISO/IEC 9899:1999 より。
> 6.9.1 Function definitions
> 4 The storage-class specifier, if any, in the declaration specifiers
> shall be either extern or static.
となってるので、関数定義につけられる記憶クラスは extern か static だけ。
> 5 If the declaration of an identifier for a function has no storage-class
> specifier, its linkage is determined exactly as if it were declared with
> the storage-class specifier extern.
なので、省略時は extern 扱い。
> 6.2.2 Linkages of identifiers
> 4 For an identifier declared with the storage-class specifier extern
> in a scope in which a prior declaration of that identifier is visible,
> if the prior declaration specifies internal or external linkage, the
> linkage of the identifier at the later declaration is the same as the
> linkage specified at the prior declaration. (後略)
となっているので、先行する宣言がある場合の extern は先行する宣言の
リンケージと同じになるから、 static の後の extern は許容された上、
static が優先されると思われ。一方、
> 3 If the declaration of a file scope identifier for an object or a
> function contains the storageclass specifier static, the identifier
> has internal linkage.
> 7 If, within a translation unit, the same identifier appears with both
> internal and external linkage, the behavior is undefined.
となっているので、extern の後の static は ill-formed ではないが、undefined
だと思われ。gcc だと警告が出るね。
0091デフォルトの名無しさん
05/02/01 23:05:30再帰を使うというのもありだと思う。特に n が可変なら。
0092デフォルトの名無しさん
05/02/01 23:07:13その意見は出てるんだよ!
もっと創造的なアイデアを出せよ。しねよ!
0093デフォルトの名無しさん
05/02/01 23:11:28AAA.hにAAAクラスを定義してあり
BBB.hにBBBクラスを定義してあるとします。
AAAクラスの中でBBBクラスのポインタを宣言したかったので
AAA.hでBBB.hをincludeしました。
BBBクラスでもAAAクラスのポインタが必要になった時に
リンクはどのようにすれば良いんでしょうか?
A→B B→Aと双方をリンクの場合です
よろしくお願い致します…
0094デフォルトの名無しさん
05/02/01 23:13:160095デフォルトの名無しさん
05/02/01 23:19:370096デフォルトの名無しさん
05/02/01 23:24:39Cの問題と言えばCの問題と言う気もするが、
クラスを使っているのなら素直にC++スレに逝け!
0097デフォルトの名無しさん
05/02/01 23:29:26{
int count[N] = {0に初期化};
int max[N] = {どこかで設定};
int i;
for (;;) {
count[0]++;
for (i = 0; i < n-1 && count[i] == max[i]; i++) {
count[i] = 0;
count[i+1]++;
}
if (count[n] == max[n])
break;
なんかやりたいこと;
}
}
0098デフォルトの名無しさん
05/02/01 23:30:170099デフォルトの名無しさん
05/02/01 23:30:210100デフォルトの名無しさん
05/02/01 23:32:56おおう、済まねぇ。ポップアップで見て間とばしてた。じゃ、こんなんでどう?
int i[N], j, start[N], end[N]; /* start[], end[] は適当に設定しる */
for(j=0;j<N;j++) i[j]=start[j]; /* 初期値 */
while(1) {
/* i[] を使って適当に処理 */
j=0;
while(j<N&&++i[j]>=end[j]) {
i[j]=start[j];
j++;
}
if(j==N) break;
}
最後の判定を最初の while に持ってくることもできるし、中の while を for に書き直すことも
できるけど、一応素直にしてみた。
0101デフォルトの名無しさん
05/02/01 23:34:40■ このスレッドは過去ログ倉庫に格納されています