c 中的“signed short”数据类型有多少字节?
How many bytes in " signed short " data type in c ?
首先,我尝试了sizeof(signed short),输出是2个字节。
但是
当我试图通过带符号的 short 的十六进制表示来检查时,结果是 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 位!
说明符 %x
需要一个整数,编译器会在打印之前自动将您的 short
转换为 int
。
如果您的类型是有符号类型,编译器也会执行 符号扩展 ,这意味着如果值为负,它将传播到 int 的高位字。 IE。如果我们有 -17=0xffef
将其转换为 int,我们将有 oxffffffef
。如果我们有一个像 17=0x11
这样的正值,对于 int 也将是 0x11
并且将打印为 0x11
.
所以你做的测试没有意义。
另一方面,类型的大小(int
、short
等)取决于编译器 and/or 机器,使用 sizeof()
运算符是检查其大小的正确方法尺寸。
维基百科有一些 nice tables 显示不同类型整数的不同 min/max 大小,包括 short int
:
Short signed integer type. Capable of containing at least the [−32767,
+32767] range; thus, it is at least 16 bits in size.
这意味着如果您希望您的代码是跨平台和跨编译器的,您应该考虑 short int
不大于 16 位。但是,如果您需要实际大小(用于在运行时计算数据长度),您仍应使用 sizeof(short int)
,因为 short int
在某些平台上可能是 32 位。
printf
是可变参数函数;它的原型是:
int printf(const char *format, ...);
这意味着第一个参数的类型为const char*
,其余参数没有指定类型。
没有指定类型的参数接受默认参数提升:
float
参数转换为 double
.
严格小于 int
的整数类型(有符号和无符号)被转换为 signed int
.
所有其他参数不变。
这发生在调用 printf
之前,并不以任何方式特定于 printf
。调用任何可变参数函数的参数(其原型中有一个 ...
)。
Varargs 函数无法知道其参数的类型,因此它们需要有一些约定,让调用者告诉函数期望的类型。在 printf
的情况下,类型在格式字符串中指定,并且 printf
使用格式字符串中指定的类型 期望它是正确的 .如果你通过告诉 printf
一个参数是某种类型而实际上它是另一种类型来欺骗 printf
,那么由此产生的行为是未定义的,并且偶尔是灾难性的(尽管通常它只是意味着错误的事情是印刷。)
Printf 知道默认参数提升。因此,例如,如果您告诉它期待一个无符号短整型,那么它实际上会期待一个 int
(如果 int
比 unsigned short
宽)或 unsigned int
如果 int
和 short
大小相同。
格式项的类型使用格式代码(例如 d
和 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
实际上比 int
短)到 int
。 int
是实际发送到 printf
的内容。当printf
看到%hx
格式代码时,它知道它应该期待一个unsigned short
(即一个int
)的默认提升;它需要 int
并将其转换回 unsigned short
,然后打印出来。
许多 程序员会像您一样直接编写 %x
而无需强制转换。从技术上讲,这是未定义的行为,上面比较冗长的表达是正确的但迂腐。但是,值得注意的是它会产生预期值,而没有转换的不正确 %x
格式代码不会。
首先,我尝试了sizeof(signed short),输出是2个字节。
但是 当我试图通过带符号的 short 的十六进制表示来检查时,结果是 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 位!
说明符 %x
需要一个整数,编译器会在打印之前自动将您的 short
转换为 int
。
如果您的类型是有符号类型,编译器也会执行 符号扩展 ,这意味着如果值为负,它将传播到 int 的高位字。 IE。如果我们有 -17=0xffef
将其转换为 int,我们将有 oxffffffef
。如果我们有一个像 17=0x11
这样的正值,对于 int 也将是 0x11
并且将打印为 0x11
.
所以你做的测试没有意义。
另一方面,类型的大小(int
、short
等)取决于编译器 and/or 机器,使用 sizeof()
运算符是检查其大小的正确方法尺寸。
维基百科有一些 nice tables 显示不同类型整数的不同 min/max 大小,包括 short int
:
Short signed integer type. Capable of containing at least the [−32767, +32767] range; thus, it is at least 16 bits in size.
这意味着如果您希望您的代码是跨平台和跨编译器的,您应该考虑 short int
不大于 16 位。但是,如果您需要实际大小(用于在运行时计算数据长度),您仍应使用 sizeof(short int)
,因为 short int
在某些平台上可能是 32 位。
printf
是可变参数函数;它的原型是:
int printf(const char *format, ...);
这意味着第一个参数的类型为const char*
,其余参数没有指定类型。
没有指定类型的参数接受默认参数提升:
float
参数转换为double
.严格小于
int
的整数类型(有符号和无符号)被转换为signed int
.所有其他参数不变。
这发生在调用 printf
之前,并不以任何方式特定于 printf
。调用任何可变参数函数的参数(其原型中有一个 ...
)。
Varargs 函数无法知道其参数的类型,因此它们需要有一些约定,让调用者告诉函数期望的类型。在 printf
的情况下,类型在格式字符串中指定,并且 printf
使用格式字符串中指定的类型 期望它是正确的 .如果你通过告诉 printf
一个参数是某种类型而实际上它是另一种类型来欺骗 printf
,那么由此产生的行为是未定义的,并且偶尔是灾难性的(尽管通常它只是意味着错误的事情是印刷。)
Printf 知道默认参数提升。因此,例如,如果您告诉它期待一个无符号短整型,那么它实际上会期待一个 int
(如果 int
比 unsigned short
宽)或 unsigned int
如果 int
和 short
大小相同。
格式项的类型使用格式代码(例如 d
和 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
实际上比 int
短)到 int
。 int
是实际发送到 printf
的内容。当printf
看到%hx
格式代码时,它知道它应该期待一个unsigned short
(即一个int
)的默认提升;它需要 int
并将其转换回 unsigned short
,然后打印出来。
许多 程序员会像您一样直接编写 %x
而无需强制转换。从技术上讲,这是未定义的行为,上面比较冗长的表达是正确的但迂腐。但是,值得注意的是它会产生预期值,而没有转换的不正确 %x
格式代码不会。