C言語のプログラミングコードの書き方でわからないところがあります><
C言語のプログラミングコードの書き方でわからないところがあります><
C言語のプログラミング
以下の関数を呼び出すmain関数を記述しろという問題です。試行錯誤しましたがコンパイルすら通りません。
main文で②の関数から返ってくる値を受け取る変数ってvoid (**x)();は違いますか?
②の行は何がなんだかわかりません。
どなたか取り敢えず②の行が何をしているか教えてください。。。><
void hoge(void) {
printf("hoge\n");
}
void (*a(void))(void){ //①
printf("a\n");
return hoge;
}
void (*(*b(void))(void))(void){ //②
printf("b\n");
return a;
}
void (*(*(*c(void))(void))(void))(void){ //③
printf ("c\n");
return b;
}
以下の関数を呼び出すmain関数を記述しろという問題です。試行錯誤しましたがコンパイルすら通りません。
main文で②の関数から返ってくる値を受け取る変数ってvoid (**x)();は違いますか?
②の行は何がなんだかわかりません。
どなたか取り敢えず②の行が何をしているか教えてください。。。><
void hoge(void) {
printf("hoge\n");
}
void (*a(void))(void){ //①
printf("a\n");
return hoge;
}
void (*(*b(void))(void))(void){ //②
printf("b\n");
return a;
}
void (*(*(*c(void))(void))(void))(void){ //③
printf ("c\n");
return b;
}
Re: C言語のプログラミングコードの書き方でわからないところがあります><
Manaさん返信ありがとうございます!
ということは、例えば①を のように置き換えたら,②は, のようになるということですかね?分かりにくくてすいません。。。
>呼び出すだけならこれでおしまいだがそうじゃないっぽい?
多分、関数それぞれ(a,b,c)に戻り値を入れる変数がいるのかなと思います。
最初は、以下のようにやってみたのですが駄目でした。
ということは、例えば①を のように置き換えたら,②は, のようになるということですかね?分かりにくくてすいません。。。
>呼び出すだけならこれでおしまいだがそうじゃないっぽい?
多分、関数それぞれ(a,b,c)に戻り値を入れる変数がいるのかなと思います。
最初は、以下のようにやってみたのですが駄目でした。
Re: C言語のプログラミングコードの書き方でわからないところがあります><
かずまさん返信ありがとうございます!
void1 (*a(void2))(void3){ //①
①に関しては、上のようにvoidに番号を付けると、
引数がvoid2で、戻り値が "引数がvoid3で、戻り値がvoid1の関数" へのポインタである関数aの宣言と定義。と認識しています。
分かりにくくてすいません。。。
>次のプログラムの意味は分かっているのですか?
すいませんよくわかりません。。。
関数aの引数と、関数aの戻り値のポインタ先の関数の引数にそれぞれvoidを渡している?
void1 (*a(void2))(void3){ //①
①に関しては、上のようにvoidに番号を付けると、
引数がvoid2で、戻り値が "引数がvoid3で、戻り値がvoid1の関数" へのポインタである関数aの宣言と定義。と認識しています。
分かりにくくてすいません。。。
>次のプログラムの意味は分かっているのですか?
すいませんよくわかりません。。。
関数aの引数と、関数aの戻り値のポインタ先の関数の引数にそれぞれvoidを渡している?
Re: C言語のプログラミングコードの書き方でわからないところがあります><
>るるらさん
いやvoidの意味は分かります。。。
コード内②の行で何をしているかいまいちわからないです。
いやvoidの意味は分かります。。。
コード内②の行で何をしているかいまいちわからないです。
Re: C言語のプログラミングコードの書き方でわからないところがあります><
これは分かりますよね。
これはどうですか?
その次が (1) の a です。
a() は hoge を返しますから、x は hoge。x() は hoge()。
変数 x を使わないと、 a()() は、a(); hoge();
その次が (2) の b です。 b() は a を返しますから、y は a。y() は a()。
変数 y を使わないと、 b() は a を返しますから、b()() は、a()。
b()()(); は b(); a(); hoge();
変数 x を使わないと、 a()() は、a(); hoge();
その次が (2) の b です。 b() は a を返しますから、y は a。y() は a()。
変数 y を使わないと、 b() は a を返しますから、b()() は、a()。
b()()(); は b(); a(); hoge();
Re: C言語のプログラミングコードの書き方でわからないところがあります><
こういうお遊びのような問題は関数プロトタイプだけ見て悩んでも意味ないですよ。
残りの部分が戻り値の型というのが分からないのですかね。
ヒントを順番に考えてみました?
b関数の戻り値の型は
void (*(*b(void))(void))(void)
から関数名とその直後にある括弧の引数並びを除いた部分ですよ。
voidじゃないですよ。
void (*(*)(void))(void)ですよ。
日本語で書くと「引数がvoidで戻り値がvoidの関数へのポインタを返す引数がvoidの関数へのポインタ」型ですよ。
日本語で説明するのも難しいので次のコードを見て理解してください。
かずま氏の関数呼び出し演算子の重ね掛けを理解するにはこちらを先に理解したほうがいいかもね。
残りの部分が戻り値の型というのが分からないのですかね。
ヒントを順番に考えてみました?
b関数の戻り値の型は
void (*(*b(void))(void))(void)
から関数名とその直後にある括弧の引数並びを除いた部分ですよ。
voidじゃないですよ。
void (*(*)(void))(void)ですよ。
日本語で書くと「引数がvoidで戻り値がvoidの関数へのポインタを返す引数がvoidの関数へのポインタ」型ですよ。
日本語で説明するのも難しいので次のコードを見て理解してください。
かずま氏の関数呼び出し演算子の重ね掛けを理解するにはこちらを先に理解したほうがいいかもね。
int main(void)
{
{ /* 戻り値の型を順に継承 */
typedef void (*fnx_t)(void);
typedef fnx_t (*fny_t)(void);
typedef fny_t (*fnz_t)(void);
fnx_t x = a();
fny_t y = b();
fnz_t z = c();
}
{ /* 関数プロトタイプから直に */
typedef void (*fnx_t)(void);
typedef void (*(*fny_t)(void))(void);
typedef void (*(*(*fnz_t)(void))(void))(void);
fnx_t x = a();
fny_t y = b();
fnz_t z = c();
}
return 0;
}
Re: C言語のプログラミングコードの書き方でわからないところがあります><
>Manaさん
継承していくやり方を見て、関数bの宣言の意味がようやくわかりました。関数a,b,cの戻り値だけに着目するとわかりやすくなるんですね。
ありがとうございました!
>かずまさん
二重括弧がどうしてもしっくりきません。
二重括弧について自分なりの解釈なんですが間違っていたら教えてください。 普通の変数のポインタに変数のアドレスを代入することでその変数として振る舞うことができる上記では" *k "は" l "として振る舞う。
これと同様にa()はhogeとして振る舞うので、a()()はhoge()と同じ意味を指す。
また、ここにきて初歩的な質問で申し訳ないのですが、関数aは戻り値がありますよね?main文ではその戻り値を入れる変数はなくて良いのですか?
継承していくやり方を見て、関数bの宣言の意味がようやくわかりました。関数a,b,cの戻り値だけに着目するとわかりやすくなるんですね。
ありがとうございました!
>かずまさん
二重括弧がどうしてもしっくりきません。
二重括弧について自分なりの解釈なんですが間違っていたら教えてください。 普通の変数のポインタに変数のアドレスを代入することでその変数として振る舞うことができる上記では" *k "は" l "として振る舞う。
これと同様にa()はhogeとして振る舞うので、a()()はhoge()と同じ意味を指す。
また、ここにきて初歩的な質問で申し訳ないのですが、関数aは戻り値がありますよね?main文ではその戻り値を入れる変数はなくて良いのですか?
Re: C言語のプログラミングコードの書き方でわからないところがあります><
誤:main文ほいしょー さんが書きました: また、ここにきて初歩的な質問で申し訳ないのですが、関数aは戻り値がありますよね?main文ではその戻り値を入れる変数はなくて良いのですか?
正:main関数
普通は、関数からの戻り値は呼び出し元で使うためにあります。だって、使わないんだったらvoidでいいじゃん、って話です。
ただ、例外的に、わざと捨てていることがあります。今回のケースがこれに相当しているのかもしれません。
バグのないプログラムはない。
プログラムは思ったとおりには動かない。書いたとおりに動く。
プログラムは思ったとおりには動かない。書いたとおりに動く。
Re: C言語のプログラミングコードの書き方でわからないところがあります><
関数 a は戻り値がありますよね。ほいしょー さんが書きました: また、ここにきて初歩的な質問で申し訳ないのですが、関数aは戻り値がありますよね?main文ではその戻り値を入れる変数はなくて良いのですか?
main関数では、次のプログラムのように
その戻り値を入れる変数 x はなくてよいのですか? という質問と同じですが、ご理解いただけますか?
Re: C言語のプログラミングコードの書き方でわからないところがあります><
関数へのポインタの理解が十分ではないのかな?
No.4でなんとなく関数へのポインタ型変数の宣言しているようだけども。
関数名に関数呼び出し演算子を付けて関数を呼び出せるように、関数へのポインタに関数呼び出し演算子を付けて関数を呼び出すこともできる。
かずま氏のコードに続けるとこうゆうこと。
関数の戻り値が関数へのポインタだったらそこからさらに続けて呼び出すこともできるというわけ。
No.4でなんとなく関数へのポインタ型変数の宣言しているようだけども。
関数名に関数呼び出し演算子を付けて関数を呼び出せるように、関数へのポインタに関数呼び出し演算子を付けて関数を呼び出すこともできる。
かずま氏のコードに続けるとこうゆうこと。
関数の戻り値が関数へのポインタだったらそこからさらに続けて呼び出すこともできるというわけ。
Re: C言語のプログラミングコードの書き方でわからないところがあります><
外野席からのボヤキ
c言語とはこんなにも難しいものなのでしょうか??!。
もちろん私は質問に答える能力はありません。
以前に聞いたことがあります。
C言語も高級言語だと、、、それなら誰にでもソースが分かるような記述がいいような気がしますが、
これは私の偏見でしょうか???
初心者にも分かるような記述をするのがこの言語の本来の姿と思っていました。
そうかといっても、私には分かりやすく書く方法も知りませんが。
c言語とはこんなにも難しいものなのでしょうか??!。
もちろん私は質問に答える能力はありません。
以前に聞いたことがあります。
C言語も高級言語だと、、、それなら誰にでもソースが分かるような記述がいいような気がしますが、
これは私の偏見でしょうか???
初心者にも分かるような記述をするのがこの言語の本来の姿と思っていました。
そうかといっても、私には分かりやすく書く方法も知りませんが。
- softya(ソフト屋)
- 副管理人
- 記事: 11677
- 登録日時: 13年前
- 住所: 東海地方
- 連絡を取る:
Re: C言語のプログラミングコードの書き方でわからないところがあります><
C言語はどちらかと言うと自由度が高い言語なので、読み辛いソースコードは当然のごとく書けます。三郎 さんが書きました:外野席からのボヤキ
c言語とはこんなにも難しいものなのでしょうか??!。
もちろん私は質問に答える能力はありません。
以前に聞いたことがあります。
C言語も高級言語だと、、、それなら誰にでもソースが分かるような記述がいいような気がしますが、
これは私の偏見でしょうか???
初心者にも分かるような記述をするのがこの言語の本来の姿と思っていました。
そうかといっても、私には分かりやすく書く方法も知りませんが。
初心者だと分かりづらいソースコードになりがちです。なので、分かりやすく書けるのは熟練者と言えます。
そもそも共同作業で分かりづらいソースコードを書くのはご法度ですので、熟練するほど読みやすいソースコードを書くようになります。
言語仕様の自由度と初心者にも書きやすい綺麗なコードを書ける仕様はだいたい矛盾します。
C言語は記述性と自由度と高速性を優先して設計されていますので、「初心者にも分かるような記述をするのがこの言語の本来の姿と思っていました。」と言う意図は本来ありませんね。
読みやすさとかわかり易さを優先したのは、COBOL,BASIC,PASCALなどの言語だと思います。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。
Re: C言語のプログラミングコードの書き方でわからないところがあります><
オフトピック
>外野席からのボヤキ
まぁ,「呼び出してみろ」というのが問題になっているくらいだから
わざと わからないように 書いてあるわけで,
実際に自分でコード書くときは わからなくならないように 書けばいいと思いますよ.
私もこんなコード見せられたら「は?」ってなりますし,
実際に書かなきゃならないとしたら例えば↓みたいに自分にわかるように書きますし……
まぁ,「呼び出してみろ」というのが問題になっているくらいだから
わざと わからないように 書いてあるわけで,
実際に自分でコード書くときは わからなくならないように 書けばいいと思いますよ.
私もこんなコード見せられたら「は?」ってなりますし,
実際に書かなきゃならないとしたら例えば↓みたいに自分にわかるように書きますし……