• ベストアンサー

関数の書き方について

趣味でプログラムの勉強をしております。 ネットで色々なソースを拝見していると関数の書き方が微妙に異なっているものがあります。 1. int foo(void){ } 2. int foo(void) { } 3. int foo(void) { } 各々のパターンでどのようなメリット・デメリットがあるのかご教示いただければ幸いです。 特に3つ目の関数の型の後に改行をいれる理由がよくわかりません

質問者が選んだベストアンサー

  • ベストアンサー
  • Wr5
  • ベストアンサー率53% (2177/4070)
回答No.1

一応、コンパイラ側では違いはないかと。 当人にとって見やすいかどうか? と、 使用するツール類にとって都合がいいかどうか? という問題だと認識していますけどね。 ちなみに、私はif文などのブロック区切りは1.の書き方を好んで使っています。 # ブロックの終了位置が判りやすい。(ブロック内部はインデントしてる) 関数は2.ですけどね。 # 構造体定義では開始の{は行末。基本的に関数の開始の{だけ行頭で、他は文末に置くようにしていますね…。 2.の書き方だと、「行頭の括弧」でブロックの範囲が見やすい。 となります。 使用しているエディタなどで検索する際にも便利でしょう。 # grepする時に行頭に"{"か"}"がある行を抽出とすると、関数の中身を除いた結果が出てくる。 まあ、いろいろなスタイルがある…ということで。 # 複数人で作業する時はコーディング規約などで既定されるパターンがありますね。 # 私の経験では守らない場合が多かったですが…。(各人のスタイルで記述される) 突き詰め過ぎると宗教戦争になりかねないのでほどほどに。 # 昔から出てくるネタなので…Web検索するといろいろ出てくると思いますよ。 # 「コーディング規約 メリット デメリット」辺りで検索でしょうか…。

siffon9
質問者

お礼

ご回答ありがとうございました。 > 使用するツール類にとって都合がいいかどうか? > という問題だと認識していますけどね。 なるほど何らかのツールを使用する場合に、都合の良い書き方があるということですね。 私の場合は勉強で小規模ばプログラムしか書かない為、テキストエディタしか使用していなかったので、思いつきませんでした。 あとはコーディング規約ですか、確かに業務で複数人でソースを買う場合は統一していないとマズいですね。 キーワードのご紹介ありがとうございました、検索してみます。

その他の回答 (1)

回答No.2
siffon9
質問者

お礼

リンクのご紹介ありがとうございました。 リンク先にもデメリットとして書かれている様に、やはり、型で改行するメリットが良く分かりません。 もしかしたら、昔が型で改行したほうが検索などしやすかったのかも知れませんね。 ご回答ありがとうございました。

関連するQ&A

  • VB 関数

    初めまして。 VB初心者なので,簡単な質問なのかしれませんが御願いします。 C言語で,   int      main        (void) 戻り値の型    関数名      戻り値なし と書きますが,これと同じ意味を持つプログラムをVBで書くとどのようになりますか? 関数の作り方がまだわかってないので教えていただけますか? 宜しく御願いします。 

  • 関数の引数をvoid*でキャストする

    最近見かけたCのプログラムで、関数の引数の型は void* なのですが、その関数を使うときに 引数をvoid*でキャストしていました。 例えば、 func ( (void*) p ); こういうことです。 私の知っている知識では、 void* と 任意の型のポインタは キャストなしに相互に代入可能です。 関数の引数でも、キャストは要らないものだと思っていました。 そうすると、引数を void* でキャストするのは無意味だと思うのですが、・・・ 違うのでしょうか。処理系によるとか。 逆に、関数の引数の型がchar*などで、渡すものが void* のときはどうなのでしょうか。 下のプログラムは、関数byte_orderの引数の型はvoid*ですが、int型へのポインタ( &a )を設定しています。私の環境では、コンパイルエラーも警告もないし、動作も正常です。 #include <stdio.h> #include <string.h> void byte_order(void *vp) { char char_array[4]; strncpy(char_array, vp, 4); printf("出力します:%x %x %x %x\n", char_array[0], char_array[1], char_array[2], char_array[3]); } int main(void) { int a = 0x12345678; byte_order(&a); return 0; } このプログラムは単なる一例であって、質問はバイトオーダに関するものではありません。 また、C言語の質問であって、C++ではありません。

  • 関数でファイルハンドルを読み込む

    このソースファイル'pro1-1.cと名前をつけています)の中の改行を数えるプログラムを作成しています。 main関数でファイルを開き、County関数で数をカウントし、Countx関数で改行の数を表示させる感じで作成しているのですが、County関数での数のカウントの部分で引っかかっています。 途中までできているソースは以下の通りです。 #include <stdio.h> int count[95]={0}; void Countx(void){ int x; for(x=0;x<=95;x++){ if(count[x]!=0){ printf("'%c': %d\n",x+32,count[x]); } } } void County(FILE *fh){ int c; int i; for(c=0;c<=2000;c++){ if(count[c]<32 || count[c]>126){ printf("文字コードエラー\n"); break; while((i=getc(fh))!=EOF){ if(c=='\n'){ count[fh[c]-32]++; } } } } } int main(void){ FILE* fh; if((input=fopen("pro1-1.c","r"))==NULL){ fprintf(stderr,"ファイルが開けません\n"); return 1; } County(fh); Countx(); fclose(fh); return 0; } イメージとしては "\n":○ ←改行の数が入る と言った表示を目指しています。 どなたか正しい解決方法を教えていただけないでしょうか、よろしくお願いします。

  • 割り込みベクタに飛んだ場合必ず”OSIntEnter();”という関数は使わないといけない?

    今、H8S2368のために書かれたプログラムを見ているのですが、このプログラムではuC/OSというプログラムの関数である"OSIntEnter();"という関数が出てくることがわかりました。それで、OSIntEnter()関数というのが現在のソースプログラムの中でどのように使われているのかを、全ソースに対して検索をかけてみたところ、必ずと言っていいほど割り込みベクタのプログラムである下記のようなプログラムで使われていることがわかりました。 __interrupt(vect=22) void INT_IRQ6(void) { OSIntEnter(); OSSemPost(CmxInt); OSIntExit(); } たぶん、割り込みが発生して、その割り込みの種類の割り込みベクタに飛ぶときにこの”OSIntEnter()”というのを使わなければならないのだろうと推測しているのですが、 もし、割り込みベクタで”OSIntEnter()”を使わなかった場合、どのような問題がおきるのでしょうか?

  • bsearch関数の呼び出しで

    C言語の深いところまで理解しようとしてます。今まで使わないだろうと思っていた関数へのポインタ なのですが、 2分探索のところで bsearch関数というのが出てきました。 この関数は第5引数に比較関数を引数にするのですが p = bsearch(&ky, x, nx, sizeof(int), (int (*)(const void *,const void *))int_cmp ); という形でサンプルソースには載っています。 この (int (*)(const void *,const void *))int_cmp の部分なのですが、まず戻り値をキャストするなら int (*)ではなく(int *)ではないでしょうか。 それとint_cmpは比較関数なのですが、引数が左側に来る、というところが納得できません。 ちなみにソースファイルをcppのままだとコンパイルできませんでした.cに拡張子を直したらコンパイルできました。 説明が足りないところがあったら指摘してください。お願いします。

  • qsortの関数について

    qsortの関数について 下記のようにある本に関数の呼ぶ時、関数名(int_cmp)が引数(const void *, const void *)の後に書かれて理由を教えて頂きたい。よろしくお願いします。 質問のプログラム int int_cmp(const int *a ,const int *b) { ------ } int main { qsort(x, nx , y, (int (*)(const void *, const vois *))int_cmp);

  • 関数ポインタを返す関数の型をtypedefする方法

    C言語について質問します。 ある関数を定義するとします。 その関数は引数としてintを一つ取り、返値としてその関数と同じ型の関数へのポインタを返すようにしたいのですが、どのように書けばよいのでしょうか? そして、その関数の型をtypedefで定義したいです。 例えば、FNをtypedefしたいその関数の型だとすると、 typedef FN (*FN)(int); のようなFNを定義したいのですが、上のように書いても当然コンパイラ(VC9)に怒られます。 最悪、 typedef void* (*FN)(int); とvoidポインタを返すように定義しておいて、そのポインタを返値として受け取った側でFNにキャストし直す方法で対処できなくもないですが、ちょっと強引過ぎる気がします。 何かいい方法はあるのでしょうか? boost::functionあたりを使えばできそうな、そうでもないような気がしますが、できれば純粋なCでの解決法を望みます。 よろしくお願いします。

  • ポインタのポインタの関数受け渡しについて

    現在ポインタのポインタを利用したプログラムを作成しています。 main関数で int **dt; と宣言したとして、配列のセットにはset関数を、 表示に関する処理をpt関数で行いたいと思っています。 void set(int ??); void pt(int ???); int main(void){ int **dt; set(??); pt(???); } void set(int ??){ dt = (int**)malloc(sizeof(int*) * k); for(i = 0; i < k; i++){ dt[i] = (int*)malloc(sizeof(int*) * k); } のように配列サイズの動的確保が目的 } void pt(int ???){ 二重forループ{ printf(dt[i][j]); } } ??、???には何を入れるべきかが理解できません。 ご教示のほどよろしくお願いいたします。

  • 関数をまとめる

    関数をつくるときにどうまとめれば良いのでしょうか? 例えば下のようなプログラムがあったとします. #include<iostream> int add(int, int); int multi(int, int); int main(void) {    int a = 4;    int b = 3;    std::cout << add(a, b) << std::endl;    std::cout << multi(a, b) << std::endl; } int add(int a, int b) {    return a + b; } int multi(int a, int b) {    return a * b; } add関数は足し算の結果,multi関数は掛け算の結果を返します. やっている内容はかわらずわざわざ2つに分ける必要があるか?と思ってしまいます. 要は, int arithmetic_operations(int a, int b, int pattern) {    int result;    switch(pattern) {       case 1:          result = a + b;          break;       case 2:          result = a - b;          break;       case 3:          result = a * b;          break;       case 4:          if(0 == b) {             exit(1);          }          result = a / b;          break;       default:          break;    }    return result; } このような関数を用意してpattern変数で計算を制御するほうがまとまりがあると思います.ですが,いちいち中身を確認しながらプログラムを書く必要があるので可読性は低くなります. どちらがベターでしょうか?

  • gdbで無名名前空間の関数にブレイクポイント

    Windows+cygwin+emacsでc++のプログラムを勉強しています。デバッガとしてemacs上でgdbを使っているのですが、無名の名前空間にある関数にブレイクポイントを設定する方法がわかりません。例えば、 namespace {  void foo() {    ...  } } int main(void) {  foo(); } のようなfoo.cppファイルをコンパイルしてfoo.exeファイルを作り、それをgdbによりデバッグするとします。そこで、gdb上で b main とすると、mainに入ったところにブレイクポイントが設定されますが、 b foo としても、Function "foo" not defined.と表示されてブレイクポイントが設定されません。無名の名前空間にある関数にはどのように入力してブレイクポイントを設定するのでしょうか。とりあえず、今は行番号によりブレイクポイントを設定しています。ご存じの方がいらっしゃいましたら、ご教授ください。お願いします。

専門家に質問してみよう