【问题标题】:c bit manipulation operation doesn't multiply charc位操作操作不会乘以char
【发布时间】:2015-08-03 10:55:39
【问题描述】:

我有这个简单的代码,为什么它会返回这个随机字符?

#include <stdio.h>

int main()
{
    char c = '1';
     printf("%c\n",c);
    c = c << 2;

    printf("%c\n",c);

    return 0;
}



1

? (some random character)

为什么不返回 2?

【问题讨论】:

标签: c char bit


【解决方案1】:

因为'1'1 不是同一个东西。 '1' 是表示数字 1 的字符文字,表示字符 '1' 的基础值取决于使用的字符集。

例如,在 ASCII 中,字符 1 由十进制值 49(十六进制 0x31)表示。所以假设 ASCII,c = c &lt;&lt; 2 将值 196(乘以 4)分配给c。如果 char 已签名并且长度为 8 位(通常是这种情况),则会溢出并调用未定义的行为。

如果您希望它打印 12,您应该 a) 乘以 2 而不是 4(即移位 1 而不是 2),并且 b) 存储数值而不是其表示形式(但是当然,那你需要在打印的时候调整一下):

int main()
{
    char c = 1;
    printf("%c\n", c+'0');
    c = c << 1;

    printf("%c\n", c+'0');

    return 0;
}

【讨论】:

  • 没有标准化的字符集 '0''9' 是不连续的。不过,对于字母来说,情况就不同了。
  • 在 C 中 '0''9' 必须是连续的 stackoverflow.com/q/9416926/995714
【解决方案2】:

左移一次将一个值乘以 2。左移两次将一个值乘以 4。所以首先,即使代码正确,您也肯定不会得到答案2

现在详细说一下。您正在使用打印格式%c,它将值显示为字符。 '1' 的 ASCII 码是 49。如果将其乘以 2,则得到 98,这是 'b' 的 ASCII 码。

您应该在计算之前和之后对 ASCII 进行调整:

#include <stdio.h>

int main(void)
{
    char c = '1';
    printf("%c\n", c);
    c = c - '0';                // ASCII adjustment
    c = c << 1;                 // double
    c = c + '0';                // ASCII adjustment
    printf("%c\n", c);
    return 0;
}

程序输出:

1
2

【讨论】:

  • 他乘以 4,而不是 2。
  • @LưuVĩnhPhúc 正如我解释的那样。但他问“为什么不返回 2?”,意思是他打算乘以 2。
【解决方案3】:

您似乎正在尝试访问 c 的下一个字符值。当你执行语句c = c &lt;&lt; 2

实际发生的事情:

  • 首先将字符转换为整数(它自己的 ASCII 值)
  • 49(1的ASCII值是49)然后乘以2(c &lt;&lt; 2基本上是左移2,第一个左移是原始值乘以2,第二个左移是结果乘以二)
  • 因此结果值是196 而不是2 类型转换后存储在c 中的值。

你应该做什么:

你应该简单地将1添加到变量c,因为它会将字符转换为其ASCII,然后将1添加到它,即字符c具有ASCII值49,当它将是增加后,新值将是50,当转换为字符时,它相当于 2。试试这个:

c = (int)c + 1;    //By force conversion from character to integer to get the ASCII value

希望这会有所帮助。

【讨论】:

    【解决方案4】:

    整数'1' 具有ASCII49。所以它的左移,c&lt;&lt;2 产生196,然后分配回char 变量c。如果 char 是 signed,它将溢出 char。 这可能是您的平台上发生的情况,打印随机字符。

    不知道为什么你期望位移产生2。如果您想要字符 '2',那么只需将 1 添加到 c

    c = c+1; 
    

    【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-04-06
    • 1970-01-01
    • 1970-01-01
    • 2017-01-12
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多