如何在C++中将负数写为无符号文字
How to write negative one as an unsigned literal in C++
程序中,我经常使用-1(又名UINT_MAX)作为无符号变量的值来表示特殊的东西。 我也比较这个值。 打开更高级别的警告消息表明编译器(VS 和 GCC)不喜欢这种语法。
// warning C4245: 'initializing' : conversion from 'int' to 'unsigned int', signed/unsigned mismatch
unsigned a = -1;
// warning C4146: unary minus operator applied to unsigned type, result still unsigned
unsigned b = -1U;
// fine but messy
unsigned c = unsigned(-1);
// no warning on VS, signed/unsigned comparison warning with GCC
if (a == -1)
{
std::cout << "checkn";
}
问题1:上面给出的语法(每种情况)是否合法C++代码?
问题 2:我真的必须在使用此值分配/比较无符号 int 的任何地方编写 unsigned(-1),还是有不会触发编译器警告的更简洁的方法?
就其本质而言,您不能用 C++ 或任何其他语言将负数写为无符号文字。
你不是说-1
,你是说std::numeric_limits<unsigned int>::max()
。
#include <iostream>
#include <limits>
int main()
{
unsigned a = std::numeric_limits<unsigned int>::max();
if (a == std::numeric_limits<unsigned int>::max())
{
std::cout << "check " << a << "n";
}
}
C++11标准使这个函数constexpr
,这保证了这个函数是一个编译时常数。(延伸阅读)。
如果要避免使用较旧的编译器为循环的每次迭代计算此值,请在循环外创建一个const
并进行比较:
const unsigned int magic_number = std::numeric_limits<unsigned int>::max();
// [...]
if (a == magic_number)
答案 1:
是的,它们都是适当的,尽管可以说是不愉快的,C++结构。
-
-1
被解释为整数字面。 这是正确的语法C++因为该标准允许隐式 int 到无符号 int 的转换,但编译器会在更高的警告级别使用此隐式转换时发出警告。 -
-1U
被理解为-(1U)
. 取无符号 int 的负数是正确的C++语法,因为编译器执行此操作模(UINT_MAX + 1)
,但是编译器会发出警告通知您。 -
(unsigned(-1) == -1)
也是正确的语法,因为编译器隐式地将-1
转换为unsigned(-1)
进行比较。 它确实会在更高的警告级别警告您隐式转换,让您知道它已经这样做了。
答案 2:
有几个选项可以将unsigned(-1)
作为文字编写或效果:
- 写
unsigned(-1)
. - 写
~0U
,在二的比较机器上,它取0
然后否定每个位,从而给出最大的可表示无符号数字。 - 写
UINT_MAX
,有效地#define
d 作为unsigned(-1)
。 - 如果赋值或与无符号值进行比较,请编写
-1
,并让编译器执行隐式转换并处理警告消息。 但是,应该注意的是,-1 是一个 int 文字,仅根据其在代码中的功能转换为无符号。 - 写
std::numeric_limits<unsigned>::max()
这是一个返回unsigned(-1)
的函数。 请注意,在 C++11 中,此函数将是一个 constexpr,一个好的编译器应始终将其简化为文字。 VC++ 目前将其简化为非调试版本的unsigned(-1)
。 但是,它是从函数调用返回的值,而不是文本。
为了避免处理 int 的长度,您可以使用
~0
这给了你所有的 1,在二补码机器上(现在还有其他人吗?)与 -1 相同。 但这是一个合法的未签名长。
查看本文末尾的讨论线程。
http://embeddedgurus.com/barr-code/2011/06/is-uint16_t-1-portable-c-code/
结果是(无符号)(-1)是完全合法的,并且保证具有该类型的最大值,无论实际宽度或内部表示如何。
这是否是一个好主意是另一个问题。就个人而言,我更喜欢Johnsyweb提供的解决方案。
至于你是否总是需要强制转换,这将取决于编译器。既然你已经尝试过VS和GCC,似乎就是这样。
我认为你不应该搞砸无符号和签名。 -1 是有符号的,应该保持这种方式,也许这是一个你想经常拥有 -1 的设计问题。有像boost::optional这样的解决方案。
http://www.boost.org/doc/libs/1_49_0/libs/optional/doc/html/index.html
例:
#include <boost/optional.hpp>
#include <iostream>
boost::optional<int> find (const std::string& s, char t)
{
for (int i = 0 ; i < s.length () ; ++ i)
if (s [i] == t)
return i ;
return boost::optional<int>() ;
}
int main (int argc, char* argv[])
{
std::string s = argv[1] ;
char t = *argv[2] ;
boost::optional<int> idx = find (s, t) ;
if (idx)
std::cout << "found at " << *idx << std::endl ;
else
std::cout << "not found" << std::endl ;
return 0 ;
}
只使用ULONG_MAX怎么样?您需要包含限制.h。
或者,您也可以使用 0xFFFFFFFF - 当然,在宏常量或静态常量中正确定义。
- 在C++中,将大的无符号浮点数四舍五入为整数的最佳方法是什么
- 将无符号char*转换为std::istream*C++
- 如何在C++中将一个无符号的 int 转换为两个无符号的短裤?
- 从矢量<无符号字符>转换为字符* 包括垃圾数据
- 如何理解将半精度指针转换为无符号长指针和相关的内存对齐
- C++中无符号字符溢出
- 使用无符号字符数组有效存储内存
- 如何打印boost多精度128位无符号整数
- C++模板函数,用于比较任何无符号整数和有符号整数
- 在 std::无符号字符的向量处存储 int 的十六进制表示形式
- 获取隐式转换溢出从无符号到已签名的警告
- 如何在保持其值的同时将 c++ 无符号字符变量转换为 char 变量
- 从 std::vector<无符号字符>切片中提取 int?
- 是什么导致了这种使用三进制而不是短整型的有符号int到无符号int转换
- 无法在 Arduino 中uint8_t数组转换为无符号长整型数组
- 当将负文字作为无符号参数传递时,可以g++警告
- 我们可以分配一个无符号的int变量,0xFULL文字吗
- 如何在C++中将负数写为无符号文字
- 如何将浮点文字转换为相同位模式的无符号int
- 为什么用整数文字调用重载的 ambig(long) 和 ambig(无符号 long)是不明确的