为什么strcmp返回int而不是char?

据我所知,变量类型如 charint 等之间的唯一区别是它们占用的内存量 . 我猜他们在调节他们所拥有的变量代表什么方面没有任何作用 . 如果这是真的,在here中,我已经看到 strcmp 的以下内容:

strcmp函数将字符串s1与s2进行比较,返回一个与第一个不同字符对之间的差异具有相同符号的值(解释为unsigned char对象,然后提升为int) .

我想问为什么结果提升为 int ?自 char 被比较以来,它们的差异在所有情况下都适合 char . 那么是不是将结果推广到 int 只是在结果的末尾附加一堆0?那么,为什么这样做呢?

回答(4)

3 years ago

当然,尽管其他人提到了溢出的可能性,但它只需要能够返回,例如-1,0或1 - 很容易适合签名的字符 . 真正的历史原因是,在20世纪70年代的C的原始版本中,函数无法返回char,并且任何尝试这样做都会导致返回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

3 years ago

char 可能签署也可能不签署 . strcmp 必须返回一个有符号的类型,如果差异为负,它可以是负数 .

更一般地说, int 是传递和返回简单数值的首选,因为它被定义为这些值的"natural"大小,并且在某些平台上,处理比较小的类型更有效 .

3 years ago

AFAIK,标准C库没有一个函数可以获取或返回 char 类型的值 . 它有 char*const char* 类型的参数和返回类型,但不是普通 char .

例如,在 int isalpha(int c); 寻找一个更令人震惊的实例 .

我不知道为什么,但我可以猜到 . 也许这是由于ABI . 在我知道的任何ABI中,无论如何, char 类型的任何参数或返回值都在内部提升为 int ,因此没有必要这样做 . 它实际上会使代码效率降低,因为每次使用该函数时都需要进行截断 .

3 years ago

strcmp() 促使它返回 int 的值的一个可能原因是在调用代码中备用处理器指令 .

通常(总是?) strcmp() 返回的值与comparison operator一起使用 .

让我们看看比较运算符的操作数会发生什么 .

通常的算术转换以下算术运算符的参数经历隐式转换,目的是获得公共实数类型,即执行计算的类型:二进制算术*,/,%,, - 关系运算符<,> ,<=,> =,==,!=二进制位运算&,^,|条件运算符?:... 4)否则,两个操作数都是整数 . 在这种情况下,首先,两个操作数都会进行整数提升 . ...

(来源:http://en.cppreference.com/w/c/language/conversion#Usual_arithmetic_conversions

整数提升整数提升是任意整数类型的值的隐式转换,其等级小于或等于int的等级或类型_Bool,int,signed int,unsigned int的位字段,类型为int或unsigned的值INT .

(来源:http://en.cppreference.com/w/c/language/conversion#Integer_promotions

回到strcmp()

如你看到的从上面的引号中, strcmp() 返回的可能的 char 值无论如何都会提升为 int .

为什么C的创建者选择返回int?

原因很简单:因为升级无论如何都会发生,并且因为(至少)需要一条处理器指令来执行升级,所以将该指令添加到 strcmp() (即在一个地方)的代码比将它更方便到处调用 strcmp() 函数 .

早在70年代,内存和CPU都是非常宝贵的资源 . 现在似乎无关紧要的优化(在这里和那里保存几个字节的内存,可能在代码中的几十个位置)当时具有更重要的意义 .

更新:

再想一想,我认为this answerthis answer提供的历史原因比我的更准确 .