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

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

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

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

関数

関数(ファンクション・メソッド・サブルーチンとも呼ばれる)は、はプログラムのコードの一部であり、ある特定のタスクを処理するように設計されたものです。

Q&A

解決済

5回答

4917閲覧

C言語:関数定義の場所について

cresc

総合スコア14

C

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

関数

関数(ファンクション・メソッド・サブルーチンとも呼ばれる)は、はプログラムのコードの一部であり、ある特定のタスクを処理するように設計されたものです。

0グッド

1クリップ

投稿2018/01/17 00:34

編集2018/01/17 12:00

C言語で関数定義をする際に、たいていの参考書ではmain関数の外で定義されてますが、C言語で書くプログラムのコードが膨大になるにつれて、関数定義も増えてくるので、main関数の外で定義すると、main関数と関数定義間を行ったり来たりする際にまたぐ行数が多くなるため、コードを読むのに時間がかかると思うので、main関数内の初めて自作の関数を使う直前に関数定義をした方がいいと思うのですが、この書き方は良くないですか?

C

1#include <stdio.h> 2 3int main(){ 4 int na, nb; 5 6 puts("二つの整数を入力してください。"); 7 printf("整数1 : "); 8 scanf("%d", &na); 9 printf("整数2 : "); 10 scanf("%d", &nb); 11 12 int maxof(int x, int y){ 13 if (x > y) 14 return (x); 15 else 16 return (y); 17 } 18 printf("大きい方の値は%dです。\n", maxof(na, nb)); 19 20 return (0);

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

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

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

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

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

ttyp03

2018/01/17 01:00

main関数内に定義するの意味がわからないのですが、具体例を書いていただけますか。
cresc

2018/01/17 12:01

具体例のコードを追加しました。
guest

回答5

0

残念ながら、標準的なC言語では、関数の外でしか関数を定義できません。関数内関数は、GCCなど一部のコンパイラの拡張です。

投稿2018/01/17 00:55

maisumakun

総合スコア145123

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

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

episteme

2018/01/17 01:02

あ、僕はてっきり「main()の定義されたファイルの外(=別ファイル)にそいつが呼んでる関数を...」って言いたいのかと思ってた。
cresc

2018/01/17 10:55

そうだったのですか。main関数内に定義してもちゃんと動いたのでC言語は関数内関数の機能があると思ってたのですが、使っているコンパイラがたまたま関数内関数の機能が拡張されてたということなのですか?
maisumakun

2018/01/17 12:28

多分そうだと思います(たとえば、clangやVisual C++では動かないようです)。
cresc

2018/01/17 15:25

なるほど、それではコンパイラによって実行できなくなる危険があるからmain関数に関数は定義しない方がいいですね。回答ありがとうございました。^^
guest

0

ベストアンサー

そもそも論ですが...
『その場で定義した方が読みやすい』≒『一度しか呼ばない』関数を書くのはほとんど無駄です。
適切にコメントを付ければべた書きしてもいいんじゃないでしょうか。

コールバック関数として定義する場合、今後再利用が望まれる場合は除きます。


また、コードが膨大になってあちこち飛び回る必要があるのは、構造化が弱いせいかもしれません。
責任に着目して適切にモジュールを分割、さらに適切に命名/コメントをしてください。
関数の中身を読み返す機会はそこまで増えないかと。

追記

誤解を招いてしまったようなので...

手続き的な処理をとにかく関数に細分化しようとする人がいます。
特にひどいときは、void hoge(void)みたいな関数が乱立されているのです。
『いったりきたり』という質問内容でしたので、このような状況を想定してしまいました。

適切に機能を切り分けること、つまり強度/結合度が担保されていることが重要です。
これが保たれ、同時に適切に命名出来るのなら、むしろ関数に切り分けるべきでしょう。

詭弁に逃げるようで恐縮ですが、機能の切り分けは『多過ぎはダメ』『少なすぎもダメ』です。

投稿2018/01/17 05:15

編集2018/01/19 15:00
LouiS0616

総合スコア35658

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

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

cresc

2018/01/17 11:50

回答ありがとうございます。 おっしゃる通り「一度しか呼ばない関数」を定義するのだったら適切なコメントを付けた方が綺麗なコード書けそうですね。 関数を作りすぎるのは構造化がしっかりできてなかったという考えは今までなかったので、とても勉強になりました。これからは構造化がしっかりできてるかということも気を付けて書いてみます。
LouiS0616

2018/01/17 12:23 編集

質問のコードを見ましたが、この程度なら条件演算子を使えば良さそうです。 printf("大きい方の値は%dです。\n", (na > nb) ? na : nb); 濫用するととんでもなく読みづらくなるので注意は必要ですが。
cresc

2018/01/17 15:28

質問のコードはmain関数内に関数を定義することのいみがわからないとのことだったので例としてあげたものです。私の想定している状況は大きなプログラムですので、LouiS0616さんの回答でしっかりと私の疑問の回答になってました。
guest

0

私見では「好きにすれば?」です。
いまどきの開発環境なら呼んでる関数にジャンプする機能がアタリマエに用意されてますから。

投稿2018/01/17 00:40

episteme

総合スコア16614

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

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

0

標準のC言語では、関数外でしか定義できません。
関数定義が増えてきたなら、機能や処理別に
別ファイルに定義して、コンパイル/リンクするだけです。

投稿2018/01/17 12:30

ai_2013_dev

総合スコア338

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

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

0

C++になってしまいますが、短い関数なのにいちいち外出ししないといった制約をどうにかするためにラムダ式があります。
C++も許容されているならばあまり書き直しがないのでC++にしてラムダ式で書くといった手もあります。

投稿2018/01/17 01:36

m_yoko

総合スコア156

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

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

cresc

2018/01/17 11:16

回答ありがとうございます。 今回私が想定しているのは短い関数ではなく、関数定義全般に共通しての話です。C++はまだ学習したことがないため、C++の学習をしましたら、ラムダ式も使ってみようと思います。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問