2012-01-10 101 views
2

我有兩個二維數組,我不知道爲什麼,或者如何,每個數組中的兩個元素之一的地址重合.. 這裏是源代碼:地址重合(指針,C編程)

#include <stdio.h> 

int main() 
{ 
    int i,j,m,n,o,p,*ptr; 
    printf("Enter dimension of 1st matrix: "); 
    scanf("%d * %d",&m,&n); 
    printf("Enter dimension of 2nd matrix: "); 
    scanf("%d * %d",&o,&p); 
    int *a[m][n]; 
    int *b[o][p]; 
    if (n!=o) return 0; 

    printf("\nEnter 1st matrix:\n"); 
    for (i=0;i<m;i++) 
     for (j=0;j<n;j++) 
     { printf("%d ",(a+i*(n-1)+i+j)); scanf("%d",(a+i*(n-1)+i+j)); } 

    printf("\nEnter 2nd matrix:\n"); 
    for (i=0;i<o;i++) 
     for (j=0;j<p;j++) 
     { printf("%d ",(b+i*(p-1)+i+j)); scanf("%d",(b+i*(p-1)+i+j)); } 

    /*Printing the matrices*/ 
    puts("");puts(""); 
    for (i=0;i<m;i++) 
     {for (j=0;j<n;j++) 
      { ptr = (a+i*(n-1)+i+j); 
       printf(" %d ",*ptr); } puts("");}puts(""); 
    for (i=0;i<o;i++) 
     {for (j=0;j<p;j++) 
      { ptr = (b+i*(p-1)+i+j); 
       printf(" %d ",*ptr); } puts("");} 
} 

而這裏的打印屏幕; Screen print showing two coinciding adresses

由於這一點,我已經越來越錯誤在一個簡單的程序來計算兩個矩陣的乘積。問題是,這是通常的嗎?編譯器或操作系統不應該照顧這個嗎?

而且,爲什麼我要做ptr = (a+i*(n-1)+i+j); printf(" %d ",*ptr);
爲什麼不printf(" %d ",*(a+i*(n-1)+i+j));工作?

+1

您的變量名稱非常可怕。 – ThiefMaster 2012-01-10 18:45:47

+0

@TheifMaster @TheifMaster在這種情況下,他們是可以的,因爲他們匹配在這種情況下的數學領域。 – Mark 2012-01-10 18:47:48

+1

@ThiefMaster,'i'和'j'是計數器; 'a'和'b'是矩陣; 'a'是'm' X'n'; 'b'''''''''' – 2012-01-10 18:48:47

回答

6

首先,ab是指針數組和指針永遠不會初始化。

int *a[m][n]; 
int *b[o][p]; 

我的猜測是,它的意思爲:(代碼的其餘部分將需要作相應改變)

int a[m][n]; 
int b[o][p]; 

其次,你處理的指針ints(例如在%d)。請記住,指針可以比int更寬。例如,在我的平臺上,指針是64位,而ints是32位。

+0

謝謝你..你的最後一行幫助:) 但我不想用指針替代數組(我正在學習) ,所以我將數組更改爲1D .. – 2012-01-10 19:12:33

+0

值得一提的是''%p「'是適當的指針格式 – Dave 2012-01-10 20:41:26

0

我認爲問題是ab是指向指向int(int [] [] [])的指針的指針,但是您的代碼使用它們就好像它們是指向int(int [] []指針的指針) )。因此,即使數組分配正確(情況並非如此),他們的地址可能彼此靠近存儲,導致出現意外的行爲。

1

我看到了多個問題,從而重新編寫的程序如下:

#include <stdio.h> 
#include <stdlib.h> 

void display(int **matrix, int r, int c) 
{ 
    int i, j; 
    for (i=0 ; i<r ; i++) { 
     for (j=0 ; j<c; j++) { 
      printf("%3d ", matrix[i][j]); 
     } 
     printf("\n"); 
    } 
    return; 
} 

int main(void) 
{ 
    int r1, c1, r2, c2; 
    int **matrix1, **matrix2; 
    int i, j; 

    printf("Enter r1: "); 
    scanf("%d", &r1); 
    printf("Enter c1: "); 
    scanf("%d", &c1); 

    if ((matrix1 = (int **) malloc (sizeof(int *) * r1)) == NULL) { 
     printf("unable to allocate memeory \n"); 
     return -1; 
    }; 
    for (i=0 ; i<r1 ; i++) { 
     if ((matrix1[i] = malloc (sizeof(int) * c1)) == NULL) { 
      printf("unable to allocate memory \n"); 
      return -1; 
     } 
    } 

    printf("Enter contents of matrix 1\n"); 
    for (i=0 ; i<r1 ; i++) { 
     for (j=0 ; j<c1; j++) { 
      printf("matrix1[%d][%d] :", i, j); 
      scanf("%d", &matrix1[i][j]); 
     } 
    } 

    printf("Enter r2: "); 
    scanf("%d", &r2); 
    printf("Enter c2: "); 
    scanf("%d", &c2); 

    if ((matrix2 = (int **) malloc (sizeof(int *) * r2)) == NULL) { 
     printf("unable to allocate memeory \n"); 
     return -1; 
    }; 
    for (i=0 ; i<r2 ; i++) { 
     if ((matrix2[i] = malloc (sizeof(int) * c2)) == NULL) { 
      printf("unable to allocate memory \n"); 
      return -1; 
     } 
    } 

    printf("Enter contents of matrix 2\n"); 
    for (i=0 ; i<r2 ; i++) { 
     for (j=0 ; j<c2; j++) { 
      printf("matrix1[%d][%d] :", i, j); 
      scanf("%d", &matrix2[i][j]); 
     } 
    } 

    printf("Contents of matrix 1 is as follows \n"); 
    display(matrix1, r1, c1); 
    printf("\n\n"); 
    printf("Contents of matrix 2 is as follows \n"); 
    display(matrix2, r2, c2); 

    /* now, free the contents of the matrix 1 and 2 */ 

    for (i=0 ; i<r1 ; i++) 
     free(matrix1[i]); 
    free(matrix1); 

    for (i=0 ; i<r2 ; i++) 
     free(matrix2[i]); 
    free(matrix2); 

    return 0; 
} 

輸出

$ gcc 2d.c 
$ ./a.out 
Enter r1: 2 
Enter c1: 2 
Enter contents of matrix 1 
matrix1[0][0] :1 
matrix1[0][1] :2 
matrix1[1][0] :3 
matrix1[1][1] :4 
Enter r2: 5 
Enter c2: 6 
Enter contents of matrix 2 
matrix1[0][0] :1 
matrix1[0][1] :2 
matrix1[0][2] :3 
matrix1[0][3] :4 
matrix1[0][4] :5 
matrix1[0][5] :6 
matrix1[1][0] :7 
matrix1[1][1] :8 
matrix1[1][2] :9 
matrix1[1][3] :0 
matrix1[1][4] :1 
matrix1[1][5] :2 
matrix1[2][0] :3 
matrix1[2][1] :4 
matrix1[2][2] :5 
matrix1[2][3] :6 
matrix1[2][4] :7 
matrix1[2][5] :8 
matrix1[3][0] :9 
matrix1[3][1] :0 
matrix1[3][2] :1 
matrix1[3][3] :2 
matrix1[3][4] :3 
matrix1[3][5] :4 
matrix1[4][0] :5 
matrix1[4][1] :6 
matrix1[4][2] :7 
matrix1[4][3] :8 
matrix1[4][4] :9 
matrix1[4][5] :0 
Contents of matrix 1 is as follows 
    1 2 
    3 4 


Contents of matrix 2 is as follows 
    1 2 3 4 5 6 
    7 8 9 0 1 2 
    3 4 5 6 7 8 
    9 0 1 2 3 4 
    5 6 7 8 9 0 
$ 

注:

  • 當你從用戶那裏得到的rowscolumns它更好地使用動態內存分配功能,如malloc()t ø分配相應
  • 存儲器不限malloc()「編存儲器應該是free()」編
  • 你的訪問數組細胞等(a+i*(n-1)+i+j)的方式是方式太複雜。處理指針/數組時,它很好保持簡單。請嘗試堅持a[][]訪問陣列位置的方式。
0

如上所述,可能意味着使a和b int [] []而不是int * [] []。 另外,您不應該寫a+i*(n-1)+i+j),而是&a[i][j]*(a+i)+j。 (或另一個組合,如a[i]+j)。 編譯器應該自動將地址轉換爲數組的右側成員。

(對不起我的英文不好)

附:無論如何,你爲什麼寫i*(n-1)+i而不是簡單地(但,正如我上面寫的,錯了)i*n