質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

Q&A

解決済

3回答

699閲覧

C言語の関数の定義と型についてのエラーを解消したい

toipoko

総合スコア1

C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

0グッド

0クリップ

投稿2023/01/29 13:53

前提

ここに質問の内容を詳しく書いてください。
kyuという関数で、型に問題があるような?エラーが出ていますがどこが間違っているのかわからないから知りたいです。

実現したいこと

ここに実現したいことを箇条書きで書いてください。
kyuという関数が動くようにしたい。

発生している問題・エラーメッセージ

test.c: In function ‘main’: test.c:7:3: warning: implicit declaration of function ‘kyu’ [-Wimplicit-function-declaration] 7 | kyu((int)3,(int)1000000); | ^~~ test.c: At top level: test.c:10:8: error: conflicting types for ‘kyu’ 10 | double kyu(int D,int N){ | ^~~ test.c:7:3: note: previous implicit declaration of ‘kyu’ was here 7 | kyu((int)3,(int)1000000); | ^~~

該当のソースコード

C

1#include<stdio.h> 2#include<stdlib.h> 3#include<time.h> 4#include<math.h> 5 6double main(void){ 7 kyu((int)3,(int)100); 8} 9 10double kyu(int D,int N){ 11 int i,j,l,seed,m; 12 double k,g,size; 13 14 seed=time(NULL); 15 srand(seed); 16 17 m=0; 18 19 for(i=0;i<N;i++){ 20 l=0; 21 for(j=0;j<D;j++){ 22 g=drand48(); 23 l=l+g*g; 24 } 25 if(l<1){ 26 m++; 27 } 28 } 29 k=pow(2.0,(double)D); 30 size=(double)k*(double)m/(double)N; 31 printf("%e",size); 32} 33

補足情報(FW/ツールのバージョンなど)

UbuntuとemacsでC言語を動かしてます。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

episteme

2023/01/29 14:48

関数 kyu が double 値をreturn していません。void kyu(...) の誤りでは?
guest

回答3

0

ベストアンサー

Cは、ソフトウェア的に整理された考えができる前に言語として成立してしまったので、いろいろと「キレイでない」ところがあります。
そのひとつで、先に情報が提示(宣言や定義)されていない関数に出会うと、呼び出しの記述に出てきた型の引数を受け取ってint型を返す関数「ということにする」ので、
kyu((int)3,(int)100);
が登場した時点で
int kyu(int,int);
な関数が「ある」ことになってしまいます。
(この「歴史的な解釈」に対して、現代のコンパイラが最大限の抵抗をしているが「警告」としてimplicit declaration of function ‘kyu’を出すことなのですが...)

ところが、その後
double kyu(int D,int N){
としてkyu関数が定義されるので、これが先程のint kyu(int,int);と矛盾してしまい、今度はエラーになる、という次第。

解決は、他の回答にも既に示されている通り、「ということにする」をさせないように、kyu関数の情報を呼び出しより先に与えてしまうことです。関数プロトタイプ宣言で返り値/関数名/引数名だけ教えてやるか、関数定義を先において関数の情報を全部与えてしまうか。文法的にはどちらでもかまいません。

あと、普通に書いた数値(リテラル)は整数と解釈されるので、kyu((int)3,(int)100);のintへのキャストは全く無意味です。コンパイラにも多分無視されるので害はないですけれど、普通でないことをしているので、プログラムを読む人は「なんだろう?」と身構えてしまいます...pow(2.0,(double)D);のキャストも、引数として渡される際に自動的にdoubleに拡張されるので無駄ですし、size=(double)k*(double)m/(double)N;も、kがそもそもdoubleなので無駄なキャスト。そして、演算においては表現範囲の広い方に参加メンバーが揃えられる(必要なら拡張される)ので、mやNも黙っていてもdoubleに拡張されます。「念のため」という言葉もありますけれど、あまり過剰なのはちょっと...

ついでにkyu()関数の冒頭で

seed=time(NULL); srand(seed);

としていますが、これは多分間違い。kyu()関数を一度しか呼んでいないのでこのプログラムでは問題ありませんが。
srand()を呼ぶ意味の再確認が必要かと思います。

その他、他回答へのコメントで触れたdouble main()とか、返り値のないdouble kyu()(kyu()関数に何をさせたい?)などもありますけれど、全部言っても質問者さんが飽和しちゃうかしら。(実は全部説明するのがちょっと面倒なだけ...)

投稿2023/01/29 23:14

thkana

総合スコア7639

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

kyuをmainより上に書く必要があると思います。
また、main関数にreturn 0が必要なように思います。

c

1#include<stdio.h> 2#include<stdlib.h> 3#include<time.h> 4#include<math.h> 5 6double kyu(int D,int N){ 7 int i,j,l,seed,m; 8 double k,g,size; 9 10 seed=time(NULL); 11 srand(seed); 12 13 m=0; 14 15 for(i=0;i<N;i++){ 16 l=0; 17 for(j=0;j<D;j++){ 18 g=drand48(); 19 l=l+g*g; 20 } 21 if(l<1){ 22 m++; 23 } 24 } 25 k=pow(2.0,(double)D); 26 size=(double)k*(double)m/(double)N; 27 printf("%e",size); 28} 29 30int main(void){ 31 kyu((int)3,(int)100); 32 return 0; 33} 34

投稿2023/01/29 15:21

h_krmt

総合スコア7

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

SaitoAtsushi

2023/01/29 16:24

main に関してだけは return を省略できる規則があります。 それより kyu のほうに return がないのは良くないですね。 C の仕様上は return がないときに返却値を使おうとしたときに未定義の挙動ということになっているのでそうでないなら一応は仕様内ではあるのですが……。
thkana

2023/01/29 22:46

> main関数にreturn 0が必要なように思います。 それをいうなら `double main(void)` のほうが先のような気がするけれど。普通じゃありませんが、コンパイラがいいっていうならあり。
h_krmt

2023/01/30 13:12

SaitoAtsushiさん thkanaさん お二人の仰る通り、回答に不備が多かったですね。 ご指摘ありがとうございました。
guest

0

kyumainより上に書くか、プロトタイプ宣言をしてください。

C言語はソースコードを1回読めば処理できるような構造として設計されたため、先にソースコード内で宣言もしくは定義された関数しか呼ぶことができません。

投稿2023/01/29 14:30

maisumakun

総合スコア145184

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問