Ir ao conteúdo

Posts recomendados

Postado

Estou com um probleminha, galerinha. Dentro do main possuo uma certa matriz bidimensional (digamos, mat[n][n]). Como crio uma função fora do main que utiliza essa matriz, sem saber a quantidade exata de elementos?

OBS: Se necessário, posso informar a quantidade de elementos por uma variável n.

Tentei algo do tipo:

void funcao (int matriz[][]) {

..

}

Mas não deu certo.

  • Curtir 1
Postado

Amigo, quando você cria essa função fora do main, você não a cria para usar apenas para a matriz mat[n][n]. Qualquer matriz bidimensional que você passar por parâmetro, funcionará. Isso é manipulação de ponteiros. A funcao não necessita, necessariamente, saber o tamanho da matriz pois ela manipula a matriz, que já está alocada na memória, através de ponteiros para a posição de memória da matriz mat.

Maneira correta

void funcao(int matriz[NLIN][NCOL]);

ou

void funcao(int matriz[][NCOL]);

  • Curtir 1
Postado

Quando você passa um vetor/matriz para uma função, não importa realmente qual a quantidade de elementos, visto que o compilador irá converter tal parâmetro diretamente para um ponteiro, que aponta para a região da memória onde se localiza o vetor/matriz. Agora, é importante deixar claro o tamanho da matriz dependendo da maneira com que você pretende trabalhar com ela dentro da função.

Para passar uma matriz como parâmetro para uma função, você pode passar um ponteiro:


void funcao (int *matriz);

Dessa maneira, você não poderá trabalhar com os índices indexados, porém, como em uma matriz todos os elementos ocupam espaços contíguos na memória, isto é muito eficiente em casos que você precisa percorrer toda a matriz para fazer algum cálculo ou algo do gênero.

Ainda, você pode passar a matriz com apenas o número de colunas.

A dimensão das linhas na verdade é facultativa, ou seja, o protótipo:


void funcao(int matriz[][10]);

é válido, pois sem especificar a quantidade de colunas da matriz, o compilador não seria capaz de calcular as posições corretas dos elementos da matriz na memória (não saberia quantas colunas pular para chegar na próxima linha). Já a quantidade de linhas, como dito anteriormente, é facultativa.

Ou seja,


void funcao(int matriz[][]);

não é correto.

  • Curtir 1
Postado

Correto o que o Wntd falou. Obrigado pela correção.

Mas a dúvida agora é minha..

void funcao (int *matriz);

Nesse caso, seria um array de inteiros, não uma matriz. Pois, se você for usar apenas 1 dimensão da matriz, tudo bem, funcionará, agora se você for usar as 2 dimensões, não funcionará.

Prova:


#include <stdio.h>
void mat(char *a){
int i,j;
for(i=0;i<3;i++) {
for(j=0;j<2;j++)
printf("%c ", a[i][j]);
}
}

int main(void) {
char b[3][2] = { {'k','8'}, {'h','f'}, {'a','b'}};
mat(;
return 0;
}

O código acima nem compila...

É isso mesmo ou estou falando muita besteira de novo?

  • Curtir 1
Postado

Na verdade, se você quiser trabalhar com uma matriz de maneira indexada, é necessário passar a matriz com o esquema dos colchetes.

Da maneira que tu passou, é necessário usar um pouco de aritmética de ponteiros. Mais ou menos assim:


#include <stdio.h>

void mat(char *a){
int i,j;

for(i = 0; i < 3; i++) {
for(j = 0; j < 2; j++)
printf("%3c ", *(a + (i * 2) + j));
printf("\n");
}
}

int main(){
char b[3][2] = { {'k','8'}, {'h','f'}, {'a','b'}};

mat(;

return(0);
}

Se quiser tiraro warning de tipo incompatível, basta passar para a função o endereço de memória de b[0][0], ou seja


mat(&b[0][0]);

Note a maneira em que é possível acessar os elementos da matriz através de aritmética de ponteiros:


*(a + (i * 2) + j)

Aquele '2' é a quantidade de colunas.

  • Curtir 1
Postado

#include <stdio.h>

#include <iostream>

using namespace std;

char entrada(int i,int j)

{

//entrando com os valores na matriz

int m,n,p;

char b[j],*a;

for (m=0;m<=i-1;m++)

{

for (n=0;n<=j-1;n++)

{

fflush(stdin);

printf("Valor para [%d],[%d]",m,n);

scanf("%c",&b[m][n]);

}

}

// passando os valore para um ponteiro

p = i * j - 1;

while (p>=0)

{

for (m=0;m<=i-1;m++)

{

for (n=0;n<=j-1;n++)

{

a[p] = b[m][n];

p--;

}

}

}

//retornando um ponteiro

return (*a);

}

int main (){

int z,x,y,w;

char b[0][0],*a;

int c;

//definindo o tamanho da matriz

printf("Quantidade de linhas: ");

scanf("%d",&z);

printf("Quantidade de colunas: ");

scanf("%d",&x);

//atraves de um ponteiro enviar e receber valores da matriz atraves de um ponteiro

*a = entrada(z,x);

//passando os valore do ponteiro para matriz

c = z * x -1;

while (c>=0)

{

for (y=0;y<=z-1;y++)

{

for (w=0;w<=x-1;w++)

{

b[y][w] = a[c];

printf("\nb[%d][%d] = %c",y,w,b[y][w]);

c--;

}

}

}

}

  • Curtir 1
  • 8 anos depois...
Postado
Em 21/02/2012 às 15:25, liuriloami disse:

Estou com um probleminha, galerinha. Dentro do main possuo uma certa matriz bidimensional (digamos, mat[n][n]). Como crio uma função fora do main que utiliza essa matriz, sem saber a quantidade exata de elementos?

OBS: Se necessário, posso informar a quantidade de elementos por uma variável n.

Tentei algo do tipo:

void funcao (int matriz[][]) {

..

}

Mas não deu certo.

Tente fazer:
void funcao (int n, int matriz[][n])
veja se da certo e me fale. valeu

  • Curtir 1
Postado

Imagino que nesses 8 anos e meio ele deve ter conseguido resolver, afinal esse post é de fevereiro de 2012!

 

De todo modo, @Abe usar 
 

    void funcao (int n, int matriz[][n])

 

não vai rolar. A primeira dimensão até poderia ficar assim, [ ] , mas a segunda tem que ser constante. Não  pode ser 'n' com n int.

 

A conta a ser feita para achar o endereço de cada elemento da matriz é essa: 
 

    matriz[x][y] = &matriz + ( sizeof(int) * ( y * COLUNAS + x ) )

 

e você vê na conta que o número de linhas não aparece. 

 

Exemplo
 

    1  2  3
    4  5  6

 

  • com sizeof(int) = 4 bytes
  • com uma matriz 2 x 3 de int
  • para achar o endereço do último cara, o 6

A matriz

int matriz[2][3]

O último 

matriz[1][2];

Então eles vão estar lá na memória, os seis caras, uma linha depois da outra. Pela conta lá em cima deve dar

matriz[1][2] = &matriz[0][0] + 4 * (1*3) + 2 = endereço inicial + 4 * 5 = endereço inicial + 20

E na memória os valores vão estar assim, a partir do endereço matriz, ou &matriz[0][0] que dá na mesma

    | 1 | 2 | 3 | 4 | 5 | 6 | 

como cada int ocupa 4 bytes nesse exemplo aqui, é claro que o endereço do 6 vai ser o endereço do 1 mais 20. 

 

E para confirmar? Um programa de teste para

  • alterar o último valor para 60 usando os índices
  • e depois para 600 usando a conta
  • e depois mostrando o valor usando os índices
  • e depois chamando uma função e mostrado os valores todos
     
Endereco inicial de int matriz[2][3]: 004FF8C4
valor de matriz[1][2] o ultimo elemento: 60
valor de matriz[1][2] pela formula: 60
Alterando o valor para 600 pela formula
              valor de matriz[1][2]: 600
valor de matriz[1][2] pelos indices: 600

mostra(M[2][3])
M[0,0] = 1
M[0,1] = 2
M[0,2] = 3
M[1,0] = 4
M[1,1] = 5
M[1,2] = 600

 

A fun

 

#include <iostream>
using namespace std;

void    mostra(int, int, int*);

int main(void)
{

    int matriz[2][3] =
    {   {1,2,3},
        {4,5,6}
    };
    cout << "Endereco inicial de int matriz[2][3]: " << &matriz << endl;

    matriz[1][2] = 60;
    cout << "valor de matriz[1][2] o ultimo elemento: " << matriz[1][2] << endl;

    int x = 1;
    int y = 2;
    int COLUNAS = 3;

    int* p = &matriz[0][0] +  (x * COLUNAS) + y ;
    cout << "valor de matriz[1][2] pela formula: " << *p << endl;

    int* inicio = &matriz[0][0];

    cout << "Alterando o valor para 600 pela formula" << endl;
    *(inicio + x * COLUNAS + y) = 600;
    cout << "             valor de matriz[1][2]: " << *p << endl;
    cout << "valor de matriz[1][2] pelos indices: " << matriz[1][2] << endl;

    mostra(2, 3, (int*)matriz);
};

void    mostra(int l, int c, int* M)
{
    cout << "\nmostra(M[" << l << "][" << c << "])\n";
    for (int x = 0; x < l; x += 1)
        for (int y = 0; y < c; y += 1)
            cout << "M[" << x << "," << y << "] = " << *(M + x*c + y) << endl;
    return;
}

 

A função que importa está logo acima, e a conta está como na fórmula. É o simples.

 

 

 

  • Curtir 1

Crie uma conta ou entre para comentar

Você precisa ser um usuário para fazer um comentário

Criar uma conta

Crie uma nova conta em nossa comunidade. É fácil!

Crie uma nova conta

Entrar

Já tem uma conta? Faça o login.

Entrar agora

Sobre o Clube do Hardware

No ar desde 1996, o Clube do Hardware é uma das maiores, mais antigas e mais respeitadas comunidades sobre tecnologia do Brasil. Leia mais

Direitos autorais

Não permitimos a cópia ou reprodução do conteúdo do nosso site, fórum, newsletters e redes sociais, mesmo citando-se a fonte. Leia mais

×
×
  • Criar novo...