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

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

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

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

Q&A

解決済

2回答

722閲覧

switch~case文と同様の処理を関数ポインタの一次元配列を使ってサブ関数を呼ぶプログラムを作成

amu.

総合スコア2

C

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

0グッド

0クリップ

投稿2023/05/16 11:42

実現したいこと

・switch~case文と同様の処理を関数ポインタの一次元配列を使ってサブ関数を呼ぶプログラムを作成する。
・キーボードから0~15の自然数1つを入力する。
・入力した数字が1なら”みかん”、2か3なら”りんご”4なら”ばなな”、5なら”スイカ”、6なら”いちご”、7なら”メロン”、8なら”ぶどう”、それ以外の場合は”該当するものがありません。”を表示する。
・ビジュアルスタジオを使用しています

前提

ここに質問の内容を詳しく書いてください。
(例)
TypeScriptで●●なシステムを作っています。

該当のソースコード

#define _CRT_SECURE_NO_WARNINGS #include <stdio.h> /*プロトタイプ宣言*/ int sub(int* , int ); void main(void) { /*変数の宣言*/ int* pointer[16]; int input = 0; int ret; int(*jump)(int* pointer, int input); /*関数ポインタ*/ /* 表示関数のアドレスを関数ポインタに代入 */ jump = &sub; /* 関数ポインタを使って関数コール */ ret = sub(pointer,input); /* 0を入力で表示を終了します */ int end = 0; do { printf("\n表示を終了する場合、0を入力してください\n"); scanf("%d", &end); rewind(stdin); } while (0 != end); } /*switch~case文と同様の処理関数*/ int sub(int* pointer ,int input) { /*データ入力*/ printf("0~15の自然数を1つを入力\n"); scanf("%d", &input); if (input == 1) { printf("みかん\n"); } else if (input >= pointer[2] && pointer[3] >= input) { printf("りんご\n"); } else if (input == pointer[4]) { printf("ばなな\n"); } else if (input == pointer[5]) { printf("スイカ\n"); } else if (input == pointer[6]) { printf("いちご\n"); } else if (input == pointer[7]) { printf("メロン\n"); } else if (input == pointer[8]) { printf("ぶどう\n"); } else { printf("該当するものがありません。\n"); } }

試したこと

関数ポインタを使用したときの関数のコードがわからなく、つまずいています。普通の関数であれば

if (input == 1) { printf("みかん\n"); }

上記のように書いていいと思うのですが、関数ポインタを使用したときの紐づけがわからなくアドレス等を頂ければ幸いです。

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

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

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

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

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

jimbe

2023/05/16 11:58 編集

> int(*jump)(int* pointer, int input); /*関数ポインタ*/ > /* 表示関数のアドレスを関数ポインタに代入 */ > jump = &sub; > /* 関数ポインタを使って関数コール */ > ret = sub(pointer,input); 関数ポインタを使っていませんね。 おそらく求められている仕様を勘違いしているのでは。 jump を配列化して jump[input](~) 的な呼び出しで switch と同じことをするというのではないでしょうか。
otn

2023/05/16 12:10

「switch~case文と同様の処理を関数ポインタの一次元配列を使ってサブ関数を呼ぶ」という意味が理解できてないようですね。ということは自分でこういうプログラムを書いてみようと思いついたのではなく、与えられた課題だと思いますが、 課題が求めている方向と関係ないプログラムを書いています。このままプログラムを改善しても意味が無いです。 課題を出した人に「課題の意味がわからない」と質問することは可能ですか? (授業や研修であれば可能と思いますが、書籍だと無理でしょうね)
guest

回答2

0

ベストアンサー

キー入力などなどは自分でやって。

C

1#include <stdio.h> 2#include <string.h> 3 4void mikan() { printf("みかん\n"); } 5void ringo() { printf("りんご\n"); } 6void banana() { printf("ばなな\n"); } 7void suika() { printf("スイカ\n"); } 8void ichigo() { printf("いちご\n"); } 9void melon() { printf("メロン\n"); } 10void budou() { printf("ぶどう\n"); } 11void sonota() { printf("該当するものがありません。\n"); } 12 13int main() { 14 void (*func[])() = { 15 sonota, mikan, ringo, ringo, 16 banana, suika, melon, budou, 17 sonota, sonota, sonota, sonota, 18 sonota, sonota, sonota, sonota, 19 }; 20 for ( int i = 0; i < 16; ++i ) { 21 printf("%2d : ", i); 22 func[i](); 23 } 24}

投稿2023/05/16 12:17

episteme

総合スコア16614

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

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

episteme

2023/05/17 12:03 編集

...おや? 反応ないな。関数ポインタの配列に見えなかったかしら。 typedef void (*func_ptr)(); // 関数ポインタ func_ptr func[] = { ... }; // の配列 ならちっとはマシか。
amu.

2023/05/19 23:46

返信遅れて申し訳ありません。 関数ポインタについての知識が浅く、うまく活用できていませんでした。 episteme様のように一つ一つサブ関数にしてコードを組んだらうまくいきました。 ありがとうございました!
guest

0

「関数ポインタの一次元配列がどうの」言われたから → 仕方なく無理矢理使ってる感みたいな

C

1typedef int (*IndexCvt)( int ); 2int Zero( int ){ return 0; } 3int AsIs(int i){ return i; } 4int Dec1(int i){ return i-1; } 5 6//各入力値に関して,入力値から配列 FruitNames[] のindexを求める手段 7const IndexCvt ToFruitIndex[16] = 8{ 9 Zero, //0 10 AsIs, AsIs, Dec1, Dec1, Dec1, Dec1, Dec1, Dec1, //1 - 8 11 Zero, Zero, Zero, Zero, Zero, Zero, Zero //9 - 15 12}; 13 14const char * const FruitNames[] = 15{ 16 "該当するものがありません。", 17 "みかん", "りんご", "ばなな", "スイカ", "いちご", "メロン", "ぶどう" 18}; 19 20int main() 21{ 22 for( int input=0; input<=15; ++input ) 23 { printf( "%d -> %s\n", input, FruitNames[ ToFruitIndex[input](input) ] ); } 24 25 return 0; 26}

やってることの意味:

もしも入力値がそのまま出力文字列を決めるための値(ここでは 配列 FruitNames[] のindex)としてそのまま使えるような話であったならば,
printf( "%s\n", FruitNames[入力値] );
とかすれば良いだけで,特段面倒なことは無い.
でも,実際の問題ではそうなってない.入力値と出力文字列の対応関係が微妙な感じになっているから困るなぁ.

アイデア:そしたら【入力値 → 配列 FruitNames[] のindex】という変換処理を間に噛ませれば良いよね.

実装:その変換方法を決定する手段を「関数ポインタの一次元配列」という形でねじ込んだ.

投稿2023/05/18 01:23

編集2023/05/18 05:54
fana

総合スコア11654

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問