1

不是将实际指针发送到一个值,而是将该值强制转换为一个指针。我在 GTK 程序的 GUI 界面代码中找到了这些示例。

g_signal_connect (pastebutton[pane],
                  "clicked",
                  G_CALLBACK(on_paste_button_pressed),
                  (void*)((long)pane<<4));

在上面的例子中,我指的是g_signal_connect. 当on_paste_button_pressed被 GTK2 调用时,on_paste_button_presseduser_datavoid 指针转换回来,如下所示:

int pane = ((long)user_data) >> 4;

实际上,我在代码中添加了这个特定的示例,但我基于已经存在的内容。我添加了位移以避免有关投射的警告。该程序本身有四个窗格,其中包含相当多的小部件,复制和粘贴按钮允许您将所有值从一个窗格复制到另一个窗格。

这种将值转换为指针地址的方法是否经常使用,是否有不应该使用的原因?

编辑:

从整数到空指针的转换也可以像这样实现:

void* void_ptr = some_int - NULL;
4

7 回答 7

3

它被使用。它在执行所需操作时非常常用

不使用它的一个原因是理论上指针大小可能小于源整数大小。

不使用它的另一个原因是它只允许您将一个整数数据传递给回调。如果将来您需要添加另一条数据(或切换到非整数),则必须找到并重写回调访问传递数据的每个位置。因此,如果将来有可能必须扩展数据,最好创建一个struct(即使int此时它只包含一个)并将指针传递给该struct.

但是,如果您确定您永远不必传递除该单个整数之外的任何内容并且您的整数适合 a void *,那么这种技术无论如何都不会被破坏。

PS迂腐地说,C 和 C++ 似乎都没有整数到空 * 到整数转换的往返保证,即它们不保证它会工作并恢复原始整数值。

于 2009-12-21T14:57:42.087 回答
3

您应该使用宏 GINT_TO_POINTER() 和 GPOINTER_TO_INT() 在指针和整数之间进行转换。

glib:类型转换宏

于 2009-12-21T15:14:31.963 回答
1

将整数转换为指针用于按值传递值。如果确实需要引用参数,这是首选方法,因为编译器不需要取消引用指针。

位移是一个坏主意,因为它可能导致溢出。

对于真正可移植的代码,您应该使用 intptr_t 作为整数类型,因为它很适合指针。

于 2009-12-21T14:48:24.777 回答
0

它已被使用,但绝不是便携式的,因此您必须小心。

C 标准不要求指针类型至少具有与整数类型一样多的位,因此您可能并不总是能够做到这一点。

但我不记得有任何平台实际上指针小于整数,所以你可能是安全的(尽管在技术上不安全)。

我可以认为铸造可能存在的唯一原因是消除对齐警告的可能性。C1x 草案第 6.3.2.3 节规定:

整数可以转换为任何指针类型。除非前面指定,结果是实现定义的,可能没有正确对齐,可能不指向引用类型的实体,并且可能是陷阱表示。

于 2009-12-21T14:48:20.280 回答
0

它确实在这些情况下有用,是的。它适用于许多平台,但可能会失败,因为任意整数并不总是有效的指针值,尽管您所做的移位应该可以解决这个问题。指针也可能无法保存整数可以保存的所有值。如果您long在指针为 32 位的平台上使用 64 位,就会出现这种情况,当然,由于您正在移动值,即使指针和整数大小相同,它也可能会失败。如果你想使用这个技巧,你可能应该检查sizeof (void*)根据您使用的整数类型的大小,如果指针不够大,则在运行时检查实际值。使它完全可移植可能不值得,以便您在需要的平台上使用实际的指针,因此要么将自己限制在这个技巧有效的平台上,要么完全放弃这个技巧。

于 2009-12-21T14:49:53.083 回答
0

我觉得刚刚好。没有关于使用频率的统计数据,但你真的在乎吗?

不过,我不确定我是否理解位移的帮助。

于 2009-12-21T14:50:11.553 回答
0

这是来自 C-FAQ:

问:整数如何与指针相互转换?我可以暂时将整数填充到指针中,反之亦然吗?

答:曾几何时,保证可以将指针转换为整数(尽管人们永远不知道是否需要 int 或 long),并且可以将整数转换为指针,并且指针当转换为(足够大的)整数并再次返回时保持不变,并且转换(和任何映射)旨在“对于那些知道机器寻址结构的人来说不足为奇”。换句话说,有一些对整数/指针转换的先例和支持,但它们始终依赖于机器,因此不可移植。一直需要显式强制转换(尽管早期编译器很少抱怨如果你忽略它们)。

ANSI/ISO C 标准,为了确保 C 可以广泛实施,削弱了那些早期的保证。指针到整数和整数到指针的转换是实现定义的(参见问题 11.33),并且不再保证指针可以在不改变的情况下转换为整数并返回。

将指针强制转换为整数,或将整数强制转换为指针,从来都不是好的做法。当您需要一个可以容纳任何一种数据的通用插槽时,联合是一个更好的主意。

另见问题 4.15、5.18 和 19.25。

参考文献:K&R1 秒。A14.4 页。210 K&R2 秒。A6.6 页。199 ISO 秒。6.3.4 基本原理 3.3.4 H&S 部分 6.2.3 页。170,秒。6.2.7 第 171-2 页

于 2009-12-21T15:00:50.417 回答