代码之家  ›  专栏  ›  技术社区  ›  Bhargav Patil

运算符的大小并尝试打印数组

  •  0
  • Bhargav Patil  · 技术社区  · 10 月前

    考虑这个C程序

    #include <stdio.h>
    #define TOTAL_ELEMENTS (sizeof(arr))/sizeof(arr[0])
    int arr[] = {23, 34, 12, 17, 204, 99, 16};
    int main() {
     int d;
     printf("%zu\n", TOTAL_ELEMENTS);
     for (d = -1; d <= (TOTAL_ELEMENTS - 2); d++) {
      printf("%d ", arr[d + 1]);
     }
     return 0;
    }
    

    编译器给出的输出为7 根据我的模拟和推理输出应该是
    7.
    23 34 12 17 204 99 16

    现在,为了找出问题所在,我应用了一些变体 考虑这段代码

    #include <stdio.h>
    #define TOTAL_ELEMENTS (sizeof(arr))/sizeof(arr[0])
    int arr[] = {23, 34, 12, 17, 204, 99, 16};
    int main() {
     int d;
     printf("%zu\n", TOTAL_ELEMENTS);
     for (d = -1; d <=(int) ((TOTAL_ELEMENTS) - 2); d++) {
      printf("%d ", arr[d + 1]);
     }
     return 0;
    }
    

    请注意,我所做的唯一更改是引入了int类型转换,现在它给出了预期的结果。

    现在,据我所知,当我们在C程序中进行比较时,它可以正确地转换为更大的数据类型,所以假设TOTAL_ELEMENT甚至有更大的类型,比如long,那么d应该转换为long,程序应该运行良好,但这并没有发生。我在这里遗漏了哪些要点?

    1 回复  |  直到 10 月前
        1
  •  2
  •   Allan Wind    10 月前

    在比较中 d <= (TOTAL_ELEMENTS - 2) 排名 d 低于排名 (TOTAL_ELEMENTS - 2) 作为 int 精度低于 size_t 根据6.3.1.1在您的平台上:

    有符号整数类型的秩应大于精度较低的任何有符号整数的秩。

    编译器将强制转换 int d = -1 size_t 这产生了一个非常大的数字( SIZE_MAX 来自stdint.h),因此循环条件为false,循环体永远不会执行。

    1. 更喜欢循环习惯用法的标准。然后你可以使用 size_t d 哪种类型与你的上限类型相匹配。
    2. 这真是个好主意 () 宏观的右侧和每个宏观论点都要避免意外。
    3. 避免全局变量。
    4. 删除未使用的变量。
    5. 尽量缩小变量的范围;在这种情况下,通过声明 d for -循环。
    6. 使用正确的格式字符串 %zu 对于 size_t .
    7. (可选)您只需要 {} 如果thers大于1个语句,则围绕循环体,以及 return 0 是默认设置,所以我把两者都省略了。
    #include <stdio.h>
    
    #define TOTAL_ELEMENTS (sizeof (arr) / sizeof *(arr))
    
    int main() {
        int arr[] = {23, 34, 12, 17, 204, 99, 16};
        printf("%zu\n", TOTAL_ELEMENTS);
        for (size_t d = 0; d < TOTAL_ELEMENTS; d++)
            printf("%d ", arr[d]);
    }
    

    您将得到预期的输出:

    7
    23 34 12 17 204 99 16