Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/57.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ C++;数组[索引]与索引[数组]_C++_C_Arrays - Fatal编程技术网

C++ C++;数组[索引]与索引[数组]

C++ C++;数组[索引]与索引[数组],c++,c,arrays,C++,C,Arrays,可能重复: array[index]和index[array]都可能是编译器功能或语言功能。第二个怎么可能呢?从C的早期开始,表达式a[i]只是将a[0]的地址添加到i(按a[0]的大小放大)然后取消引用。事实上,所有这些都是等价的: a[i] i[a] *(a+i) ==== 我唯一关心的是实际的去引用。虽然它们都产生相同的地址,但如果a和i的类型不同,则可能需要考虑取消引用 例如: 实际上我还没有测试过这种行为,但这是你可能需要注意的。如果它确实改变了被取消引用的内容,那么很可能会导致对

可能重复:


array[index]和index[array]都可能是编译器功能或语言功能。第二个怎么可能呢?

从C的早期开始,表达式
a[i]
只是将a[0]的地址添加到i(按a[0]的大小放大)然后取消引用。事实上,所有这些都是等价的:

a[i]
i[a]
*(a+i)
====

我唯一关心的是实际的去引用。虽然它们都产生相同的地址,但如果
a
i
的类型不同,则可能需要考虑取消引用

例如:

实际上我还没有测试过这种行为,但这是你可能需要注意的。如果它确实改变了被取消引用的内容,那么很可能会导致对象数组出现各种各样的问题

====

更新:

您可能可以安全地忽略
===
行之间的上述位。我已经在Cygwin下用一个短的和一个长的测试了它,看起来还可以,所以我想我的担心是没有根据的,至少在基本情况下是这样。我仍然不知道更复杂的会发生什么,因为这不是我想做的事情。

编译器将启动

index[array]
进入

按照正常语法,它将

array[index]
进入


因此,您可以看到这两个表达式的计算结果是相同的。这对于C和C++都适用。

< P>如Matthew Wilson所讨论的,这可以用来在C++中强制类型安全,通过防止使用<代码>维度>(/)代码>类宏,并定义定义下标操作符的类型的实例,如:

#define DIMENSION_OF_UNSAFE(x)  (sizeof(x) / sizeof((x)[0]))

#define DIMENSION_OF_SAFER(x)  (sizeof(x) / sizeof(0[(x)]))

int ints[4];

DIMENSION_OF_UNSAFE(ints); // 4
DIMENSION_OF_SAFER(ints); // 4

std::vector v(4);

DIMENSION_OF_UNSAFE(v); // gives impl-defined value; v likely wrong
DIMENSION_OF_SAFER(v); // does not compile
对于处理指针,还有更多内容,但这需要一些额外的模板智能。查看库中的
STLSOFT\u NUM\u ELEMENTS()
的实现,并在的第14章中详细阅读

编辑:一些评论员建议实现不拒绝指针。它可以(以及用户定义的类型),如以下程序所示。您可以通过未注释的第16行和第18行来验证这一点。(我只是在Mac/GCC4上做的,它拒绝了这两种形式)

#包括
#包括
#包括
int main()
{
int-ar[1];
int*p=ar;
std::向量v(1);
printf(“ar:%lu\n”,STLSOFT_NUM_元素(ar));
//printf(“p:%lu\n”,STLSOFT_NUM_元素(p));
//printf(“v:%lu\n”,STLSOFT_NUM_元素(v));
返回0;
}
在C和C++中,

>(数组是指针或数组),它是一种语言特征:指针算术。其中a或b为指针的操作a[b]被转换为指针算术:*(a+b)。由于加法是对称的,重新排序不会改变含义


现在,非指针有不同之处。事实上,给定一个带有重载运算符[]的类型a,那么[4]是一个有效的方法调用(将调用::运算符),但相反的方法甚至不会编译。

我认为这没有什么不同。我的意思是它可以追溯到最早的时候,而不是说它只是早期的样子。这是错误的。无论哪种方式,编译器都知道向long*(按任意顺序)添加int将导致long*,然后将其解引用到long。这适用于任何指针类型,包括用户定义的。错误方式@马太福音?我已经说过,我的怀疑是不正确的,标准类型工作正常。至于更复杂的类型,我没有发表评论,只是因为我没有尝试过(或可能尝试过)。为什么在投票结束时发布了这篇文章?dup有很多很好的答案,但你至少应该做这个CW。我在别人发现dup之前很久就发布了这个答案。然后,我同意在我检查完被骗者后关闭的决定。这不是火箭科学。而且,真的,人们如何回答问题或者他们是否让他们回答问题并不取决于你。这取决于回答者自己。如果这不是一个合适的问题,那么我会去CW(或者更可能只是留下一条评论),但这是一个合适的问题,只是重复了。这个“转换”说明仅适用于其中一个变量是指针或数组,另一个是整数类型,即通常的C情况。在C++中,[b]失去了它的对称性,因为运算符[]可以是重载成员函数,而编译器不允许使用*(a+b)代替。(a+b)可能具有不同的类型和值,或者它可能根本不是有效的表达式。+1。酷。从来没有这样想过。重复:。使用模板可以实现更好的“维度”实现:template std::size_t dimension(t[N]&x){return N;}。这将比sizeof(a)/sizeof(a[0])的数组(没有衰减为指针)更安全。dribeas:问题是它不再是编译时表达式。Wilson描述的技术演示了编译时版本。正如我所说,它可以在STLSoft库中获得,还有一种方法可以获得编译时表达式:模板char(&an_数组(T(&)[N])[N];这将计算为对具有相同大小的字符数组的引用。像这样使用:intv[sizeof an_数组(另一个_数组)];请注意,当然,mine和dribea的宏都不同于wilson的宏。我们的人会拒绝一个指针。他的人会接受的。因此,这些是不同的用例。tlib,dribeas:你们都错了。请参见上面编辑的回复。
array[index]
*(array + index)
#define DIMENSION_OF_UNSAFE(x)  (sizeof(x) / sizeof((x)[0]))

#define DIMENSION_OF_SAFER(x)  (sizeof(x) / sizeof(0[(x)]))

int ints[4];

DIMENSION_OF_UNSAFE(ints); // 4
DIMENSION_OF_SAFER(ints); // 4

std::vector v(4);

DIMENSION_OF_UNSAFE(v); // gives impl-defined value; v likely wrong
DIMENSION_OF_SAFER(v); // does not compile
#include <stlsoft/stlsoft.h>
#include <vector>
#include <stdio.h>

int main()
{
    int     ar[1];
    int*    p = ar;
    std::vector<int>        v(1);

    printf("ar: %lu\n", STLSOFT_NUM_ELEMENTS(ar));

//  printf("p: %lu\n", STLSOFT_NUM_ELEMENTS(p));

//  printf("v: %lu\n", STLSOFT_NUM_ELEMENTS(v));

    return 0;
}