sizeof()运算符的输出数据类型 [英] Output data type of sizeof() operator

查看:814
本文介绍了sizeof()运算符的输出数据类型的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用Ubuntu 16.04.5和GCC版本5.4.0.

I am using Ubuntu 16.04.5 and GCC version 5.4.0.

我正在和sizeof()运算符一起玩,写了下面的代码:

I was playing with sizeof() operator, wrote the code below:

#include <stdio.h>

int main(int argc, char *argv[]){

        long int mylint = 31331313131.1313;

        printf("size of long int is %d\n", sizeof(mylint));
        printf("size of long int is %d\n", sizeof(long int));

        return 0;
}

我尝试使用gcc -o ... ...命令进行编译,并且期望:

I tried to compile using gcc -o ... ... command and was expecting:

size of long int is 8
size of long int is 8

但是我遇到了以下错误:

But I got the following error:

fl_double_lint.c: In function ‘main’:
fl_double_lint.c:11:9: warning: format ‘%d’ expects argument of type ‘int’, but argument 2 has type ‘long unsigned int’ [-Wformat=]

  printf("size of long int is %d\n", sizeof(mylint));
         ^
fl_double_lint.c:12:9: warning: format ‘%d’ expects argument of type ‘int’, but argument 2 has type ‘long unsigned int’ [-Wformat=]
  printf("size of long int is %d\n", sizeof(long int));

当我使用%ld时,它可以按预期工作.为什么sizeof()无法与%d一起使用? (为什么是"long unsigned int"而不是"int"?)

When I use %ld instead it works as expected. Why sizeof() is not working with %d? (Why 'long unsigned int' but not 'int'?)

编辑:我知道,关于sizeof()运算符的输出,很多问题都被问到(如注释中所建议).但是,他们没有回答为什么使用%d不起作用(即不给出任何结果)的问题.我知道这是不正确的格式,但是只要我们有一个使用%dchar类型变量,我们都可以得到等效的int结果,这对于short,uint8_t,uint16_t,uint32_t(通常对于相等的类型)也是如此或小于32位).以下代码有效:

I know that many questions were asked regarding output of sizeof() operator (as suggested in comments). However, they do not answer the question of why using %d does not work (i.e. does not give any result). I know it is not correct format, but whenever we have a char type variable using %d we can get equivalent int result, this is also the case for short, uint8_t, uint16_t, uint32_t (generally for types with equal or less than 32 bit). The following code works:

#include <stdio.h>
#include <stdint.h>

int main(int argc, char *argv[]){

        char mychar = 'd';
        uint32_t myuint32 = 32;
        uint16_t myuint16 = 16;
        uint8_t myuint8 = 8;
        short myshort = 26945;
        int myint = 100;

        printf("integer equivalent of mychar is %d\n", mychar);
        printf("integer equivalent of myuint8 is %d\n", myuint8);
        printf("integer equivalent of myuint16 is %d\n", myuint16);
        printf("integer equivalent of myuint32 is %d\n", myuint32);
        printf("character equivalent of myint is %c\n", myint);
        printf("integer equivalent of myshort is %d\n", myshort);


        return 0;
}

结果是:

integer equivalent of mychar is 100
integer equivalent of myuint8 is 8
integer equivalent of myuint16 is 16
integer equivalent of myuint32 is 32
character equivalent of myint is d
integer equivalent of myshort is 26945

现在我发现%d不适用于需要存储大于32位的任何变量.在考虑了这个问题之后,我对,也许在我的系统中是unsigned long(%ld给出的结果也证明了这一点).因此,如果size_t是我系统中的unsigned int,我会得到结果,是真的吗?

And now I discovered that %d does not work for any variable that needs larger than 32 bit to be stored. After considering this question I have some idea about implementation dependence of size_t, maybe in my system it was unsigned long (%ld also giving the result proves it). So maybe if size_t was an unsigned int in my system I would get a result, is it true?

从上面的代码可以看出,%cint的最后8位解码为字符,为什么%d不能这样做(即,解码size_t的内容的最后32位) >变量是否为int?我相信,如果这样做的话,对于足够小的数字,我们可以获得相同的结果,这就是我最初问这个问题时的意思.

As it can be seen from the code above, %c decodes the last 8 bits of int as a character, why %d does not do the same (i.e. decode the last 32 bits of content of size_t variable as it was int? I believe if it would do so we could get the same result for small enough numbers, and this was what I meant when I initially asked the question).

推荐答案

sizeof运算符求值为类型size_t的值.此类型是无符号的,通常大于int,这就是收到警告的原因.

The sizeof operator evaluates to a value of type size_t. This type is unsigned and typically larger than an int, which is why you get the warning.

printf使用错误的格式说明符会调用未定义行为.但是,由于C标准的6.3.1.1p2节中的整数促销规则,对于小于int的类型,您可以避免这种情况:

Using the wrong format specifier to printf invokes undefined behavior. You can get away with this however for types smaller than int due to the rules of integer promotions in section 6.3.1.1p2 of the C standard:

以下表达式可以在表达式中使用,无论是int还是unsigned 可以使用int:

The following may be used in an expression wherever an int or unsigned int may be used:

  • 具有整数类型(小于int或unsigned int)的整数转换等级小于的对象或表达式 或等于int和unsigned int的等级.
  • 类型的位字段 _Bool,int,signed int或unsigned int.
  • An object or expression with an integer type (other than int or unsigned int ) whose integer conversion rank is less than or equal to the rank of int and unsigned int .
  • A bit-field of type _Bool , int , signed int ,or unsigned int .

如果int可以表示原始类型的所有值(受宽度限制, 对于位字段),该值将转换为int;否则, 它被转换为unsigned int.这些被称为 整数促销.所有其他类型均未更改 整数促销.

If an int can represent all values of the original type (as restricted by the width, for a bit-field), the value is converted to an int ; otherwise, it is converted to an unsigned int . These are called the integer promotions . All other types are unchanged by the integer promotions.

只要这不会导致从无符号更改为有符号,可以使用%d打印小于int的类型.

So as long this doesn't result in a change from unsigned to signed, types smaller than int can be printed with %d.

根据

The proper type modifier for size_t is %zu, as per section 7.21.6.1p7 of the C standard regarding length modifiers for the fprintf function (and by extension, printf):

z

指定以下d,i,o,u,x或X转换 说明符适用于size_t或相应的带符号整数 类型参数或以下n个转换说明符适用 指向与size_t对应的有符号整数类型的指针 论点.

Specifies that a following d , i , o , u , x ,or X conversion specifier applies to a size_t or the corresponding signed integer type argument; or that a following n conversion specifier applies to a pointer to a signed integer type corresponding to size_t argument.

所以你想要的是:

printf("size of long int is %zu\n", sizeof(mylint));

这篇关于sizeof()运算符的输出数据类型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆