2015-02-11 2 views
1

Я искал способ обмена именами между двумя матрицами в C. У меня есть 2 квадратных размера x размера матрицы. Я делаю некоторую операцию с одним из них, я помещаю результат в ячейку в другой матрице, затем я меняю свои имена и повторяю.Переменные имена квадратных матриц в C

Ниже я привожу свой код

int main(void){ 
int const size = 1000; 
int const steps = 10; 
float A[size][size], B[size][size]; 
int i,j,k; 
int t = 0; 
double sum = 0; 
double sum1 = 0; 
int const ed = size - 1; 
for(i = 0; i < size; ++i){ 
    for(j = 0; j < size; ++j){// initialize the matrices 
     A[i][j] = i+j; 
     B[i][j] = 0; 
    } 
} 
for(i = 0; i < size; ++i){//find the sum of the values in the first matrix 
    for(j = 0; j < size; ++j){ 
     sum = sum + A[i][j]; 
    } 
} 
printf("The total sum of the matrix 1 is %lf \n",sum); 

for(k = 0; k < steps; ++k){//for each cell of the matrix A calculate the average of the values' of the cell and its surroundings and put it in the coresponding place in the matrix B and then copy matrix B to matrix A and repeat. There are special cases for the cells who are at the edges and the last or first row/column. 
    for(i = 0; i < size; ++i){ 
     for(j = 0; j < size; ++j){ 
      if(i==0){ 
       if(j==0) 
        B[i][j]=(A[0][0]+A[0][1]+A[0][ed]+A[1][0]+A[ed][0])/5.0; 
       else if(j==ed) 
        B[i][j]=(A[0][ed]+A[0][0]+A[0][ed-1]+A[1][ed]+A[ed][ed])/5.0; 
       else 
        B[i][j]=(A[0][j]+A[0][j+1]+A[0][j-1]+A[1][j]+A[ed][j])/5.0; 
      }else if(i==ed){ 
       if(j==0) 
        B[i][j]=(A[ed][0]+A[ed][1]+A[ed][ed]+A[0][0]+A[ed-1][0])/5.0; 
       else if(j==ed) 
        B[i][j]=(A[ed][ed]+A[ed][0]+A[ed][ed-1]+A[0][ed]+A[ed-1][ed])/5.0; 
       else 
        B[i][j]=(A[ed][j]+A[ed][j+1]+A[ed][j-1]+A[0][j]+A[ed-1][j])/5.0; 
      }else{ 
       if(j==0) 
        B[i][j]=(A[i][0]+A[i][1]+A[i][ed]+A[i+1][0]+A[i-1][0])/5.0; 
       else if(j==ed) 
        B[i][j]=(A[i][ed]+A[i][0]+A[i][ed-1]+A[i+1][ed]+A[i-1][ed])/5.0; 
       else 
        B[i][j]=(A[i][j]+A[i][j+1]+A[i][j-1]+A[i+1][j]+A[i-1][j])/5.0; 
      } 
     } 
    } 
    sum1 = 0; 
    for(i = 0; i < size; ++i){ 
     for(j = 0; j < size; ++j){ 
      sum1 = sum1 + B[i][j]; 
     } 
    } 
    t=t+1; 
    for(i = 0; i < size; ++i){ 
     for(j = 0; j < size; ++j){ 
      A[i][j] = B[i][j]; 
     } 
    } 
    printf("%lf \n",sum1-sum); 
} 
printf("The total sum of the matrix 2 is %lf \n",sum1); 
printf("Number of steps completed: %i \n",t); 
printf("Number of steps failed to complete: %i \n", steps-t); 
return 0; 

}

я использовал метод копирования каждый раз, когда одну матрицу к другому, но это не эффективно.

У меня есть намек на то, что я должен использовать указатели, но я не могу понять это. Любая помощь будет высоко ценится.

ответ

0

Да, вы должны обязательно использовать указатели, например:

void swap (int*** m1, int*** m2) 
{ 
    int** temp; 
    temp = *m1; 
    *m1 = *m2; 
    *m2 = temp; 
} 

И затем вызвать:

int m1[5][5] = 0; 
int m2[5][5] = 0; 
swap (&m1, &m2); 
+1

Это выглядит удобно, но на самом деле не работает. (a) Вы передаете 'int (*) [5] [5]' функции, ожидающей 'int ***', и значение несоответствия типов, и (b) вы не можете изменить такой массив. –

+0

Спасибо за ваши усилия Михал, но он не работает из-за несоответствия. – user2149122

2

Вы можете поменять значения любых двух переменных одного и того же типа, присвоив значение от первой до временной переменной, затем присваивая значение второй первой, затем присваивая значение временной переменной второму:

int a = 2, b = 3, tmp; 

tmp = a; 
a = b; 
b = tmp; 

В частности, она работает точно так же, когда переменные имеют тип указателя, так

/* The matrices */ 
double one[3][3], another[3][3]; 

/* pointers to the matrices */ 
double (*matrix1p)[3] = one; 
double (*matrix2p)[3] = another; 
double (*tmp)[3]; 

/* ... perform matrix operations using matrix1p and matrix2p ... */ 

/* swap labels (pointers): */ 
tmp = matrix1p; 
matrix1p = matrix2p; 
matrix2p = tmp; 

/* ... perform more matrix operations using matrix1p and matrix2p ... */ 

Обновлено уточнить:

matrix1p изначально псевдоним one и matrix2p первоначально является псевдонимом для another. После свопа matrix1p является псевдонимом для another, тогда как matrix2p является псевдонимом для one. Конечно, вы можете выполнять такую ​​своп столько раз, сколько хотите. Однако вы не можете поменять местами one и another, за исключением элементарных свопов.


Обратите внимание, что это дает улучшенную эффективность, поскольку указатели довольно малы относительно самих матриц. Вам не нужно перемещать элементы матриц, но только для изменения той матрицы, на которую ссылается каждый указатель.

+0

Я пытаюсь понять ваше предложение: после выполнения этих шагов один раз, когда я ссылаюсь на элемент другой [i] [j], это тот же самый элемент из одного [i] [j] перед заменой? – user2149122

+0

@ user2149122, no. Элементы 'one' и' another' не перемещаются, что является точно такой же точкой. Кроме того, это не имена «один» и «другой», которые меняются местами; скорее, имена «matrix1p» и «matrix2p», которые (эффективно) меняются местами. Более технически это матрица, к которой относится каждое из этих последних имен, которое заменяется. Нет никакой эффективности, которую можно получить, если вам нужно переместить матричные элементы. –

+0

Хорошо. Еще один вопрос для вас: как я могу получить доступ к определенному элементу one [i] [j] с помощью указателя? – user2149122