C/C++ 中两个字符的总和

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/19471235/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-27 22:52:11  来源:igfitidea点击:

Sum of two chars in C/C++

c++c

提问by Mahnerak

In C/C++ when I want to find sum of two chars - I get result in int.
For example:

在 C/C++ 中,当我想找到两个字符的总和时 - 我得到 int 的结果。
例如:

#include <stdio.h>
int main(){
   char a = 'a', b = 'b';
   printf("%d + %d = %d\n", sizeof(a), sizeof(b), sizeof(a + b));
   return 0;
}

Prints

印刷

1 + 1 = 4

Why?

为什么?

回答by Lee Daniel Crocker

Because although aand bare each of type char, the expression a + bis of type int. Anytime you do math with char types, they are converted to int before doing the actual calculations.

因为虽然ab都是 type char,但表达式a + b是 type int。任何时候使用 char 类型进行数学运算时,它们都会在进行实际计算之前转换为 int。

回答by Captain Giraffe

Section 4.5 Integral promotions

第 4.5 节 积分促销

A prvalue of an integer type other than bool, char16_t, char32_t, or wchar_t whose integer conversion rank (4.13) is less than the rank of int can be converted to a prvalue of type int if int can represent all the values of the source type; otherwise, the source prvalue can be converted to a prvalue of type unsigned int.

整数转换等级 (4.13) 小于 int 等级的 bool、char16_t、char32_t 或 wchar_t 以外的整数类型的纯右值可以转换为 int 类型的纯右值,如果 int 可以表示源类型的所有值; 否则,源纯右值可以转换为 unsigned int 类型的纯右值。

The conversion is mandated by the standard in what is called "The usual arithmetic conversions" Clause 5 [expr] point 10:

标准在所谓的“常用算术转换”第 5 条 [expr] 第 10 点中强制要求转换:

Many binary operators that expect operands of arithmetic or enumeration type cause conversions and yield result types in a similarMany binary operators that expect operands of arithmetic or enumeration type cause conversions and yield result types in a similar way. The purpose is to yield a common type, which is also the type of the result. This pattern is called the usual arithmetic conversions, which are defined as follows: way. The purpose is to yield a common type, which is also the type of the result. This pattern is called the usual arithmetic conversions, which are defined as follows:

许多期望算术或枚举类型的操作数的二元运算符导致转换并产生类似的结果类型许多期望算术或枚举类型的操作数的二元运算符导致转换并以类似的方式产生结果类型。目的是产生一个通用类型,它也是结果的类型。这种模式称为通常的算术转换,其定义如下:方式。目的是产生一个通用类型,它也是结果的类型。这种模式称为通常的算术转换,其定义如下:

Unless for a few select types. long double, doubleand float

除非对于少数选择类型。long double, doublefloat

Otherwise, the integral promotions (4.5) shall be performed on both operands.59

否则,应在两个操作数上执行积分提升 (4.5)。 59

The (char)+(char) results in an int.

(char)+(char) 结果为 int。

Also note that a char+char is tricky. The char can be signed or unsigned depending on implementation; so the result might easily overflow for normal values which is likely why it is not included in the standard as an exception.

另请注意,char+char 很棘手。根据实现,char 可以是有符号或无符号的;因此对于正常值,结果可能很容易溢出,这可能是为什么它没有作为例外包含在标准中的原因。

回答by Jens

Looking at the ANSI C specification, hereis how additive expressions are parsed.

查看 ANSI C 规范,这里是附加表达式的解析方式。

More elaboration on how this is parsed and how operands are read:

关于如何解析以及如何读取操作数的更多详细说明:

The integral operand of an additive operator involving a pointer and an integer is specified to be a TypeIs_unsigned_long. Any integral type can be converted to TypeIs_unsigned_long by means of implicit conversions, so this specification is equivalent to that of the standard. The main reason for using TypeIs_unsigned_long is that OIL does not permit sets as operand specifications within a class definition, but a secondary reason is that this approach reduces the total number of operators in the compiler's database.

涉及指针和整数的加法运算符的整数操作数被指定为 TypeIs_unsigned_long。任何整数类型都可以通过隐式转换的方式转换为 TypeIs_unsigned_long,因此本规范等效于标准的规范。使用 TypeIs_unsigned_long 的主要原因是 OIL 不允许在类定义中将集合作为操作数规范,但次要原因是这种方法减少了编译器数据库中的运算符总数。

回答by fkl

Because, if not promoted, the result can overflow.

因为,如果不提升,结果可能会溢出

A single byte char cannot hold value greater than 255 (unsigned)or +127 (signed). When you sum two instances, there is always the possibilityof overflow i.e. result exceeding 255. This means it cannot be stored in a single byte. Hence int is used which cannot over flow max sum of two chars or bytes.

单字节字符不能保存大于255 (unsigned)+127 (signed) 的值。当您对两个实例求和时,总是存在溢出的可能性,即结果超过 255。这意味着它不能存储在单个字节中。因此使用 int 不能超过两个字符或字节的最大总和。

回答by paulsm4

1) This just prints out the text string "something + something else": you're not actually addinganything: printf("%d + %d = %d\n",..)

1)这只是打印出文本字符串“something + something else”:你实际上没有添加任何东西:printf("%d + %d = %d\n",..)

2) sizeof(<some char>)will always be "1". That's what "sizeof()" means - it can never be anything besides"1".

2)sizeof(<some char>)永远是“1”。这就是“sizeof()”的意思——它永远不会是“1”之外的任何东西。

3) Yes, adding type "char" (which is an integer subtype) will give an integral result.

3)是的,添加类型“char”(这是一个整数子类型)将给出一个整数结果。

For further details:

欲知更多详情:

http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1124.pdf

The type char, the signed and unsigned integer types, and the enumerated types are collectively called integer types. The integer and real floating types are collectively called real types.

http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1124.pdf

char 类型、有符号和无符号整数类型以及枚举类型统称为整数类型。整型和实型浮点型统称为实型。

回答by anatolyg

This is how C and C++ work: before doing anything on variables of type char, the compiler converts them to intfirst. This is called integer promotion. Note: anythingis defined by the C and C++ Standards; it doesn't include sizeofbut includes most of other operations (I cannot remember any exceptions besides the sizeofone).

这就是 C 和 C++ 的工作方式:在对 type 变量执行任何操作之前char,编译器int首先将它们转换为。这称为整数提升。注意:任何东西都是由 C 和 C++ 标准定义的;它不包括sizeof但包括大多数其他操作(我不记得除了sizeof一个例外)。

As to the reason for this maybe surprising behavior - this is probably a decision taken in ancient times, resulting in modern C and C++ behaving in that way since then, for compatibility.

至于这种可能令人惊讶的行为的原因 - 这可能是古代做出的决定,导致现代 C 和 C++ 从那时起就以这种方式运行,以实现兼容性。

People often had large arrays of chars, which were not really characters, but small numbers. When doing arithmetic with these, it was natural to convert each number to intautomatically and doing arithmetic on these, because intis the type for which arithmetic works the fastest. There is also the pleasant side-effect that overflow is much less likely to happen when promotion is in effect (consider a*bwhen aand bare of chartype).

人们经常有大量的chars,它们并不是真正的字符,而是小数字。使用这些进行算术运算时,很自然地将每个数字转换为int自动并对其进行算术运算,因为这int是运算速度最快的类型。还有一个令人愉快的副作用,即促销有效时发生溢出的可能性要小得多(考虑a*b何时abchar类型)。

In addition, printfrelies on integer promotion to implement printing ASCII values for characters: printf("%d", a)expects the char-typed parameter to be promoted to intwhen printfis called.

此外,printf依靠整数提升来实现字符的打印 ASCII 值:printf("%d", a)期望在char调用int时提升 -typed 参数printf

回答by Pete Becker

The reason for this promotion is historical: when C was invented, 40+ years ago, processors did math on a single integral type; you could store smaller types, but there was no byte-level arithmetic. So the promotion rule reflects reality at the time: types smaller than the processor's integer type would be promoted by the hardware to that integer type. Sure, you could do the math in software (which is how longwas often implemented), but that would have been much slower (as longoften was).

这种提升的原因是历史性的:40 多年前 C 被发明时,处理器对单一整数类型进行数学运算;您可以存储较小的类型,但没有字节级算术。所以提升规则反映了当时的现实:小于处理器整数类型的类型将由硬件提升为该整数类型。当然,您可以在软件中进行数学计算(这是long经常实现的方式),但这会慢得多(long通常如此)。