【问题标题】:Confusion around using a macro for an array length使用宏来获取数组长度的困惑
【发布时间】:2020-12-07 13:25:01
【问题描述】:

下面的代码只是读取 10 个整数并将它们存储在长度为 10 的数组中。我有两个问题:

  1. 本示例中使用宏 N ((int)(sizeof(a) / sizeof(a[0]))) 或仅使用表示数组长度的整数(本示例中为 10)有什么区别?
  2. 在初始化之前不是sizeof()调用了a[0]吗?

任何帮助将不胜感激。

#include <stdio.h>

#define N ((int)(sizeof(a) / sizeof(a[0])))

int main(void)
{
    int a[10], i;

    printf("\nEnter %d numbers ", N);
    for (i = 0; i < N; i++)
        scanf("%d", &a[i]);

    return 0;
}

【问题讨论】:

  • sizeof 关心的是类型a[0]的类型无论是否被初始化都是一样的。
  • 旁白:对于这个简单的示例,使用#define N 10int a[N], i; 会更容易。

标签: arrays c macros sizeof


【解决方案1】:

使用类型转换为 int 是个坏主意。写就够了

#define N (sizeof(a) / sizeof(a[0]))

没有使用 a[0] 的值。 sizeof 运算符确定操作数的类型,然后确定该类型对象的大小。

注意sizeof 不是函数。它是一个运算符。你也可以写

#define N (sizeof a / sizeof a[0] )

使用 10 之类的幻数代替宏会降低程序的灵活性。如果数组中的元素数量会发生变化,您需要找到所有使用幻数来更新它们的位置。

【讨论】:

  • 那么除了灵活性之外,没有什么比使用宏更有好处了?
  • @alt72 让程序更灵活、更易读、更不容易出错。
  • “不易出错”?只有 after 宏已被正确验证。但除此之外,宏也会使调试使用它们的代码变得更加困难。单步执行代码时,执行流程会跳过宏的内容。对于任何不重要的宏,如果它包含错误,这可能是一个问题。
  • @ryyker 宏被编写一次并多次使用。因此,它们在使用前经过验证。使用幻数很容易出错。例如,可能有错字,而不是 10,可能是 11 或其他内容。此外,您将无法说出它是数组中的元素数还是其子数组中的元素数。
  • 还有一件事,我不明白为什么强制转换为int 是个坏主意。我认为 sizeof 返回一些无符号整数类型 (size_t),并且没有强制转换,我将有符号整数 i 与无符号整数 N 进行比较,这在某些情况下会导致奇怪的行为。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-08-05
  • 2015-08-14
  • 1970-01-01
相关资源
最近更新 更多