使用sizeof(数组)的宏没有给出预期的输出

问题描述:

#include <stdio.h> 
int arr[] = {1, 2,3,4,5}; 
#define TOT (sizeof(arr)/sizeof(arr[0])) 

int main() 
{ 
    int d = -1, x = 0; 
    if(d<= TOT){ 
     x = arr[4]; 
     printf("%d", TOT); 
    } 
    printf("%d", TOT); 
} 

TOT的值为5,但if条件失败......为什么?使用sizeof(数组)的宏没有给出预期的输出

+0

你有[UB](HTTP ://c2.com/cgi/wiki?UndefinedBehavior)在'printf's中:你说你会传递一个'int',但'TOT'的类型不匹配。 – pmg

+0

@pmg实际上C编译器是否支持%zd语法?看起来甚至没有GCC做到这一点,我试着用-std = c99 -pedantic并打印出“zd”。 – Lundin

+0

@pmg我想我有一个太过旧版本的GCC ... – Lundin

因为在if的工作中存在“通常的算术转换”。

运算符sizeof返回无符号类型...并且d转换为无符号使其大于arr中的元素数。

尝试

#define TOT (int)(sizeof(arr)/sizeof(arr[0])) 

if(d<= (int)TOT){ 
+0

挑剔的是,这里发生的隐式升级是“通常的算术转换”(又名平衡)。 “整数升级”通常指的是何时将一个小整数类型隐式转换为“int”。除非size_t小于int,但我不认为C标准允许这样做。 – Lundin

+0

已更改。谢谢@Lundin – pmg

这是因为sizeof返回一个无符号数,而d签署。当d隐式转换为单数号码,然后它比TOT大得多。

您应该收到关于比较编译器的无符号比较的警告。

您的TOT表达式是unsigned值,因为操作者sizeof()总是返回无符号(正)值。

当你比较signed可变d有了它,d被自动转换为一个非常大的unsigned值,并因此变得更大TOT。的sizeof

返回类型为无符号整数....这就是为什么如果失败......因为“d”由编译器作为签署了被视为比TOT更大