【问题标题】:Can anyone explain why the following program outputs nothing? [duplicate]谁能解释为什么下面的程序什么都不输出? [复制]
【发布时间】:2017-03-25 08:39:18
【问题描述】:

以下程序编译成功,但是当我运行它时,当我用 -1 初始化 for 循环时它什么也不打印,但是当我用 0 初始化 for 循环时,它成功遍历所有数组。我想问一下我们可以不' t 在我们用负值初始化for循环的时候遍历数组??

#include <stdio.h>

#define TOTAL_ELEMENTS (sizeof(array) / sizeof(array[0]))
int array[] = {23, 34, 12, 17, 204, 99, 16};

int main(void) {
    int d;
    //printf("%d",TOTAL_ELEMENTS);
    for (d = -1; d <= (TOTAL_ELEMENTS - 2); d++) 
    {
        printf("%d ",d);
        printf("%d\n", array[d+1]);
    }    
    return 0;
}

【问题讨论】:

标签: c arrays sizeof unsigned signed


【解决方案1】:

sizeof 运算符的结果是size_t 类型,这是一个无符号类型。

因此,TOTAL_ELEMENTS 的类型也是无符号的。当-1 与它比较时,它被转换为一个大的无符号数。这就是为什么d &lt;= (TOTAL_ELEMENTS - 2) 是假的。

【讨论】:

    【解决方案2】:

    这里d &lt;= (TOTAL_ELEMENTS - 2) 操作数是通常算术转换(6.3.1.8) 的主题。实际上,整数促销规则适用于您的情况:

    1. 如果两个操作数的类型相同,则不再进行转换 需要。

    2. 否则,如果两个操作数都具有有符号整数类型或两者都有 有无符号整数类型,具有较小类型的操作数 整数转换等级转换为操作数的类型 排名更高。

    3. 否则,如果操作数为无符号整数类型 等级大于或等于其他类型的等级 操作数,然后将带符号整数类型的操作数转换为 无符号整数类型的操作数类型。

    4. 否则,如果类型 有符号整数类型的操作数可以表示所有 具有无符号整数类型的操作数的类型的值,然后 无符号整数类型的操作数转换为 带符号整数类型的操作数。

    5. 否则,两个操作数都是 转换为类型对应的无符号整数类型 带符号整数类型的操作数。

    根据您的代码属于第 3 条,然后您的签名 -1 将通过规则 (6.3.1.3) 进行转换:

    否则,如果新类型是无符号的,则值转换为 反复加或减一大于最大值 可以用新类型表示,直到值在 新类型。

    结果它变成了一个非常大的无符号值,肯定大于TOTAL_ELEMENTS - 2,你永远不会进入循环。

    【讨论】:

      【解决方案3】:

      这并不像你认为的那样:

      d <= (TOTAL_ELEMENTS - 2)
      

      相反,这样做:

      d <= int(TOTAL_ELEMENTS - 2)
      

      否则,您将进行有符号与无符号比较,您的 -1 将成为可能的最大 size_t。

      【讨论】:

        【解决方案4】:

        sizeof 产生size_t 的结果,它是无符号的。比较有符号和无符号类型,你只能期待事情会爆炸。

        详细地说,当您尝试在算术运算中同时使用有符号和无符号类型时,有符号类型将被提升为无符号类型,从而产生一个巨大数。因此,d 的值,提升为无符号类型,将无法满足条件d &lt;= (TOTAL_ELEMENTS - 2);,因此循环体不会执行。

        对于期望算术类型的操作数的运算符会导致转换。这种模式称为通常的算术转换。对于这种特殊情况,引用标准,第 §6.3.1.8 章

        否则,整数提升将在两个操作数上执行。然后 以下规则适用于提升的操作数:

        [...]

        • 否则,如果具有无符号整数类型的操作数的秩大于或 等于另一个操作数的类型的等级,然后是操作数 有符号整数类型转换为无符号操作数的类型 整数类型。

        并且,关于排名,

        • 任何无符号整数类型的等级应等于相应的等级 有符号整数类型(如果有)。

        另外,作为参考,引用C11,第 7.19 章,(强调我的)

        size_t

        是sizeof运算符结果的无符号整数类型;

        提示:启用编译器警告,它会指出你的错误。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2015-11-01
          • 1970-01-01
          • 2015-08-23
          • 2015-08-13
          • 1970-01-01
          相关资源
          最近更新 更多