ponteiros como usar e qual a vantagem ??

Software e Hardware para uC PIC

Moderadores: andre_luis, 51, guest2003, Renie

Mensagempor RobL » 08 Abr 2010 13:23

cristian
Sim.

Code:

void troca (unisgned int*s1,unisgned int *s2)
{
int temp;
temp = *s1 ; // PASSA O VALOR DE S1 ( Q APONTA PARA {A} ) PARA TEMP
*s1 = *s2 ;// COPIA O VALOR DE S2 PARA S1
*s1= temp ;// DEPOIS PASSA O 'VALOR' DA VAR TEMP PARA S1( QUE APONTA PARA {A}
}

maiin(){
int a=1,b=2;

troca(&a,&b);// PASSA OS ENDEREÇOS DE A E B PARA A FUNÇAO TROCA


}


ESTA CERTO ASSIM ??
RobL
Dword
 
Mensagens: 1546
Registrado em: 20 Fev 2007 17:56

Mensagempor cristian » 10 Abr 2010 09:09

uma outra perguntinha :


en termo de eficiencia ainda

nas seguintes fuçoes
Código: Selecionar todos
//--------------------------
void soma1 (*a )
{
a=a+10;
}
//---------------------------
void soma2 (a )
{
a=a+10;
}


main
{
soma1(&var);
soma2(var);

}

as funçoes tem o mesma eficiencia ???
cristian
Word
 
Mensagens: 570
Registrado em: 03 Nov 2006 08:15
Localização: serrinha-ba

Mensagempor RobL » 10 Abr 2010 10:33

Não dá para comparar eficiência pois são dois casos bem distintos.

Ao chamar soma1(&var) a variável var será modificada com o valor da soma.
Em soma2 a mesma função será executada mas não modificará a variável
(a).
Soma 2:
Este é o caso, por exemplo, quando você quer o valor de a para tomar decisão dentro do bloco.

Soma1:
Se quer usar a variável (a) para outras operações ou decisões fora do bloco da função.

Portanto neste caso na soma1 além de executar a operação no bloco da função, finalmente ainda terá que alterar o valor da variável a. Então terá mais código de máquina. Fica similar (não a mesma coisa) a um return a mais. Mas são dois casos diferentes e não é um bom exemplo para comparar eficiência.

Aliás é um bom exemplo de aplicação indispensável de ponteiros, em soma1 a fim de alterar a variável do(s) parâmentro(s) da chamada.

O uso de ponteiros só será menos eficiente em casos absurdos, similar ao de se criar uma função para inicializar uma só variável.
Por exemplo:
void init(int a)
{
a=0;
}
A cada chamada vai ser gerado um call e um return, além da operação de associação de a com zero . Melhor seria fazer a=0 diretamente onde for necessário.
Felizmente um compilador, na otimização, passará por cima(corrigirá) desta manobra burra.
RobL
Dword
 
Mensagens: 1546
Registrado em: 20 Fev 2007 17:56

Mensagempor jalves » 10 Abr 2010 10:57

Veja se este link acrescenta mais informações:

http://www.best-microcontroller-project ... wbies.html
jalves
Bit
 
Mensagens: 46
Registrado em: 18 Nov 2006 16:36

Mensagempor msamsoniuk » 10 Abr 2010 16:37

bom, a comparacao nao tem nexo pq tem dois erros ae... primeiro que a funcao para incrementar a variavel com ponteiro seria:

Código: Selecionar todos
void somap(int *p)
{
  *p = *p + 1;
}


isso implica, tipicamente, em jogar na stack o ponteiro p, chamar a funcao, recuperar p para um registro e entao jogar novamente na memoria. alguns processadores podem fazer isso diretamente na memoria, o que pode ser um pequeno bonus.

enquanto q a funcao sem ponteiro tem que fazer isso via stack:

Código: Selecionar todos
int soma(int i)
{
  return i+1;
}


basicamente, joga i na stack, chama a funcao, que recupera i da stack para um registro, soma 1 e entao devolve na stack. eventualmente, tambem dah para fazer isso diretamente na stack, o q eh resulta em um pequeno bonus se o processador assim suportar.

daih no fim das contas fica completamente equivalente! pq no fundo, stack eh uma area de memoria como qq outra, exceto que no lugar de *p, vc usa o stack pointer como ponteiro! :)

mesmo no caso de otimizar para ser inline, onde i fica em um registro, possivelmente a otimizacao tambem faz a carga previa de *p, assim o resultado de ambas na pratica eh o mesmo.

mas veja, isso vale para tipos basicos. se vc quiser manipular uma string ou struct, obrigatoriamente tem q partir para ponteiros. eh valido passar uma struct pela stack, mas totalmente desaconselhavel, pq eh computacionalmente muito ineficiente.

cristian escreveu:uma outra perguntinha :


en termo de eficiencia ainda

nas seguintes fuçoes
Código: Selecionar todos
//--------------------------
void soma1 (*a )
{
a=a+10;
}
//---------------------------
void soma2 (a )
{
a=a+10;
}


main
{
soma1(&var);
soma2(var);

}

as funçoes tem o mesma eficiencia ???
Avatar do usuário
msamsoniuk
Dword
 
Mensagens: 2935
Registrado em: 13 Out 2006 18:04

Mensagempor Fabio_Jerena » 29 Mar 2011 15:07

Aproveitando o assunto, na verdade minha dúvida é um mesclado de ponteiro e uso de funções...
Estou fazendo o seguinte código:

signed int TABSPRKADV[8][8] = {15, 15, 15, 15, 15, 15, 15, 15,
15, 15, 15, 15, 15, 15, 15, 15,
15, 15, 15, 15, 15, 15, 15, 15,
15, 15, 15, 15, 15, 15, 15, 15,
15, 15, 15, 15, 15, 15, 15, 15,
15, 15, 15, 15, 15, 15, 15, 15,
15, 15, 15, 15, 15, 15, 15, 15,
15, 15, 15, 15, 15, 15, 15, 15};

E vamos fazer um programa de teste:

signed int Funcao_Teste(int x, int y, *Tabela)
{
return (Tabela[x][y]);
}

Leve em consideração que eu estou usando o CCS:

Bom, isso não funciona, porque???
Primeiro, não aceita o "Tabela", deve ser escrito da seguinte forma:

signed int Funcao_Teste(int x, int y, *Tabela[8][8])
{
return (Tabela[x][y]);
}

Daí o primeiro problema que eu já perco a liberdade de colocar a tabela com a quantidade de elementos que eu quiser...
Segundo problema, os valores devolvidos pela função não são os da tabela de origem:

saida_da_tabela = Funcao_Teste(3,3, TABSPRKADV);

Ao invés de ler o valor 15 vem 12 e outros que não os valores da tabela, isso com certeza não é um bom sinal...

Como eu faço para trabalhar com a tabela apontada dentro da minha função? Para um vetor (unica dimensão funcionou perfeitamente), agora para um vetor bidimensional não funciona por nada neste mundo, um verdadeiro parto!

Quem souber e puder ajudar agradeço, pois quebrei a cabeça de diversas formas e ainda não consegui resolver!
Obrigado!
Fábio Jerena
Fabio_Jerena
Nibble
 
Mensagens: 52
Registrado em: 08 Mar 2007 08:59

Mensagempor ze » 29 Mar 2011 17:19

esta tabela parece estar na ram (!). experiemente colocar na flash tipo
unsigned char const tabela{... (hitech - c)
mas isso pode não ter a ver com seu problema que no momento não lhe posso auxiliar
abç
Avatar do usuário
ze
Dword
 
Mensagens: 1655
Registrado em: 05 Jun 2007 14:32

Mensagempor Fabio_Jerena » 29 Mar 2011 19:13

Agradeço primeiramente a ajuda amigo!
Então, tentei mudar mas não funcionou...
Acho que não é problema de alocação da memória e sim um problema de sintaxe...
No entanto sigo um livro, no livro não há exemplos com matrizes bidimensionais, segui a lógica que é aplicada em vetores(que funcionam, eu testei), mas no meu caso não funcionam de maneira alguma!!!
Dá uma desanimada pois estou a dois dias fritando nisso e nada, e o problema é idiota, tenho até uma noção do conceito, acredito que não têm nenhuma mágica por trás disso mas estou me matando e não sei nem como pesquisar, já que é uma dúvida muito específica!
Obrigado!!!
Fábio Jerena
Fabio_Jerena
Nibble
 
Mensagens: 52
Registrado em: 08 Mar 2007 08:59

Mensagempor chipselect » 29 Mar 2011 23:54

Fabio

altere sua função pra ficar assim:

Código: Selecionar todos
int Funcao_Teste(int x, int y, int Tabela[8][8])
{
return Tabela[x][y];
}


O seu erro era simples...

int Funcao_Teste(int x, int y, int *Tabela[8][8]);

isso ai tá falando que a função recebe uma tabela bidimensional de 8x8 que APONTA para inteiros, ou seja, é uma matriz para ponteiro de inteiros... tira o "*" que resolve teu problema.
chipselect
Word
 
Mensagens: 744
Registrado em: 16 Out 2006 18:50

Mensagempor Fabio_Jerena » 30 Mar 2011 08:00

Então amigo, o grande problema é que eu quero passar como parâmetro uma tabela x, não quero especificar as dimensões dela, não queria fazer uma função restrita e sim uma que pudesse ser reutilizada...
Só quero jogar com as regras, estou usando como literatura base o livro "Programação em C" do Fábio Pereira e como lá não diz que o que eu quero fazer é impossível eu continuo tentando!
Ontem, após mais uma infinidade de testes entendi o que acontece, não sei explicar e não achei coeso.
Quando faço:

int Funcao_Teste(int x,*tabela)
{
return tabela[x];
}

e usando um vetor de teste:

int TABTESTE[2][2] = { 1 , 5,
7 , 3};

O sistema ao invés de entender:

TABTESTE[0][0] (0) TABTESTE[0][1] (1)
TABTESTE[1][0] (2) TABTESTE[1][1] (3)

Entende:

TABTESTE[0], TABTESTE[1], TABTESTE[2], TABTESTE[3]

Como se fosse um vetor unidimensional, e consigo consultar os valores dentro da minha função!

Agora a dúvida é a seguinte, porque isso, qual o conceito por trás? Será que não posso passar vetores bidimensionais como parâmetro de funções, será que existe uma sintaxe própria, será que eu estou declarando o vetor e inicializando ele de maneira indevida?

O pior é q quando consulto (leio) o vetor fora de uma função funciona direitinho o esquema:

- tabela[L][C]

Não sei agora se também estou fazendo algum esquema errado quanto à alocação de memória...
Miinha idéia é fazer um sistema baseado em tabelas, buscas lookuptables, e não estou conseguindo fazer o básico, montar e trabalhar com as tabelas...

Meu objetivo é fazer busca na tabela e interpolar os 4 valores encontrados, gerando um resultante!
Obrigado pela ajuda!
Fábio Jerena
Fabio_Jerena
Nibble
 
Mensagens: 52
Registrado em: 08 Mar 2007 08:59

Mensagempor chipselect » 30 Mar 2011 08:56

Para matrizes com mais de um índice, você pode omitir, no máximo, uma dimensão, porque senão o compilador não vai saber como fazer o cálculo com os ponteiros, e vai ter que fazer cast também, e infelizmente vai ficar pelo menos uma dimensão travada (óbvio...).

Bem genérico dá pra fazer o cálculo de ponteiro na mão. Neste caso você pode mudar sua função para a seguinte forma:
Código: Selecionar todos
signed int Funcao_Teste(int x, int y, int *Tabela, int nrElementosY)
{
return Tabela[nrElementosY*x + y];
}


void funcao(){
int x;
x=(1,2,(int *) TABSPRKADV, 8);
}



só precisa fazer um cast na matriz para acertar o tipo e o compilador não reclamar. Outro ponto importante é testar os valores de x e y antes de usá-los (programação defensiva).

Como você pode ver, a sua matriz de 2 dimensões foi acessada via ponteiro, e o código encarou ela como uma matriz de uma dimensão só. Isso é possível porque em C, os elementos da matriz são colocados em sequência.
chipselect
Word
 
Mensagens: 744
Registrado em: 16 Out 2006 18:50

Mensagempor Fabio_Jerena » 30 Mar 2011 11:19

Então cara, mas olha só que bizarro...
Ok, resolvo o problema, já que entendemos como que o compilador está se comportando para essa minha sintaxe, mas e aí, é assim mesmo? Pelo que eu entendi não é isso que o C prevê!
Ficou chateado de ser algo tão simples e não funcionar de jeito nenhum, como alguem que está aprendendo fica nessas horas? O livro não é preciso, o compilador não funciona, eu não estou sabendo escrever o código???
Fora que pensando em otimização, prá quê fazer mais contas se o compilador deveria me entregar essa informação através de index que eu forneço?
Isso que eu não consigo entender e queria o veredito de quem trabalha com o CCS e saber se é uma limitação dele, se estou abordando o problema incorretamente, costumo ter bastante problema (principalmente na depuração dos meus códigos), mas até o presente momento só erros meus, não achei nenhum problema no CCS...
Agradeço a ajuda!
Fábio Jerena
Fabio_Jerena
Nibble
 
Mensagens: 52
Registrado em: 08 Mar 2007 08:59

Mensagempor Fabio_Jerena » 30 Mar 2011 11:22

Então cara, mas olha só que bizarro...
Ok, resolvo o problema, já que entendemos como que o compilador está se comportando para essa minha sintaxe, mas e aí, é assim mesmo? Pelo que eu entendi não é isso que o C prevê!
Ficou chateado de ser algo tão simples e não funcionar de jeito nenhum, como alguem que está aprendendo fica nessas horas? O livro não é preciso, o compilador não funciona, eu não estou sabendo escrever o código???
Fora que pensando em otimização, prá quê fazer mais contas se o compilador deveria me entregar essa informação através de index que eu forneço?
Isso que eu não consigo entender e queria o veredito de quem trabalha com o CCS e saber se é uma limitação dele, se estou abordando o problema incorretamente, costumo ter bastante problema (principalmente na depuração dos meus códigos), mas até o presente momento só erros meus, não achei nenhum problema no CCS...
Agradeço a ajuda!
Fábio Jerena
Fabio_Jerena
Nibble
 
Mensagens: 52
Registrado em: 08 Mar 2007 08:59

Mensagempor vtrx » 30 Mar 2011 11:56

fabio,programar em C para um microcontrolador,não é a mesma coisa que se programar para windows ou Linux.
O compilador,vai verificar a estrutura do microcontrolador primeiro.
Avatar do usuário
vtrx
Dword
 
Mensagens: 2239
Registrado em: 20 Abr 2008 21:01

Mensagempor chipselect » 01 Abr 2011 08:54

Fabio

Talvez seja melhor aprender C primeiro no Linux ou Windows.

Não sei qual livro você está seguindo, mas os melhores livros de linguagem C que eu vi não são para microcontroladores.
chipselect
Word
 
Mensagens: 744
Registrado em: 16 Out 2006 18:50

AnteriorPróximo

Voltar para PIC

Quem está online

Usuários navegando neste fórum: Nenhum usuário registrado e 1 visitante

x