为什么在C++中使用"*(*(array + i) + j)"而不是"array[i][j]"?

Why use "*(*(array + i) + j)" over "array[i][j]" in C++?

本文关键字:array C++ 为什么      更新时间:2023-10-16

在什么示例情况下,我应该使用更棘手的形式?它会生成更快的二进制代码吗?如果我可以用[][]表示法来完成这项工作,那么出于某种原因,我是否还应该付出额外的努力,并用指针来实现它?对于单个数据,我理解指针的必要性。我特别要求二维数组,而不是使用指针的一般意义。

在什么示例情况下,我应该使用更棘手的形式?

永远,除非您正在参加@M.M评论中提到的代码混淆比赛

它能生成更快的二进制代码吗?

否,发出的汇编指令应该与任何像样的编译器相同。

出于某种原因,我是否还应该付出额外的努力,并用指针实现它?

否。请改用标准容器或智能指针。避免使用原始c样式数组和指针。

对于已知尺寸,最简单的方法是

std::array<std::array<T,5>,10> array2D;

对于大小不同的2D阵列,可以使用

size_t rows, columns;
std::cout << "Enter row and column size please > " << std::flush;
if(std::cin >> rows >> columns) {
std::vector<std::vector<T>> array2D(rows,std::vector<T>(columns));
}

要优化2D阵列以使用连续的动态内存块,请考虑编写一个小包装类,将行和列偏移转换为内部值位置(例如,在简单的std::vector中维护)。

除了@πάῥεῖ'根据建议,最好编写C++表达式,以便用类似的类型替换变量——这是泛型代码的原理。

CCD_ 2是C阵列的优选替代方案。(二维大小写看起来像std::array< std::array< int, M >, N >。)它不支持+运算符,因此模糊表达式会阻碍迁移到它或任何其他类似容器的类型(如std::vector)。

通常没有理由喜欢*(array + i)形式而不是array[i]形式。同样,也没有理由喜欢*(*(array + i) + j)形式而不是array[i][j]

从语义上讲,它们是等效的,编译器能够发出更有效的"二进制代码"——在这两种情况下通常是相同的。

实际上,人类通常会发现更容易理解array[i][j]形式,所以这是最好的,除非你试图混淆人们(例如混淆)。

当使用其他形式的指针算术时,理解等价性是至关重要的。这样可以更有效地选择技术。C++标准库支持迭代器(指针的一种通用形式)来处理范围,并且在简单的array[i]语法中经常鼓励使用这些迭代器,这并非偶然,。

当您解释2d数组如何工作时。若数组是多维的,那个么该表达式就是使用数组名称可能出错的反例。比方说,这不是一个罕见的错误。许多缺乏经验的程序员所做的:

int arr[10][20];
for (int I =0; I<200; I+=1) *(arr + I) = <some value based on I>;

在最好的情况下,他们会遇到"无法从'int'转换为'int[20]"的错误,并转到他们更好的网站(或SO网站)。在最坏的情况下,它们会变得"聪明",并使用类型转换来欺骗编译器。

他们知道一维数组是如何工作的,因为自从K&R、 并且他们没有意识到,一旦我变得大于9,他们就会脱离数组绑定。表达式

*(*(arr + i) + j)

显示数组的索引相对于数组名称降级的指针是相乘的。更"正确"的方法是使用指向int:的指针

int  *p = (int *)&arr[0][0];
for (int I = 0; I < 200; I++) 
*(p+I) = <some value based on I;

但严格来说,C++标准也不能保证这一点,除非您使用指向无符号字符的指针。

unsigned char *p = (unsigned char*)&arr[0][0];
for (int I = 0; I < 200; I++) 
*(int*)(p + I*sizeof(int)) = I;

这里还必须小心,在平台假设填充的情况下,数组的元素实际上是需要在末尾填充的类型(例如结构)。

如果我们输出结果数组:

cout << "arr[][] = { ";
for (int i = 0; i < 10; i++) 
{
cout << "n{";
for (int j = 0; j < 20; j++) 
cout << arr[i][j]<< " ";
cout << "}";
}
cout << "}n";

我们将得到:

arr[][] = { 
{0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 }
{20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 }
{40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 }
{60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 }
{80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 }
{100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 }
{120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 }
{140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 }
{160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 }
{180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 }}