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指针类型是的,因为constvolatile.

顺便说一句,您的代码的另一个问题是您选择的名称。_t作为结尾是为将来在 POSIX 中使用而保留的。

于 2010-08-17T12:57:23.543 回答
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 回答
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到另一个。如果是inta 或 afloat或 a struct,则写作foo = bar会复制。ifsome_structure_t被定义为一个指向结构的指针,现在foobar指向同一个对象。也许这就是你想要的,但对我来说这似乎很冒险。

我想知道 MISRA 是否对作为指针的 typedef 有什么要说的。

于 2010-08-17T16:11:12.217 回答
1

我用

typedef struct some_s *some_t;

在重要的地方我使用const struct some_s*or typedef const struct some_s *const_some_t,但我想这是个人品味的问题。

于 2010-08-17T13:03:13.657 回答
0

我曾经使用第一种样式,但我发现我倾向于对访问结构成员所需的间接级别感到困惑,所以我开始为指针类型添加后缀,例如

typedef struct AStruct *AStructRef;

但后来我意识到我实际上是在重新发明 * 运算符,以防止自己因试图隐藏 * 运算符而感到困惑。所以现在我选择第二种风格。

于 2010-08-17T15:15:19.520 回答