据我所知,char
,int
等变量类型之间的唯一区别是它们占用的内存量。我猜他们在调节他们所拥有的变量代表什么方面没有任何作用。如果这是真的,在here中,我看到了strcmp
的以下内容:
strcmp函数将字符串s1与s2进行比较,返回a 与第一个之间的差异具有相同符号的值 不同的字符对(解释为unsigned char对象, 然后升级到int)。
我想问为什么结果会提升为int
?由于char
被比较,因此在所有情况下它们的差异都适合char
。那么是不是将结果提升到int
只是在结果的末尾附加一堆0?那么,为什么要这样做呢?
答案 0 :(得分:28)
char
可能签署也可能不签署。 strcmp
必须返回已签名的类型,如果差异为负,则可以为负数。
更一般地说,int
是传递和返回简单数值的首选,因为它被定义为这些值的“自然”大小,并且在某些平台上,处理比较小的类型更有效。 / p>
答案 1 :(得分:11)
当然,尽管其他人提到了溢出的可能性,但只有需要能够返回,例如-1,0或1 - 很容易适合签名的字符。真正的历史原因是,在20世纪70年代的原始版本的C中,函数无法返回一个字符,任何尝试这样做都会导致返回一个int。
在这些早期编译器中,int也是默认类型(很多情况,包括函数返回值,如下面的主要部分所示,允许你将int声明为int而不实际使用int关键字),因此定义任何函数没有特别需要返回一个不同的类型作为返回int。
即使是现在,无论如何,char返回只是将值符号扩展到int返回寄存器(pdp11上的r0,x86上的eax)。将其作为char处理将不会有任何性能优势,而允许它作为实际差异而不是强制它为-1或1确实具有小的性能益处。对于比较运算符而言,axiac的回答也很有必要将其提升回int。这些促销的原因也是历史性的,顺便说一下,编译器不必为char和int的每种可能组合实现单独的运算符,特别是因为许多处理器上的比较指令只能用于int。
证明:如果我在Unix V6上为PDP-11制作测试程序,则会忽略char类型并返回范围之外的整数值:
char foo() {
return 257;
}
main() {
printf("%d\n", foo());
return 0;
}
# cc foo.c
# a.out
257
答案 2 :(得分:3)
AFAIK,标准C库没有一个函数可以获取或返回类型char
的值。它具有char*
或const char*
类型的参数和返回类型,但不是普通的char
。
在int isalpha(int c);
找一个更令人震惊的例子。
我不知道为什么,但我可以猜到。也许这是由于ABI。在我所知道的任何ABI中,类型char
的任何参数或返回值无论如何都会在内部提升为int
,因此没有必要这样做。它实际上会使代码 less 有效,因为每次使用该函数时都需要截断。
答案 3 :(得分:3)
int
提升它返回strcmp()
的值的一个可能原因是在调用代码中备用处理器指令。
通常(总是?)*
返回的值与comparison operator一起使用。
让我们看看比较运算符的操作数会发生什么。
常用算术转换
以下算术运算符的参数经历隐式转换以获取公共实数类型,即执行计算的类型:
- 二进制算术
/
,%
,+
,-
,<
- 关系型运营商
>
,<=
,>=
,==
,!=
,&
- 二进制按位算术
^
,|
,?:
- 条件运算符
int
...
4)否则,两个操作数都是整数。在那种情况下,
首先,两个操作数都会进行整数提升 ...
(来源:http://en.cppreference.com/w/c/language/conversion#Usual_arithmetic_conversions)
整体促销
整数提升是任意整数类型的值的隐式转换,其等级小于或等于int的等级或类型_Bool,int,signed int,unsigned int的位字段的值,类型为{{1 }或
unsigned int
。
(来源:http://en.cppreference.com/w/c/language/conversion#Integer_promotions)
strcmp()
从上面的引文中可以看出,char
返回的strcmp()
值可能会提升为int
。
int
?一个非常简单的原因:因为升级无论如何都会发生,并且因为(至少)需要一条处理器指令来执行升级,所以将该指令添加到strcmp()
的代码更方便(即在一个地方),而不是在任何地方调用strcmp()
函数。
早在70年代,内存和CPU都是非常宝贵的资源。现在似乎无关紧要的优化(在这里和那里保存了几个字节的内存,可能在代码中的几十个位置)当时具有更重要的意义。
再想一想,我认为this answer和this answer提供的历史原因比我的更准确。