在C语言中如何将字符转换为整数?

5

我在阅读如何将字符转换为整数的示例,这是我看到的代码:

#include <stdio.h>

int main()
{
    char ch1 = 125, ch2 = 10;
    ch1 = ch1 + ch2;
    printf("%d\n", ch1);
    printf("%c\n", ch1 - ch2 - 4);
    return 0;
}

据我所知,如果我们进行任何字符算术运算,char 类型将转换为 int。

那么为什么第一个 printf 语句的结果是 -121 而不是 135 呢?因为 int 范围可以处理 135,所以不会发生溢出。

第二个 printf 语句将打印 y,因为我们在 printf 中使用了 %c。


5
任何字符算术运算都会将char类型转换为int类型。是的,但如果你要将结果存储在char类型中,你需要将其再次转换回char类型。 - bolov
4
如果你的编译器使用有符号字符,那么ch1 = ch1 + ch2;很可能会发生溢出。 - UnholySheep
1
@UnholySheep:没有溢出。在 ch1 + ch2 中,两个操作数都被提升为 int,并且结果适合于 int。在赋值中,右操作数被转换为 char。当值在转换为有符号整数类型时不适合时,结果不是溢出,这将具有未定义的行为,而是一个实现定义的结果或信号,根据 C 2018 6.3.1.3 3。 - Eric Postpischil
2个回答

2

"char"变量类型通常默认为"signed char"类型。
"signed char"变量的取值范围是从-127到+127。

超过正数范围限制导致了这个程序的负数结果。

-121的值被显示出来,因为这是设置为无符号char值135的二进制补码值。


2
char 是有符号还是无符号的是由实现定义的,不应该假定为“通常”。 - sj95126
1
"signed char"变量的取值范围为-128(而不是-127)到+127。 - Elec1
@johnH 谢谢,现在我明白为什么结果是负数了,但是为什么是-121呢?你能否解释一下,谢谢。 - LEarn123
@LEarn123 - 我扩展了我的答案,以解释-121值的显示。请注意,无符号字符具有8个值位和没有符号位;然而,有符号字符有7个值位和一个(1)符号位。对于负值,二进制补码解释比正值更复杂。 - JohnH

0
正如bolov所指出的那样,结果是char类型,因此您正在将其转换回char。
解释:由于ch1 + ch2的结果存储在ch1中,而ch1是char类型,计算操作将最大化为127,并将继续从-128的最低char值开始。因此,结果的ch1将为-121:
ch1 =  -128 - 1 + (125 + 10 - 127)
or ch1 = -121

为了解决这个问题,只需将结果存储到一个int变量中,或者如果您真的想优化内存,那么可以存储到一个unsigned char变量中。
#include <stdio.h>
int main(){
    char ch1 = 125, ch2 = 10;
    unsigned char ch3;
    ch3 = ch1 + ch2;
    ch1 = ch1 + ch2;
    printf("%d\n", ch1);
    printf("%c\n", ch1 - ch2 - 4);
    printf("%d\n", ch3);
    return 0;
}

结果:

-121
y
135

@curios,我其实不理解你的解决方案,为什么要用“-128 - 1 + (125 + 10 - 127)”?根据C语言的哪个规则你得出这个公式的?谢谢。 - LEarn123
@LEarn123,你可以通过赋值 char ch = 128; 进行验证。打印结果将会是 -128。现在让我们按照我的回答中提到的方法进行计算,即 ch = -128 - 1 + (128 - 127)。= -128。原因在我的回答中已经说明。 - curious

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接