Я застрял в вопросах b, c, d этой проблемы, которые просят меня настроить матрицу целых чисел (выделенную память) и спросить пользователя, что делать: а) Распечатайте матрицу. б) Показать элемент, удвоенный в массиве позиций [i][j]. c) Добавить все элементы строки, выбранной пользователем. г) Добавить все элементы столбца, выбранного пользователем. e) Сложите все элементы матрицы.
Я уже пытался реализовать с помощью учебника основное представление строки, где я использовал эту формулу:
адрес = базовый адрес + (индекс строки * размер столбца + индекс столбца) * размер данных
До сих пор я понял, как сделать диагональную сумму, но я не знаю, как суммировать строки и столбцы с первым адресом массива [0] [0], который я получил с основным представлением строки.
В вопросе б). Я не нашел ничего в Интернете о том, как это сделать.
Английский не мой родной язык, если вам нужно что-то объяснить лучше, дайте мне знать, и я попробую!
.text
main:
# Sum diagonal
la $a0, mat
lw $a1, size
jal sumDiagonal
move $a0, $v0
li $v0, 1
syscall
sumDiagonal:
li $v0, 0 # sum = 0
li $t0, 0 # $t0 as the index
sumLoop:
mul $t1, $t0, $a1 # t1 = rowIndex * colSize
add $t1, $t1, $t0 # + colIndex
mul $t1, $t1, DATA_SIZE # * DATA_SIZE
add $t1, $t1, $a0 # + base address
lw $t2, ($t1)
add $v0, $v0, $t2 # sum = sum + mdArray[i][i]
addi $t0, $t0, 1 # i = i + i
blt $t0, $a1, sumLoop # if i < size, then loop again
jr $ra
Матрица представляет собой матрицу 3x3, в которой все значения равны 3. Если вы хотите увидеть весь код, проверьте этот файл pastebin. https://pastebin.com/8619qHrL Спасибо за прочтение!
При реализации циклов, как правило, проще полностью разделить индекс цикла (i) и управление адресами (вычисление @ элементов массива), вместо того, чтобы вычислять адрес из индекса на каждой итерации. Это проще для понимания и более эффективно (и так работают компиляторы).
Чтобы вычислить суммы строк или столбцов, это может соответствовать следующему коду
sumRow(int *mat, int size, int row){
int sum
for(int i=0, int *ptr=mat+row*size; i!=size; i++, ptr++)
sum += *ptr
return sum;
}
sumRow(int *mat, int size, int col){
int sum=0;
for(int i=0, int *ptr=mat+col, int increment=size; i!=size; i++, ptr+=increment)
sum += *ptr
return sum;
}
Когда у вас есть код C, реализация становится простой. Сначала вычислите начальные значения, затем переберите тело + приращение + тестовое условие.
Вот возможная версия mips.
sumRow:
#expects $a0 matrix, $a1 size, $a2 row to add
li $v0, 0 # sum = 0
# compute address of first element
# as ptr=matrix+rwnbr*size*4
mult $a2, $a1 # rnbr*size
mflo $t1 # get result from mult
sll $t1, $t1, 2 # *4
add $t0,$a0,$t1 # @ first element to add
li $t1,0 # index=0
sumRowLoop:
lw $t2,($t0) # sum+=*ptr
add $v0,$v0,$t2
addi $t0, $t0, 4# ptr++
addi $t1,$t1,1 # i++
bne $t1, $a1, sumRowLoop # if i != size, then loop again
jr $ra
sumCol:
#expects $a0 matrix, $a1 size, $a2 col to add
li $v0, 0 # sum = 0
# compute address of first element to add
# as ptr=array+colnbr*4
srl $t1, $a2, 2 # colnbr*4
add $t0,$a0,$t1 # $t0 @ 1rst element
li $t1,0 # $t1 i=0
srl $t3,$a1,2 # ptr increment in $t3 is size*4
sumColLoop:
lw $t2,($t0) # sum+=*ptr
add $v0,$v0,$t2
add $t0,$t0,$t3 # ptr+=increment
addi $t1,$t1,1 # i++
bne $t1, $a1, sumColLoop # if i != size, then loop again
jr $ra
Для получения элемента по адресу [i][j] вам просто нужно вычислить (i*size+ j)*4 и добавьте его к адресу массива, чтобы получить элемент.
elementAt:
#expects $a0 matrix, $a1 size, $a2 i, $a3 j
mult $a1,$a2 # size*i
mflo $t0 # t0<-result of mult
add $t0,$t0, $a3# add it +j
sll $t0, $t0, 2 # and *sizeof(int)
add $t1, $a1,$t0# matrix+i*size+j
lw $v0,0($t1)
jr ra