- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
运行以下程序显示 -4 而预期为 252:
unsigned char a=3;
printf ("%d", ~a);
为什么这段代码不显示252?
我还根据建议的答案测试了以下内容:
printf ("%u", ~a);
显示:4294967292
printf ("%hu", ~a);
显示:65532
为什么 ~a
不返回 unsigned char
因为 a 是 unsigned char
?
我的问题不是我应该怎么做才能显示 252 ?我的问题是为什么不显示252?
最佳答案
除了the answer of @Someprogrammerdude , 以下是 The Book1) 中的相关段落:
The result of the ~ operator is the bitwise complement of its (promoted [ !! ] ) operand (that is, each bit in the result is set if and only if the corresponding bit in the converted operand is not set). The integer promotions are performed on the operand, and the result has the promoted type. If the promoted type is an unsigned type, the expression ~E is equivalent to the maximum value representable in that type minus E.
Every integer type has an integer conversion rank defined as follows:
- No two signed integer types shall have the same rank, even if they have the same representation.
- The rank of a signed integer type shall be greater than the rank of any signed integer type with less precision.
- The rank of long long int shall be greater than the rank of long int, which shall be greater than the rank of int, which shall be greater than the rank of short int, which shall be greater than the rank of signed char.
- The rank of any unsigned integer type shall equal the rank of the corresponding signed integer type, if any.
- The rank of any standard integer type shall be greater than the rank of any extended integer type with the same width.
- The rank of char shall equal the rank of signed char and unsigned char.
- The rank of _Bool shall be less than the rank of all other standard integer types.
- The rank of any enumerated type shall equal the rank of the compatible integer type (see 6.7.2.2).
- The rank of any extended signed integer type relative to another extended signed integer type with the same precision is implementation-defined, but still subject to the other rules for determining the integer conversion rank.
- For all integer types T1, T2, and T3, if T1 has greater rank than T2 and T2 has greater rank than T3, then T1 has greater rank than T3.
The following may be used in an expression wherever an int or unsigned int may be used:
- An object or expression with an integer type whose integer conversion rank is less than or equal to the rank of int and unsigned int.
- A bit-field of type _Bool, int, signed int, or unsigned int. If an int can represent all values of the original type, the value is converted to an int; otherwise, it is converted to an unsigned int. These are called the integer promotions.48) All other types are unchanged by the integer promotions.
- The integer promotions preserve value including sign. As discussed earlier, whether a "plain" char is treated as signed is implementation-defined.
48) The integer promotions are applied only: as part of the usual arithmetic conversions, to certain argument expressions, to the operands of the unary +, -, and ~ operators, and to both operands of the shift operators, as specified by their respective subclauses.
Why
~a
doesn't return anunsigned char
sincea
is anunsigned char
?
因为适用整数促销。
unsigned char a = 3;
printf ("%d", ~a);
a
是一个 unsigned char
,一种范围可以用 int
表示的类型。所以 a
被提升为 int
。假设 32 位宽 int
和 two's complement :
310 = 0000 0000 0000 0000 0000 0000 0000 0011
2
~310 = 1111 1111 1111 1111 1111 1111 1111 1100
2
解释为 signed int
的结果是负数,因为设置了最高有效位,即符号位。
转换为十进制:1111 1111 1111 1111 1111 1111 1111 1100
2
¬ 0000 0000 0000 0000 0000 0000 0000 0011
2
+ 0000 0000 0000 0000 0000 0000 0000 0001
2
──────────────────────────────0000 0000 0000 0000 0000 0000 0000 0100
2
01002 = 0 × 23 + 1 × 22 + 0 × 22 + 0 × 22
= 1 × 22
= 410
= −410(带原符号)
printf()
打印 -4
。要使用使用 "%d"
作为格式说明符的原始代码获得 252 的预期结果,需要进行一些转换:
unsigned char a = 3;
printf("%d\n", (int)((unsigned char) ~a)); // prints 252
// ^^^ ^^^^^^^^^^^^^
// | cast the result of ~a back to unsigned char *)
// | to discard the bits > CHAR_BIT
// cast the char back to int to agree with the format specifier
*)感谢 chux 让我记住 char
可以被签名
!强制转换为(可能是 signed
)char
会给出 -4 的错误结果。
要在不进行转换的情况下获得相同的结果,您可以使用长度修饰符 hh
:
The length modifiers and their meanings are:
hh Specifies that a following d, i, o, u, x, or X conversion specifier applies to a signed char or unsigned char argument (the argument will have been promoted according to the integer promotions, but its value shall be converted to signed char or unsigned char before printing); or that a following n conversion specifier applies to a pointer to a signed char argument.
[...]
unsigned char a = 3;
printf("%hhu\n", ~a); // prints 252
printf ("%u", ~a);
displays: 4294967292
printf ("%hu", ~a);
displays: 65532
由于 ~a
是一个 int
eger,它不是格式说明符 u
和
If a conversion specification is invalid, the behavior is undefined.248) If any argument is not the correct type for the corresponding conversion specification, the behavior is undefined.
1) ISO/IEC 9899/Cor3:2007 又名 C99:TR3 又名 C99
关于c - 为什么 printf ("%d", ~a);当 a 等于 3 时显示 -4?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53479444/
关闭。这个问题需要debugging details .它目前不接受答案。 编辑问题以包含 desired behavior, a specific problem or error, and th
我试图用这种形式简单地获取数字 28 integer+space+integer+integer+space+integer我试过这个正则表达式 \\s\\d\\d\\s 但我得到了两个数字11 和
最近一直在学习D语言。我一直对运行时感到困惑。 从我能收集到的关于它的信息中,(这不是很多)我知道它是一种有助于 D 的一些特性的运行时。像垃圾收集一样,它与您自己的程序一起运行。但是既然 D 是编译
想问一下这两个正则表达式有区别吗? \d\d\d 与 \d{3} 我已经在我的本地机器上使用 Java 和 Windows 操作系统对此进行了测试,两者都工作正常并且结果相同。但是,当在 linux
我正在学习 Go,而且我坚持使用 Go 之旅(exercise-stringer.go:https://tour.golang.org/methods/7)。 这是一些代码: type IPAddr
我在Java正则表达式中发现了一段令我困惑的代码: Pattern.compile( "J.*\\d[0-35-9]-\\d\\d-\\d\\d" ); 要编译的字符串是: String string
我在 ruby 代码上偶然发现了这个。我知道\d{4})\/(\d\d)\/(\d\d)\/(.*)/是什么意思,但是\1-\2-\3-\4 是什么意思? 最佳答案 \1-\2-\3-\4 是 b
我一直在努力解决这个问题,这让我很恼火。我了解 D 运行时库。它是什么,它做什么。我也明白你可以在没有它的情况下编译 D 应用程序。就像 XoMB 所做的那样。好吧,XoMB 定义了自己的运行时,但是
我有两个列表列表,子列表代表路径。我想找到所有路径。 List> pathList1 List> pathList2 当然是天真的解决方案: List> result = new ArrayList>
我需要使用 Regex 格式化一个字符串,该字符串包含数字、字母 a-z 和 A-Z,同时还包含破折号和空格。 从用户输入我有02-219 8 53 24 输出应该是022 198 53 24 我正在
目标是达到与this C++ example相同的效果: 避免创建临时文件。我曾尝试将 C++ 示例翻译为 D,但没有成功。我也尝试过不同的方法。 import std.datetime : benc
tl;dr:你好吗perfect forwarding在 D? 该链接有一个很好的解释,但例如,假设我有这个方法: void foo(T)(in int a, out int b, ref int c
有什么方法可以在 D 中使用abstract auto 函数吗? 如果我声明一个类如下: class MyClass { abstract auto foo(); } 我收到以下错误: mai
有没有人为内存中重叠的数组切片实现交集?算法在没有重叠时返回 []。 当 pretty-print (使用重叠缩进)内存中重叠的数组切片时,我想要这个。 最佳答案 如果您确定它们是数组,那么只需取 p
我已经开始学习 D,但我在使用 Andrei Alexandrescu 所著的 The D Programming Language 一书中提供的示例时遇到了一些麻烦。由于 int 和 ulong 类
如何创建一个不可变的类? 我的目标是创建一个实例始终不可变的类。现在我只是用不可变的方法和构造函数创建了一个“可变”类。我将其称为 mData,m 表示可变。然后我创建一个别名 alias immut
不久前我买了《The D Programming Language》。好书,很有教育意义。但是,我在尝试编译书中列出的语言功能时遇到了麻烦:扩展函数。 在这本书中,Andrei 写了任何可以像这样调用
我在 D http://www.digitalmars.com/d/2.0/lazy-evaluation.html 中找到了函数参数的惰性求值示例 我想知道如何在 D 中实现可能的无限数据结构,就像
这个问题在这里已经有了答案: 12 年前关闭。 Possible Duplicate: Could anyone explain these undefined behaviors (i = i++
当前是否可以跨模块扫描/查询/迭代具有某些属性的所有函数(或类)? 例如: source/packageA/something.d: @sillyWalk(10) void doSomething()
我是一名优秀的程序员,十分优秀!