有人能解释为什么sizeof()用一元运算符返回这些值吗? #包括 int main(){ INTA; 字符b; 短int-c; 双d; printf(“%d%d%d%d\n”、sizeof(a)、sizeof(b)、sizeof(c)、sizeof(d)); printf(“%d%d%d%d\n”),sizeof(+a)、sizeof(+b)、sizeof(+c)、sizeof(+d)); printf(“%d%d%d%d\n”、sizeof(-a)、sizeof(-b)、sizeof(-c)、sizeof(-d)); 返回0; }

有人能解释为什么sizeof()用一元运算符返回这些值吗? #包括 int main(){ INTA; 字符b; 短int-c; 双d; printf(“%d%d%d%d\n”、sizeof(a)、sizeof(b)、sizeof(c)、sizeof(d)); printf(“%d%d%d%d\n”),sizeof(+a)、sizeof(+b)、sizeof(+c)、sizeof(+d)); printf(“%d%d%d%d\n”、sizeof(-a)、sizeof(-b)、sizeof(-c)、sizeof(-d)); 返回0; },c,operators,sizeof,unary-operator,C,Operators,Sizeof,Unary Operator,32位编译器输出: #include <stdio.h> int main() { int a; char b; short int c; double d; printf("%d %d %d %d\n", sizeof(a), sizeof(b), sizeof(c), sizeof(d)); printf("%d %d %d %d\n", sizeof(+a), sizeof(+b), si

32位编译器输出:

#include <stdio.h>

int main() {
    int a;
    char b;
    short int c;
    double d;
    printf("%d %d %d %d\n", sizeof(a), sizeof(b), sizeof(c), sizeof(d));
    printf("%d %d %d %d\n", sizeof(+a), sizeof(+b), sizeof(+c), sizeof(+d));
    printf("%d %d %d %d\n", sizeof(-a), sizeof(-b), sizeof(-c), sizeof(-d));
    return 0;
}
4 1 2 8 4 4 4 8 4 4 4 8
如果我更改
sizeof()
中的符号,例如
sizeof(-a)
,则输出是相同的。我想知道为什么会这样。
+
-
运算符是否提升了数据类型?

是的,一元
+
-
运算符整数将小整数类型提升为
int
。C17 6.5.3.3:

一元+运算符的结果是其(提升)操作数的值。整数 对操作数执行升级,结果具有升级类型

一元运算符的结果是其(提升的)操作数的负数。整数 对操作数执行升级,结果具有升级类型

有关整数升级的详细信息,请参阅


您可以使用
\u Generic
查找任何表达式的实际类型:

4 1 2 8 4 4 4 8 4 4 4 8
就是这样。当进行计算(例如+或-)时,较短的整数格式为基本大小,即int,长度为4字节。

在简单算术表达式中用作参数时,小整数类型升级为
int
无符号int
。因此
sizeof(b)
1
,是
char
的大小,但是
sizeof(+b)
4
,是平台上
int
的大小

但是请注意,
printf
要求
%d
转换规范使用
int
参数
sizeof()
具有类型
size\u t
,这是一种可能不同于
无符号int
的无符号类型。您应该使用
%zu
或将
sizeof()
表达式转换为
(int)

下面是一个示例程序,用于说明:

a is int
+a is int
b is char
+b is int
c is short
+c is int

您还可以提到,
%d
需要一个
int
值,而
sizeof()
具有type
size\u t
,可能与
int
不兼容@chqrlie这在实践中是否重要?我怀疑很少有真正的案例,
%d
会导致不正确的行为,
%zu
会挽救一天,只要我们坚持在
INT\u MAX
以下。这取决于ABI。64位参数可以通过不同于32位参数的寄存器传递,或者使用不同数量的堆栈空间,这将使错误具有意外行为。我不确定当前针对Linux、Windows和OS/X的ABI是否会造成这样的问题,但如果传递足够多的64位参数,而
printf
需要32位整数,则会导致意外行为,并且我不愿意冒险。Re“作为
sizeof()
\u Alignof()
的参数除外”:除作为类型参数的参数参数外,
\u Generic
的控制表达式、括号的操作数、带指针的
+
-
操作数、递增或递减运算符的操作数、强制转换的操作数、简单赋值的右操作数,或者逗号运算符的操作数。@EricPostpischil:我同意现实更微妙。。。我修改了答案,尽量保持简单。
a is int
+a is int
b is char
+b is int
c is short
+c is int
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>

#define typeof(X)  _Generic((X),                                        \
                   long double: "long double",                          \
                   double: "double",                                    \
                   float: "float",                                      \
                   unsigned long long int: "unsigned long long int",    \
                   long long int: "long long int",                      \
                   unsigned long int: "unsigned long int",              \
                   long int: "long int",                                \
                   unsigned int: "unsigned int",                        \
                   int: "int",                                          \
                   unsigned short: "unsigned short",                    \
                   short: "short",                                      \
                   unsigned char: "unsigned char",                      \
                   signed char: "signed char",                          \
                   char: "char",                                        \
                   bool: "bool",                                        \
                   __int128_t: "__int128_t",                            \
                   __uint128_t: "__uint128_t",                          \
                   default: "other")

int main() {
    int a;
    char b;
    short int c;

#define TEST(x)  printf("%8s has type %s and size %zu\n", #x, typeof(x), sizeof(x))
    TEST(a);
    TEST(+a);
    TEST(b);
    TEST(+b);
    TEST(c);
    TEST(+c);
    TEST('0');
    TEST(*"");
    TEST(0);
    TEST(0L);
    TEST(0LL);
    TEST(0.F);
    TEST(0.);
    TEST(0.L);
    TEST(sizeof(a));

    return 0;
}
       a has type int and size 4
      +a has type int and size 4
       b has type char and size 1
      +b has type int and size 4
       c has type short and size 2
      +c has type int and size 4
     '0' has type int and size 4
     *"" has type char and size 1
       0 has type int and size 4
      0L has type long int and size 8
     0LL has type long long int and size 8
     0.F has type float and size 4
      0. has type double and size 8
     0.L has type long double and size 16
sizeof(a) has type unsigned long int and size 8