Ir para conteúdo

Arquivado

Este tópico foi arquivado e está fechado para novas respostas.

tesla

ponteiros?

Recommended Posts

nunca consegui intender direito os ponteiros então tenho as seguintes dúvidas:

o que são?

para que servem?

exemplo prático de uso dos mesmos.

Compartilhar este post


Link para o post
Compartilhar em outros sites

O próprio nome já diz, vão apontar pra um determinado endereço de memória.

Compartilhar este post


Link para o post
Compartilhar em outros sites

Pra que eles servem: pra ter alguns dados na memória, e variáveis ao invés de representarem diretamente os dados, apontarem pra memória, ou seja, você pode ter várias 'variáveis' apontando pro mesmo dado, assim muda uma, muda todas (útil por exemplo quando você tem várias estruturas, e algum critério para selecionar uma delas para edição), ou então passar um ponteiro pra uma função, assim a função edita os dados apontados pelo ponteiro e assim não precisa retornar a variável editada quando termina a função, entre outras utilidades. Isso vai muito do que você vai fazer.

Exemplo prático tem muitos na net.

Compartilhar este post


Link para o post
Compartilhar em outros sites
Um deles é simular uma passagem por referência.

 

Quando se usa ponteiros se faz passagem por referência. Não tem essa de simular.

Compartilhar este post


Link para o post
Compartilhar em outros sites

Quando se usa ponteiros se faz passagem por referência. Não tem essa de simular.

Até hoje, vários livros sobre C que li alegam que essa leinguagem não possui passagem por referência nativamente, como muitas outras. Por isso o uso de ponteiros simula uma passagem por referência.

Compartilhar este post


Link para o post
Compartilhar em outros sites

Em C, todas as chamadas são por valor. Como vermos no Capítulo 7, é possível simular uma passagem por referência usando operadores de endereço e de ações indiretas.

Fonte: Como Programar em C, de H. M. Deitel, 2a. Edição, Página 131

 

 

EM C, SÓ EXISTE PASSAGEM POR VALOR.

(está em caixa alta)

 

Fonte: Linguagem C, de Luis Damas, 10a. edição, página 209

 

 

Como você já viu nas notas anteriores, em C os argumentos são passados por valor. Uma vez que somente os valores das variáveis são passados, não é possível para a função troca() alterar os valores de a e b porque troca() não sabe onde na memória estas variáveis estão armazenadas. Além disso, troca() não poderia ser escrito usando a sentença return porque só podemos retornar um valor (não dois) através da sentença return.

Fonte: http://www.inf.ufpr.br/nicolui/grad/ci067/...c_coes_Qua.html

 

 

Além disso, alguns professores da UFPR que me deram aula até hoje disseram a mesma coisa.

 

 

Acho que ainda não estou tão louco ou com memória tão fraca... :P http://forum.imasters.com.br/public/style_emoticons/default/closedeyes.gif

Compartilhar este post


Link para o post
Compartilhar em outros sites

Não sei o que os livros e professores quiseram dizer com isso, mas se ponteiros "simulam" passagem por referência, então os ponteiros "simulam" isso muito bem pelo que eu vejo hehhehehehhe

Compartilhar este post


Link para o post
Compartilhar em outros sites

No livro The C Programming Language não existe nenhuma linha falando que ponteiros simulam algo. Os autores citam o Fortran como exemplo de linguagem com passagem por referência. Se você procurar um pouco vai encontrar coisas tipo essas:

 

Fortran 77 uses the so-called call-by-reference paradigm. This means that instead of just passing the values of the function/subroutine arguments (call-by-value), the memory address of the arguments (pointers) are passed instead

 

A coisa é simples: o que tem dentro de um ponteiro? Um endereço, também conhecido como referência. Se você está passando o endereço da variável que quer modificar, é meio nonsense falar que não existe passagem por referência.

 

http://www.macs.hw.ac.uk/~pjbk/pathways/cpp1/node170.html

Compartilhar este post


Link para o post
Compartilhar em outros sites

Afinal, o que é a passagem por referência? É manipulação de memória? Se for, C tem esse recurso.

Não exatamente...

Em várias linguagens você pode escolher se vai passar um parâmetro por referência ou por valor !

No caso de passagem por valor o compilador copia o valor da variável e cria uma nova exatamente igual...Ou seja, mesmo que a variável seja modificada seu valor continuará o mesmo na função anterior

Já no caso da passagem por referência qualquer modificação afetará a variável "principal" !

 

Quanto a ser ou não um recurso nativo da linguagem C é algo mais complicado...

Em algumas linguagens você escreve "ByVal" ou "ByRef" antes do parâmetro para indicar o tipo de passagem de valores...

Se você for parar pra pensar o C não possui isso de forma tão "clara"

Por outro lado, como vocês acham que as linguagens fazem passagem por referência ??

 

É algo difícil de se analisar, ainda mais por ficar só na teoria...

Compartilhar este post


Link para o post
Compartilhar em outros sites

Salve galera! Estava dando uma olhada no post e acabei resolendo mostrar meu ponto de vista quanto ao assunto de passagem por cópia ou por referência no C.

 

Eu, de certa forma concordo quando é dito que a passagem de ponteiros em argumentos na linguagem C são por cópia. Por quê ? Pelo simples fato que você cópia o valor da referência de uma variável pra outra, assim as duas variáveis apontam para o mesmo lugar, porém são variáveis diferentes. Se eu mudo o valor da referência em uma das variáveis, a outra permance inalterada.

 

Agora, tomando como base o C++, que permite a passagem por referência quando o símbolo '&' está presente na assinatura do argumento. As duas variáveis são a mesma, se uma for alterada, a outra também será.

 

Concluindo, existe essa pequena diferença do primeiro caso para o segundo, e eu acho que os autores levam ela em consideração quando fazem a afirmação de que o C simula a passagem por referência com ponteiros, e que de certa forma é uma passagem por cópia e não por referência.

 

Fica ai meu ponto de vista...

Compartilhar este post


Link para o post
Compartilhar em outros sites

Isis, o link que você passou fala de C++. Em C++ é um pouco diferente de C - pelo menos até onde sei acerca de C++ (que não é muita coisa, ainda). Em C, deve-se ter um protótipo assim:

 

void troca(int*, int*);

Ao chamar, tem que especificar o endereço:

troca(&num1, &num2);

O que não ocorre no C++.

Por isso, na minha perspectiva, C++ tem passagem por referência, mas C, não.

 

No PHP também é como C++. Basta declarar uma função assim:

function troca(&num1, &num2)
{
...
}
E chamar assim:

troca(var1, var2);
Isso é passagem por referência.

 

 

 

 

Afinal, o que é a passagem por referência? É manipulação de memória? Se for, C tem esse recurso.

Não exatamente...

Em várias linguagens você pode escolher se vai passar um parâmetro por referência ou por valor !

No caso de passagem por valor o compilador copia o valor da variável e cria uma nova exatamente igual...Ou seja, mesmo que a variável seja modificada seu valor continuará o mesmo na função anterior

Já no caso da passagem por referência qualquer modificação afetará a variável "principal" !

 

Isso eu sei.

A minha pergunta era sobre o conceito de passagem por referência em baixo nível, digamos. O que acontece no código binário, compilado. Afetar variável principal é consequência, quero entender o conceito, o que ocorre nos registradores e na memória. http://forum.imasters.com.br/public/style_emoticons/default/thumbsup.gif

 

 

Compartilho da mesma opinião do Lukas. :)

Compartilhar este post


Link para o post
Compartilhar em outros sites

Beraldo, leia o inicio do link.

 

Values cannot be returned to the calling program via call-by-value parameters because the function only operates on a copy of the value of the parameters, not on the actual parameter itself. If it is required to return a value by a parameter then the address of the actual parameter used in the function call must be passed to the function. The function can then use this address to access the actual parameter in its own space in the calling program and change it if required. Thus what we are passing is a reference to the parameter. Hence call-by-reference parameters.

 

Em C++ também usa-se ponteiros de C. Não criaram a cstdlib à toa.

Compartilhar este post


Link para o post
Compartilhar em outros sites

Ainda estou na dúvida...

 

Vejamos:

 

teste.c

#include <stdio.h>

void troca(int *, int *);

int main()
{
	int x = 7, y = 8;
	
	printf("main : x=%d | y=%d | &x=%p | &y=%p\n", x, y, &x, &y);
	
	troca(&x, &y);
	
	return 0;
}


void troca( int * x, int * y )
{
	int aux = *x;
	*x = *y;
	*y = aux;
	
	printf("troca: x=%d | y=%d | &x=%p | &y=%p\n", *x, *y, &x, &y);
}

teste.cpp

#include <iostream>
using namespace std;


void troca( int&, int& );

int main ()
{
	int x = 7, y = 8;
	
	cout << "main : x=" << x << " | y=" << y << " | &x=" << &x << "  | &y=" << &y << "\n";
	
	troca(x, y);
	
	return 0;
}


void troca( int & x, int & y )
{
	int aux = x;
	x = y;
	y = aux;
	
	cout << "troca: x=" << x << " | y=" << y << " | &x=" << &x << "  | &y=" << &y << "\n";
}

 

Saída da compilação de ambos os programas:

beraldo@metropolis:~/src$ gcc -Wall teste.c -o teste && ./teste

main : x=7 | y=8 | &x=0x7fff3782ec1c | &y=0x7fff3782ec18

troca: x=8 | y=7 | &x=0x7fff3782ebe8 | &y=0x7fff3782ebe0

beraldo@metropolis:~/src$ g++ -Wall teste.cpp -o teste_cpp && ./teste_cpp

main : x=7 | y=8 | &x=0x7fff9a89bc6c | &y=0x7fff9a89bc68

troca: x=8 | y=7 | &x=0x7fff9a89bc6c | &y=0x7fff9a89bc68

beraldo@metropolis:~/src$

No C++, o endereço da memória das variáveis em ambas as funções são os mesmos. Ou seja, está-se alterando a variável propriamente dita. No C, há uma outra variável no escopo local da função, porém ela aponta para o endereço da memória da variável que está na função que a chamou.

 

Por isso ainda acho que C simula a passagem por referência, e C++, não.

Compartilhar este post


Link para o post
Compartilhar em outros sites

#include <stdio.h>
void troca(int *x, int *y) {
  int aux = *x;
  *x = *y;
  *y = aux;
}

int main() {
  int x = 7, y = 8;
  troca(&x,&y);
}

 

GDB:

 

(gdb) r

Starting program: /home/isis/src/Imasters/a.out

 

Breakpoint 6, main () at ref.c : 9

9 int x = 7, y = 8;

(gdb) display x

1: x = -1208028640

(gdb) display y

2: y = 134513769

(gdb) s

 

Breakpoint 7, main () at ref.c : 10

10 troca(&x,&y);

2: x = 7

1: y = 8

(gdb) print &x

$1 = (int *) 0xbffff1e0

(gdb) print &y

$2 = (int *) 0xbffff1dc

(gdb) s

 

Breakpoint 1, troca(x = 0xbffff1e0, y = 0xbffff1dc) at ref.c : 3

3 int aux = *x;

(gdb) s

 

Breakpoint 2, troca(x = 0xbffff1e0, y = 0xbffff1dc) at ref.c : 4

4 *x = *y;

(gdb) s

 

Breakpoint 4, troca(x = 0xbffff1e0, y = 0xbffff1dc) at ref.c : 5

5 *y = aux;

(gdb) c

 

Breakpoint 7, main() at ref.c : 11

11 }

2: y = 7

1: x = 8

(gdb) print &x

$3 = (int *) 0xbffff1e0

(gdb) print &y

$4 = (int *) 0xbffff1dc

 

 

http://www.cs.cf.ac.uk/Dave/C/node10.html

 

What is a Pointer?

 

A pointer is a variable which contains the address in memory of another variable. We can have a pointer to any variable type.

 

When C passes arguments to functions it passes them by value.

 

There are many cases when we may want to alter a passed argument in the function and receive the new value back once to function has finished. Other languages do this (e.g. var parameters in PASCAL). C uses pointers explicitly to do this. Other languages mask the fact that pointers also underpin the implementation of this.

 

DETALHE: Dizer que os argumentos normalmente são passados por valor e não por referência não é a mesma coisa que dizer que não existe passagem por referência. Continuo dizendo que você conseguir passar um endereço de uma variável como argumento e dizer que não existe passagem por referência em C é insano.

Compartilhar este post


Link para o post
Compartilhar em outros sites

When C passes arguments to functions it passes them by value.

 

There are many cases when we may want to alter a passed argument in the function and receive the new value back once to function has finished. Other languages do this (e.g. var parameters in PASCAL). C uses pointers explicitly to do this. Other languages mask the fact that pointers also underpin the implementation of this.

Se isso é realmente fato, eu me rendo, então.

 

 

Mas ainda acho meio estranho.

Por que no C++ eu não posso pegar o endereço real de x e y, já que elas são "ponteiros mascarados"?

 

 

isso quer dizer que o compilador do C++ troca isto:

void troca( int & x, int & y )
{
	int aux = x;
	x = y;
	y = aux;
}

por isto:

void troca( int *x, int *y )
{
	int aux = *x;
	*x = *y;
	*y = aux;
}

??

Compartilhar este post


Link para o post
Compartilhar em outros sites

×

Informação importante

Ao usar o fórum, você concorda com nossos Termos e condições.