ponteiros como usar e qual a vantagem ??

Software e Hardware para uC PIC

Moderadores: andre_luis, 51, guest2003, Renie

Mensagempor xultz » 07 Abr 2010 14:09

Duas coisas: primeiro, eu jamais diria em minha vida que ponteiros são legais, na melhor das hipóteses um mal necessário.
A linha
while(*p) putchar(*p++);

pode ser traduzida para

while (*p != 0) {
putchar (*p);
p++;
}

que é menos criptográfica que a original, e depois de compilada, o resultado geralmente é exatamente o mesmo (só programadores que gostam de masturbação mental curtem agrupar os comandos desse jeito).
98% das vezes estou certo, e não estou nem aí pros outros 3%.
Avatar do usuário
xultz
Dword
 
Mensagens: 3001
Registrado em: 13 Out 2006 18:41
Localização: Curitiba

Mensagempor msamsoniuk » 07 Abr 2010 17:37

estou apenas seguindo as recomendacoes de estilo indicadas pelos grandes mestres brian kernighan e dennis ritchie! :)

http://www.lysator.liu.se/c/bwk-tutor.html#pointers

Código: Selecionar todos
       strcopy(s,t)
          char *s, *t; {
               while(*t++ = *s++);
       }


show de bola neh?!? :D

xultz escreveu:Duas coisas: primeiro, eu jamais diria em minha vida que ponteiros são legais, na melhor das hipóteses um mal necessário.
A linha
while(*p) putchar(*p++);

pode ser traduzida para

while (*p != 0) {
putchar (*p);
p++;
}

que é menos criptográfica que a original, e depois de compilada, o resultado geralmente é exatamente o mesmo (só programadores que gostam de masturbação mental curtem agrupar os comandos desse jeito).
#innovation #poweredby #riscv https://github.com/darklife/darkriscv
Avatar do usuário
msamsoniuk
Dword
 
Mensagens: 2935
Registrado em: 13 Out 2006 18:04

Mensagempor xultz » 07 Abr 2010 17:51

"This "tutorial'" is presented as a historical document, not as a tutorial."

Bem que dizem que beleza está nos olhos de quem a vê. Principalmente em código escrito de forma críptica, onde só o programador consegue ver a beleza.
98% das vezes estou certo, e não estou nem aí pros outros 3%.
Avatar do usuário
xultz
Dword
 
Mensagens: 3001
Registrado em: 13 Out 2006 18:41
Localização: Curitiba

Mensagempor RobL » 07 Abr 2010 18:59

Voltando a questão original:
nao consigo entender este tal de ponteiros sei que
aponta para um endereço da memoria mas pra que realmente serve
nao uso ponteiros nos meus codigos justamente pq nao entendo a eficiencia q isso pode causar


Mas para que serve os ponteiros ?
O pessoal deixou vários exemplos ai. Tentei mostrar um para desmontar um inteiro e pegar o byte baixo ou o alto.

"nao entendo a eficiencia q isso pode causar"

Se você tentar desmontar um inteiro sem o uso de ponteiro vai gerar muita instrução e looping para resolver. Terá que usar operação logica e rotação, pelo menos. Com ponteiro será somente uma atribuição de valor, mas por dentro (código máquina gerado) o código é pequeno comparado com o código de máquina gerado pelo método sem ponteiros fora os ciclos do looping para deslocamento.
A velocidade com ponteiro será gritantemente maior.

Pergunta que você não fez? Há casos que não dá para fazer sem ponteiros?
Sim, alterar uma variável passada para uma função.
Um exemplo clássico é o da troca de duas variáveis:
Código: Selecionar todos
void troca (a, b)
{
int a,b, temp;
temp = a ;
a = b ;
b = temp ;
}

Teste essa função para trocar a por b que ela não funciona. Não troca de jeito nenhum. Ao final a e b estarão intactos.
Só com ponteiros!!!
RobL
Dword
 
Mensagens: 1546
Registrado em: 20 Fev 2007 17:56

Mensagempor cristian » 07 Abr 2010 19:20

galera valeu pelos tutoriais e dicas ja consegui fazer algumas coisas com ponteiros e RobL vc fez uma pergunta boa

Há casos que não dá para fazer sem ponteiros?
Código: Selecionar todos
void troca (a, b)
{
int a,b, temp;
temp = a ;
a = b ;
b = temp ;
}


FARIA ASSIM para alterar os valores de a e b?

Código: Selecionar todos
void troca (*a, *b)
{
int a,b, temp;
temp = *a ;
*a = *b ;
*b = temp ;
}

troca(&a,&b);



e tem outra O Q O PONTEIRO NAO FAZ( OU SERVE) ????
cristian
Word
 
Mensagens: 570
Registrado em: 03 Nov 2006 08:15
Localização: serrinha-ba

Mensagempor RobL » 07 Abr 2010 19:34

Rapaz!!! Nunca ví um cara aprender ponteiros tão rapidinho. É isso.

Em C o caso genérico que não se faz sem ponteiros é alterar valor de variável passada para funções. Mas isto é tudo em C. Qualquer caso similar é o caso. Strings por exemplo, manobrar sem ponteiro não dá (vetores são ponteiros). Aí você usa ponteiro até sem querer ou saber que são ponteiros.
Estruturas pequenas dá pra não usar ponteiro mas grandes só com ponteiro ou o programa não roda ou não há RAM para ajeitar, etc.
No entanto, vários algoritmos ficarão mais simples e principalmente rápido com ponteiros. C por si só é ponteiro pra todo lado.
Quando você quiser atingir algo dentro de uma variável, string, etc na RAM é com os -> .
RobL
Dword
 
Mensagens: 1546
Registrado em: 20 Fev 2007 17:56

Mensagempor EDSONCAN » 08 Abr 2010 07:15

Código:

void troca (*a, *b)
{
int a,b, temp;
temp = *a ;
*a = *b ;
b = &temp ;
}

troca(&a,&b);
EDSONCAN
Word
 
Mensagens: 876
Registrado em: 11 Out 2006 14:11

Mensagempor cristian » 08 Abr 2010 07:41

porque &temp

nao pode ser temp sem '&'
cristian
Word
 
Mensagens: 570
Registrado em: 03 Nov 2006 08:15
Localização: serrinha-ba

Mensagempor Sergio38br » 08 Abr 2010 07:55

& é usado para passar o endereço para o ponteiro..

[ ]'s
Sergio
Avatar do usuário
Sergio38br
Word
 
Mensagens: 759
Registrado em: 22 Nov 2007 13:39
Localização: São Paulo - SP

Mensagempor EDSONCAN » 08 Abr 2010 08:32

Interessante ponteiros, um errinho tão pequeno iria fazer um estrago tão grande no programa.

Os compiladores ja fazer um monte de errros sozinhos imagine com o usuario cooperando.

Edson
EDSONCAN
Word
 
Mensagens: 876
Registrado em: 11 Out 2006 14:11

Mensagempor cristian » 08 Abr 2010 08:52

mas vc ta passando o endereço de temp para B nao seria o valor de temp para b? b=temp

*b=temp ?
cristian
Word
 
Mensagens: 570
Registrado em: 03 Nov 2006 08:15
Localização: serrinha-ba

Mensagempor EDSONCAN » 08 Abr 2010 09:34

A resposta esta no seu codigo:
maiin(){
in a=1,b=2;
troca(&a,&b);
}
void troca (*a, *b) {
int temp;
temp = *a ;
*a = *b ;
b = &temp ;

}
Quando voce passou os parametros para rotina troca a e b, voce passou os endereços (&), pois a sua rotina trabalha com ponteiros, que apontam para o endereço de memoria das variaveis a e b da rotina main.
Na rotina troca, voce passou o conteudo da memoria do endereço apontado pelo ponteiro a a variavel temp, temp=*a;
Me parece razoavel supor que para o ponteiro b, voce tenha que passar o endereco de temp, voce esta passando o conteudo de temp.
Como regra nunca misture conteudo com endereço de memoria, pelo menos até voce dominar melhor esse assunto.
Editado pela última vez por EDSONCAN em 08 Abr 2010 12:46, em um total de 1 vez.
EDSONCAN
Word
 
Mensagens: 876
Registrado em: 11 Out 2006 14:11

Mensagempor RobL » 08 Abr 2010 10:10

O que se passa dentro do C é que passa a ser o cerne de confusões.

A confusão foi devido ao seu pensamento pelo método indutivo. Só que há uma definição dentro do C de como ele interpreta parâmetros de função passadas como endereço de variáveis (&x) e é limitado somente aos parâmetros da função. O pensamento indutivo foi levado para dentro do bloco, onde não há mais seqüência.

O C, quando numa função, se os parâmetros são passados como endereço, o "programa nativo" vai pegar o valor desse endereço e associa-los às variáveis relativa a esses parâmetros.

Já dentro do bloco da função, as variáveis definidas nesse bloco, o C, não vai interpretar como acima (como parâmetros passados por endereços ). A situação é outra. Se passar um &temp, vai passar o endereço e não o valor contido nesse endereço.
Neste caso o Cristian está correto.
Queremos o valor e não o endereço da variável "temp", dentro do bloco.
Note que temp está definida dentro do bloco e armazenou o valor de uma variável dentro desse bloco.

Em outras palavras, a forma do C interpretar parâmetros passados como endereço de variáveis, nada tem a ver com as variáveis dentro do bloco da função.

Talvez, também, não tenha entendido sua colocação.
RobL
Dword
 
Mensagens: 1546
Registrado em: 20 Fev 2007 17:56

Mensagempor cristian » 08 Abr 2010 12:33

vamos mudar o nome das varaiveis para nao ter duvidas


Código: Selecionar todos
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 ??
cristian
Word
 
Mensagens: 570
Registrado em: 03 Nov 2006 08:15
Localização: serrinha-ba

Mensagempor ivan » 08 Abr 2010 13:11

Código: Selecionar todos
main(){
in a=1,b=2;
troca(&a,&b);
}
void troca (*a, *b) {
int temp;
temp = *a ;
*a = *b ;
b = &temp ;
}


CUIDADO COM ISSO!
b = &temp ;


temp é variável local a função troca. Com o retorno da função esta area de memória pode, e em algum momento vai, ser reutilizada pelo compilador!

O ideal é colocar o conteudo de temp no endereço apontado por b
*b=temp


Outra coisa, se as variáveis são int os parâmetros serão "int *" e, internamente, na funçao a mesma coisa. Não se deve misturar tipos int com unsigned int e assim evitar o casting e warnings desnecessários.

abs.
Editado pela última vez por ivan em 08 Abr 2010 13:24, em um total de 1 vez.
"A mente que se abre a uma nova idéia jamais volta ao seu tamanho original." (Albert Einstein).
Avatar do usuário
ivan
Word
 
Mensagens: 618
Registrado em: 12 Out 2006 21:27

AnteriorPróximo

Voltar para PIC

Quem está online

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

cron

x