アプリ版:「スタンプのみでお礼する」機能のリリースについて

現在、C言語の勉強中です。

プロトタイプ宣言は関数内で宣言をすることは可能でしょうか。
その際、宣言が有効なのはその関数内ということになりますか?
OS:windows7
VS2010 express

で次のプログラムを記述してもコンパイルエラーにはなりませんでした。
もし、プロトタイプ宣言もスコープを持つとしたら、関数plus()の中でminus()
を呼び出したところでwarningかエラーをはくと考えましたが、出ませんでした。

どなたか、教えてください。

#include <stdio.h>

int main(void){
char* plus(void);//プロトタイプ宣言
char* minus(void);//
char *ans;
ans = plus();
printf("mainFunc = %s", ans);
ans = minus();
printf("mainFunc = %s", ans);
}

char* plus(){
char *answer;//関数の戻り値はポインタ
answer = minus();//プロトタイプ宣言なしで関数を使用
printf("plusFunc = %s",answer);
return "plus success\n";
}

char* minus(){
return "minus success\n";
}

A 回答 (7件)

>LinuxやUnixの環境でテストしなくては


>ダメということですね。

どういう事でしょう?
もしかしてコンパイル時に警告やエラーが起きないことで、自分のコーディングが正しいかの判定をしようとしてますか?
もしそうなのでしたらコンパイル時にエラーや警告もなく、実際に実行して意図した動作をしたとしても、コーディングは間違っている場合もありますのでお気を付けください。

よくあるのはNULLと0の混同。
    • good
    • 0

同意>#5. あの会社は正直なところ「『C++ があるんだから, もう C なんかど~でもいいじゃん』って考えてるんじゃないか」と思えるときがある. 未だに C99 にすら対応してないくらいだし.



ちなみに今回の話は「関数へのポインタ」とは全くもって無関係です>#4.
    • good
    • 0
この回答へのお礼

LinuxやUnixの環境でテストしなくては
ダメということですね。

ありがとうございました。

お礼日時:2014/04/15 03:16

>Cのスコープって実際にはコンパイラによって違うんですね。


>っていうか。。。結構、いいかげんなものなのでしょうか?

「VC++のCコンパイラモードでのスコープの扱いはおかしい」という話だと思うんですが・・・
「いいかげんなのはVC++のCコンパイラモード」といった方がわかりやすいですか?
    • good
    • 0
この回答へのお礼

私の言いたかったことを正確に表現して
いただいてありがとうございました。

表現力が乏しくてすみません。。。

お礼日時:2014/04/15 03:12

まったく違う話になります。



私はこれを見たとき、関数ポインタに見えてしまって。
一緒に勉強してもらえたらと思って、回答してみました。

char hoge() {
return ('A');
}
main () {
char *abc();

abc=hoge;

abc();

// この場合、abcは関数のプロトタイプではなく、char (*abc)();というポインターそのもの。

}

多分この書式のせいで、コンパイラーによって、問題が出るのかもしれません。。

正式なプロトタイプは
char* plus(void);//プロトタイプ宣言
なら、
typedef char * (FUNC)(void);
ということで、これらが問題を起こしているのかも、と
私はちょっと、推測してしまいました。
    • good
    • 0
この回答へのお礼

勉強になりました。
ありがとうございました。

関数のポインタ宣言は私のコンパイラでは
char *abc() //エラー
char (*abc)() //OK
でした。こちらも環境依存かも?

あわてて、勉強したので返信がおそくなってしまいました。

お礼日時:2014/04/15 03:08

あ~, たぶんわかった.



C において 1つのプログラムに「同じ外部名を持つ実体」は 1つしか存在できない. だから, 当該プロトタイプの「本来のスコープ」から外れても「その外部名である以上それだ」と判断できるってことじゃないかな. ちなみに gcc だと (こっちは逆にスコープを「正しく」判断した結果として) エラーになりますね.

そして main と plus を入れ替えると VC はアホなエラーメッセージを出しやがる.

#2 の話は, おそらく単純なバグ.
    • good
    • 0
この回答へのお礼

ありがとうございました。

Cのスコープって実際にはコンパイラによって違うんですね。
っていうか。。。結構、いいかげんなものなのでしょうか?

お礼日時:2014/04/15 00:58

main関数を少し変えて、


#include <stdio.h>
int main(void){
char* plus(void);//プロトタイプ宣言
int minus;
{
char* minus(void);//
char *ans;
ans = plus();
printf("mainFunc = %s", ans);
ans = minus();
printf("mainFunc = %s", ans);
}
minus=-1;
}
これでも、文法違反はないはずですが、Visual StudioのCコンパイラではエラーになります。
同じVisual StudioのC++コンパイラを使うとエラーにはなりません。Cコンパイラのバグかもしれません。
    • good
    • 0
この回答へのお礼

ありがとうございました。
cygwinのgccでいただいたsampleのコードをコンパイルしました。
おっしゃる通りエラーはなく実行できました。
こちらはVSのcコンパイラのバグだと理解しました。

mainの中のブロック内で宣言したプロトタイプのスコープは
予想通りでしたが、なぜmain直下に記述したプロトタイプは
main外の関数で有効になるのでしょうか?

しつこくて、すみません。

#include <stdio.h>
int main(void){
char* plus(void);//プロトタイプ宣言
//char* minus(void); //ここで宣言した場合はmainの外でも有効?
int minus;
{
char* minus(void);//ここで宣言したので、当然、plus()では無効
char *ans;
ans = plus();
printf("mainFunc = %s", ans);
ans = minus();
printf("mainFunc = %s", ans);
}
minus=-1;
}
char *plus(){
char *minus(void);//再度、プロトタイプ宣言
char *ans;
ans = minus();
printf("%s", ans);
return "plus\n";
}
char *minus(){
return "minus\n";
}

お礼日時:2014/04/15 00:14

そもそも C ではプロトタイプなしで関数を呼び出してもエラーにはなりません.



でもって, プロトタイプ宣言自体は「普通の」規則に従ったスコープを持ちます.
    • good
    • 0

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!