【发布时间】:2014-04-27 18:55:30
【问题描述】:
我正在阅读一本名为 C Programming: A Modern Approach 的书,在讨论数组的第一部分中,作者指出:
使用宏来定义数组的长度是很好的做法
然后用简单的例子:
#define N 10
...
int a[N];
我知道这与能够返回程序的源代码并更改值有关,并且将其设为宏可能会使程序员更容易,但我不确定。 为什么这是一个很好的做法,还是客观的?
【问题讨论】:
我正在阅读一本名为 C Programming: A Modern Approach 的书,在讨论数组的第一部分中,作者指出:
使用宏来定义数组的长度是很好的做法
然后用简单的例子:
#define N 10
...
int a[N];
我知道这与能够返回程序的源代码并更改值有关,并且将其设为宏可能会使程序员更容易,但我不确定。 为什么这是一个很好的做法,还是客观的?
【问题讨论】:
这是一个很好的做法,因为
话虽如此,我不确定我是否同意这是最好的方法。枚举也可以工作并避免宏的一些问题(例如,难以覆盖和静默编译)。 IIRC const int 也可以。
编译为cc:
const int s = 1;
int a[s];
int main() {
return 0;
}
Apple LLVM 版本 4.2 (clang-425.0.28)(基于 LLVM 3.2svn)
目标:x86_64-apple-darwin12.4.0
线程模型:posix
【讨论】:
N 和 10 的运行时间没有区别,因为编译后实际上没有更多的 N。 N 是 10 的简单别名
这是一个非常好的做法,C 语言规范本身说永远不要将常量埋入代码中,而是用有意义的名称来定义它们。有几种方法可以做到这一点,宏(我个人最喜欢,因为它们不使用内存)、全局变量(使用内存并且可以修改)、常量全局变量(使用内存但永远不会改变)。
【讨论】:
(clang-425.0.28) (based on LLVM 3.2svn) Target: x86_64-apple-darwin12.4.0 Thread model: posix
使用宏而不是常量整数文字的一个主要原因是,当一个值在代码中的多个位置使用时,更新单个宏值要比遍历并找到一个值的所有用途来更新要容易得多他们。
例如,考虑以下代码:
int a[10];
...
for(i = 0; i < 10; i++) printf("%d\n", a[i]);
...
myFunc(a, 10); // 10 indicates the size of the array
如果您稍后决定更改数组的大小,则必须遍历并找到用于指示大小的 10 的每个实例。但是,如果我们这样做:
#define N 10
int a[N];
...
for(i = 0; i < N; i++) printf("%d\n", a[i]);
...
myFunc(a, N); // N indicates the size of the array
您所要做的就是将 N 的值更改为某个新数字以更改数组的大小,您的所有其他代码都会正常工作。
就性能而言,使用宏与硬编码常量值一样快,因为宏只是基于文本的替换。在编译时,如果宏N的值为10,那么在实际编译之前,C源代码中N的每个实例都会被更改为10。
【讨论】:
for(int i = 0; i < sizeof(a)/sizeof(a[0]); i++),它完美地解决了这个问题。 (它在零大小的数组上失败。应该没问题。)
myFunc 相同。您实际想要的示例类似于Foo foo[10]; int someFooProperty[10];,由于某种原因,您需要两个相应的数组。
int a[N]; myFunc(a, sizeof(a)/sizeof(a[0]));,但请使用N,就像int *a = malloc(N * sizeof(*a)); myFunc(a, N)一样。
sizeof(a) / sizeof(a[0]) 只能在创建数组的同一上下文中使用,所以如果你在通过指针传递的数组上这样做,它是无效的。