Ir para o conteúdo
  • Revista PROGRAMAR: Já está disponível a edição #57 da revista programar. Faz já o download aqui!

cris_minims

Matriz e alocacao de memoria em C++

Mensagens Recomendadas

cris_minims    1
cris_minims

Ola pessoal... Estou a fazer um programa em c++ em  q tenho d alocar memoria para uma matriz, e depois criar uma funcao para ler a matriz e outra para a escrever, so que a parte dos apontadores é um pouco confusa, e n estou a conseguir escrever a matriz...

Aí vai o codigo:

#include "stdafx.h"
#include "malloc.h"

int *alocar (int nl, int nc)
{
int *aponta; // declara um apontador
aponta =((int*)malloc(nl*nc*sizeof(int))); // o apontador recebe o resultado do malloc feito para as variaveis de entrada

return aponta;

}
int *le_matriz(int *p, int nl, int nc)
{
for(int i=0;i<nl;i++)
for(int j=0; j<nc; j++)
{
	printf("Introduza um valor para a posicao L%d - C%d \n", i+1, j+1);
	scanf("%d", &p);
	printf("O valor lido foi %d \n", p);
}

return p;
}

void escreve_matriz(int p, int nl, int nc)
{
for(int i=0; i<nl; i++) //percorre as linhas
for(int j=0; j<nc; j++)//percorre as colunas
	printf(" %d \n ", p);

}

int _tmain(int argc, _TCHAR* argv[])
{
int numlinha, numcoluna;
printf("Introduza o numero de linhas que deseja para a sua matriz \n");
scanf("%d", &numlinha);
printf("Introduza o numero de colunas que deseja para a sua matriz \n");
scanf("%d", &numcoluna);

int *pont = alocar(numlinha,numcoluna);

le_matriz(pont,numlinha,numcoluna);
escreve_matriz(*pont,numlinha,numcoluna);

return 0;
}

Se alguem m conseguisse ajudar, agradecia!  :-[

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites
HappyHippyHippo    1125
HappyHippyHippo

claro que sei a resposta ... mas para te por a pensar :

void escreve_matriz(int p, int nl, int nc)

não deveria ser algo assim :

void escreve_matriz(int * p, int nl, int nc)

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites
cris_minims    1
cris_minims

HappyHippyHippo, eu tb experimentei assim, e dava uns valores estranhos na mesma...  :confused:

pmg, foi assim q m explicaram lol é assim q tenho de usar...  ;)

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites
KTachyon    272
KTachyon

Alteraste como o HappyHippyHippo disse, mas o que fizeste ao printf para compensar a mudança? :confused:

Já agora, não sei se é assim que pretendes escrever a matriz, mas penso só devias imprimir o '\n' a cada ciclo de i.

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites
cris_minims    1
cris_minims

void escreve_matriz(int *p, int nl, int nc)
{
for(int i=0; i<nl; i++) //percorre as linhas
for(int j=0; j<nc; j++)//percorre as colunas
	printf(" %d \n ", *p);

Fiz assim..

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites
KTachyon    272
KTachyon

... e chamaste o método da mesma forma que está no código? É que, para além disso tens que percorrer os ponteiros. Só estás a ir buscar o primeiro elemento.

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites
SamLapin    0
SamLapin

Se queres trabalhar com matrizes então faz isso mesmo.

se calhar a tua função alocar que devolve *int deveria devolver **int.

Uma matriz pode ser vista como um array de arrays.

E já agora, se é C++ porquê utilizar printf?

É tão mais simples fazer std::cout << <o que se quer imprimir no stdout>;

O que escreveste é código C. Não vejo aí nada de programação com objectos.

Cumprimentos

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites
HappyHippyHippo    1125
HappyHippyHippo

se calhar a tua função alocar que devolve *int deveria devolver **int.

Uma matriz pode ser vista como um array de arrays.

O código está correcto ... depende sempre da maneira como se codifica uma matrix

Eu, por exemplo, nunca uso o modelo de array de array. Para mim é sempre um único array onde as posições da metrix são bem definidas.

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites
cris_minims    1
cris_minims

Se queres trabalhar com matrizes então faz isso mesmo.

se calhar a tua função alocar que devolve *int deveria devolver **int.

Uma matriz pode ser vista como um array de arrays.

E já agora, se é C++ porquê utilizar printf?

É tão mais simples fazer std::cout << <o que se quer imprimir no stdout>;

O que escreveste é código C. Não vejo aí nada de programação com objectos.

Cumprimentos

Mas eu tenho de programar assim porq é assim q estou a aprender na faculdade, é assim q tenho de fazer....

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites
cris_minims    1
cris_minims

... e chamaste o método da mesma forma que está no código? É que, para além disso tens que percorrer os ponteiros. Só estás a ir buscar o primeiro elemento.

Neste caso devo colocar p++, certo?

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites
HappyHippyHippo    1125
HappyHippyHippo

Neste caso devo colocar p++, certo?

em teoria deveria de dar ... mas não é uma boa prática ... até por causa da maneira como tens codificada a matrix

cria uma função que retorna o valor i,j da matrix e será esse resultado a ser dado ao printf

int valor_matrix(int * p, int i, int j) {
  return p[...]; // faz os calculos, não são complicados
}
...
for(int i=0; i<nl; i++) //percorre as linhas
        for(int j=0; j<nc; j++)//percorre as colunas
                printf(" %d \n ", valor_matrix(p, i, j));
...

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites
Flinger    50
Flinger

Desculpem meter-me, mas porque não usar directamente os indexes?

printf(" %d \n ", p[i][j]);

ou caso não funcione, usar apenas um:

printf(" %d \n ", p[...]);  //Não vou ser desmancha prazeres e nao vou por os cálculos...  

Já vi que é basicamente o que estás a fazer :)

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites
cris_minims    1
cris_minims

em teoria deveria de dar ... mas não é uma boa prática ... até por causa da maneira como tens codificada a matrix

cria uma função que retorna o valor i,j da matrix e será esse resultado a ser dado ao printf

int valor_matrix(int * p, int i, int j) {
  return p[...]; // faz os calculos, não são complicados
}
...
for(int i=0; i<nl; i++) //percorre as linhas
        for(int j=0; j<nc; j++)//percorre as colunas
                printf(" %d \n ", valor_matrix(p, i, j));
...

Mas supostamente se eu usasse o p++ deveria funcionar, certo?

e supondo que eu n implementava o p, o primeiro valor deveria dar correcto, e n dá...  :)

Isto dos apontadores confunde-m completamente!

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites
Flinger    50
Flinger

int *le_matriz(int *p, int nl, int nc)
{
for(int i=0;i<nl;i++)
        for(int j=0; j<nc; j++)
        {
                printf("Introduza um valor para a posicao L%d - C%d \n", i+1, j+1);
                scanf("%d", &p);
                printf("O valor lido foi %d \n", p);
        }

        return p;
}

Olhou-se para a função de escrita, e não para a de leitura.

scanf("%d", &p);

p já é um apontador, logo no scanf apenas tens de passar a variável e não o endereço:

scanf("%d", p);

Ao imprimir o valor, tens de mandar imprimir o valor apontado por p:

printf("O valor lido foi %d \n", *p);

Claro que vais estar sempre a ler para o mesmo sítio, visto que não utilizas os indexes aqui, ou seja, no final, em p vai ter apenas o ultimo valor lido.

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites
KTachyon    272
KTachyon

Mas não podes apenas dar o ponteiro para a leitura/escrita quando pretendes ler e escrever nas várias posições de memória. Tens que indicar em que posições é que pretendes ler e escrever, senão acabas por estar a escrever e a ler tudo no mesmo sítio.

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites
Flinger    50
Flinger

Sim, é basicamente isso que eu disse na última linha. Apenas chamei a atenção que o primeiro elemento não estava a ser escrito correctamente (o OP referiu isso no último post), porque também não estava a ser lido correctamente.

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites
cris_minims    1
cris_minims

int *le_matriz(int *p, int nl, int nc)
{
for(int i=0;i<nl;i++)
        for(int j=0; j<nc; j++)
        {
                printf("Introduza um valor para a posicao L%d - C%d \n", i+1, j+1);
                scanf("%d", &p);
                printf("O valor lido foi %d \n", p);
        }

        return p;
}

Olhou-se para a função de escrita, e não para a de leitura.

scanf("%d", &p);

p já é um apontador, logo no scanf apesnas tens de passar a variável e não o endereço:

scanf("%d", p);

Ao imprimir o valor, tens de mandar imprimir o valor apontado por p:

printf("O valor lido foi %d \n", *p);

Claro que vais estar sempre a ler para o mesmo sítio, visto que não utilizas os indexes aqui, ou seja, no final, em p vai ter apenas o ultimo valor lido.

Ahhh ok, penso que agora ja percebi...  :D

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites
Flinger    50
Flinger

De qualquer forma não te esqueças que tens na ler o mesmo problema que tens na escrever. Estás sempre a ler para a primeira posição do array.

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites
KTachyon    272
KTachyon

@Flinger

Ya, tens razão. Achei que estava a responder à pessoa errada e só li por alto :D

@cris_minims

A cena do p++ tem alguns inconvenientes quando estás a brincar com ponteiros. Por exemplo acessos transversais (ou qualquer tipo de acesso não sequencial). Para além de que tens que ter em atenção o scope onde estas a alterar esse ponteiro (porque, ao utilizares p++, estás de facto a mudar o local para onde ele está a apontar). Muita atenção aos scopes onde fazes esse tipo de alterações.

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites
cris_minims    1
cris_minims

@Flinger

Ya, tens razão. Achei que estava a responder à pessoa errada e só li por alto :D

@cris_minims

A cena do p++ tem alguns inconvenientes quando estás a brincar com ponteiros. Por exemplo acessos transversais (ou qualquer tipo de acesso não sequencial). Para além de que tens que ter em atenção o scope onde estas a alterar esse ponteiro (porque, ao utilizares p++, estás de facto a mudar o local para onde ele está a apontar). Muita atenção aos scopes onde fazes esse tipo de alterações.

Entao e qual a melhor forma de contornar esses prob?

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites
HappyHippyHippo    1125
HappyHippyHippo

em teoria deveria de dar ... mas não é uma boa prática ... até por causa da maneira como tens codificada a matrix

cria uma função que retorna o valor i,j da matrix e será esse resultado a ser dado ao printf

int valor_matrix(int * p, int i, int j) {
  return p[...]; // faz os calculos, não são complicados
}
...
for(int i=0; i<nl; i++) //percorre as linhas
        for(int j=0; j<nc; j++)//percorre as colunas
                printf(" %d \n ", valor_matrix(p, i, j));
...

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites
Flinger    50
Flinger

isso  :D

Pensa assim. Se tivesse a trabalhar com uma matriz normal, tinhas de trabar com 2 indexes:

int valor_matrix(int * p, int i, int j) {
  return p[i][j]; 
}

Neste caso, creio que não podes, porque para isso precisavas de um apontador duplo (int **). Estou a falar de cabeça, mas creio que não me estou a enganar.

uma matriz 3x2 podes representar assim:

      j=0  j=1

i=0  _    _

i=1  _    _

i=2  _    _

no teu caso vais ter tudo seguido:

i=      0        1        2 

        _  _  _ _    _ _

j=    0  1  0 1    0 1

só tens de calcular qual é a posição total que queres, e retornar esse valor na função.

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Crie uma conta ou ligue-se para comentar

Só membros podem comentar

Criar nova conta

Registe para ter uma conta na nossa comunidade. É fácil!

Registar nova conta

Entra

Já tem conta? Inicie sessão aqui.

Entrar Agora


×

Aviso Sobre Cookies

Ao usar este site você aceita a nossa Política de Privacidade