C 使用'时进行铸造==';操作人员

C 使用'时进行铸造==';操作人员,c,arrays,C,Arrays,在我的C程序中,有一行使用了“==”运算符,两个操作数被转换为char,如下所示: char top_level_domain[sizeof(char) * 128]; ... if((char)top_level_domain[i] == ':' || (char)top_level_domain[i] == '/') 这是推荐的/安全的吗?如果不是,我应该如何检查数组中某个元素的内容 编辑:添加声明并删除对字符文本的强制转换一般来说,避免强制转换更安全有效,因为它允许编译器执行类

在我的C程序中,有一行使用了“==”运算符,两个操作数被转换为char,如下所示:

char top_level_domain[sizeof(char) * 128];
...
if((char)top_level_domain[i] == ':' 
    || (char)top_level_domain[i] == '/')
这是推荐的/安全的吗?如果不是,我应该如何检查数组中某个元素的内容

编辑:添加声明并删除对字符文本的强制转换一般来说,避免强制转换更安全有效,因为它允许编译器执行类型检查。例如,找出错误:

// Let's pretend you forgot or mixed up the type here...
char **top_level_domain;
// ...
if ((char) top_level_domain[i] == (char) ':')
    ...
或者也许

char top_level_domain[sizeof(char) * 128];
...
// Whoops! forgot to type [i]
if((char)top_level_domain[i] == ':' 
    || (char)top_level_domain == '/')
哎呀!你忘了去引用指针,你得到的是垃圾。编译器会给您一条诊断消息,但由于您使用了强制转换,诊断消息就消失了

注意:这实际上会在某些编译器上产生一条诊断消息,因为
char
char*
窄,但是如果我们使用
size\u t
而不是
char
,那么就不会缩小,但它仍然是一个错误

为什么要使用石膏? 在相当多的情况下,C“整数提升”和“常用算术转换”会导致不希望的行为。比如说,

size_t align_to_16_bytes(size_t x)
{
    // return x & ~15u; // WRONG
    return x & ~(size_t) 15u; // RIGHT
}
但是,一般来说,只有在使用比
int
宽的类型时,或者在混合使用至少与
int
宽的有符号类型和无符号类型时,才会导致问题

Java和C等较新的语言只允许扩大隐式类型转换,从而在很大程度上避免了这一问题。

这些类型转换是“安全的”,但没有用处,而且样式非常糟糕。一般来说,在C语言中,任何需要强制转换的东西最多都是糟糕的样式,更常见的是,调用未定义的行为,因此源文件中出现强制转换是一种“代码气味”——这表明作者可能做了一些错误,读者需要格外小心地查找bug


只要删除强制转换,您的代码就会非常好。

强制转换是不安全的,这不仅是因为Dietrich Epp提到的编译器类型检查问题,还因为值范围的缩小可能导致误报:

int myValue = 'a' + 768;      //A number that is not equal to 'a'
assert(myValue != 'a');       //This is true...
assert((char)myValue == 'a'); //...but so is this!

当然,之所以会出现这种情况,是因为我构造myValue的方式产生了这种假阳性。但是,如果将整数强制转换为字符,则所有整数中的1/256将与特定字符进行比较,这可能是很多误报。如果允许编译器为比较选择整数表示,则不会发生这种情况。

强制转换是一种显式语句,用于编译器,您希望覆盖该语言提供给您的默认隐式类型转换(或说明没有隐式类型转换)。一般来说,这些默认的隐式类型转换是经过语言设计者深思熟虑的,并且使用C的类型安全性,而不是反对它

一个很好的例子是
void*
,根据C11第6.5.16.1.1节,它可以通过赋值隐式转换为“指向任何对象类型的指针”。例如,这意味着您不能将其隐式转换为指向函数的指针。这正是您在调用
malloc()
时希望它工作的方式,例如,它必须转换为其他类型的指针,因为您显然无法创建类型为
void
的对象,但为函数动态分配内存块毫无意义。因此,这里的默认隐式类型转换正是您想要的-允许您转换为指向任何对象类型的指针,因为这是全部目的,但是如果您试图转换为其他任何对象类型,请大声抱怨

有些人似乎认为,从
malloc()
转换返回值可以“明确”你想要做的事情,但是(1)你从来没有看到过那些人做过类似
inti=1的事情;双d=(双)i,他们似乎把
malloc()
变成了一个特例;(2)它根本不这样做,因为强制转换实际上使显式化的事实是,您想要覆盖C提供的类型安全和默认转换,而在这种情况下,您真正想要做的是遵守它们

或者,有时隐式类型转换无法提供所需的内容,因此需要强制转换。一个明显的例子是整数除法,它总是给你一个
int
。制造C的人可以提供另一个运算符来执行浮点整数除法,如果他们愿意的话,但是他们没有,结果是如果你想用两个整数进行除法,而整数除法不是你想要的,然后必须将其中一个转换为浮点类型,以覆盖默认行为以实现所需的功能。如果在特定情况下需要整数除法,那么显然不需要强制转换


所以,一般来说,当C在不使用强制转换的情况下给出你想要的结果时——大多数情况下都是这样——不要使用强制转换。只有当C的默认行为不能满足您的要求,并且您愿意明确放弃它为您提供的类型安全性时,才能强制转换。

请添加top_level_domain的声明,以便知道该类型。我想这取决于top_level_domain的类型。
。像“
”:“
这样的字符常量不都是
char
类型的吗?也就是说,不需要强制转换常量!?在C语言中,像
”这样的常量:“
int
,而不是
char
(部分原因是在计算中它会自动升级为
int
)。我试图理解为什么您会考虑将此特定代码作为强制转换的候选代码。(按照问题的顺序,不,如果你移除了石膏,你做的是正确的)。如果这样的东西在没有它们的情况下无法编译,那么您可能会遇到一个更大的问题(比如完全不正确的数据类型比较)。@JohnB:Well
sizeof(char)
是没有用的,而且还表明您不知道<