- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
请看我的测试代码:
#include <stdlib.h>
#include <stdio.h>
#define PRINT_COMPARE_RESULT(a, b) \
if (a > b) { \
printf( #a " > " #b "\n"); \
} \
else if (a < b) { \
printf( #a " < " #b "\n"); \
} \
else { \
printf( #a " = " #b "\n" ); \
}
int main()
{
signed int a = -1;
unsigned int b = 2;
signed short c = -1;
unsigned short d = 2;
PRINT_COMPARE_RESULT(a,b);
PRINT_COMPARE_RESULT(c,d);
return 0;
}
结果如下:
a > b
c < d
我的平台是Linux,我的gcc版本是4.4.2。我对第二行输出感到惊讶。第一行输出是由整数提升引起的。但是为什么第二行的结果不一样呢?
以下规则来自C99标准:
If both operands have the same type, then no further conversion is needed. Otherwise, if both operands have signed integer types or both have unsigned integer types, the operand with the type of lesser integer conversion rank is converted to the type of the operand with greater rank.
Otherwise, if the operand that has unsigned integer type has rank greater or equal to the rank of the type of the other operand, then the operand with signed integer type is converted to the type of the operand with unsigned integer type.
Otherwise, if the type of the operand with signed integer type can represent all of the values of the type of the operand with unsigned integer type, then the operand with unsigned integer type is converted to the type of the operand with signed integer type.
Otherwise, both operands are converted to the unsigned integer type corresponding to the type of the operand with signed integer type.
我觉得这两次比较应该属于同一种情况,整数提升的第二种情况。
最佳答案
当您使用算术运算符时,操作数会经过两次转换。
整数提升:如果int
可以表示该类型的所有值,则操作数被提升为 int。这适用于 short
和 unsigned short
在大多数平台上。在此阶段执行的转换是针对每个操作数单独完成的,而不考虑其他操作数。 (还有更多规则,但这是适用的规则。)
通常的算术转换:如果你比较 unsigned int
针对 signed int
,因为两者都不包括另一个的整个范围,并且两者具有相同的排名,那么两者都被转换为 unsigned
类型。此转换是在检查两个操作数的类型后完成的。
显然,如果没有两个操作数,“通常的算术转换”并不总是适用。这就是为什么有两套规则。例如,一个问题是移位运算符 <<
和 >>
不要做通常的算术转换,因为结果的类型应该只取决于左操作数(所以如果你看到有人输入 x << 5U
,那么 U
代表“不必要的”)。
分解:让我们假设一个典型的系统有 32 位 int 和 16 位 short。
int a = -1; // "signed" is implied
unsigned b = 2; // "int" is implied
if (a < b)
puts("a < b"); // not printed
else
puts("a >= b"); // printed
int
或 unsigned int
, 没有促销事件。int
不能表示 unsigned
的所有可能值, 和 unsigned
不能表示 int
的所有可能值,没有明显的选择。在这种情况下,两者都转换为 unsigned
.if (4294967295u < 2u)
, 这是错误的。现在让我们用 short
试试看:
short c = -1; // "signed" is implied
unsigned short d = 2;
if (c < d)
puts("c < d"); // printed
else
puts("c >= d"); // not printed
int
, 两者都提升为 int
.int
, 所以什么也没做。if (-1 < 2)
, 这是真的。编写好的代码:有一种简单的方法可以在您的代码中捕获这些“陷阱”。始终在打开警告的情况下进行编译,并修复警告。我倾向于这样写代码:
int x = ...;
unsigned y = ...;
if (x < 0 || (unsigned) x < y)
...;
您必须注意,您编写的任何代码都不会遇到其他有符号与无符号陷阱:有符号溢出。例如下面的代码:
int x = ..., y = ...;
if (x + 100 < y + 100)
...;
unsigned a = ..., b = ...;
if (a + 100 < b + 100)
...;
一些流行的编译器会优化(x + 100 < y + 100)
至 (x < y)
,但这是另一天的故事。只是不要溢出您的签名号码。
Footnote: Note that while
signed
is implied forint
,short
,long
, andlong long
, it is NOT implied forchar
. Instead, it depends on the platform.
关于c - 为什么整数提升的结果不同?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7711124/
我有 table 像这样 -------------------------------------------- id size title priority
我的应用在不同的 Activity (4 个 Activity )中仅包含横幅广告。所以我的疑问是, 我可以对所有横幅广告使用一个广告单元 ID 吗? 或者 每个 Activity 使用不同的广告单元
我有任意(但统一)数字列表的任意列表。 (它们是 n 空间中 bin 的边界坐标,我想绘制其角,但这并不重要。)我想生成所有可能组合的列表。所以:[[1,2], [3,4],[5,6]] 产生 [[1
我刚刚在学校开始学习 Java,正在尝试自定义控件和图形。我目前正在研究图案锁,一开始一切都很好,但突然间它绘制不正确。我确实更改了一些代码,但是当我看到错误时,我立即将其更改回来(撤消,ftw),但
在获取 Distinct 的 Count 时,我在使用 Group By With Rollup 时遇到了一个小问题。 问题是 Rollup 摘要只是所有分组中 Distinct 值的总数,而不是所有
这不起作用: select count(distinct colA, colB) from mytable 我知道我可以通过双选来简单地解决这个问题。 select count(*) from (
这个问题在这里已经有了答案: JavaScript regex whitespace characters (5 个回答) 2年前关闭。 你能解释一下为什么我会得到 false比较 text ===
这个问题已经有答案了: 奥 git _a (56 个回答) 已关闭 9 年前。 我被要求用 Javascript 编写一个函数 sortByFoo 来正确响应此测试: // Does not cras
所以,我不得不说,SQL 是迄今为止我作为开发人员最薄弱的一面。也许我想要完成的事情很简单。我有这样的东西(这不是真正的模型,但为了使其易于理解而不浪费太多时间解释它,我想出了一个完全模仿我必须使用的
这个问题在这里已经有了答案: How does the "this" keyword work? (22 个回答) 3年前关闭。 简而言之:为什么在使用 Objects 时,直接调用的函数和通过引用传
这个问题在这里已经有了答案: 关闭 12 年前。 Possible Duplicate: what is the difference between (.) dot operator and (-
我真的不明白这里发生了什么但是: 当我这样做时: colorIndex += len - stopPos; for(int m = 0; m < len - stopPos; m++) { c
思考 MySQL 中的 Group By 函数的最佳方式是什么? 我正在编写一个 MySQL 查询,通过 ODBC 连接在 Excel 的数据透视表中提取数据,以便用户可以轻松访问数据。 例如,我有:
我想要的SQL是这样的: SELECT week_no, type, SELECT count(distinct user_id) FROM group WHERE pts > 0 FROM bas
商店表: +--+-------+--------+ |id|name |date | +--+-------+--------+ |1 |x |Ma
对于 chrome 和 ff,当涉及到可怕的 ie 时,这个脚本工作完美。有问题 function getY(oElement) { var curtop = 0; if (oElem
我现在无法提供代码,因为我目前正在脑海中研究这个想法并在互联网上四处乱逛。 我了解了进程间通信和使用共享内存在进程之间共享数据(特别是结构)。 但是,在对保存在不同 .c 文件中的程序使用 fork(
我想在用户集合中使用不同的功能。在 mongo shell 中,我可以像下面这样使用: db.users.distinct("name"); 其中名称是用于区分的集合字段。 同样我想要,在 C
List nastava_izvjestaj = new List(); var data_context = new DataEvidencijaDataContext();
我的 Rails 应用程序中有 Ransack 搜索和 Foundation,本地 css 渲染正常,而生产中的同一个应用程序有一个怪癖: 应用程序中的其他内容完全相同。 我在 Chrome 和 Sa
我是一名优秀的程序员,十分优秀!