【问题标题】:char* ptr to structchar* ptr 到结构
【发布时间】:2012-05-03 18:02:07
【问题描述】:

我遇到了一些我不太理解的 C 代码。以下编译并运行得很好。 1) 为什么我可以将 char* 转换为 struct* 和 2) 使用这个成语而不是 void* 有什么好处?

struct foo
{
    int a;
    int b;
    char *nextPtr;
};

. . .

// This seems wrong
char *charPtr = NULL;

// Why not
//void *structPtr = NULL;

struct foo *fooPtr;
fooPtr = (struct foo*)charPtr;

// 编辑删除字符串部分,因为这不是问题的重点。

【问题讨论】:

  • 什么是string?这是 C 还是 C++?
  • 您可以使用 C 风格的强制转换语法将任何东西强制转换为任何东西。编译器只是信任你。在void* 发明之前有一段时间使用char* 代替,但那个时间已经过去了。
  • 抱歉,如果相关,请使用 c++。
  • 我看不到你的代码是如何运行的,你写到 fooPtr->a,但是 fooPtr 是 NULL。

标签: c


【解决方案1】:
  1. 您可以在指针类型之间进行转换,因为这是语言为您提供的灵活性。但是,您应该谨慎并知道自己在做什么或可能出现问题。

  2. 没有。使用属性指针类型有一个优点,因此不需要转换。如果这不可能,那么是否使用 void* 并不重要,尽管对于阅读您的代码的开发人员来说可能会更清楚一些。

【讨论】:

  • 使用用于调试目的的 char * 在一个句子中打印结构的元素,例如 printf("*fooPtr contains %s\n", charPtr)
  • @AhmedJolani:这似乎是一个可怕的设计。结构可以包含转换为不可打印字符的数据,并且可能会或可能不会正确终止。
  • 根据他的情况,两个整数永远不会有 NULL 值 \x00,如果 *nextPtr 为 NULL,那么 printf 将完美地描述这些值,并且整数总是有一个可打印的字符(数字) .
  • 好吧,我不确定整数永远不会包含0,但即便如此,如果将来需要更改结构怎么办?
  • 它会,并且 0 的 ASCII 码是 0x30 而不是 0x00 (NULL POINTER),它永远不会终止字符串读取过程。
【解决方案2】:

1) 如前所述,您可以转换为 C 中的任何指针类型。(C++ 可能有更复杂的规则,我不知道其中的细节)...

2) char*void* 的优势在于,您可以在 char* 上执行指针运算,但不能在 void* 上执行。

根据您发布的代码,执行指针运算的智慧可能值得怀疑,但对于具有可变长度“数据”的结构,它通常很方便。

【讨论】:

    【解决方案3】:

    我认为你只是遇到了 C 的经典“双刃剑”之一。

    实际上,指针就是一个指针——只是一个保存地址的变量。从理论上讲,您可以尝试强制该指针指向任何东西;一个结构,一个整数,一个(填空)。当您尝试将指向某事物的指针转换为指向其他事物的指针时,C 不会抱怨;它表明你知道你在做什么。如果你不这样做,天堂会帮助你:)

    实际上,是的,一个 void * 可能是一种更恰当的方式来声明一个可以指向任何东西旁边的指针,但我不确定它在操作上有多大的不同。不会发誓,因为可能会有编译器优化,如果指针是强类型的,可能会发生这种情况......

    【讨论】:

      猜你喜欢
      • 2020-08-14
      • 1970-01-01
      • 2013-05-15
      • 1970-01-01
      • 2012-11-16
      • 2012-10-24
      • 1970-01-01
      • 1970-01-01
      • 2017-07-26
      相关资源
      最近更新 更多