Eu fiz um procedimento para uma matriz específica. Este procedimento transpõe uma matriz. Eu preciso passar para o procedimento o número de linhas para qualquer matriz na chamada deste procedimento. A função que eu criei invocará o procedimento anterior que transpõe a matriz. Eu sei que a linguagem C não faz distinção entre procedimento e função mas eu prefiro fazer esta distinção. Não quero encher muito este tópico. Quem tiver idéia sobre minha dúvida ,eu coloco aqui o código fonte que escrevi.
O esclarecimento pra mim será de grande utilidade. Obrigado.
Coloque o código, mas, eu não entendi o que é para ser feito!
#include <iostream>
#include <cmath>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <cstring>
#include <string.h>
#define M 12
void invt(float v[][M]) ;
int main(int argc, char *argv[])
{
float v[][M] = {
{130.0,155.0,74.0,180.0, 34.0, 40.0, 80.0, 75.0, 20.0, 70.0, 82.0, 58.0} ,
{150.0,188.0,159.0,126.0,151.0,137.0,121.0,130.0,50.0,100.0, 83.0, 60.0} ,
{138.0, 110.0, 168.0, 160.0, 174.0, 120.0, 150.0, 139.0, 96.0, 104.0, 82.0, 60.0}
} ;
invt(v) ;
system("pause >> NULL");
}
void invt(float v[][M])
{
int i , j ;
float S[12][3];
for(i=0; i < (sizeof(v[M])/sizeof(v[0][0])) ; i+=1)
{
for(j=0; j < 3 ; j+=1)
{
S[i][j] = 0;
}
printf("\n") ;
}
puts("\n") ;
for(j=0; j < (sizeof(v[M])/sizeof(v[0][0])) ; j+=1)
{
for(i=0; i < 3 ; i+=1)
{
S[j][i] = v[i][j] ;
}
printf("\n") ;
}
for(j=0; j < (sizeof(v[M])/sizeof(v[0][0])) ; j+=1)
{
for(i=0; i < 3 ; i+=1)
{
printf("%.2f\t",S[j][i]) ;
}
printf("\n") ;
}
}
Seria muito mais fácil se você postasse o enunciado do seu exercício.
Não é exercício. Eu não faço mais para-casas.
Eu quero enviar para a função o número de linha de uma matriz que pode variar.
Em C, passar arrays para funções é um tópico mais complicado do que parece. Se quiser uma explicação bem detalhada e aprofundada, sugiro ler aqui e aqui.
Mas em resumo, em geral é preferível que a função receba o array e o tamanho como parâmetros. No caso de array multi-dimensional, todas as dimensões que não são fixas seriam passadas como parâmetros.
No seu caso, você usou float v[][M]
, e como M
é um valor fixo (criado no #define M 12
), então apenas a quantidade de linhas não é fixa (a quantidade de colunas é conhecida).
Além disso, a matriz transposta terá dimensões diferentes da original (a menos que seja uma matriz quadrada, o que não é o caso). Por exemplo, no seu código você criou uma matriz 3x12, então a transposta será 12x3. Se você cria essa nova matriz dentro da função, o melhor seria retorná-la (e depois, fora da função, você faz o que quiser com ela - podendo inclusive imprimir, por exemplo).
Só que retornar matrizes em C também é meio chato, pois na verdade não dá, então teria que retornar um ponteiro. Ficaria assim:
#include <stdio.h>
#include <stdlib.h>
#define ARRAY_LEN(array) (sizeof(array) / sizeof(array[0]))
// número de linhas em um array 2D
#define NUM_ROWS(array_2d) ARRAY_LEN(array_2d)
// número de colunas em um array 2D
#define NUM_COLS(array_2d) ARRAY_LEN(array_2d[0])
#define M 12
float **transposta(float v[][M], size_t linhas) {
size_t colunas = NUM_COLS(v);
// matriz transposta tem dimensões "invertidas" (linhas da original são as colunas da transposta)
// aloca a matriz
float **t = malloc(sizeof(float *) * colunas);
for (size_t i = 0; i < colunas; i++) {
t[i] = malloc(sizeof(float) * linhas);
}
for (size_t i = 0; i < linhas; i++) {
for (size_t j = 0; j < colunas; j++) {
t[j][i] = v[i][j];
}
}
return t;
}
int main(void) {
float v[][M] = {
{130.0, 155.0, 74.0, 180.0, 34.0, 40.0, 80.0, 75.0, 20.0, 70.0, 82.0, 58.0},
{150.0, 188.0, 159.0, 126.0, 151.0, 137.0, 121.0, 130.0, 50.0, 100.0, 83.0, 60.0},
{138.0, 110.0, 168.0, 160.0, 174.0, 120.0, 150.0, 139.0, 96.0, 104.0, 82.0, 60.0}
};
float **t = transposta(v, NUM_ROWS(v));
// colunas da matriz original = linhas da matriz transposta (e vice-versa)
size_t linhas_transposta = NUM_COLS(v);
size_t colunas_transposta = NUM_ROWS(v);
for (size_t i = 0; i < linhas_transposta; i++) {
for (size_t j = 0; j < colunas_transposta; j++) {
printf("%8.2f", t[i][j]);
}
printf("\n");
}
// libera a memória alocada pela função
for (size_t i = 0; i < linhas_transposta; i++) {
free(t[i]);
}
free(t);
return 0;
}
Ou seja, a função cria a matriz transposta, retorna, e fora da função eu faço o que quiser com ela - no caso, eu imprimi, e a saída foi:
130.00 150.00 138.00
155.00 188.00 110.00
74.00 159.00 168.00
180.00 126.00 160.00
34.00 151.00 174.00
40.00 137.00 120.00
80.00 121.00 150.00
75.00 130.00 139.00
20.00 50.00 96.00
70.00 100.00 104.00
82.00 83.00 82.00
58.00 60.00 60.00
Claro que a função poderia criar a matriz e também imprimir, mas aí teria menos utilidade. Por exemplo, se você tivesse que passar a matriz transposta para outra função, ou fazer qualquer outra operação com ela que não seja imprimir, não seria possível. Fazendo desta forma, você tem a matriz e pode usá-la da forma que bem entender.
Outra alternativa é passar um ponteiro para a matriz transposta, e dentro da função ela aloca a memória e preenche os valores (assim não precisa retorná-la):
#define ARRAY_LEN(array) (sizeof(array) / sizeof(array[0]))
// número de linhas em um array 2D
#define NUM_ROWS(array_2d) ARRAY_LEN(array_2d)
// número de colunas em um array 2D
#define NUM_COLS(array_2d) ARRAY_LEN(array_2d[0])
#define M 12
// passa a transposta como parâmetro, aí ela será preenchida dentro da função
void transposta(float v[][M], size_t linhas, float ***t) {
size_t colunas = NUM_COLS(v);
*t = malloc(sizeof(float *) * colunas);
for (size_t i = 0; i < colunas; i++) {
(*t)[i] = malloc(sizeof(float) * linhas);
}
for (size_t i = 0; i < linhas; i++) {
for (size_t j = 0; j < colunas; j++) {
(*t)[j][i] = v[i][j];
}
}
}
int main(void) {
float v[][M] = {
{130.0, 155.0, 74.0, 180.0, 34.0, 40.0, 80.0, 75.0, 20.0, 70.0, 82.0, 58.0},
{150.0, 188.0, 159.0, 126.0, 151.0, 137.0, 121.0, 130.0, 50.0, 100.0, 83.0, 60.0},
{138.0, 110.0, 168.0, 160.0, 174.0, 120.0, 150.0, 139.0, 96.0, 104.0, 82.0, 60.0}
};
float **t;
transposta(v, NUM_ROWS(v), &t);
size_t linhas_transposta = NUM_COLS(v);
size_t colunas_transposta = NUM_ROWS(v);
for (size_t i = 0; i < linhas_transposta; i++) {
for (size_t j = 0; j < colunas_transposta; j++) {
printf("%8.2f", t[i][j]);
}
printf("\n");
}
// libera a memória alocada pela função
for (size_t i = 0; i < linhas_transposta; i++) {
free(t[i]);
}
free(t);
return 0;
}
E claro que o recomendado é sempre verificar o retorno de malloc
para saber se a alocação deu certo - algo como:
*t = malloc(sizeof(float *) * colunas);
if (*t == NULL) {
printf("Erro\n");
exit(1);
}
Eu omiti essas verificações para deixar um pouco mais sucinto.