2012-01-27 83 views
0

我似乎无法理解以下指针符号之间的区别,有人可以引导我吗?指针语法查询

typedef struct some_struct struct_name; 
    struct_name this; 
    char buf[50]; 
    this = *((some_struct *)(buf)); 

现在我想了一下周围玩耍,做上述的事情,如:

struct some_struct * this; 
    char buf[50]; 
    this=(struct some_struct *)buf; 

就我个人而言,我认为两者的实现应该产生相同的结果,有人能指导我两者之间是否有区别,如果是的话,有人能指出吗?

谢谢。

+1

摆脱使用“this”作为变量名现在的习惯。如果你现在正在做C语言,有一天你会做C++,并且你会后悔那种习惯。 – 2012-01-27 20:16:53

+0

@PaulTomblin:C和C++是不同的语言。我不认为在C中使用“this”作为变量名是一件大事。 – 2012-01-27 20:27:32

+0

@ Paul Tomblin感谢您的建议,我其实只是想澄清事情,所以无意中将其写成变量名。 – Abdullah 2012-01-27 20:30:29

回答

3

在您的第一个片段中,this不是指针,它是some_struct的实例。你所做的任务做了buf内容的浅拷贝(即memcpy()),就好像它也是some_struct的实例一样。

在第二个片段中,this是一个指针,它只是指向buf的地址。

所以,基本上总结一下,第一个片段this不是一个指针,结构被复制到它。第二,它是一个指针,并被分配到与buf相同的内存(即不是副本)。

+0

非常感谢,这解释了:) – Abdullah 2012-01-27 20:32:03

+0

@Abdullah,你有点太快了。这个答案是正确的(我给了它我的+1),但它并没有告诉你你的代码存在隐藏的问题。请看我的答案。 – 2012-01-27 20:47:13

0

在第二个中,“this”将指向“buf”的第一个内存位置。在第一个例子中,你将得到一个编译器错误(我不认为你可以用=来指定C中的结构体,尽管我可能是错误的),或者buf的内容(直到sizeof(struct_name))将被复制进入这个位于堆栈上的位置。

0

两种方法都有问题。

  • 对齐:您的buf可能未正确对齐结构类型的变量。如果是这样,这会产生未定义的行为(UB):在最好的情况下,它会中止你的程序,但它可能会造成比这更糟糕的事情。
  • 初始化:在第一种情况下,您访问未初始化的内存以供读取。在最好的情况下,给你非特定的数据,这是一些随机字节。在最糟糕的情况下,char是您平台上的带符号整数类型,并且您按照上述方法击中char => UB的陷阱代理。 (你的第二个情况下也会遇到同样的问题,一旦你尝试在指针的另一端访问的对象。)

如何避免一切:

  • 始终初始化变量。一个简单的= { 0 }应该在所有情况下。
  • 从不使用char作为通用类型字节,但使用unsigned char
  • 从未投任意取向的一个字节缓冲器到另一种数据类型。如果需要,反过来,将struct对象投射到unsigned char
+0

非常感谢Jens,今后我会尽量避免这种错误,欢呼:) – Abdullah 2012-01-27 20:58:36