scanf %u 负数? [英] scanf %u negative number?

查看:134
本文介绍了scanf %u 负数?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经尝试过 scanf("%u",&number) 并且我输入了负数问题是当我 printf("%d",number) 我得到负数.我认为这会阻止我阅读负数.scanf("%d",&number)scanf("%u",&number) 真的是一回事吗?还是只是为了便于阅读.

I have tried scanf("%u",&number) and I have entered negative number the problem is when I printf("%d",number) I get the negative number. I thought this will prevent me from reading negative number. Are scanf("%d",&number) and scanf("%u",&number) the same thing really ? or is it only for readibility.

我是否在做一些称为未定义行为的事情?

Am I doing something called undefined behavior so ?

维基百科我读到:

%u : 扫描十进制无符号整数(注意在 C99 标准中输入值减号是可选的,因此如果读取减号,则没有会出现错误,结果将是 a 的二进制补码负数,可能是一个非常大的值.

%u : Scan for decimal unsigned int (Note that in the C99 standard the input value minus sign is optional, so if a minus sign is read, no errors will arise and the result will be the two's complement of a negative number, likely a very large value.

阅读SO答案及以上内容有点令人困惑.有人能说得更清楚吗?

It is a little bit confusing reading SO answers and above. Can someone make it more clear ?

推荐答案

正如 Sourav Ghosh 详细解释的那样,使用与传递的实际类型不一致的格式是一个潜在的问题.然而对于这种特殊情况,在当前的 PC 架构上,这并不是真正的问题,因为 intunsigned int 都没有陷阱表示.

As explained in detail by Sourav Ghosh, using formats that are inconsistent with the actual types passed is a potential problem. Yet for this particular case, on current PC architectures, this is not really a problem, as neither int nor unsigned int have trap representations.

您可以使用 scanf("%u", &number); 扫描负数.它将在目标类型中取反,即 unsigned int,与有符号 int 中的负数具有相同的按位表示,对于几乎通用的二进制补码表示当前架构.

You can scan a negative number with scanf("%u", &number);. It will be negated in the destination type, namely unsigned int, with the same bitwise representation as the negative number in a signed int, for two's complement representation which is almost universal on current architectures.

scanf 通过匹配可选的有符号十进制整数来转换 %u,其格式与 strtoul 的主题序列的预期格式相同基本参数值为 10 的函数.相应的参数应该是一个指向无符号整数的指针.

scanf converts %u by matching an optionally signed decimal integer, whose format is the same as expected for the subject sequence of the strtoul function with the value 10 for the base argument. The corresponding argument shall be a pointer to unsigned integer.

strtolstrtollstrtoulstrtoull 函数转换指向的字符串的初始部分通过 nptrlong intlong long intunsigned long intunsigned long long int 表示,分别.首先,他们将输入字符串分解为三个部分:一个初始的,可能为空的空白字符序列(由 isspace 函数指定),一个类似于以某个确定的基数表示的整数的主题序列由 base 的值和一个或多个无法识别的字符组成的最终字符串,包括输入字符串的终止空字符.然后,他们尝试将主题序列转换为整数,并返回结果.

The strtol, strtoll, strtoul, and strtoull functions convert the initial portion of the string pointed to by nptr to long int, long long int, unsigned long int, and unsigned long long int representation, respectively. First, they decompose the input string into three parts: an initial, possibly empty, sequence of white-space characters (as specified by the isspace function), a subject sequence resembling an integer represented in some radix determined by the value of base, and a final string of one or more unrecognized characters, including the terminating null character of the input string. Then, they attempt to convert the subject sequence to an integer, and return the result.

如果 base 的值在 2 到 36(含)之间,则主题序列的预期形式是一个字母和数字序列,表示一个整数,其基数由 base 指定,可选地在前面加上一个加号或减号,但不包括整数后缀.

If the value of base is between 2 and 36 (inclusive), the expected form of the subject sequence is a sequence of letters and digits representing an integer with the radix specified by base, optionally preceded by a plus or minus sign, but not including an integer suffix.

... 如果主题序列具有预期的形式并且基数的值在 2 到 36 之间,则将其用作转换的基数,将每个字母的值归因于上面给出的值.如果主题序列以减号开头,则转换产生的值将被否定(在返回类型中).

... If the subject sequence has the expected form and the value of base is between 2 and 36, it is used as the base for conversion, ascribing to each letter its value as given above. If the subject sequence begins with a minus sign, the value resulting from the conversion is negated (in the return type).

如果number 的类型是unsigned int,则定义行为并使用无符号否定将负值解析并存储为number语义.使用 printf("%d", number); 打印此值至多是实现定义的,但同样,在当前的 PC 架构上,将打印最初由 scanf 解析的负数("%u", &number);

If the type of number is unsigned int, behavior is defined and the negative value is parsed and stored into number using the unsigned negation semantics. Printing this value with printf("%d", number); is at best implementation defined, but again, on current PC architectures, will print the negative number that was originally parsed by scanf("%u", &number);

结论:虽然看起来无害,但是将intunsigned int互换使用,并且在printf中使用错误的格式是很草率的和 scanf.事实上,在表达式中混合有符号和无符号类型,尤其是.在比较中非常容易出错,因为这种结构的 C 语义有时是违反直觉的.

Conclusion: although it seems harmless, it is very sloppy to use int and unsigned int interchangeably and to use the wrong formats in printf and scanf. As a matter of fact, mixing signed and unsigned types in expressions, esp. in comparisons is very error prone as the C semantics for such constructions are sometimes counter-intuitive.

这篇关于scanf %u 负数?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆