C++ C的通用数组长度宏?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/4415524/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-28 15:20:32  来源:igfitidea点击:

Common array length macro for C?

c++carraysc-preprocessor

提问by Matt Joiner

I've seen several macros for array length floating around:

我已经看到了几个数组长度的宏:

From this question:

这个问题

  • #define length(array) (sizeof(array)/sizeof(*(array)))
  • #define ARRAY_LENGTH(array) (sizeof((array))/sizeof((array)[0]))
  • #define SIZE(array, type) (sizeof(array) / (sizeof(type))
  • #define length(array) (sizeof(array)/sizeof(*(array)))
  • #define ARRAY_LENGTH(array) (sizeof((array))/sizeof((array)[0]))
  • #define SIZE(array, type) (sizeof(array) / (sizeof(type))

And Visual Studio's _countof:

和 Visual Studio 的_countof

#define _countof(_Array) (sizeof(_Array) / sizeof(_Array[0]))

What I'd like to know is:

我想知道的是:

  1. What's the difference between those using array[0]and *array?
  2. Why should either be preferred?
  3. Do they differ in C++?
  1. 使用array[0]和 的那些有什么区别*array
  2. 为什么应该首选?
  3. 它们在 C++ 中有何不同?

回答by Michael Burr

Here's a better C version (from Google's Chromium project):

这是一个更好的 C 版本(来自 Google 的 Chromium 项目):

#define COUNT_OF(x) ((sizeof(x)/sizeof(0[x])) / ((size_t)(!(sizeof(x) % sizeof(0[x])))))

It improves on the array[0]or *arrayversion by using 0[array], which is equivalent to array[0]on plain arrays, but will fail to compile if arrayhappens to be a C++ type that overloads operator[]().

它通过 using改进了array[0]or*array版本0[array],这相当于array[0]在普通数组上,但如果array碰巧是重载 的 C++ 类型,将无法编译operator[]()

The division causes a divide-by-zero operation (that should be caught at compile time since it's a compile-time constant expression) for many (but not all) situations where a pointer is passed as the arrayparameter.

在将指针作为array参数传递的许多(但不是全部)情况下,除法会导致除以零操作(应该在编译时捕获,因为它是编译时常量表达式)。

See Is there a standard function in C that would return the length of an array?for more details.

请参阅C 中是否有标准函数可以返回数组的长度?更多细节。

There's a better option for C++ code. See Compile time sizeof_array without using a macrofor details.

C++ 代码有更好的选择。有关详细信息,请参阅不使用宏的编译时 sizeof_array

回答by Cheers and hth. - Alf

  1. What's the difference between those using array[0] and *array?
  2. Why should either be preferred?
  3. Do they differ in C++?
  1. 使用 array[0] 和 *array 的有什么区别?
  2. 为什么应该首选?
  3. 它们在 C++ 中有何不同?

(1) No difference in C. No difference for an actual raw array in C++.

(1) C 没有区别。C++ 中的实际原始数组没有区别。

(2) No technical grounds to prefer one or the other, but newbies might be confused by the pointer dereference.

(2) 没有技术依据来偏爱其中一个,但新手可能会被指针解引用混淆。

(3) In C++ you would normally not use the macro, because it's very unsafe. If you pass in a pointer instead of an actual raw array, code will compile but yield incorrect result. So in C++ you would/should instead use a function template, like …

(3) 在 C++ 中,您通常不会使用宏,因为它非常不安全。如果您传入一个指针而不是实际的原始数组,代码将编译但会产生错误的结果。因此,在 C++ 中,您将/应该使用函数模板,例如……

#include <stddef.h>

typedef ptrdiff_t Size;

template< class Type, Size n >
Size countOf( Type (&)[n] ) { return n; }

This only accepts actual raw array as argument.

这只接受实际的原始数组作为参数。

It's part of a triad of functions startOf, endOfand countOfthat it's very convenient to define so that they can be applied to both raw arrays and standard library containers. As far as I know this triad was first identified by Dietmar Kuehl. In C++0x startOfand endOfwill most probably be available as std::beginand std::end.

它的功能是黑社会的一部分startOfendOf而且countOf,它是非常方便的定义,使他们能够同时适用于原数组和标准库容器。据我所知,这个黑社会最早是由迪特玛·库尔 (Dietmar Kuehl) 发现的。在 C++0x 中startOfendOf很可能会以std::begin和 的形式提供std::end

Cheers & hth.,

干杯 & hth.,

回答by SiegeX

1) Nothing, the value of an array is a pointer to it's first element. So *array == array[0]
2) Personal Preference
3) No

1) 没什么,数组的值是指向它的第一个元素的指针。所以 *array == array[0]
2) 个人偏好
3) 否

Note that this macro wont work if called inside a function where the array is passed as a parameter into the function. This is because the array object passed "decays" into a pointer rather than a deep copy.

请注意,如果在将数组作为参数传递给函数的函数内部调用该宏,则该宏将不起作用。这是因为数组对象将“衰减”传递给指针而不是深层副本。