你好,我现在正在中介C班,我想到了这个想法:
int multi[3][4]; // const multidimensional array
int* ptr = *multi; // ptr is a pointer variable that hold the address of multi const array
那么,访问多维数组位置的更快/更小/优化是什么?
此:
multi[3][1]; // index the value position
或
*(*(multi+2)+1); // pointer to the position on the array
或(更新)
ptr += 9; // pointer arithmetic using auxiliary pointer
由于“multi”是一个const数组,编译器应该“知道”元素位置的本地化,如果使用指向该数组的变量指针可能需要更多的处理时间,另一方面可能会更快搜索我想要显示的项目时。什么是更快/更小/优化的方法?
提前谢谢。
答案 0 :(得分:8)
它们都以相同的方式编译,*(pointer_to_first_element + x + y)
。
答案 1 :(得分:6)
首先
int multi[3][4];
不是const
数组。此声明中没有const
。
其次,
int* ptr = *multi;
会使ptr
指向元素multi[0][0]
。数字上它与multi[0]
的地址和整个multi
的地址相同,但类型不同。
第三,
multi[3][1];
根据定义,与
相同*(*(multi + 3) + 1);
所以性能上没有任何合理的差异。如何与上述内容联系起来并不清楚。
第四,
*ptr + 9;
其中没有“指针算术”。它相当于
multi[0][0] + 9;
这是普通的整体添加。再次,它与上述内容的联系方式尚不清楚。
最后,您的问题标题为“常量指针数组或指向数组的指针”,而在问题的实际文本中,我看不到。
答案 2 :(得分:4)
如果你的代码被抛出的速度有多快并不重要,因为没有其他人可以理解和维护代码;此外,棘手的代码有时会阻止编译器进行更好的优化。
例如:
int main(void)
{
int arr[3][4] = {{0,1,2,3},{4,5,6,7},{8,9,10,11}};
int *p = *arr; // == arr[0] == &arr[0][0]
int x;
x = arr[2][3]; // Straightforward array access
x = *(*(arr+2)+3); // Ugly pointer arithmetic
x = *(ptr + 11); // Slightly less ugly pointer arithmetic
return 0;
}
我通过gcc -c -g -Wa,-a,-ad > foo.lst
运行上面的内容,以使生成的程序集和源代码交错。
以下是x = arr[2][3];
的翻译:
movl -16(%ebp), %eax
movl %eax, -8(%ebp)
以下是x = *(*(arr+2)+3);
的翻译:
leal -60(%ebp), %eax
addl $44, %eax
movl (%eax), %eax
movl %eax, -8(%ebp)
最后,x = *(ptr + 11);
的翻译:
movl -12(%ebp), %eax
addl $44, %eax
movl (%eax), %eax
movl %eax, -8(%ebp)
不要试图超越你的编译器。这不再是20世纪70年代了。 gcc知道如何有效地进行数组访问,而无需告诉它。
你甚至不应该思考关于这个级别的性能,除非你已经调整了算法和数据结构,在编译器上使用了最高的优化设置(FWIW) ,-O1
为所有三个版本生成相同的代码),并且仍然无法满足硬性能要求(在这种情况下,正确的答案通常是购买更快的硬件) 。如果没有先通过分析器运行代码来找到真正的瓶颈,就不应该更改任何。 测量,不要猜。
修改强>
当然,当文字2
和3
被变量替换时,情况会发生变化。在这种情况下,*(ptr + offset);
看起来最好。但不是很多。而且我仍然认为清晰度在这个层面更重要。
答案 3 :(得分:2)
a[i]
表示 *(a+i)
,实际上您也可以编写i[a]
,您的编译器也会接受它。
*(ptr+i)
在理论上可能比ptr[j][k]
略快,因为你只做了一次加法(而ptr[j][k]
可能需要2)。
答案 4 :(得分:1)
我不确定const数组的来源,但是对于讨论,我们假设原始帖子中有一些。
由于原始海报未明确提及PC编程,因此const数组和常规数组不一定以相同的方式编译。
在嵌入式系统中,如果const数组分配在真正的非易失性存储器(即具有真实ROM的嵌入式应用程序)中,则const数组可能比非const数组慢。这种缓慢与ROM的访问时间有关,而且与硬件特定有关。
关于指针运算,这是访问数组的唯一方法。 C语言中的数组语法是编译器所谓的“语法糖”,即它只是用于外观。像
这样的数组访问ARR [I]
由编译器翻译为
*(ARR + I)
它们在性能和功能上是相同的。