【发布时间】:2020-06-23 09:31:35
【问题描述】:
问题
我正在学习 C++,并且正在编写代码来转置二维数组和反转一维数组。
请查看调用。为什么我必须使用reverse(arr, 4) 进行反向,而我必须使用transpose(*in_matrix, *out_matrix) 进行转置?
每个函数签名有两种编写方式。两者似乎给出了相同的结果。
谢谢。
编辑:我知道如何用数组下标来解决它。我特意这样做是为了练习。现在我明白了尝试这个没有意义。但是,我添加了一些从下面的答案中总结出来的注释。
代码
#include <iostream>
using namespace std;
const int LENGTH = 2;
const int WIDTH = 3;
void printArray(const int arr[], const int N) {
cout << arr[0];
for (int i = 1; i < N; ++i) {
cout << ", " << arr[i];
}
cout << "\n";
}
// void transpose(int* const input, int* const output) { // both these signatures
void transpose(const int input[], int output[]) { // works (I find the top one clearer)
for (int i = 0; i < WIDTH; ++i) {
for (int j = 0; j < LENGTH; ++j) {
*(output + j * WIDTH + i) = *(input + i * LENGTH + j);
}
}
}
// void reverse(int arr[], const int N) { // both these signatures
void reverse(int* arr, const int N) { // works (I prefer this one)
for (int i = 0; i < N / 2; ++i) {
int temp = *(arr + i);
*(arr + i) = *(arr + N - 1 - i);
*(arr + N - 1 - i) = temp;
}
}
int main() {
int arr[4] = {2,4,6,8};
printArray(arr, 4);
reverse(arr, 4); // this works
// reverse(*arr, 4); // this doesn't work
printArray(arr, 4);
int in_matrix[WIDTH][LENGTH];
in_matrix[0][0] = 1;
in_matrix[0][1] = 2;
in_matrix[1][0] = 3;
in_matrix[1][1] = 4;
in_matrix[2][0] = 5;
in_matrix[2][1] = 6;
int out_matrix[LENGTH][WIDTH];
// transpose(in_matrix, out_matrix); // this doesn't work
transpose(*in_matrix, *out_matrix); // this works
cout << "in_matrix is:\n";
for (int i = 0; i < WIDTH; ++i) {
printArray(in_matrix[i], LENGTH);
}
cout << "out_matrix is:\n";
for (int i = 0; i < LENGTH; ++i) {
printArray(out_matrix[i], WIDTH);
}
return 0;
}
答案摘要
LESSON: DO NOT USE pointer-arithmetic for 2D-arrays
decay
KEY IDEA: arr -----> &arr[0] type int*
This is also the reason the two function signatures are equivalent.
// transpose(int* const input, int* const output) // alt.
Signature: transpose(const int input[], int output[])
i.e. it expects an array of ints (or equiv., a pointer to an int)
(id)
IDENTITY: a[i] = *(a + i) ALWAYS TRUE
Reason transpose(in_matrix, out_matrix) doesn't work:
decay
out_matrix -----> &out_matrix[0] type int(*)[WIDTH]
Reason transpose(*in_matrix, *out_matrix) works:
(id) decay
*out_matrix = out_matrix[0] -----> &(out_matrix[0])[0]
【问题讨论】:
-
数组可以衰减到指向其第一个元素的指针。例如,
arr将衰减为&arr[0],其类型为int*。数组数组也是如此,例如out_matrix。out_matrix也将衰减为指向其第一个元素的指针,即&out_matrix[0],但由于out_matrix的每个元素都是一个数组,因此类型将是指向数组的指针(对于&out_array[0],该类型具体为int (*)[WIDTH]) .指向数组的指针不能衰减。 -
另请注意,对于任何数组或指针
a和索引i,表达式a[i]完全等于@987654338 @。由此得出*out_array等于out_array[0],这是一个可以衰减为指针的实际数组。这意味着*out_array实际上与&((out_array[0])[0])相同(添加括号以使其更清晰)。 -
如果没有
cout,我认为是C -
@Someprogrammerdude 谢谢。这是完全有道理的。你解释得很好。如果你很好奇,问题来自ocw.mit.edu/courses/electrical-engineering-and-computer-science/…(作业2,最后一个问题)。事实上,我读错了这个问题。它没有特别要求使用指针偏移(仅数组下标)实现
transpose。经历了这一切,难怪他们没有问这个问题。
标签: c++ arrays pointers reference transpose