C:关于指针作函数参数时求矩阵转置的思考(对比行指针和列指针)

行指针

实质

实质是将每一行看成一个元素,即原本矩阵的“形状”是不变的。
如一个33的矩阵
1|2|3
4|5|6
7|8|9
存储在一个4
4的、被初始化为0矩阵中为:
1|2|3|0
4|5|6|0
7|8|9|0
0|0|0|0

表示

p[i][j] <-> (p[i] + j) <-> *( * (p + i) + j) <->*((p +i) )[j]
p[i]表示的仍然是一个地址

实现

即将a[i][j]与a[j][i]交换
由于矩阵形状不变,故可以直接将表示中ij互换。
具体代码如下:

#include <stdio.h>
#define N 10
void Input(int (*a)[N], int m, int n);
void Output(int (*a)[N], int m, int n);
void Transpose(int (*a)[N], int m, int n);
void Swap(int *a, int *b);
int m, n;
int main(){
    int a[N][N];
    printf("input m n:\n");
    scanf("%d %d", &m, &n);
    printf("input the numbers:\n");
    Input(a, m, n);
    Transpose(a, m, n);
    Output(a, n, m);
    return 0;
}

void Input(int (*a)[N], int m, int n){
    int i, j;
    for(i = 0; i < m; i++){
        for(j = 0; j < n; j ++){
            scanf("%d", *(a + i) + j);
        }
    }
}

void Transpose(int (*a)[N],int m, int n){
    int i, j;
    for(i = 0; i <N; i++){
        for(j = i; j < N; j++){
            Swap(*(a + i)+ j, *(a + j) + i);

        }
    }
}

void Output(int (*a)[N], int m, int n){
    int i, j;
    for(i = 0; i < m; i++){
        for(j = 0; j < n; j ++){
            printf("%d\t", *(*(a + i) + j));
        }
        printf("\n");
    }

}

void Swap(int *a, int *b){
    int temp;
    temp = *a;
    *a = *b;
    *b = temp;
}

列指针

实质:

相当于是将所有元素去除格式以一维数组形式存储。
仍以上述例子为例:
如果用简单的i* n + j的形式
相当于存储为:
1|2|3|4|5|6|7|8|9|0|0|0|0|0|0|0
由于重新输出时会按格式输出,所以会变成如下结果
1|2|3|4
5|6|7|8
9|0|0|0
0|0|0|0
这不是我们想要的结果
因此我们应将需要存储的矩阵“嵌入”大矩阵中,即将上文n改为N

表示

表示为a[i * n + j] (其中n为每行元素个数)

实现

#include <stdio.h>
#define N 10
void Input(int *a, int m, int n);

void Output(int *a, int m, int n);
void Transpose(int *a, int *b,int m, int n);
void Swap(int *a, int *b);
int m, n;
int main(){
    int a[N][N];
    int b[N][N];
    printf("input m n:\n");
    scanf("%d %d", &m, &n);
    printf("input the numbers:\n");
    Input(*a, m, n);
    Transpose(*a,*b, m, n);
    Output(*a, n, m);
    return 0;
}

void Input(int *a, int m, int n){
    int i, j;
    for(i = 0; i < m; i++){
        for(j = 0; j < n; j ++){
            scanf("%d", &a[N * i + j]);
        }
    }
}

void Transpose(int *a,int *b, int m, int n){
    int i, j;
    int temp;
    for(i = 0; i <N; i++){
        for(j = i; j < N; j++){
            Swap(&a[i * N+ j], &a[j * N+ i]);
        }
    }
}

void Output(int *a, int m, int n){
    int i, j;
    for(i = 0; i < m; i++){
        for(j = 0; j < n; j ++){
            printf("%d\t", a[N * i + j]);
        }
        printf("\n");
    }

}

void Swap(int *a, int *b){
    int temp;
    temp = *a;
    *a = *b;
    *b = temp;
}

应特别注意,除了对元素的表示形式不同外,此代码与以行指针为参数的代码最大的区别就是将n换成了N

猜你喜欢

转载自blog.csdn.net/XIAOHEwenjue/article/details/83690955
今日推荐