【问题标题】:Why does char datatype behave like int datatype when we assign negative value to it?当我们为它分配负值时,为什么 char 数据类型的行为类似于 int 数据类型?
【发布时间】:2012-10-04 21:07:44
【问题描述】:

我知道,当我们为无符号数据类型分配负值时,会存储它的二进制补码,即数据类型可以存储的最大值减去我们分配的负值。 为了测试这一点,我编写了一个程序来说明这一点,但是我无法理解 char 数据类型的行为。

#include <iostream>
using namespace std;


template<class T>
void compare(T a,T b)
{
    cout<<dec<<"a:"<<(int)a<<"\tb:"<<(int)b<<endl; //first line
    cout<<hex<<"a:"<<(int)a<<"\tb:"<<(int)b<<endl; //second line

    if(a>b)
        cout<<"a is greater than b"<<endl;
    else
        cout<<"b is greater than a"<<endl;
}

int main()
{
    unsigned short as=2;
    unsigned short bs=-4;
    compare(as,bs);

    unsigned int al = 2;
    unsigned int bl =-4;
    compare(al,bl);

    char ac=2;
    char bc=-4;
    compare(ac,bc);

    int ai =2;
    int bi =-4;
    compare(ai,bi);
}

输出是

a:2     b:65532
a:2     b:fffc
b is greater than a
a:2     b:-4
a:2     b:fffffffc
b is greater than a
a:2     b:-4
a:2     b:fffffffc
a is greater than b
a:2     b:-4
a:2     b:fffffffc
a is greater than b

使用不同数据类型的参数多次调用 compare(...) 函数

  1. unsigned short- 2 bytes,因此 -4 存储为 65532。
  2. unsigned int - 4 bytes,但是当我们在输出时尝试将其类型转换为 int 时,它在输出中显示为 -4,因此它欺骗了编译器,但是十六进制输出和逻辑比较结果表明内部表示是互补的。
  3. char - 1 字节,这就是 我感到困惑的地方
  4. int - 4 个字节,有符号数据类型,没有意外,正常结果。

我要问的问题是为什么 char 表现得像一个有符号的 int? 即使我们在输出结果的第一行之前将类型转换为 int,为什么 char 显示的值类似于 int,即使 char 是 1 字节而 int 是 4 字节。 unsigned short 显示不同的值,因为它的内存要求是 2 字节。 unsigned int 和 int 在结果的第一行显示相同的结果,因为两者都是 4 个字节,编译器被成功欺骗,并且是可以接受的。 但是为什么char也显示相同的值,好像它的内存布局和int一样呢?

而且逻辑比较还表明 char 不是无符号数据类型,而是有符号数据类型。无符号数据类型显示 b 大于一。虽然 char 显示 a 大于 b ,但就带符号数据类型而言。为什么?

char 不是 1 字节无符号数据类型吗? 这是我在 B.Tech 学位上学习 C 和 C++ 课程时学到的。

任何解释都会有所帮助。 使用的编译器是mingw 2.19.1。

【问题讨论】:

    标签: c++


    【解决方案1】:

    char 不是 1 字节无符号数据类型吗?

    也许,也许不是。 char 的签名是实现定义的。

    在您当前的实现中,它显然是签名的。

    compare 方法的输出中,您会看到显示的四个字节,因为您将输出转换为int,因此char-4 被转换为int 值@987654328 @。

    【讨论】:

    • 所以,char 已签名。有趣。谢谢,这解决了我的困惑,但太糟糕了,我无法投票赞成你的答案,说我的声誉必须是 15。:p :)
    • 嗯,它可能已签名,也可能未签名。这取决于实施。使用 gcc 和 clang,您可以选择使用命令行标志 -funsigned-char 分别对 char 进行签名还是未签名。 -fsigned-char.
    • 只有 gcc 可以选择将 char 实现为有符号或无符号?还是每个编译器都有这个选项?
    • @RaunakMukhia 其实VS有/J option
    • 请注意charsigned charunsigned char是3种不同的类型,而intsigned int相同。
    猜你喜欢
    • 1970-01-01
    • 2015-10-23
    • 2016-05-24
    • 2013-08-01
    • 1970-01-01
    • 2020-10-22
    • 2011-11-20
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多