asuerhao's Blog

如果有什么做的不到的地方请尽管留言, 我会改进的 : )

C语言 char型也是分有符号数和无符号数的

  unsigned char型表示无符号数, 取值范围是 0~255.
  signed char型表示无符号数, 取值范围是 -128~127.

  在x86平台上, gcc规定不带'unsigned'或'signed'关键字的char是有符号的. 参见以下代码 :

#include<stdio.h>
int main(void)
{
	printf("(signed char)200: %d\n", (signed char)200);
	printf("(unsigned char)200: %d\n", (unsigned char)200);
	printf("(char)200: %d\n", (char)200);	// gcc定义char型是有符号的。
	return 0;
}


打印结果为:

(signed char)200: -56
(unsigned char)200: 200
(char)200: -56

  利用objdump工具对其进行反汇编, 观察向printf函数传递的第二个参数, 节选部分汇编代码:
    printf("(signed char)200: %d\n", (signed char)200);
 80483cd:    b8 e0 84 04 08                mov    $0x80484e0,%eax
 80483d2:    c7 44 24 04 c8 ff ff        movl   $0xffffffc8,0x4(%esp)
 80483d9:    ff
 80483da:    89 04 24                            mov    %eax,(%esp)
 80483dd:    e8 12 ff ff ff                    call   80482f4 <printf@plt>
    printf("(unsigned char)200: %d\n", (unsigned char)200);
 80483e2:    b8 f6 84 04 08                mov    $0x80484f6,%eax
 80483e7:    c7 44 24 04 c8 00 00    movl   $0xc8,0x4(%esp)
 80483ee:    00
 80483ef:    89 04 24                            mov    %eax,(%esp)
 80483f2:    e8 fd fe ff ff                     call   80482f4 <printf@plt>
    printf("(char)200: %d\n", (char)200);    // gcc定义char型是有符号的。
 80483f7:    b8 0e 85 04 08                mov    $0x804850e,%eax
 80483fc:    c7 44 24 04 c8 ff ff         movl   $0xffffffc8,0x4(%esp)
 8048403:    ff
 8048404:    89 04 24                            mov    %eax,(%esp)
 8048407:    e8 e8 fe ff ff                    call   80482f4 <printf@plt>

  还有一个问题需要注意, 从汇编代码可以看到, 实际上用了四个字节存储char类型的参量, 即: 像printf这种形参类型未知的函数, 调用函数时编译器会自动对相应的实参做Integer Promotion.