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

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

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

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

関数

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

配列

配列は、各データの要素(値または変数)が連続的に並べられたデータ構造です。各配列は添え字(INDEX)で識別されています。

Q&A

解決済

2回答

488閲覧

C言語 配列で関数演算後の値を使いたいです。

pzzz_6

総合スコア1

C

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

関数

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

配列

配列は、各データの要素(値または変数)が連続的に並べられたデータ構造です。各配列は添え字(INDEX)で識別されています。

0グッド

0クリップ

投稿2022/09/23 10:22

前提

ソースコードでは1つのファイル、1つの関数からの呼び出しですが、

配列はヘッダファイルに記述したいです。
配列は複数の関数で使いたいです。

以上のことを踏まえてどのような実装が綺麗か教えていただきたいです。

実現したいこと

関数の演算結果を配列の値に用いたいです。どのような実装をすれば綺麗にまとまるか知りたいです。
配列のclacNum_20_25 の箇所にはcalcNum(20,25)の値を入れたいです。

今の状態だと配列を使う関数で毎回 clacNum_20_25 の値を求めなければいけません。新しい関数を作成して、この配列を使う時に気づけない可能性があるのでこれは避けたいです。

該当のソースコード

C

1#include <stdio.h> 2 3#define ARRAY_X 2 4#define ARRAY_Y 3 5 6#define clacNum_20_25 0 7#define clacNum_30_35 0 8#define clacNum_40_45 0 9 10int calcNum(int a , int b); 11 12struct NUM { 13 int a; 14 int b; 15}; 16 17struct NUM num[ARRAY_X][ARRAY_Y] = { 18 { 19 {35 , 40}, 20 {45 , 50}, 21 {55 , 60} 22 }, 23 { 24 {clacNum_20_25,50},//clacNum(20,25) 25 {clacNum_30_35,60},//clacNum(20,25) 26 {clacNum_40_45,70} //clacNum(20,25) 27 } 28}; 29 30int main (void){ 31 num[1][0].a = calcNum(20,25); 32 num[1][1].a = calcNum(30,35); 33 num[1][2].a = calcNum(40,45); 34 35 int i,j; 36 for(i = 0; i < ARRAY_X; i++){ 37 for(j = 0; j < ARRAY_Y; j++){ 38 printf("%d\t%d\n",num[i][j].a,num[i][j].b); 39 } 40 } 41 42} 43 44int calcNum(int a , int b){ 45 int c; 46 c = a + b; 47 return (c); 48}

試したこと

補足情報(FW/ツールのバージョンなど)

ここにより詳細な情報を記載してください。

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

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

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

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

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

jimbe

2022/09/23 10:28

配列、というのは struct NUM num[ARRAY_X][ARRAY_Y] のことでしょうか。 例としてかもしれませんが、各値は固定値に見えます。なぜ予め計算した結果を配列に入れないのでしょうか。
pzzz_6

2022/09/23 10:35

配列、というのは struct NUM num[ARRAY_X][ARRAY_Y] のことでしょうか。  そうです。 例としてかもしれませんが、各値は固定値に見えます。なぜ予め計算した結果を配列に入れないのでしょうか。  例を簡単にしすぎていますが、本来は複雑な計算をする関数の値を配列に代入したいです。 質問の本質としては、関数の計算結果を配列の値で使いたい場合、どのような実装がよいか。ということになります。 載せているソースコードでは必要ないですが、よろしければ教えていただければと思います。
maisumakun

2022/09/23 10:49

> 例を簡単にしすぎていますが、本来は複雑な計算をする関数の値を配列に代入したいです。 それを初期化で回してしまう、では何がよくないのでしょうか?
dodox86

2022/09/23 10:57

@質問者 pzzz_6さん ご質問に直接関係は無いですが、他者の文の引用をするときは行頭に">"、">"を付けると読んだ者に混乱が無くてよいです。これはEメールなどでも使われる一般的なマナーです。 例えば > 載せているソースコードでは必要ないですが、よろしければ教えていただければと思います。 >> 配列、というのは struct NUM num[ARRAY_X][ARRAY_Y] のことでしょうか。 >  そうです。 のように使います。
pzzz_6

2022/09/23 11:09

>> それを初期化で回してしまう、では何がよくないのでしょうか? > 私の知識不足で発想がありませんでした。ほかの方からの回答もあり解決しました。ありがとうございます。 dodox86さん、丁寧に教えていただきありがとうございます。
guest

回答2

0

ライブラリを作る際等は、 include ファイル内にプリプロセッサ命令を書いて extern の有無を切り替えたりすることがありました。
num の表示を関数・別ファイル化する形にしてみました。
(NUM_MAIN の有無で extern/初期化を切り替えています。initNum も include 内で宣言していますが、main 以外で初期化する場合を想定しているだけです。)

q_lcdf8djc0wqo24.c

c

1#include <stdio.h> 2 3#define NUM_MAIN 4#include "q_lcdf8djc0wqo24.h" 5 6void printNum(); 7 8int main (void){ 9 initNum(); 10 11 printNum(); 12} 13 14int calcNum(int a , int b){ 15 int c; 16 c = a + b; 17 return (c); 18} 19 20void initNum() { 21 num[1][0].a = calcNum(20,25); 22 num[1][1].a = calcNum(30,35); 23 num[1][2].a = calcNum(40,45); 24}

q_lcdf8djc0wqo24.h

c

1#ifndef Q_LCDF8DJC0WQO24_H_ 2#define Q_LCDF8DJC0WQO24_H_ 3 4#define ARRAY_X 2 5#define ARRAY_Y 3 6 7struct NUM { 8 int a; 9 int b; 10}; 11 12#ifndef NUM_MAIN 13extern 14#endif //NUM_MAIN 15struct NUM num[ARRAY_X][ARRAY_Y] 16#ifdef NUM_MAIN 17= { 18 { 19 {35 , 40}, 20 {45 , 50}, 21 {55 , 60} 22 }, 23 { 24 {/*clacNum_20_25*/0, 50}, 25 {/*clacNum_30_35*/0, 60}, 26 {/*clacNum_40_45*/0, 70} 27 } 28} 29#endif //NUM_MAIN 30; 31 32void initNum(); 33 34#endif /* Q_LCDF8DJC0WQO24_H_ */

q_lcdf8djc0wqo24_sub.c

c

1#include <stdio.h> 2 3#include "q_lcdf8djc0wqo24.h" 4 5void printNum() { 6 for(int i = 0; i < ARRAY_X; i++){ 7 for(int j = 0; j < ARRAY_Y; j++){ 8 printf("%d\t%d\n",num[i][j].a,num[i][j].b); 9 } 10 } 11}

実行結果

plain

135 40 245 50 355 60 445 50 565 60 685 70

投稿2022/09/23 14:49

編集2022/09/23 14:50
jimbe

総合スコア12632

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

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

pzzz_6

2022/09/24 05:47

ありがとうございます。 具体的にコードを示していただけたので、大変勉強になりました。 参考にさせていただきます。
pzzz_6

2022/09/24 05:54 編集

コンパイルするとエラーが出ました(私のやり方が悪いのかもしれません) undefined reference to `printNum' q_lcdf8djc0wqo24_sub.cをq_lcdf8djc0wqo24.cでincludeしたら改善したのですが、対処法としてこれは合っているのでしょうか?
jimbe

2022/09/24 06:57

*.c を *.c に include することは、余程なことで無ければやらないことと思います。 undefined ということはコードをコンパイルした後のリンクで sub を入れていないのではないでしょうか。
pzzz_6

2022/09/24 07:59

その通りでした。ありがとうございます。
guest

0

ベストアンサー

ヘッダファイルには、

#define ARRAY_X 2 #define ARRAY_Y 3 struct NUM { int a; int b; }; extern struct NUM num[ARRAY_X][ARRAY_Y];

と記述しておけばいいです

投稿2022/09/23 10:36

y_waiwai

総合スコア87749

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

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

pzzz_6

2022/09/23 10:56

ありがとうございます。 externを使うのですね。 この通りにしてみると配列への代入のための計算は一度で済みました。勉強になりました。 この構造体配列を複数の関数で使い、その呼び出しの順番が決まっていない場合についてです。 この場合の実装は、main関数でそれらの関数が呼び出される前に値の計算と代入を行えば良いという認識であっていますでしょうか?
y_waiwai

2022/09/23 10:59

そのとおりです。 値を代入しないと、初期値が出てくるだけです
pzzz_6

2022/09/23 11:11

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問