"中有多少字节签名短" c中的数据类型?

时间:2016-01-24 19:09:01

标签: c types int size

首先,我尝试 sizeof (签名短),输出为2个字节。

BUT 当我尝试通过签名短语的十六进制表示进行检查时,结果是4个字节:

#include <stdio.h>
 void main(){
 signed short  test  ;
 test=-17; /* any number */
 printf(" -17 when viewed as signed short Hexa is \t %x\n ", test);
 }`

输出:

-17 when viewed as signed short Hexa is      ffffffef

ffffffef表示32位而不是16位!

3 个答案:

答案 0 :(得分:2)

说明符%x需要一个整数,编译器会自动将short转换为int,然后再将其打印出来。
如果您的类型是有符号类型,编译器也会执行符号扩展,这意味着如果值为负,它将传播到int的高位字。即如果我们将-17=0xffef短暂转换为int,我们将oxffffffef。如果我们有一个像17=0x11这样的正值,那么对于一个int也会是0x11,并打印为0x11
所以你做的测试毫无意义 另一方面,类型(intshort等)的大小取决于编译器和/或机器,并且使用sizeof()运算符是检查其大小的正确方法。

答案 1 :(得分:2)

printf是一个varargs函数;它的原型是:

int printf(const char *format, ...);

这意味着第一个参数的类型为const char*,其余参数没有指定的类型。

没有指定类型的参数会经历默认参数提升

  1. float参数转换为double

  2. 严格比int更窄的整数类型(有符号和无符号)转换为signed int

  3. 所有其他参数均未更改。

  4. 这在调用printf之前发生,并且不以printf为特定。调用任何varargs函数的参数(原型中有...)。

    Varargs函数无法知道它们的参数类型,所以它们需要有一些约定,让调用者告诉函数期望什么类型。在printf的情况下,类型在格式字符串中指定,printf使用格式字符串中指定的类型,期望它是正确的。如果你通过告诉某个参数属于某种类型,当它实际上是一个不同的类型而欺骗printf时,结果的行为是不确定的,偶尔也会是灾难性的(虽然通常它只是意味着错误的东西是打印。)

    Printf知道默认参数促销。因此,如果你告诉它期望一个无符号的短片,那么它实际上会期望int(如果int宽于unsigned short)或unsigned int如果{ {1}}和int的大小相同。

    格式项的类型是使用格式代码指定的(例如shortd,分别是有符号和无符号x)和可能的修饰符。特别是,修饰符int会将期望从h更改为int,而short会将其更改为hh。 (它不会影响签名。)

    因此,如果您提供签名的char,则应使用格式代码short。如果提供无符号短整数,则应使用%hd%hu,具体取决于您希望输出是十进制还是十六进制。无法指定带符号参数的十六进制转换,因此您需要将参数强制转换为无符号类型,以便使用十六进制格式代码:

    %hx

    首先将printf("This signed short is printed as unsigned: %hx\n", (unsigned short)x); x转换为short;然后(因为默认参数促销,假设unsigned short实际上比short更短)到intint是实际发送到int的内容。当printf看到printf格式代码时,它知道它应该预期%hx的默认促销(即unsigned short);它需要int并将其转换回int,然后打印出来。

    许多程序员只会在没有演员的情况下编写unsigned short,就像你一样。从技术上讲,这是不明确的行为,上面相当晦涩的表达是正确但迂腐的。但是,值得注意的是它产生了预期的值,而没有强制转换的不正确的%x格式代码却没有。

答案 2 :(得分:1)

Wikipedia有一些nice tables显示不同类型整数的不同最小/最大大小,包括short int

  

短签名整数类型。能够至少含有[-32767,   +32767]范围;因此,它的大小至少为16位。

这意味着如果您希望代码是跨平台和交叉编译器,则应将short int视为不大于16位。但是如果你需要实际大小(用于在运行时计算数据长度),你仍然应该使用sizeof(short int),因为在某些平台上short int可能是32位。