我正在研究无符号整数类型的按位运算。我想为uint8_t,uint16_t,...,uint64_t类型编写左循环移位函数。
我的解决方案是:
(void*) left_circular_shift(void* number, size_t size);
如果size为64,我将void *转换为uint64_t等,但许多程序员避免使用void *。我应该为所有无符号整数类型实现该函数吗?
答案 0 :(得分:1)
在您的情况下,您不能使用void *。如果你的泛型函数无效*你将无法测量你得到的大小(它如何知道你的数字在哪里结束?),所以你将无法将其强制转换。
关于Void *是“安全的”:你可能听说它“不安全”的原因是因为它是一个通用的无类型指针,它要求你准确地知道你正在处理什么样的数据用(你需要把它扔掉)。因此,如果不小心使用,它更容易引起意外和奇怪的错误。
这样做的简单方法是为每个使用一个函数。与其他人建议的一样,另一种选择是使用通用宏,关于这一点,您可能会对此感兴趣:http://www.ibm.com/developerworks/linux/library/l-gcc-hacks/index.html
答案 1 :(得分:1)
在C ++中,为所有无符号类型实现此函数是有意义的(保持相同的函数名称)。在C语言中,这是不可能的,但您可以为所有类型创建不同的函数,例如left_circular_shift_64
等。
如果您想保留自己的界面,则应将void*
转换为uint64_t*
(而不是uint64_t
)。以字节为单位指定size
可能也很有用,而不是位。然后可以使用以下结构:
uint64_t value;
left_circular_shift(&value, sizeof(value));
例如,如果value
的类型更改为uint32_t
,这将有所帮助。
即使此选项有效且“安全”,我建议对每种类型使用不同的函数。支持此选项的一些原因:
float
,struct
或对象。void*
转换为某些复杂类型(例如,具有多重继承的类)。答案 2 :(得分: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
为常量的情况下,现代编译器应该能够内联调用。
答案 3 :(得分:0)
由于您需要取消引用void指针以移动指向的数字,因此不允许这样做,因为例如指向不同大小的数字的指针可能以不同方式对齐。 在不知道更多细节的情况下,这可能是宏适合的情况 - 这可能会改变您的数字变量,如果这是您想要的。