C++ C的公共数组长度宏?

C++ C的公共数组长度宏?,c++,c,arrays,c-preprocessor,C++,C,Arrays,C Preprocessor,我见过几个数组长度的宏浮动: 发件人: #定义长度(数组)(sizeof(数组)/sizeof(*(数组))) #定义数组长度(数组)(sizeof((数组))/sizeof((数组)[0]) #定义大小(数组,类型)(sizeof(数组)/(sizeof(类型)) 以及Visual Studio的: 我想知道的是: 使用array[0]和*array有什么区别 为什么两者都应该优先 它们在C++中有区别吗? 1) 无,数组的值是指向其第一个元素的指针。所以*数组==数组[0] 2) 个人偏

我见过几个数组长度的宏浮动:

发件人:

  • #定义长度(数组)(sizeof(数组)/sizeof(*(数组)))
  • #定义数组长度(数组)(sizeof((数组))/sizeof((数组)[0])
  • #定义大小(数组,类型)(sizeof(数组)/(sizeof(类型))
以及Visual Studio的:

我想知道的是:

  • 使用
    array[0]
    *array
    有什么区别
  • 为什么两者都应该优先
  • 它们在C++中有区别吗? 1) 无,数组的值是指向其第一个元素的指针。所以*数组==数组[0]
    2) 个人偏好
    3) 否

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

  • 使用数组[0]和*array有什么区别
  • 为什么两者都应该优先
  • 它们在C++中有区别吗? <>(1)C无差异,C++中的实际原始数组无差异。

    (2) 没有技术上的理由选择其中一个,但新手可能会被指针取消引用弄糊涂

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

    #include <stddef.h>
    
    typedef ptrdiff_t Size;
    
    template< class Type, Size n >
    Size countOf( Type (&)[n] ) { return n; }
    
    #包括
    typedef ptrdiff\t大小;
    模板<类别类型,大小n>
    (类型(&)[n]){return n;}的大小计数
    
    这只接受实际原始数组作为参数

    它是函数集
    startOf
    endOf
    countOf
    的一部分,定义起来非常方便,因此它们可以应用于原始数组和标准库容器。据我所知,这个三合会组织是由迪特马尔·库尔首先发现的。在C++0x中,
    startOf
    endOf
    很可能作为
    std::begin
    std::end
    提供

    干杯,这里有一个更好的C版本(来自谷歌的Chromium项目):

    < > >使用< <代码> > 0 [数组] < /C> >,在代码数组上,改进了<代码> >或>代码> *数组< /COD>版本,它等同于“纯数组”中的“代码>数组[0 ] < /C> >,但是如果<代码>数组恰好是一个C++类型,它重载<代码>操作符[]()

    。 对于许多(但不是所有)情况,如果指针作为
    数组
    参数传递,除法会导致一个除法为零的操作(由于它是一个编译时常量表达式,所以应该在编译时捕获)

    有关更多详细信息,请参阅


    <> C++代码有更好的选择。有关详细信息,请参见。

    +1:有趣!是否有理由使用
    而不是
    ?我想不出来;我可以想出几个理由来选择。对于这一点,它是值得的,下面是我在代码< >代码> vs.代码> <代码>推理(注:我更喜欢老式的C变体):我在 STDDEF.H./C>中,甚至在C++的cAMP中也是如此。试图贬低C标准库是荒谬的。值得注意的是,通常
    *a
    a[0]
    之间存在差异,当
    a
    是指向不完整类型的指针时就会出现这种差异。但是,这并不影响<代码> >代码>,因为在这种情况下,代码> <代码> <代码>将无效。这是非常隐秘的,只是为了防止在C++中被错误地使用,考虑到C++中还应该使用其他东西。C++是不应该使用的,这是正确的。但是,为C++提供了一些安全性的位并不太神秘(它只是异常索引)。真正神秘的部分是防止C语言中某些类型的误用,而这些误用实际上很难防止(宏甚至不能完美地防止这种误用)。它所防止的误用(传递指针而不是数组参数)经常发生,以至于它需要付出代价才能获得复杂性。在一个宏中,复杂性并不是一个太大的问题(而且这个宏没有我遇到的许多宏那么神秘)。地狱类型是什么?你能做到吗?@Matt:
    []
    运算符是可交换的(因为它是根据指针算术定义的)。然而,宏的这一部分是不太重要的“安全性”——很抱歉,它似乎引起了人们的注意。正如链接来源中所指出的,这项检查的后半部分只涉及一些情况。(特别是它没有捕捉到
    x
    是一个
    char*
    ,这是一个常见的用例)是的,它可以有效地作为
    sizeof(void*)/sizeof(array[0])
    ,在当代现实中,这意味着8、4、2、1或0无论如何,在编译时没有任何东西可以帮助您处理这样的函数,您永远不知道是谁调用它,以及数组有多大。
    #include <stddef.h>
    
    typedef ptrdiff_t Size;
    
    template< class Type, Size n >
    Size countOf( Type (&)[n] ) { return n; }
    
    #define COUNT_OF(x) ((sizeof(x)/sizeof(0[x])) / ((size_t)(!(sizeof(x) % sizeof(0[x])))))