E_T*_*ony 6 c++ arrays pointers element
据我所知,有两种方法可以在C++中访问数组元素:
int array[5]; //If we have an array of 5 integers
Run Code Online (Sandbox Code Playgroud)
1)使用方括号
array[i]
2)使用指针
*(array+i)
Run Code Online (Sandbox Code Playgroud)
我大学的老师强迫我使用*(array+i)方法,告诉我"它更优化".
那么,请你解释一下,它们之间有什么真正的区别吗?第二种方法是否比第一种方法有任何优势?
Chr*_*phe 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
Run Code Online (Sandbox Code Playgroud)
好吧,有了最好的意愿,我看不出生成的代码有什么不同.
顺便提一下,有人最近在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));
Run Code Online (Sandbox Code Playgroud)
事实上,第二个选项实际上是误导的**,因为你必须仔细阅读公式,以了解它是否是一个双重引用或乘以一个解除引用的指针.不是说那些可能被ADA等其他语言误导的人,**意思是"权力"
实施例2:所述的计算行列式的2×2矩阵的
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);
Run Code Online (Sandbox Code Playgroud)
对于多维数组,选项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];
Run Code Online (Sandbox Code Playgroud)
之后你决定使用a std::vector而不是数组,因为你已经知道它更加灵活和强大.您所要做的就是更改以下内容的定义(和初始化)w:
vector<int> w(10,0);
Run Code Online (Sandbox Code Playgroud)
其余代码将起作用,因为[]两个数据结构的语义相同.我让你想象一下,如果你使用过老师的建议会有什么问题......
"我大学的老师强迫我使用
*(array+i)方法,告诉我"它更优化"."
他们告诉你什么?如果你没有对这个陈述1完全错误,请向他们询问有关生成的汇编代码的证明(@Christophe在这里给出了答案).当我深入研究时,我不相信他们会给你这样的.
您可以使用例如GCC -S选项生成汇编程序代码,并将结果与一个或另一个版本进行比较,从而轻松地自行检查.
任何体面的,现代的C++编译器都会为这两个语句生成完全相同的汇编代码,只要它们引用任何c ++基本类型.
"第二种方法比第一种方法有任何优势吗?"
不会出现相反情况,因为代码的可读性不太直观.
1)对于class/ struct类型,可能会有T& operator[](int index)幕后做事的重载,但如果是这样,*(array+i)应该实现一致的行为.
我大学的老师强迫我使用
*(array+i)方法,告诉我"它更优化".
你的老师是完全错的.
标准定义array[i]为等同于*(array+i),并且编译器没有理由以其他方式处理它们.他们是一样的.两者都不会比另一个更"优化".
推荐一个而不是另一个的唯一原因是约定和可读性,并且在那些比赛中array[i]获胜.
我想知道你的老师还有什么问题?:(
| 归档时间: |
|
| 查看次数: |
5263 次 |
| 最近记录: |