据我所知,有两种方法可以访问C ++中的数组元素:
int array[5]; //If we have an array of 5 integers
1)使用方括号
array[i]
2)使用指针
*(array+i)
我的大学老师强迫我使用*(array+i)
方法,告诉我"它更优化"。
那么,请你解释一下,它们之间有什么真正的区别吗?第二种方法是否比第一种方法有任何优势?
答案 0 :(得分:11)
好吧,让我们看一下用MSVC2013生成的汇编代码(NON-OPTIMIZED调试模式):
; 21 : array[i] = 8;
mov eax, DWORD PTR _i$[ebp]
mov DWORD PTR _array$[ebp+eax*4], 8
; 22 : *(array + i) = 8;
mov eax, DWORD PTR _i$[ebp]
mov DWORD PTR _array$[ebp+eax*4], 8
好吧,有了最好的意愿,我看不出生成的代码有什么不同。
顺便提一下,有人最近在SO上写道:过早优化是所有邪恶的根源。你的老师应该知道!
显然,选项一具有直观和可读的优点。 Option2在数学应用程序中变得很快无法实现。
示例1:作为数组实现的2D数学向量的距离。
double v[2] = { 2.0, 1.0 };
// option 1:
double d1 = sqrt(v[0] * v[0] + v[1] * v[1]);
//option 2:
double d2 = sqrt(*v**v + *(v + 1)**(v + 1));
事实上,由于**
,第二个选项确实具有误导性,因为您必须仔细阅读公式,以了解它是否是双引用或乘以解除引用的指针。不是说那些可能被ADA等其他语言误导的人,**
意味着“权力”
示例2:计算2x2矩阵的determinant
double m[2][2] = { { 1.0, 2.0 }, { 3.0, 4.0 } };
// option 1
double dt1 = m[0][0] * m[1][1] - m[1][0] * m[0][1];
// option 2
double *x = reinterpret_cast<double*>(m);
double dt2 = *x **(x+2*1+1) - *(x+2*1) * *(x+1);
对于多维数组,选项2是一场噩梦。请注意:
我使用临时的一维指针x
来使用公式。在这里使用m会导致误导性的编译错误消息。
您必须知道对象的精确布局,并且必须在每个公式中引入第一维的大小!
想象一下,稍后你想增加2D数组中的元素数量。你必须重写一切!
您的老师在这里缺少的是,运算符[]
具有编译器和读者很好理解的含义。它是一种抽象,不依赖于您的数据结构在现实中的实现方式。
假设您有一个数组和一个非常简单的代码:
int w[10] {0};
... // put something in w
int sum = 0;
for (int i = 0; i < 10; i++)
sum += w[i];
稍后您决定使用std::vector
而不是数组,因为您已经了解它更加灵活和强大。您所要做的就是更改w
的定义(和初始化):
vector<int> w(10,0);
其余代码将起作用,因为[]
的语义对于两个数据结构是相同的。我让你想象一下,如果你已经使用了老师的建议,会发生什么事情......
答案 1 :(得分:9)
“我大学的老师强迫我使用
*(array+i)
方法,告诉我”它更优化“。”
他们告诉你什么?如果你没有对这个语句 1 没有完全错误,请向他们询问有关生成的汇编代码的证明(@Christophe在his answer中给出了一个)。当我深入研究时,我不相信他们会给你这样的。
您可以使用以下方法轻松自行检查。 GCC的-S
option生成汇编代码,并将获得的结果与一个或另一个版本进行比较。
任何体面的,现代的C ++编译器都会为这两个语句生成完全相同的汇编代码,只要它们引用任何c++ fundamental types。
“第二种方法是否比第一种方法有任何优势?”
没有。由于代码的可读性不太直观,似乎会出现相反的情况。
1)对于class
/ struct
类型,T& operator[](int index)
可能会出现在幕后执行操作的重载,但如果是这样,*(array+i)
应该是实施以保持一致。
子>
答案 2 :(得分:7)
我的大学老师强迫我使用
*(array+i)
方法,告诉我&#34;它更优化&#34;。
您的老师绝对错误。
标准定义array[i]
等同于*(array+i)
,编译器没有理由对其进行处理。他们是一样的。两者都不会更优化&#34;比另一个。
推荐一个优于另一个的唯一理由是约定和可读性,在那些比赛中,array[i]
获胜。
我想知道你的老师还有什么问题? :(