LusoRobótica - Robótica em Português

Software => C/C++ => Tópico iniciado por: Kristey em 11 de Abril de 2017, 01:14

Título: Uso de ponteiros
Enviado por: Kristey em 11 de Abril de 2017, 01:14
Boa noite rapaziada.

Estou aqui com um trabalho numa cadeira e a programar veio-me à cabeça algo em que nunca pensei.
Normalmente uso variáveis para manipular variáveis:

Código: [Seleccione]
int a=2, b=3, c=0;

c= a + b

Nunca usei muito ponteiros, e acho que um pouco confuso.
E nunca me falaram das vantagens de o fazer.
Mas se existem devem ser úteis para alguma coisa.
Título: Re: Uso de ponteiros
Enviado por: SerraCabo em 11 de Abril de 2017, 09:43
Têm vantagens e desvantagens. A desvantagem é a de aumentar o nível de dificuldade, embora não muito. A vantagem consiste em evitar que o CPU perca tempo a copiar variáveis para as enviar (para as passar) a outra função. Em vez de passar à função o valor da variável (imagine-se o tempo que perde em passar e receber de volta uma tabela de 1MByte), passa o ponteiro para a variável para que a função trabalhe sobre o que está no endereço.

SC
Título: Re: Uso de ponteiros
Enviado por: jm_araujo em 11 de Abril de 2017, 10:46
(eu chamo tanto ponteiro como apontador, uso os dois no texto)

Na programação corrente surgem cada vez menos (felizmente).

Tirando o uso obvio que em C todos os arrays e strings são ponteiros encapotados, a utilização mais comum é em buffers (circulares ou não), e apontadores para funções de retorno (quando há uma acção tipo interrupção ou género é chamada uma função que passas como parâmetro). Outra utilização que descobri recentemente é em máquinas de estados, em vez de ter uma variável com um ENUM com o estado e um switch, passa-se a ter um apontador para a função a chamar, e a mudança do estado é feita alterando o ponteiro dentro das próprias funções. Parece confuso mas o código fica mais limpo. Tens aqui o artigo onde vi por primeira vez essa técnica: http://hackaday.com/2015/09/04/embed-with-elliot-practical-state-machines/

Hoje em dia não se justifica muito a sua utilização para outros casos. São um risco grande pois tornam o código mais confuso, e se não forem bem utilizados o risco de corromper a memória e estourar o programa é grande. As linguagens por objetos tornaram-nos quase obsoletos, as classes cobrem a maior parte dos casos em que eram usados ponteiros, e provavelmente por isso é que até agora nunca precisaste deles.
Não vás à sua procura, quando fizerem falta eles aparecem naturalmente.
Título: Re: Uso de ponteiros
Enviado por: KammutierSpule em 11 de Abril de 2017, 12:10
Nunca usei muito ponteiros, e acho que um pouco confuso.
E nunca me falaram das vantagens de o fazer.
Mas se existem devem ser úteis para alguma coisa.

Nao especificaste a linguagem, mas se for uma linguagem baixo nivel (Assembly, C, C++, Pascal, etc),
entao nao se trata (principalmente) de ter vantagens ou nao mas sim de: ha coisas que so se podem fazer (em linguagem C) usando ponteiros.
Como dizes, o que fizeste ate hoje so precisaste de usar variaveis, quando tiveres a necessidade usar buffers / arrays / strings, entao vais descobrir a necessidade de usar ponteiros e vais ter mesmo que usar.

Se for linguagens de mais alto nivel ou scriptadas, geralmente usam outras formas (de " mais alto nivel" ) para implementar as funcionalidades necessarias. Penso que ha linguagens que nem suportam o uso de ponteiros de memoria.
Título: Re: Uso de ponteiros
Enviado por: dropes em 11 de Abril de 2017, 15:05
Em Assembly usam-se bastante, a posição de memória acaba por ser imperativa e joga-se um pouco com isso, registos ou acumuladores à mistura, pois não basta lhe dizer que se quer uma variável ou array, a memória de manipulação vai-se imediatamente.

Em liguagens de alto nível já se passa sem nos aperceber-mos dedicando-nos a algo que é mais importante como a sequência do programa sem erros ou atropelamentos despercibidos por colocar um ponteiro fora de parâmetros.
Título: Re: Uso de ponteiros
Enviado por: Njay em 11 de Abril de 2017, 15:57
O livro "The C programming language" do Kernighan & Ritchie (os gajos que inventaram o C) é muito pequeno e o melhor que já vi sobre C. Se procurarem por isto até o encontram logo on-line, já é antigo, não sei se está disponível gratuitamente.
Título: Re: Uso de ponteiros
Enviado por: Kristey em 12 de Abril de 2017, 10:12
Esta duvida veio-me à cabeça, porque estou a programar um robo que tem de navegar e actualizar um mapa de 45 por 45 celulas, enquanto navega calculando o que "ve nos sonares" e actualizando as celular como ocupadas/livres.

O tempo de computação da função de calculo da probabilidade de ocupação é estupidamente elevado, e eu lembrei-me que aceder directamente à memória poderia ser mais rápido.
Título: Re: Uso de ponteiros
Enviado por: Njay em 12 de Abril de 2017, 11:20
"Aceder directamente à memória"? Quer dizer que andas a copiar arrays de 45x45 para dentro de funções e depois para fora? Se for é curioso, porque a única forma que me lembro de passar um array para dentro ou para fora duma função em C é passando um ponteiro (o nome do array é um ponteiro) e copiando a memória. Se quiseres partilhar algum código podemos opinar melhor.
Título: Re: Uso de ponteiros
Enviado por: jm_araujo em 12 de Abril de 2017, 12:05
Cuidado com as falsas optimizações.
Quando escrevo umas linhas de código tenho de lutar para evitar fazer otimizações e tornar o código mais complexo e difícil de ler. Já programei em assembly e a tentação é grande, ficam alguns vícios (como fazer os "for" a diminuir para zero, fazer shifts em vez de divisões/multiplicações, etc).
Hoje em dias os compiladores estão bastante otimizados e fazem esse trabalho por nos, e o poder de computação é tanto que é preferível deixar o código legível. Haverá exceções, mas acho que se deve primeiro fazer bom código, e só depois se tivermos problemas de tempo de execução é que devemos proceder a otimizações, mas nunca à toa ("acho que é dali") mas sempre na sequencia de um profiling.

Quando aos arrays, é como o Njay  disse, por defeito em C passam como ponteiros e em termos práticos já é acesso direto à memória. Um cuidado que podes ter é usar o tipo de variavel mais pequeno possível na sua definição. Se um char for suficiente (1 byte por valor), não vale a pena definir como int (2 ou 4 bytes). Quanto mais memória ocupa o array mais lento pode ser o acesso ao mesmo.

Título: Re: Uso de ponteiros
Enviado por: senso em 12 de Abril de 2017, 13:38
Só com código para ver o que estás ai a fazer, mas isso parece-me algo parecido com o concurso micro-rato da UA, e já houve pessoal que o ganhou a usar uma TI-83 ou TI-89 como cérebro da coisa, tambem tenho um rato arrumado aqui em casa e um atmega128 qualquer coisa com 16KB de RAM a correr a 16Mhz chegou e sobrou para ele andar e se localizar no mapa.
Título: Re: Uso de ponteiros
Enviado por: KammutierSpule em 12 de Abril de 2017, 23:44
Só com código para ver o que estás ai a fazer, mas isso parece-me algo parecido com o concurso micro-rato da UA, e já houve pessoal que o ganhou a usar uma TI-83 ou TI-89 como cérebro da coisa, tambem tenho um rato arrumado aqui em casa e um atmega128 qualquer coisa com 16KB de RAM a correr a 16Mhz chegou e sobrou para ele andar e se localizar no mapa.

A única pessoa/equipa que usou TIs no microrato da UA AFAIK foi a minha e não ganhamos :( (melhor lugar foi em 4° ..so se houve alguem depois disso a usar. )
Quando usei a TI89 foi so para mostrar / desenhar o mapa e fazer debug em dos sensores.
Muito útil pois estavamos numa altura que ainda nao havia Laptops para andar ligado ao robot.. nem havia paginas da internet para ir buscar modulos wireless a preços da china.. e o supplier que usavamos para material era a "TV lar" em Aveiro :/

Mas depois de usar a TI so para debug, ja ficamos em 1° lugar :p
ver links na minha assinatura..

http://sweet.ua.pt/mrluzeiro/azeite4/marco/IMAG0005.JPG
Título: Re: Uso de ponteiros
Enviado por: Njay em 13 de Abril de 2017, 00:35
Tenho uma TI-86... fiz um compilador para um sub-conjunto de C (para ficar on-topic: suportava ponteiros :D ). Aquilo tem um Z80 a 6MHz... o spectrum tem um Z80 a 3.54MHz...
Título: Re: Uso de ponteiros
Enviado por: Kristey em 13 de Abril de 2017, 09:30
Não paso tabelas para dentro de funções manipulo-as no main, por exemplo:

Código: [Seleccione]
for(i=0;i<45;i++){
                for(j=0;j<45;j++){
                    // CALCULAR THETA_map_P E DELTA_P
                    delta_pf=sqrt( (X_sf)*(X_sf) + (Y_sf)*(Y_sf));
                    theta_pf=atan2(Y_sf,X_sf);
                    Pmxy=calcProb(delta_pf,theta_pf,omega,sensor_front,epson);
                    LogMap[i][j]=LogMap[i][j] + log( Pmxy /(1-Pmxy) );

O metodo para construir o mapa que estamos a usar é dividir o mapa por células e avaliar com os sonares se as células estão ocupadas ou não.
Título: Re: Uso de ponteiros
Enviado por: jm_araujo em 13 de Abril de 2017, 10:34
LOL,
Calculas 45*45=2025 raízes quadradas, quadrados *2 , arco-tangentes e logaritmos, nem mostras o que o calcProb  faz, e achas que o problema é no acesso à memória?

Essa é a secção completa ou cortaste partes no meio? é que como está podes tornar isso estupidamente mais rápido se mudares o cálculo do "delta_pf" e do "theta_pf" para fora dos "for".

Se são mesmo necessários tens de dar uma vista de olhos aos teus algoritmos, isso como está nunca vai ser rápido.
Título: Re: Uso de ponteiros
Enviado por: KammutierSpule em 13 de Abril de 2017, 12:00
O tempo de computação da função de calculo da probabilidade de ocupação é estupidamente elevado, e eu lembrei-me que aceder directamente à memória poderia ser mais rápido.

Entao está explicado, mais um caso de tentativa de "early optimizations".
O problema está nos calculos matematicos que estas a fazer.
Nao falaste qual o sistema que estas a fazer esses calculos, mas se for um microcontrolador, floats e funcoes matematicas é algo overkill.

Como diz o jm_araujo ..

o codigo tambem parece cortado, porque ha ai algo que nao me esta a fazer sentido porque os calculos que estao no loop nao dependem das variaveis i e j.. por isso ou falta ai codigo ou esses calculos nao estao a fazer nada dentro do loop.
Título: Re: Uso de ponteiros
Enviado por: senso em 13 de Abril de 2017, 17:57
Isso está estranho..
A nossa aborgagem á coisa foi bem mais simples, sabes que começas num dos lados, logo o nosso rato considerava que estava em 0, 22
A partir dai, usa os sensores, se tem tralha á frente mete 0xF0 em 1,22, se tem coisas á esquerda mete em 0,23 se tem á direite mete em 0,21
Os motores andam o que foi considerado na altura a resolução da matrix(10cm), scanna, preenche, rinse, repeat.
Não estou a entender ai essa trigonometria toda, saber se tens obstáculo á frente, esquerda ou direita deve ser tratado após a aquisição dos dados e filtragem dos mesmo, não no meio da rotina de navegação.