1. 程式人生 > >C:關於指標作函式引數時求矩陣轉置的思考(對比行指標和列指標)

C:關於指標作函式引數時求矩陣轉置的思考(對比行指標和列指標)

行指標

實質

實質是將每一行看成一個元素,即原本矩陣的“形狀”是不變的。 如一個33的矩陣 1|2|3 4|5|6 7|8|9 儲存在一個44的、被初始化為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