Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/143.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ C++;语法差异:2D和1D数组(指针算法)_C++_Arrays_Pointers_Reference_Transpose - Fatal编程技术网

C++ C++;语法差异:2D和1D数组(指针算法)

C++ C++;语法差异:2D和1D数组(指针算法),c++,arrays,pointers,reference,transpose,C++,Arrays,Pointers,Reference,Transpose,问题 我正在学习C++,并且编写代码到转置二维数组< /强>,并对逆一维数组>/P> 请看这些调用。为什么我必须使用reverse(arr,4)进行反转,而我必须使用transpose(*in_矩阵,*out_矩阵)进行转置 编写每个函数签名有两种方法。两者似乎得出了相同的结果 多谢各位 编辑:我知道如何用数组下标来解决它。我这样做是为了练习。现在我明白了,尝试这个是没有意义的。不过,我补充了以下答案总结的一些注释 代码 #include <iostream> using names

问题

我正在学习C++,并且编写代码到<强>转置二维数组< /强>,并对<强>逆一维数组>/P> 请看这些调用。为什么我必须使用

reverse(arr,4)
进行反转,而我必须使用
transpose(*in_矩阵,*out_矩阵)
进行转置

编写每个函数签名有两种方法。两者似乎得出了相同的结果

多谢各位

编辑:我知道如何用数组下标来解决它。我这样做是为了练习。现在我明白了,尝试这个是没有意义的。不过,我补充了以下答案总结的一些注释

代码

#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;
}

在C语言中,数组和指针有点复杂地混合在一起。一个数组可以被看作是一个带有一些“大小”信息的指针(它不存储在任何地方,但编译器知道)。因此,当在数组上使用时,
sizeof
给出整个数组内容的大小,而在指针上,它给出指针的大小

将数组传递给函数时,大小信息将丢失—实际上,数组将衰减为指针。对于大多数实际用途,指向类型的指针可以像该类型的一维数组一样使用。数组下标符号(
[]
)也可用于使用指针访问连续元素

但是,对于二维阵列,这会变得更加复杂。二维数组和双指针可以使用与
a[i][j]
形式相同的访问语法,但它们不能互换。二维数组衰减为指向数组的指针,而双指针是指向指针的指针

回到您的问题,两种编写函数签名的方法本质上是等效的,因为一维数组在传递给函数时会衰减为指针。所以
void reverse(int*arr,const int N)
void reverse(int arr[],const int N)
相同

然而,在转置函数中,传递的是一个2D数组。它将衰减为指向数组的指针。但是在函数声明中,您接受这些参数作为数组(或者实际上是指针)。这仍然可以很好地工作,因为C有一些奇怪的地方。2D数组也可以被视为一个大的1D数组,其中一行一行地连续排列。然而,这并不是最好的办法。这还反映在将数组名传递给转置函数时必须取消对它们的引用,因为它需要1D数组(或指针),而不是2D数组(或指向数组的指针)

此外,C/C++提供了一种比使用笨拙的指针算法更优雅的访问数组的方法。因此,我建议采用以下方法。它的工作原理应该与您最初发布的代码完全相同,但会更清晰、可读性更强

#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(const int input[][LENGTH], int output[][WIDTH]) {
    for (int i = 0; i < WIDTH; ++i) {
        for (int j = 0; j < LENGTH; ++j) {
            output[j][i] = input[i][j];
        }
    }
}

void reverse(int* arr, const int N) {
    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);
    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);

    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;
}
#包括
使用名称空间std;
常数int长度=2;
常数int宽度=3;
void printary(常量int arr[],常量int N){

cout数组可以衰减为指向其第一个元素的指针。例如,
arr
将衰减为类型为
int*
&arr[0]
。数组也可以衰减为指向其第一个元素的指针,例如
&out\u矩阵[0]
,但由于
out\u矩阵的每个元素都是数组,因此类型将是指向数组的指针(对于
out\u数组[0]
而言,类型特别是
int(*)[WIDTH]
)。指向数组的指针不会衰减。还请注意,对于任何数组或指针
A
和索引
i
,表达式
A[i]
完全等于
*(a+i)
。由此可知
*out\u数组
等于
out\u数组[0]
,这是一个可以衰减为指针的实际数组。这意味着
*out\u数组
实际上与
&((out\u数组[0])[0])
(添加括号以使其更清晰).我想如果没有
cout
@某个程序员,那就是
C
。谢谢。这完全有道理。你解释得很好。如果你好奇,问题来自(作业2,最后一个问题)事实上,我读错了这个问题。它没有明确要求使用指针偏移量(仅数组下标)实现
转置
。在经历了所有这些之后,难怪他们没有问这个问题。谢谢。这很有道理。也许我应该说我确切地知道如何使用数组下标(代码中的方法)完成任务。我只是故意尝试练习使用指针算法。对于二阶数组,也许我不应该这样做。这完全没有理由。(此外,对我的“黑客”代码工作原理的解释也是有道理的)
#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(const int input[][LENGTH], int output[][WIDTH]) {
    for (int i = 0; i < WIDTH; ++i) {
        for (int j = 0; j < LENGTH; ++j) {
            output[j][i] = input[i][j];
        }
    }
}

void reverse(int* arr, const int N) {
    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);
    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);

    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;
}