0

理論的には、本はCでADTを次のように宣言しているようです。

struct some_structure;
typedef some_structure *some_structure_t;

ほとんどのコードは以下を使用します:

struct some_structure;
typedef some_structure some_structure_t;

私はそれconstが最初のスタイルでは機能していないことを知っています。これが、実際の図書館が最初のアプローチを使用しない唯一の理由ですか?それ以上の通知や提案はありますか?

4

5 に答える 5

4

抽象データ型を意味しますか?コードスニップセットの構文エラーから;-)を抽象化すると、とtypedefの問題があるため、ポインタ型のyesは嫌われていると思います。constvolatile

ところで、コードのもう1つの問題は、選択した名前です。_tエンディングはPOSIXでの将来の使用のために予約されています。

于 2010-08-17T12:57:23.543 に答える
2

それは、他の人のコードがそれらの型で何をするかによって異なります。あなたのライブラリのユーザーとして、some_structure_t が構造体へのポインターではなく構造体であると仮定すると、次のようにするかもしれません。

some_structure_t *p;

p = malloc( sizeof *p);
memcpy( p, &another_p, sizeof *p);

some_structure_t組み込みプログラマーとしての私の背景かもしれませんが、それを使用するコードについてもっと知りたいです。真に抽象化された型であり、エンド ユーザー コードでパラメーターまたは戻り値としてのみ使用される場合でも、その型をサポートするライブラリで処理する必要があります。次のコードを見た場合、私はダブルテイクを行います。

some_structure_t some_function( some_structure_t foo)
{
    some_structure_t retval;

    retval = malloc( sizeof *retval);  // assigning pointer to struct?
    retval->member = foo->member;      // using -> instead of .?

    return retval;                     // returning potentially large structure on stack?
}

おそらくこれが最大のものです - あるものsome_structure_tから別のものへのコピーです。intか か のfloat場合、struct書き込みfoo = barはコピーを作成します。some_structure_tが構造体へのポインタとして定義されている場合、現在はfoobar同じオブジェクトを指しています。多分それはあなたが望んでいることですが、私には危険に思えます.

MISRA はポインタである typedef について何か言いたいことがあるのだろうか。

于 2010-08-17T16:11:12.217 に答える
2

抽象データ型は、「オブジェクト」などに対して効果的にアクションを実行する方法として役立ちます。

可能であれば、C では、構造体で「typedef」キーワードを完全に避けてください。それは実際に起こっていることを覆い隠します。初心者としてstruct AStruct、typedef を使用したくなる場所はいつでも明示的に入力することをお勧めします。

そこから、最初のパラメーターとして「抽象データ型」(または私が考えるのが好きなオブジェクト) へのポインターを受け取り、次に通常のパラメーターを受け取る関数を宣言することにより、「抽象データ型」に対して「アクション」を実行します。その後。

例えば

int some_func( struct AStruct *pObject, int param1, int param2 ) {
  if ( ( param1 < 0 ) || ( param2 < 0 ) )
    return( 0 );
  pObject->val = param1 + param2;
  return( 1 );
}

次に使用します:

#include <stdio.h>
int main( void ) {
  struct AStruct myObject;

  if ( some_func( &myObject, 10, 12 ) ) {
    printf( "Processed: %d\n", myObject.val );
  } else {
    printf( "Failed\n" );
  }
  return( 0 );
}
于 2010-08-17T15:26:18.613 に答える
1

私が使う

typedef struct some_s *some_t;

const struct some_s*重要なのは、またはを使用するtypedef const struct some_s *const_some_tことですが、それは個人的な好みの問題だと思います。

于 2010-08-17T13:03:13.657 に答える
0

以前は最初のスタイルを使用していましたが、構造体メンバーにアクセスするために必要な間接参照のレベルについて混乱する傾向があることがわかったので、ポインター型に接尾辞を追加し始めました。

typedef struct AStruct *AStructRef;

しかし、* 演算子を隠蔽しようとして混乱するのを防ぐために、* 演算子を効果的に再発明していることに気付きました。だから今、私は2番目のスタイルに行きます。

于 2010-08-17T15:15:19.520 に答える