1

我正在研究无符号整数类型的按位运算。我想为 uint8_t、uint16_t、...、uint64_t 类型编写左循环移位函数。

我的解决方案是:

(void*) left_circular_shift(void* number, size_t size);

如果大小为 64,我将 void* 转换为 uint64_t 等,但许多程序员避免使用 void*。我应该为所有无符号整数类型实现该函数吗?

4

4 回答 4

2

在您的情况下,您不能使用 void*。如果你有一个使用 void* 的通用函数,你将无法测量你得到的东西的大小(它怎么知道你的数字在哪里结束?),所以你将无法将它回滚。

关于 Void* 是“安全的”:您可能听说它“不安全”的原因是因为它是一个通用的无类型指针,它需要您确切知道您正在处理的数据类型(您需要把它扔回去)。所以如果使用不小心,更容易导致意外和奇怪的错误。

执行此操作的简单方法是为每个函数使用一个函数。另一种选择是,就像其他人建议的那样,使用通用宏,对此,您可能会感兴趣:http: //www.ibm.com/developerworks/linux/library/l-gcc-hacks/index.html

于 2013-06-22T23:41:01.947 回答
1

对于这样的基本任务,根本没有理由使用指针类型。利用

inline
uintmax_t left_circular_shift(uintmax_t number, size_t size) {
  return /* your implementation goes here */
}

在头文件中,并且

extern inline uintmax_t left_circular_shift(uintmax_t number, size_t size);

在一个 .c 文件中。

然后,现代编译器应该能够在size常量的情况下内联调用。

于 2013-06-23T07:01:22.237 回答
1

在 C++ 中,为所有无符号类型实现此函数是有意义的(保持相同的函数名称)。在 C 中这是不可能的,但您可以为所有类型创建不同的函数,例如left_circular_shift_64等。

如果你想保留你的界面,那么你应该转换void*uint64_t*(而不是uint64_t)。size指定in 字节而不是位也可能很有用。然后可以使用以下构造:

uint64_t value;
left_circular_shift(&value, sizeof(value));

例如,如果类型value更改为,这将有所帮助uint32_t

即使此选项有效且“安全”,我仍建议对每种类型使用不同的功能。支持此选项的一些原因:

  • 不可能将不正确的数据传递给函数,例如floatstruct或对象。
  • 向函数传递不正确的大小是不可能的,例如 62。因此,如果函数得到奇怪的输入,您不需要发明要做什么。
  • 您不需要保持两个参数(指针和大小)的健全,从而减少了错误的可能性。
  • void*在 C++ 中,如果您需要为此类类型实现移位操作,则转换为某些复杂类型(例如具有多重继承的类)可能会出现问题。
于 2013-06-22T23:54:02.147 回答
0

由于您需要取消对 void 指针的引用以移动指向的数字,因此这是不允许的,因为例如指向不同大小数字的指针可能会以不同方式对齐。在不了解更多详细信息的情况下,这可能是适合使用宏的情况 - 如果您想要的话,这可能会更改您的数字变量。

于 2013-06-22T23:39:42.440 回答