c-有人能解释为什么sizeof()用一元运算符返回这些值吗


#include <stdio.h>
int main() {
int a;
char b;
short int c;
double d;
printf("%d %d %d %dn", sizeof(a), sizeof(b), sizeof(c), sizeof(d));
printf("%d %d %d %dn", sizeof(+a), sizeof(+b), sizeof(+c), sizeof(+d));
printf("%d %d %d %dn", sizeof(-a), sizeof(-b), sizeof(-c), sizeof(-d));
return 0;
}

32位编译器输出:

4 1 2 84 4 4 84 4 4 8

如果我像sizeof(-a)一样更改sizeof()内部的符号,则输出是相同的。我想知道为什么会发生这种事。+-运算符是否在推广数据类型?

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

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

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

有关整数提升的详细信息,请参阅隐式类型提升规则。


你可以玩_Generic来找出任何表达式的实际类型:

#include<stdio.h>
#define type(x) _Generic((x),    
int:   puts(#x " is int"),     
short: puts(#x " is short"),   
char:  puts(#x " is char") );  
int main (void)
{
int a;
char b;
short int c;

type(a); type(+a);
type(b); type(+b);
type(c); type(+c);
}

输出:

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

正是这样。当进行计算时(例如+或-(,较短的整数格式会提升到基本大小,即int,即4字节长。

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

但是请注意,printf期望%d转换规范有一个int参数。sizeof()具有类型size_t,这是一种可能不同于unsigned int的无符号类型。您应该使用%zu或将sizeof()表达式强制转换为(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 %zun", #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;
}

64位操作系统/X:上的输出

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

最新更新