我有两个关于C编程的问题:
适用于int
和uint16_t
,long
和uint32_t
,依此类推。我应该何时使用u*_t
类型而不是int
,long
等等?我发现选择哪一个最适合我的程序会让人感到困惑。
我什么时候需要施放类型? 我的程序中有以下声明:
long * src;
long * dst;
...
memcpy(dst, src, len);
我的朋友将此更改为
memcpy((char *)dst, (char *)src, len).
这只是我遇到的例子。一般来说,在需要演员时我很困惑?
答案 0 :(得分:3)
使用普通类型(int
等),除非您需要精确大小的类型。如果使用有线协议来定义大小字段应为2字节无符号整数(因此为uint16_t
),则可能需要精确大小的类型,但对于大多数工作,大多数情况下,使用普通类型。 (对此有一些警告,但大多数时候,大多数人都可以使用普通类型进行简单的数字工作。如果你正在使用一组接口,请使用接口所规定的类型。如果你'如果使用多个接口和类型冲突,你必须考虑在某些时候使用转换 - 或者改变一个或两个接口。等等。
你朋友添加的演员阵容毫无意义。 memcpy()
的实际原型是:
void *memcpy(void * restrict s1, const void * restrict s2, size_t n);
编译器将long *
值转换为void *
(名义上通过char *
因为转换而来),所有这几乎总是无操作。
更一般地说,当您需要更改某些内容的类型时,可以使用强制转换。您可能需要它的一个地方是按位运算,您需要64位结果,但操作数是32位并保留转换,直到按位运算得到与您想要的结果不同的结果。例如,假设int
为32位且long
为64位的系统。
unsigned int x = 0x012345678;
unsigned long y = (~x << 22) | 0x1111;
这会将~x
计算为32位数量,并且将在32位数量上执行移位,从而丢失多个位。相比之下:
unsigned long z = (~(unsigned long)x << 22) | 0x1111;
确保计算以64位运算完成,并且不会丢失原始值中的任何位。
答案 1 :(得分:0)
&#34;经典&#34;的大小类似int
和long int
的类型可能因系统而异。例如,当访问具有固定宽度数据结构的文件时,这可能会导致问题。例如, int
long
目前在新系统上是64位整数,但在旧系统上只有32位。
intN_t
和uintN_t
类型随C99一起引入,并在<inttypes.h>
中定义。由于它们明确指定了位数,因此消除了任何歧义。作为一项规则,如果您完全担心使代码可移植,则应优先使用这些类型。
答案 2 :(得分:0)
如果您不想依赖编译器,请使用标准库头提供的预定义类型。您编译的每个C库都保证分配适当的类型,至少具有存储其类型声明的大小值的大小。
在你朋友的特定情况下,人们可以假设他做了这种类型的演员只是因为他想指向其他读者,两个指针实际上持有符号字符。或者也许他是一个老式的人,他记得没有void
类型的时候,而“最低公约数”是指向char
的指针。在我的开发人员生活中,如果我想强调一些我的行为,我会做一个明确的类型转换,即使它实际上是多余的。
答案 3 :(得分:-3)
对于第一个问题,请查看:https://stackoverflow.com/questions/11786113/difference-between-different-integer-types
基本上,_t是真正的标准类型名称,没有,它是相同类型的定义。 你是无符号的,不允许负数。
至于你的第二个问题,你经常需要在被调用的函数需要另一种类型的参数时进行强制转换。您可以查看here投标提示,或here...