タイトルをどう書いてよいか分からなかったので
あいまいなタイトルになってしまって申し訳ないです。
見て頂き有難う御座います。
どちらかと言えばCプログラミングのノウハウについて質問です。
ある構造体定義があります。
typedef struct _A{
int a;
int b;
}A;
これを以下のように定義し直し、ユーザには
Bの名前で公開させたいと考えています。
typedef A B;
なぜかと言うと、Aはハード寄りの定義の為、
ハードの定義名を意識させない為にBの名前にした方が分かりやすいと
考えた為です。
このような実装により、分かりやすくなりますでしょうか?
また、他に理想的な実装方法はありますでしょうか?
よろしくお願い致します。
A 回答 (2件)
- 最新から表示
- 回答順に表示
No.2
- 回答日時:
No.1 です。
今後ハードウエアの変更が予想されるのであれば、typedef のような直接の割り当ては危険です。
それこそ、理想は、論理的な層での関数を準備して、その関数の定義以外の場所では、A の存在を見えなくすることです。
そうすれば、LEDの色数が増えても、それまでのプログラムは変更しなくてすみます。
たとえば、ハードウエアの機能が加わることで、物理的な割り当ての順序は簡単に変わってしまいますから。
オーバーヘッドの関係で関数をかぶせられない場合でも、型名をいじるのではなく、適切な変数名と、その後で、必要があれば、ポートの変換をしたほうがいいでしょう。
そうすれば、データ定義の段階で、(見えるにしても)どのポートにLEDが割あたっているのかわかります。
単純にLEDを制御するのなら、
struct port
{
unsigned b0: 1;
unsigned b1: 1;
unsigned b2: 2;
};
に対して、
struct port LED_No1 = (ポートアドレスの割り当てなど)
という定義で、
LED_No1.b0 = 0; で赤くなったり、
LED_No1.b1 = 1; で緑になったり
とかですね。
さらにわかりやすくすのであれば、
#define RED b0
#defien GREEN b1
#define ON 0
#define OFF 1
で、
LED_No1.RED = ON;
LED_No.1.GREEN = OFF;
など。
なるほどとても参考になりました。
オーバーヘッドはそれ程制限が厳しいわけではないので
教えて頂いたイメージで関数をかぶせて実装してみたいと思います。
丁寧に説明して頂きありがとうございました。
質問の締め切りはもう少し時間をあけてから行いたいと思います。
No.1
- 回答日時:
ただ単に、ハードよりの名前を意識させないために、名前を変えるというのは、あまり意味がない気がします。
逆に懸念されるべき事が。
ハードよりの名前と、よりわかりやすい名前というのが考えられるということは、ハードウエアの要素(例えば、具体的なポート番号)と、ユーザーインターフェースの要素(例えば、LEDの色など)という考え方があるということだと思います。
そして、今は、たまたま、それらが、特定の構造体を通じて密接に関わっているということになります。
ケース1:今後ハードウエアの変更などが考えらる場合
このとき、ハードウエアの要素と、ユーザーインターフェースの要素の関係が壊れる可能性があります。この場合、構造体はどちらの要素に併せて変更すべきなのでしょうか?
ハードウエアの構成に併せて変更したとして、LEDの色とアンマッチになるかも知れません。
しかも、プログラムの中では、別の名前の構造体を経由して、「正しい色」を制御しているとしたら、なぜ、目的の色が制御できないのか、判断に困るかも知れません。
ケース2:今後ハードウエアの変更などが「絶対に」ない場合
この場合、はじめから、Aを定義せずに、Bを使うというのも方法だと思います。
一般的にいえば、ユーザーから、ハードウエアを隠す場兄は、ユーザーインターフェースの層と、ハードウエアの層を分離することが考えられます。
ただ、少なからず、オーバーヘッドが発生するので、それとのかねあいになりますが。
例えば、ハードウエアのポートがあって、それに、LEDがつながっているとすれば、ユーザー側には、LED を制御するための関数だけを提供します。
具体的な、ハードウエアへのアクセスはその関数の中だけで行うわけです。
そうすれば、ハードウエアの変更があっても、プログラムの変更は最低限ですみます。
構造体などのデータに直接アクセスする場合でも、今回の例では、ハードウエア側には、構造体のAを、ユーザー側には、構造体Bを別々に定義します。(内容は同じになりますが)
そして、プログラムからは、
1)構造体Bのデータにアクセスして、設定を行う
2)構造体Bをもとに、ハードウエアを制御するための関数を準備して、それを呼び出してもらう。今回の例では、構造体Bから構造体Aへの単純な代入になりますが。
のようにします。
※設定値を読み出す必要があれば、逆の手順になります。
これは、ユーザー側の目的(LEDを点灯させるなど)と、ハードウエアの働き(特定のポートを ON/OFF するなど)を分離するということでもあります。
C++などで、「オブジェクト指向」をすると、このあたりが、もっとスマートに記述できるようになりますが。
この回答への補足
とても丁寧な回答ありがとうございました。
質問文の中で1点訂正なのですが、構造体Aの定義は
自担当コードではなく、includeしているハードウェア側の定義です。そして、例えばLEDだとした場合、今後色数が増える可能性があります。
やはりtypedefA B;が無難なやり方ですかね。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- C言語・C++・C# C言語初心者 構造体 課題について 2 2023/03/10 19:48
- C言語・C++・C# C言語初心者 構造体 課題について 1 2023/03/10 19:30
- C言語・C++・C# プログラムが書けません。 4 2023/01/22 22:57
- 日本語 複合名詞(造語)について教えて欲しいです 2 2022/05/22 17:14
- 法学 法学の問題についてさっぱり分からないので○✕で教えてください 2 2022/10/23 01:05
- 相続・贈与 遺言書の書き方 2 2022/09/18 12:49
- C言語・C++・C# c言語の問題です 3 2023/01/10 16:15
- その他(芸能人・有名人) 私の推しが「ファンは恋愛対象になりますか?」と言う質問に対し「ファンの定義による」とだけ回答しました 5 2022/07/17 19:36
- お酒・アルコール 断酒団体AAについての質問です 今年に入ってからお酒をやめました 自助グループとして「断酒会」と「A 3 2023/05/22 11:39
- 哲学 非構造主義 1 2023/04/06 16:02
関連するカテゴリからQ&Aを探す
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
Integer変数をカラにしたいので...
-
VBAのプログラムで、DIAG = 1# ...
-
C言語 構造体の中に共用体を定...
-
「#undef」と「#define」の使い...
-
構造体のデータを丸ごとコピー...
-
VBAで符号無し整数
-
C++ 構造体の一括初期化 {0}
-
winsockのsendtoで送れるデータ型
-
VB6変数の宣言dim j,k,p,m,n as...
-
値が代入されてない時
-
OpenCV「cv::bitwise_and」につ...
-
VBAの変数のデータ型を変更する...
-
10進数の変換方法
-
VBAにてcolorindexを変数に格納...
-
ヘッダファイルと構造体
-
日付チェック関数について
-
構造体の初期化方法について
-
コンストラクタ内での動的メモ...
-
VB.NETのStructureというのはど...
-
long型のデータをバイト型の配...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
VBAのプログラムで、DIAG = 1# ...
-
Integer変数をカラにしたいので...
-
C++ 構造体の一括初期化 {0}
-
構造体のデータを丸ごとコピー...
-
C言語 構造体の中に共用体を定...
-
「#undef」と「#define」の使い...
-
VBAにてcolorindexを変数に格納...
-
long型のデータをバイト型の配...
-
値が代入されてない時
-
異なる構造体のデータのコピー
-
構造体のポインタにNULLが入らない
-
VBAの変数のデータ型を変更する...
-
変数の初期化について
-
構造体の初期化方法について
-
ユーザー定義型変数の一括初期化
-
FILE構造体がどのように定...
-
charとucharの違い
-
typedefをプログラム中で解除す...
-
整数から16進数への変換 現在c...
-
VB.NETのStructureというのはど...
おすすめ情報